Поделиться через


Selecting a Capture Device

 
Microsoft DirectShow 9.0

Selecting a Capture Device

To select a capture device, use the System Device Enumerator, as described in the topic Using the System Device Enumerator. This helper object returns a collection of device monikers, selected by filter category. (A moniker is a COM object that contains information about another object, which enables the application to get information about the object without creating the object itself. Later, the application can use the moniker to create the object. For more information about monikers, see the documentation for IMoniker in the Platform SDK.)

For capture devices, the following categories are relevant.

Category GUID Description
CLSID_AudioInputDeviceCategory Audio capture devices
CLSID_VideoInputDeviceCategory Video capture devices

A device can appear in both categories. The following code creates an enumerator for video capture devices:

ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;

// Create the System Device Enumerator.
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
    CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, 
    reinterpret_cast<void**>(&pDevEnum));
if (SUCCEEDED(hr))
{
    // Create an enumerator for the video capture category.
    hr = pDevEnum->CreateClassEnumerator(
        CLSID_VideoInputDeviceCategory,
        &pEnum, 0);
}

The IEnumMoniker interface returns a list of IMoniker interfaces, each of which represents a device moniker. Typically, you would display a list of devices and enable the user to select one. Call the IMoniker::BindToStorage method, which returns an IPropertyBag interface pointer, and then call IPropertyBag::Read to read properties from the moniker. Properties include the following.

Property Description
FriendlyName The name of the device.
Description A description of the device.
DevicePath A unique string.
  • The FriendlyName property is available for every device. It contains a human-readable name for the device.
  • The Description property is available only for DV and D-VHS/MPEG camcorder devices. For more information, see MSDV Driver and MSTape Driver. If available, it contains a description of the device which is more specific than the FriendlyName property. Typically it includes the vendor name.
  • The DevicePath property is not a human-readable string, but is guaranteed to be unique per device. You can use this property to distinguish between two or more instances of the same model of device.

The following code example shows how to populate a list box with the device names:

HWND hList; // Handle to the list box.
IMoniker *pMoniker = NULL;
while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
{
    IPropertyBag *pPropBag;
    hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, 
        (void**)(&pPropBag));
    if (FAILED(hr))
    {
        pMoniker->Release();
        continue;  // Skip this one, maybe the next one will work.
    } 
    // Find the description or friendly name.
    VARIANT varName;
    VariantInit(&varName);
    hr = pPropBag->Read(L"Description", &varName, 0);
    if (FAILED(hr))
    {
        hr = pPropBag->Read(L"FriendlyName", &varName, 0);
    }
    if (SUCCEEDED(hr))
    {
        // Add it to the application's list box.
        USES_CONVERSION;
        (long)SendMessage(hList, LB_ADDSTRING, 0, 
            (LPARAM)OLE2T(varName.bstrVal));
        VariantClear(&varName); 
    }
    pPropBag->Release();
    pMoniker->Release();
}

When the user selects a device, create the capture filter for the device by calling IMoniker::BindToObject on the moniker. Then call AddFilter to add the filter to the filter graph:

IBaseFilter *pCap = NULL;
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
if (SUCCEEDED(hr))
{
    hr = m_pGraph->AddFilter(pCap, L"Capture Filter");
}