Filtergraph生成空文件

时间:2014-03-02 13:09:43

标签: c++ directshow

我正在尝试使用c ++建模我在graphedt中创建的工作过滤器图。

这是过滤器图: enter image description here

这是我生成空输出文件的代码。

#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只返回一个引脚(输入引脚)。但我不知道为什么或如何添加输出引脚。

1 个答案:

答案 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错误,这可以帮助您更快地将其绑定!