惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
Webroot Blog
Webroot Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
Threat Research - Cisco Blogs
V2EX - 技术
V2EX - 技术
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
Recorded Future
Recorded Future
S
Schneier on Security
I
InfoQ
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The GitHub Blog
The GitHub Blog
S
Security @ Cisco Blogs
O
OpenAI News
W
WeLiveSecurity
Vercel News
Vercel News
阮一峰的网络日志
阮一峰的网络日志
Simon Willison's Weblog
Simon Willison's Weblog
人人都是产品经理
人人都是产品经理
Cloudbric
Cloudbric
The Last Watchdog
The Last Watchdog
The Hacker News
The Hacker News
Google Online Security Blog
Google Online Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
GbyAI
GbyAI
NISL@THU
NISL@THU
T
Tailwind CSS Blog
V
Visual Studio Blog
PCI Perspectives
PCI Perspectives
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
D
DataBreaches.Net
B
Blog RSS Feed
N
News and Events Feed by Topic
N
News and Events Feed by Topic
H
Heimdal Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
腾讯CDC
Latest news
Latest news
V
Vulnerabilities – Threatpost
Hacker News: Ask HN
Hacker News: Ask HN
WordPress大学
WordPress大学
V
V2EX
aimingoo的专栏
aimingoo的专栏
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Register - Security
The Register - Security
Help Net Security
Help Net Security

博客园 - ____Justin____

很久没写东西了 中秋!! 开学了!! 生日 学吉他啦 快开学了 人际交往是大学问啊! 2005年国内各大公司的薪酬 DTV VS IPTV 如何删除Windows Media Player VC远程访问数据库 PCR的工作原理 (转)寻找生命小意义——我的价值观和理想 交流贴 爱的格言 4月30写工作总结,不要忘了!!filter数量不对! DSHOW编译错误:strmbasd.lib(dllentry.obj) : error LNK2001: unresolved external symbol "class CFactoryTemplate * g_Templates" (?g_Templates@@3PAVCFactoryTemplate@@A) 新项目,关于NC 工作
根据clsid取得取得filter
____Justin____ · 2005-04-29 · via 博客园 - ____Justin____

  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;
}