Enumerating Video Capture Devices

This topic describes how to enumerate the video capture devices on the user's system, and how create an instance of a device.

To enumerate the video capture devices on the system, do the following:

  1. Call MFCreateAttributes to create an attribute store. This function receives an IMFAttributes pointer.
  2. Call IMFAttributes::SetGUID to set the MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE attribute. Set the attribute value to MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID.
  3. Call MFEnumDeviceSources. This function receives an array of IMFActivate pointers and the array size. Each pointer represents a distinct video capture device.

To create an instance of a capture device, call IMFActivate::ActivateObject to get a pointer to the IMFMediaSource interface.

Note

Windows allows users to grant or deny access to the device's camera in the Windows Settings app, under Privacy & Security -> Camera. When initializing the capture device, apps should check whether they have access to the camera and handle the case where access is denied by the user. For more information, see Handle the Windows camera privacy setting.

The following code shows these steps:

HRESULT CreateVideoDeviceSource(IMFMediaSource **ppSource)
{
    *ppSource = NULL;

    IMFMediaSource *pSource = NULL;
    IMFAttributes *pAttributes = NULL;
    IMFActivate **ppDevices = NULL;

    // Create an attribute store to specify the enumeration parameters.
    HRESULT hr = MFCreateAttributes(&pAttributes, 1);
    if (FAILED(hr))
    {
        goto done;
    }

    // Source type: video capture devices
    hr = pAttributes->SetGUID(
        MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, 
        MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
        );
    if (FAILED(hr))
    {
        goto done;
    }

    // Enumerate devices.
    UINT32 count;
    hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
    if (FAILED(hr))
    {
        goto done;
    }

    if (count == 0)
    {
        hr = E_FAIL;
        goto done;
    }

    // Create the media source object.
    hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(&pSource));
    if (FAILED(hr))
    {
        goto done;
    }

    *ppSource = pSource;
    (*ppSource)->AddRef();

done:
    SafeRelease(&pAttributes);

    for (DWORD i = 0; i < count; i++)
    {
        SafeRelease(&ppDevices[i]);
    }
    CoTaskMemFree(ppDevices);
    SafeRelease(&pSource);
    return hr;
}

After you create media source, release the interface pointers and free the memory for the array:

    SafeRelease(&pAttributes);

    for (DWORD i = 0; i < count; i++)
    {
        SafeRelease(&ppDevices[i]);
    }
    CoTaskMemFree(ppDevices);

Video Capture