• 根据clsid取得取得filter


      CoInitialize(NULL);

        HRESULT hr;
        IGraphBuilder* pGraphBuilder=NULL;
        CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&pGraphBuilder);

        IBaseFilter*    pMpeg4PSFileStream;
        IBaseFilter*    pMpegDemuxFilter;
        IBaseFilter*    pMpeg4VideoDecoder;
        IBaseFilter*    pOverlayMaxer2;
        IBaseFilter*    pVideoRenderer;
        
        hr=CoCreateInstance(CLSID_Mpeg4PSFileStream, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pMpeg4PSFileStream);
        if (FAILED(hr))
          AfxMessageBox("err create CLSID_Mpeg4PSFileStream");

        hr=CoCreateInstance(CLSID_MpegDemuxFilter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pMpegDemuxFilter);
        if (FAILED(hr))
          AfxMessageBox("err create CLSID_MpegDemuxFilter");

        hr=CoCreateInstance(CLSID_Mpeg4VideoDecoder, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pMpeg4VideoDecoder);
        if (FAILED(hr))
          AfxMessageBox("err create CLSID_Mpeg4VideoDecoder");

        hr=CoCreateInstance(CLSID_OverlayMaxer2, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pOverlayMaxer2);
        if (FAILED(hr))
          AfxMessageBox("err create CLSID_OverlayMaxer2");

        hr=CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pVideoRenderer);
        if (FAILED(hr))
          AfxMessageBox("err create CLSID_VideoRenderer");

        pGraphBuilder->AddFilter(pMpeg4PSFileStream    , NULL);
        pGraphBuilder->AddFilter(pMpegDemuxFilter    , NULL);
        pGraphBuilder->AddFilter(pMpeg4VideoDecoder , NULL);
        pGraphBuilder->AddFilter(pOverlayMaxer2     , NULL);
        pGraphBuilder->AddFilter(pVideoRenderer     , NULL);

        //set the source file
        IFileSourceFilter * pLoader;
        pMpeg4PSFileStream->QueryInterface(IID_IFileSourceFilter, (void **)&pLoader);

        hr=pLoader->Load(L"E:\\temp\\mpeg4_ps.mpg",NULL);
        if (FAILED(hr))
          AfxMessageBox("装载文件出错!");

        //connect filter
        char *strPinName = new char;
        IEnumPins*    EnumPins;
        IPin*        OutPin;
        IPin*        InPin;
        ULONG        fetched;
        PIN_INFO    pinfo;
        
        
        // find source output
        pMpeg4PSFileStream->EnumPins(&EnumPins);
        EnumPins->Reset();
        EnumPins->Next(1, &OutPin, &fetched);    // only 1 pin for source, so we know this is the one we need
        EnumPins->Release();

        // find Demux Filter input
        pMpegDemuxFilter->EnumPins(&EnumPins);
        EnumPins->Reset();
        EnumPins->Next(1, &InPin, &fetched);
        InPin->QueryPinInfo(&pinfo);
        pinfo.pFilter->Release();        // make sure you release the returned IBaseFilter interface
        while (pinfo.dir == PINDIR_OUTPUT)        // check if we have wrong pin (not input pin),2 output pin
        {
            InPin->Release();
            EnumPins->Next(1, &InPin, &fetched);        // if so, get next pin
            InPin->QueryPinInfo(&pinfo);
            pinfo.pFilter->Release();
        }

        // connect -- 1
        pGraphBuilder->Connect(OutPin, InPin);
        InPin->Release();
        OutPin->Release();

        // find Demux Filter output
        EnumPins->Reset();
        EnumPins->Next(1, &OutPin, &fetched);
        OutPin->QueryPinInfo(&pinfo);
        pinfo.pFilter->Release();
        if (pinfo.dir == PINDIR_INPUT)        // check if we have wrong pin (not input pin),only 1 input pin
        {
            InPin->Release();
            EnumPins->Next(1, &OutPin, &fetched);        // if so, get next pin
        }
        EnumPins->Release();

        // find Vweb Mpeg4 Video Decoder input
        pMpeg4VideoDecoder->EnumPins(&EnumPins);
        EnumPins->Reset();
        EnumPins->Next(1, &InPin, &fetched);
        InPin->QueryPinInfo(&pinfo);
        pinfo.pFilter->Release();        // make sure you release the returned IBaseFilter interface
        if (pinfo.dir == PINDIR_OUTPUT)        // check if we have wrong pin (not input pin),only 1 input pin
        {
            InPin->Release();
            EnumPins->Next(1, &InPin, &fetched);        // if so, get next pin
        }

        // connect -- 2
        pGraphBuilder->Connect(OutPin, InPin);
        InPin->Release();
        OutPin->Release();

        // find Vweb Mpeg4 Video Decoder output *****************************************
        EnumPins->Reset();
        EnumPins->Next(1, &OutPin, &fetched);
        OutPin->QueryPinInfo(&pinfo);
        pinfo.pFilter->Release();        // make sure you release the returned IBaseFilter interface
        if (pinfo.dir == PINDIR_INPUT)        // check if we have wrong pin (not input pin),only 1 input pin
        {
            OutPin->Release();
            EnumPins->Next(1, &OutPin, &fetched);        // if so, get next pin
            OutPin->QueryPinInfo(&pinfo);
            pinfo.pFilter->Release();
            WCHAR *s=pinfo.achName;
        }
        EnumPins->Release();

        // find Overlay Mixer2 input
        pOverlayMaxer2->EnumPins(&EnumPins);
        EnumPins->Reset();
        EnumPins->Next(1, &InPin, &fetched);
        InPin->QueryPinInfo(&pinfo);
        pinfo.pFilter->Release();        // make sure you release the returned IBaseFilter interface
        WCHAR *s=pinfo.achName;
        if (pinfo.dir == PINDIR_OUTPUT)        // check if we have wrong pin (not input pin),2 input pin
        {
            InPin->Release();
            EnumPins->Next(1, &InPin, &fetched);        // if so, get next pin
        }
        // connect -- 3
        pGraphBuilder->Connect(OutPin, InPin);
        InPin->Release();
        OutPin->Release();

        // find Overlay Mixer2 output
        EnumPins->Reset();
        EnumPins->Next(1, &OutPin, &fetched);
        OutPin->QueryPinInfo(&pinfo);
        pinfo.pFilter->Release();        // make sure you release the returned IBaseFilter interface
        while (pinfo.dir == PINDIR_INPUT)        // check if we have wrong pin (not input pin),2 input pin
        {
            OutPin->Release();
            EnumPins->Next(1, &OutPin, &fetched);        // if so, get next pin
            OutPin->QueryPinInfo(&pinfo);
            pinfo.pFilter->Release();
            WCHAR *s=pinfo.achName;
        }
        EnumPins->Release();

        // find renderer input
        pVideoRenderer->EnumPins(&EnumPins);
        EnumPins->Reset();
        EnumPins->Next(1, &InPin, &fetched);    // renderer has only 1 pin, so this is the pin we need
        EnumPins->Release();

        // connect -- 4
        pGraphBuilder->Connect(OutPin, InPin);
        InPin->Release();
        OutPin->Release();

        IMediaEvent   *pEvent;
        IMediaControl *pMediaControl;
       // Create the filter graph manager and query for interfaces.
      
        hr=pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
        hr=pGraphBuilder->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

      
        // Run the graph.
        pMediaControl->Run();

        // Wait for completion.
        long evCode;
        pEvent->WaitForCompletion(INFINITE, &evCode);

        // Clean up.
        pMpeg4PSFileStream->Release();
        pMpegDemuxFilter->Release();
        pMpeg4VideoDecoder->Release();
        pOverlayMaxer2->Release();
        pVideoRenderer->Release();

        pMediaControl->Release();
        pEvent->Release();
        pGraphBuilder->Release();

        delete strPinName;
        CoUninitialize();

    长枪大戟的代码都已经包括了,不过听说不在directshow filter里的filter需要枚举才能正常使用,但是我没有试过,不知道是不是,以下代码是枚举捕捉设备的.
    HRESULT CCaptureEx::FindCaptureDevice(IBaseFilter **ppSrcFilter)
    {
        HRESULT hr;
        IBaseFilter * pSrc = NULL;
        CComPtr <IMoniker> pMoniker =NULL;
        ULONG cFetched;

        if (!ppSrcFilter)
            return E_POINTER;
      
        // Create the system device enumerator
        CComPtr <ICreateDevEnum> pDevEnum =NULL;

        hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
                               IID_ICreateDevEnum, (void **) &pDevEnum);
        if (FAILED(hr))
        {
            Msg(TEXT("Couldn't create system enumerator!  hr=0x%x"), hr);
            return hr;
        }

        // Create an enumerator for the video capture devices
        CComPtr <IEnumMoniker> pClassEnum = NULL;

        hr = pDevEnum->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
        if (FAILED(hr))
        {
            //Msg(TEXT("Couldn't create class enumerator!  hr=0x%x"), hr);
            return hr;
        }

        // If there are no enumerators for the requested type, then
        // CreateClassEnumerator will succeed, but pClassEnum will be NULL.
        if (pClassEnum == NULL)
        {
           return E_FAIL;
        }

        // Use the first video capture device on the device list.
        // Note that if the Next() call succeeds but there are no monikers,
        // it will return S_FALSE (which is not a failure).  Therefore, we
        // check that the return code is S_OK instead of using SUCCEEDED() macro.
        if (S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched)))
        {
            // Bind Moniker to a filter object
            hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)&pSrc);
            if (FAILED(hr))
            {
                //Msg(TEXT("Couldn't bind moniker to filter object!  hr=0x%x"), hr);
                return hr;
            }
        }
        else
        {
            //Msg(TEXT("Unable to access video capture device!"));  
            return E_FAIL;
        }

        // Copy the found filter pointer to the output parameter.
        // Do NOT Release() the reference, since it will still be used
        // by the calling function.
        *ppSrcFilter = pSrc;

        return hr;
    }

     / 根据Filter的DisplayName来获取其IMoniker指针,并将IMoniker指针绑定到一个IBaseFilter指针中
    HRESULT CDXGraph::DisplayNameToMoniker(WCHAR * szDisplayName, IBaseFilter ** ppBf)
    {
        if (! mGraph || ! szDisplayName|| ! ppBf)
            return E_POINTER;

        IBaseFilter *pFilter = NULL;

        IBindCtx *pBindCtx;
        HRESULT hr = CreateBindCtx(0, &pBindCtx);
        ULONG chEaten = 0;

        CComPtr <IMoniker> pMoniker = NULL;
        hr = MkParseDisplayName(pBindCtx, szDisplayName, &chEaten, &pMoniker);
        pBindCtx->Release();

        if (SUCCEEDED(hr))
        {
            hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,(void **)&pFilter);
            if (FAILED(hr))
            {
                AfxMessageBox(TEXT("Couldn't bind moniker to filter object!"));
                return E_FAIL;
            }

            // Copy the found filter pointer to the output parameter.
            // Do NOT Release() the reference, since it will still be used
            // by the calling function.
            *ppBf = pFilter;

            return hr;
        }
        return hr;
    }

    //使用xvid mpge4的代码,其中szDisplay存储的是Filter的DisplayName,可以重GraphEdit中查看
        WCHAR szDisplay[] = L"@device:cm:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\\xvid";
        if (SUCCEEDED(mFilterGraph->DisplayNameToMoniker(szDisplay, &pVideoCompressFilter)))
        {
            if (SUCCEEDED(mFilterGraph->GetGraph()->AddFilter(pVideoCompressFilter,L"XVid MPEG-4 Codec")))
            {
                //pVideoCompressFilter->Release();
            }
        }
     

    // 获取视频采集的Capture Source Filter和FriendlyName
    HRESULT CDXGraph::EnumVideoCaptureSource(IBaseFilter ** ppBf, WCHAR* szFilterName)
    {
        if (!mGraph || ! ppBf)
            return E_POINTER;
        // Create the System Device Enumerator.
        IBaseFilter *pFilter = NULL;

        HRESULT hr;
        CComPtr <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 capture Source category.
         CComPtr <IEnumMoniker> pEnumCat = NULL;
        hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);
        if (FAILED(hr))
        {
            AfxMessageBox("Create class enumerator for the video capture Failed.");
            return hr;
        }

        // If there are no enumerators for the requested type, then
        // CreateClassEnumerator will succeed, but pClassEnum will be NULL.
        if (pEnumCat == NULL)
        {
            CString str("");
            str += TEXT("No video capture device was detected.\r\n\r\n");
            str += TEXT("This sample requires a video capture device, such as a USB WebCam,\r\n");
            str += TEXT("This sample requires a video capture device, such as a USB WebCam,\r\n");
            str += TEXT("This sample requires a video capture device, such as a USB WebCam,\r\n");
            str += TEXT("to be installed and working properly.  The sample will now close.");

            AfxMessageBox(str);
            return E_FAIL;
        }

        // Use the first video capture device on the device list.
        // Note that if the Next() call succeeds but there are no monikers,
        // it will return S_FALSE (which is not a failure).  Therefore, we
        // check that the return code is S_OK instead of using SUCCEEDED() macro.
        CComPtr <IMoniker> pMoniker = NULL;
        ULONG cFetched;
        if(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.
                    //使用W2A()、A2W()、T2OLE()、OLE2T()等转换函数需要使用USES_CONVERSION语句
                    USES_CONVERSION;
                    //varName.bstrVal的值为局部变量,需要将数据复制到数组变量中
                    //如果使用指针指向局部变量,则产生错误
                    wsprintfW(szFilterName,varName.bstrVal);
                    //AfxMessageBox(W2A(szFilterName));
                }
                VariantClear(&varName);
                pPropBag->Release();
                // To create an instance of the filter, do the following:

                hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,(void **)&pFilter);
                if (FAILED(hr))
                {
                    AfxMessageBox(TEXT("Couldn't bind moniker to filter object!"));
                    return hr;
                }
            }
            else
            {
                AfxMessageBox(TEXT("Unable to access video capture device!"));  
                return E_FAIL;
            }
            // Copy the found filter pointer to the output parameter.
            // Do NOT Release() the reference, since it will still be used
            // by the calling function.
            *ppBf = pFilter;

            return hr;
        }
        return hr;
    }

  • 相关阅读:
    用数据泵技术实现逻辑备份Oracle 11g R2 数据泵技术详解(expdp impdp)
    用mysql实现类似于oracle dblink的功能
    统计1的个数
    转置字符串,其中单词内的字符需要正常
    经典排序之归并排序
    公共子序列与公共子串问题
    placement new (转)
    数组排序组合最小数字
    实现两个数相加不用四则运算
    操作系统中作业、线程、进程、内存管理、垃圾回收以及缓存等概念
  • 原文地址:https://www.cnblogs.com/justin/p/147409.html
Copyright © 2020-2023  润新知