各位大侠:小弟刚开始学DirectShow,有一问题请教:用
CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0)可以枚举采集卡,但不能枚举压缩卡,请问如何才能枚举出压缩卡。跪求答案!!!!!

解决方案 »

  1.   

    这个问题很难吗??????没有人做过视频压缩卡的DLL开发包的编程吗????
    我在GraphEdit.exe中的Filter中也看不到压缩卡设备,这是为什么???
    请各路大侠帮忙!!!!!!!!!!!!!!!!
      

  2.   

    如果压缩卡的驱动不支持WDM或VFW,还可以使用DirectShow技术进行视频预览和录象吗??
    如果可以,怎么处理???谢谢各位大侠指点!!!
      

  3.   

    1 系统设备枚举器
    系统设备枚举器提供了一个很好的方法根据种类来枚举系统中注册的过虑器。也许枚一种不同的硬件都会有自己的过虑器,或许所有的硬件设备共用同一个filter。这个对于采用WDM驱动程序的硬件很有用。
    系统设备枚举器根据不同的种类创建了一个枚举器,例如,音频压缩,视频捕捉。不同种类的枚举器对于每一种设备返回一个独立的名称(moniker)。种类枚举器自动将相关的即插即用,演播设备包括进来。
    按照下面的步骤使用设备枚举器
    1 创建枚举器组件,CLSID为CLSID_SystemDeviceEnum
    2 指定某一种类型设备,参数CLSID,通过ICreateDevEnum::CreateClassEnumerator获取某一种类的枚举器,这个函数返回一个IEnumMoniker接口指针,如果该种类的空或者不存在,这个方法就返回S_FALSE。因此,当你调用这个函数时一定要检查返回值是否为S_OK,而不要用SUCCEEDED宏。
    3 然后IEnumMoniker::Next枚举每一个moniker。这个方法返回一个IMoniker接口指针。
    4 要想知道设备的名称,可以通过下面的函数IMoniker::BindToStorage
    5 然后利用IMoniker::BindToObject生成绑定道设备上的filter。调用IFilterGraph::AddFilter将filter添加到Graph图中。
     
    // Create the System Device Enumerator.
    HRESULT hr;
    ICreateDevEnum *pSysDevEnum = NULL;
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
        IID_ICreateDevEnum, (void **)&pSysDevEnum);
    if (FAILED(hr))
    {
        return hr;
    }// Obtain a class enumerator for the video compressor category.
    IEnumMoniker *pEnumCat = NULL;
    hr=pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnumCat, 0);if (hr == S_OK) 
    {
        // Enumerate the monikers.
        IMoniker *pMoniker = NULL;
        ULONG cFetched;
        while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
        {
            IPropertyBag *pPropBag;
            hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, 
                (void **)&pPropBag);//知道设备的名称
            if (SUCCEEDED(hr))
            {
                // To retrieve the filter's friendly name, do the following:
                VARIANT varName;
                VariantInit(&varName);
                hr = pPropBag->Read(L"FriendlyName", &varName, 0);
                if (SUCCEEDED(hr))
                {
                    // Display the name in your UI somehow.
                }
                VariantClear(&varName);            // To create an instance of the filter, do the following:
                IBaseFilter *pFilter;
                hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
                    (void**)&pFilter); //生成一个filter绑定到设备上。
                // Now add the filter to the graph. 
                //Remember to release pFilter later.
                pPropBag->Release();
            }
            pMoniker->Release();
        }
        pEnumCat->Release();
    }
    pSysDevEnum->Release();
    在上面我们用IMoniker::BindToObject生成绑定道设备上的filter,当然我们还可以用另外的一种方法来生成绑定到设备上的filter
    利用IMoniker::GetDisplayName得到moniker的名字。然后你把moniker的名字做参数传递给IFilterGraph2::AddSourceFilterForMoniker,就可以创建一个绑定到设备的filter了。在上面我们是调用IMoniker::BindToObject生成filter的,还是上面的简单些。看看代码吧。
    LPOLESTR strName = NULL;
    IBaseFilter pSrc = NULL;
    hr = pMoniker->GetDisplayName(NULL, NULL, &strName);
    if (SUCCEEDED(hr))
    {
        // Query the Filter Graph Manager for IFilterGraph2.
        IFilterGraph2 *pFG2 = NULL;
        hr = pGraph->QueryInterface(IID_IFilterGraph2, (void**)&pFG2);
        if (SUCCEEDED(hr))
        {
            hr = pFG2->AddSourceFilterForMoniker(pMoniker, 0, L"Source", &pSrc);
            pFG2->Release();
        }
        CoTaskMemFree(strName);
    }
    // If successful, remember to release pSrc.