游戏开发者社区

[其他] 创建一个directshow应用程序一

查看: 2125|回复: 1

威望
4 点
义气
6 点

CDC广州-灿烂笑脸

发表于 2015-1-17 23:56:25 |显示全部楼层

                                                                    <div class="ad_1">
                                               
                        </div>
                                       
                                                <p style="text-align: left; text-indent: 2em"><strong>创建dshow应用程序一般有三个步骤:</strong><br/><br/></p>
<p style="text-align: left; text-indent: 2em">1.创建一个Filter Graph Manager组件。<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IGraphBuilder * pGraph = NULL;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,<br/><br/></p>
<p style="text-align: left; text-indent: 2em">CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph);,<br/><br/></p>
<p style="text-align: left; text-indent: 2em">2.根据实际的应用,创建一个filter链,比如播放一个本地文件,最简单快速的代码如下:<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = pGraph-&gt;RenderFile(L”path”, NULL);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">3.调用Filter Graph Manager上的各个接口进行控制,并且完成Filter Graph Manager与应用程序的交互,比如调用IMediaControl接口方法控制Filter Graph的状态转换。<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IMediaControl *pControl = NULL;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = pGraph-&gt;QueryInterface(IID_IMediaControl, (void**)pControl);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = pControl-&gt;Run();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">通用的Filter Graph构建技术:<br/><br/></p>
<p style="text-align: left; text-indent: 2em"><strong>1.加入一个指定CLSID的Filter</strong><br/><br/></p>
<p style="text-align: left; text-indent: 2em">给定了一个Filter的CLSID,就可以调用CoCreateInstance来创建它。并使用IFilterGraph::AddFilter接口将其加入到Filter Graph中。<br/><br/></p>
<p style="text-align: left; text-indent: 2em">代码如下:<br/><br/></p>
<p style="text-align: left; text-indent: 2em">HRESULT AddFilterByCLSID(<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IGraphBuilder *pGraph,// Pointer to the Filter Graph Manager.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">const GUID& clsid,// CLSID of the filter to create.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">LPCWSTR wszName,// A name for the filter.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IBaseFilter **ppF)// Receives a pointer to the filter.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (!pGraph || ! ppF) return E_POINTER;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">*ppF = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IBaseFilter *pF = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">HRESULT hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER,<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IID_IBaseFilter, reinterpret_cast&lt;void**&gt;(&pF));<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (SUCCEEDED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = pGraph-&gt;AddFilter(pF, wszName);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (SUCCEEDED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">*ppF = pF;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">else<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pF-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return hr;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">要在Filter Graph中加入一个AVI Mux Filter<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IBaseFilter *pMux;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = AddFilterByCLSID(pGraph, CLSID_AviDest, L”AVI Mux”, &pMux);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if(SUCCEEDED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">/*…*/<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pMux-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em"><strong>2.得到Filter上的未连接的Pin</strong><br/><br/></p>
<p style="text-align: left; text-indent: 2em">当在程序中连接filter的时候,首先要取得filter上未连接的Pin或者输出Pin。方法是,枚举Filter上的所有的Pin,调用IPin:ueryDirection查询Pin的方向。然后调用IPin::ConnectedTo查看Pin的连接状态。<br/><br/></p>
<p style="text-align: left; text-indent: 2em">HRESULT GetUnconnectedPin(<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IBaseFilter *pFilter, // Pointer to the filter.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IN_DIRECTION PinDir, // Direction of the pin to find.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IPin **ppPin) // Receives a pointer to the pin.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">*ppPin = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IEnumPins *pEnum = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IPin *pPin = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">HRESULT hr = pFilter-&gt;EnumPins(&pEnum);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (FAILED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return hr;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">while (pEnum-&gt;Next(1, &pPin, NULL) == S_OK)<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IN_DIRECTION ThisPinDir;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pPin-&gt;QueryDirection(&ThisPinDir);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (ThisPinDir == PinDir)<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IPin *pTmp = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = pPin-&gt;ConnectedTo(&pTmp);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (SUCCEEDED(hr))// Already connected, not the pin we want.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pTmp-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">else// Unconnected, this is the pin we want.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pEnum-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">*ppPin = pPin;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return S_OK;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pPin-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pEnum-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// Did not find a matching pin.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return E_FAIL;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">比如现在要得到一个未连接的输出Pin<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IPin *pOut = NULL;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">HRESULT hr = GetUnConnectedPin(pFilter, PINDIR_OUTPUT, &pOut);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if(SUCCEEDED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">/*…*/<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pOut-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em"><strong>3.连接两个Filter</strong><br/><br/></p>
<p style="text-align: left; text-indent: 2em">Filter Graph中连接两个Filter的函数有IFilterGraph::ConnectDirect和IFilterGraph::Connect<br/><br/></p>
<p style="text-align: left; text-indent: 2em">HRESULT ConnectFilters(<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IGraphBuilder *pGraph, // Filter Graph Manager.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IPin *pOut,// Output pin on the upstream filter.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IBaseFilter *pDest)// Downstream filter.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if ((pGraph == NULL) || (pOut == NULL) || (pDest == NULL))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return E_POINTER;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">#ifdef debug<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IN_DIRECTION PinDir;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pOut-&gt;QueryDirection(&inDir);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">_ASSERTE(PinDir == PINDIR_OUTPUT);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">#endif<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">// Find an input pin on the downstream filter.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IPin *pIn = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">HRESULT hr = GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (FAILED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return hr;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// Try to connect them.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = pGraph-&gt;Connect(pOut, pIn);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pIn-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return hr;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em"><strong>不同参数的ConnectFilters 的函数重载形式:</strong><br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">HRESULT ConnectFilters(<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IGraphBuilder *pGraph, <br/><br/></p>
<p style="text-align: left; text-indent: 2em">IBaseFilter *pSrc, <br/><br/></p>
<p style="text-align: left; text-indent: 2em">IBaseFilter *pDest)<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if ((pGraph == NULL) || (pSrc == NULL) || (pDest == NULL))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return E_POINTER;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">// Find an output pin on the first filter.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IPin *pOut = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">HRESULT hr = GetUnconnectedPin(pSrc, PINDIR_OUTPUT, &pOut);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (FAILED(hr)) <br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return hr;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = ConnectFilters(pGraph, pOut, pDest);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pOut-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return hr;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}例如现在要加入一个AVI Mux Filter 和 一个File Writer Filter,然后将他们相连起来。代码如下:<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IBaseFilter *pMux, *pWrite;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">hr = AddFilterByCLSID(pGraph, CLSID_AviDest, L”AVI Mux”, &pMux);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if(SUCCEEDED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = AddFilterByCLSID(pGraph, CLSID_FileWriter, L”File Writer”, &pWrite);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if(SUCCEEDED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = ConnectFilters(pGraph, pMux, pWrite);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pWrite-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pMux-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">4.查找Filter和Pin上的接口<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">我们需要枚举Graph中的所有的Filter,或者枚举Filter上所有的Pin,一个一个的找接口。<br/><br/></p>
<p style="text-align: left; text-indent: 2em">//查找Filter上实现的某个接口<br/><br/></p>
<p style="text-align: left; text-indent: 2em">HRESULT FindFilterInterface(<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IGraphBuilder *pGraph, // Pointer to the Filter Graph Manager.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">REFGUID iid, // IID of the interface to retrieve.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">void **ppUnk)// Receives the interface pointer.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (!pGraph || !ppUnk) return E_POINTER;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">HRESULT hr = E_FAIL;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IEnumFilters *pEnum = NULL;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IBaseFilter *pF = NULL;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (FAILED(pGraph-&gt;EnumFilters(&pEnum)))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return E_FAIL;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// Query every filter for the interface.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">while (S_OK == pEnum-&gt;Next(1, &pF, 0))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = pF-&gt;QueryInterface(iid, ppUnk);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pF-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (SUCCEEDED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">break;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pEnum-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return hr;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">//查找给定filter的Pin上实现的某个接口<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">HRESULT FindPinInterface(<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IBaseFilter *pFilter,// Pointer to the filter to search.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">REFGUID iid, // IID of the interface.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">void **ppUnk)// Receives the interface pointer.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (!pFilter || !ppUnk) return E_POINTER;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">HRESULT hr = E_FAIL;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IEnumPins *pEnum = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (FAILED(pFilter-&gt;EnumPins(&pEnum)))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return E_FAIL;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// Query every pin for the interface.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IPin *pPin = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">while (S_OK == pEnum-&gt;Next(1, &pPin, 0))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = pPin-&gt;QueryInterface(iid, ppUnk);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pPin-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (SUCCEEDED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">break;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pEnum-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return hr;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}//综合了FindFilterInterface和FindPinInterfae两个函数的综合功能<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">HRESULT FindInterfaceAnywhere(<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IGraphBuilder *pGraph, <br/><br/></p>
<p style="text-align: left; text-indent: 2em">REFGUID iid, <br/><br/></p>
<p style="text-align: left; text-indent: 2em">void **ppUnk)<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (!pGraph || !ppUnk) return E_POINTER;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">HRESULT hr = E_FAIL;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IEnumFilters *pEnum = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (FAILED(pGraph-&gt;EnumFilters(&pEnum)))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return E_FAIL;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// Loop through every filter in the graph.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IBaseFilter *pF = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">while (S_OK == pEnum-&gt;Next(1, &pF, 0))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = pF-&gt;QueryInterface(iid, ppUnk);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (FAILED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// The filter does not expose the interface, but maybe<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// one of its pins does.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = FindPinInterface(pF, iid, ppUnk);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pF-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (SUCCEEDED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">break;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pEnum-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return hr;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">比如现在通过IGraphBuilder::RenderFile函数,构建了一条内含DV格式数据的AVI文件的回放链路。我们想要得到其中DV视频解码Filter上的IIPDVDec接口,以设置DV解码输出的图像大小为原始图像的四分之一,代码如下:<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = pGraph-&gt;RenderFile(L”C:\\example.avi”, 0);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">if(SUCCEEDED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IIPDVDec* pDvDec;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = FindFilterInterface(pGraph, IID_IIPDVDec, (void**)&pDvDec);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if(SUCCEEDED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">……..<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em"><strong>5.遍历Filter链路</strong><br/><br/></p>
<p style="text-align: left; text-indent: 2em">给定一个Filter链路上的某个Filter,我们可以向上或者向下得到所有的其他的Filter。<br/><br/></p>
<p style="text-align: left; text-indent: 2em">HRESULT GetNextFilter(<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IBaseFilter *pFilter, // Pointer to the starting filter<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IN_DIRECTION Dir,// Direction to search (upstream or downstream)<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IBaseFilter **ppNext) // Receives a pointer to the next filter.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (!pFilter || !ppNext) return E_POINTER;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">
<p style="text-align: left; text-indent: 2em">IEnumPins *pEnum = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IPin *pPin = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">HRESULT hr = pFilter-&gt;EnumPins(&pEnum);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (FAILED(hr)) return hr;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">while (S_OK == pEnum-&gt;Next(1, &pPin, 0))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// See if this pin matches the specified direction.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IN_DIRECTION ThisPinDir;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = pPin-&gt;QueryDirection(&ThisPinDir);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (FAILED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// Something strange happened.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = E_UNEXPECTED;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pPin-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">break;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (ThisPinDir == Dir)<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// Check if the pin is connected to another pin.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IPin *pPinNext = 0;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = pPin-&gt;ConnectedTo(&pPinNext);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (SUCCEEDED(hr))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// Get the filter that owns that pin.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">IN_INFO PinInfo;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">hr = pPinNext-&gt;QueryPinInfo(&inInfo);<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pPinNext-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pPin-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pEnum-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">if (FAILED(hr) || (PinInfo.pFilter == NULL))<br/><br/></p>
<p style="text-align: left; text-indent: 2em">{<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// Something strange happened.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return E_UNEXPECTED;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// This is the filter we’re looking for.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">*ppNext = PinInfo.pFilter; // Client must release.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return S_OK;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pPin-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>
<p style="text-align: left; text-indent: 2em">pEnum-&gt;Release();<br/><br/></p>
<p style="text-align: left; text-indent: 2em">// Did not find a matching filter.<br/><br/></p>
<p style="text-align: left; text-indent: 2em">return E_FAIL;<br/><br/></p>
<p style="text-align: left; text-indent: 2em">}<br/><br/></p>

                                                                                                        <p>转自:<a href="http://www.yxkfw.com/?p=55882" target="_blank">http://www.yxkfw.com/?p=55882</a></p>

举报

Rank: 3Rank: 3Rank: 3

威望
0 点
义气
0 点
发表于 2015-5-20 16:50:42
虽然不明,但觉得很厉害

举报

您需要登录后才可以回帖 登录 | 注册

关闭

江湖传闻

手机版|9RIA.com ( 京ICP备11007422号-2 

GMT+8, 2017-1-22 01:30 , Processed in 0.122800 second(s), 17 queries .

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部