我正在尝试使用c ++建模我在graphedt中创建的工作过滤器图。
这是过滤器图:
这是我生成空输出文件的代码。
#include <dshow.h>
#include "MyFilter.h"
IPin *GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir)
{
BOOL bFound = FALSE;
IEnumPins *pEnum;
IPin *pPin;
pFilter->EnumPins(&pEnum);
while (pEnum->Next(1, &pPin, 0) == S_OK)
{
PIN_DIRECTION PinDirThis;
pPin->QueryDirection(&PinDirThis);
if (bFound = (PinDir == PinDirThis))
break;
pPin->Release();
}
pEnum->Release();
return (bFound ? pPin : 0);
}
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
)
{
//INIT GRAPH
CoInitialize(NULL);
IGraphBuilder* graphBuilder = NULL;
IMediaControl* mediaControl = NULL;
IMediaEvent* mediaEvent = NULL;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IFilterGraph, (void **)&graphBuilder);
graphBuilder->QueryInterface(IID_IMediaControl, (void **)&mediaControl);
graphBuilder->QueryInterface(IID_IMediaEvent, (void **)&mediaEvent);
//SOURCE FILTER
IBaseFilter* pSource;
graphBuilder->AddSourceFilter(L"C:\\TEMP\\Zim.avi", NULL, &pSource);
IPin* sourceOUT = GetPin(pSource, PINDIR_OUTPUT);
//AVI SPLITTER
IBaseFilter* aviSplitter = NULL;
hr = CoCreateInstance(CLSID_AviSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&aviSplitter);
IPin* aviSplitIN = GetPin(aviSplitter, PINDIR_INPUT);
IPin* aviSplitOUT = GetPin(aviSplitter, PINDIR_OUTPUT);
graphBuilder->AddFilter(aviSplitter, L"AVI_SPLITTER");
graphBuilder->Connect(sourceOUT, aviSplitIN);
//AVI MUX
IBaseFilter* decompressor = NULL;
hr = CoCreateInstance(CLSID_AviDest, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&decompressor);
graphBuilder->AddFilter(decompressor, L"Decoder");
IPin* decoderIN = GetPin(decompressor, PINDIR_INPUT);
IPin* DecoderOUT = GetPin(decompressor, PINDIR_OUTPUT);
graphBuilder->Connect(aviSplitOUT, decoderIN);
//File Writer
IBaseFilter *filewriter = NULL;
IFileSinkFilter* filesink = NULL;
hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&filewriter);
filewriter->QueryInterface(IID_IFileSinkFilter, (void **)&filesink);
graphBuilder->AddFilter(filewriter, L"Filewriter");
IPin* filewriterIN = GetPin(filewriter, PINDIR_INPUT);
graphBuilder->Connect(DecoderOUT, filewriterIN);
filesink->SetFileName(L"C:\\TEMP\\myfilteroutput123.avi", NULL);
hr = mediaControl->Run();
if (SUCCEEDED(hr))
{
long evCode;
mediaEvent->WaitForCompletion(INFINITE, &evCode);
}
CoUninitialize();
}
编辑:问题似乎是avisplitter只返回一个引脚(输入引脚)。但我不知道为什么或如何添加输出引脚。
答案 0 :(得分:0)
自从我做DirectShow以来已经有一段时间但我似乎记得AVI Splitter在连接至少一个输入引脚之前没有输出引脚。
因此,请尝试执行以下操作:
IPin* aviSplitIN = GetPin(aviSplitter, PINDIR_INPUT);
graphBuilder->AddFilter(aviSplitter, L"AVI_SPLITTER");
graphBuilder->Connect(sourceOUT, aviSplitIN);
IPin* aviSplitOUT = GetPin(aviSplitter, PINDIR_OUTPUT);
我很确定这会按预期工作。
另外一点,请务必查看HRESULT
。从HRESULT
返回的Connect
会告诉您很多关于您所遭受的错误的信息。在传递NULL引脚的情况下,您将收到E_POINTER
错误,这可以帮助您更快地将其绑定!