如何使用FileWriter过滤器呈现filtergraph

时间:2014-03-01 19:36:49

标签: c++ directshow

滤镜图渲染器方法采用输出引脚的参考。但FileWriter过滤器没有输出引脚。那么如何使滤镜图形呈现呢?

HRESULT hr = pGraph->Render(FilefilterOutPin); //File Writer does not offer an outputpin

这是我用其过滤器构建图表的代码:

void static SaveFile()
{


    CoInitialize(NULL);
    IGraphBuilder *pGraph = NULL;
    IMediaControl *pControl = NULL;
    IMediaEvent *pEvent = NULL;

    HRESULT myhr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
        IID_IFilterGraph, (void **) &pGraph);

    pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
    pGraph->QueryInterface(IID_IMediaEvent, (void **) &pEvent);

    IBaseFilter *pFileWritter;
    IFileSinkFilter* fileSInk = NULL;
    CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **) &pFileWritter);
    pFileWritter->QueryInterface(IID_IFileSinkFilter, (void **) &fileSInk);



    fileSInk->SetFileName(L"C:\\TEMP\\yc1.avi", NULL);

    //get source out pin
    IBaseFilter *pSource;
    IPin* SourcePin;
    pGraph->AddSourceFilter(L"C:\\TEMP\\sample.avi", L"sample", &pSource);
    SourcePin = GetPin(pSource, PINDIR_OUTPUT);

    //AVI SPLITTER
    IBaseFilter *aviSplitter;
    CoCreateInstance(CLSID_AviSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **) &aviSplitter);
    pGraph->AddFilter(aviSplitter, L"AVI-Splitter");
    IPin* avisplitIn;
    IPin* avisplitOut;

    avisplitIn = GetPin(aviSplitter, PINDIR_INPUT);
    avisplitOut = GetPin(aviSplitter, PINDIR_OUTPUT);
    pGraph->Connect(SourcePin, avisplitIn);

    //END


    //MyFilter//
    IBaseFilter *myFilter;

    CoCreateInstance(CLSID_MyFilter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **) &myFilter);

    IMyFilter *myfilterinterface;
    myFilter->QueryInterface(IID_IMyFilter, (void **) &myfilterinterface);
    myfilterinterface->StartRecording();
    pGraph->AddFilter(myFilter, L"MyFilter");
    IPin* myInputPin;
    IPin* myOutPutPin;
    myInputPin = myfilterinterface->GetMyPin(0);
    myOutPutPin = myfilterinterface->GetMyPin(3);

    pGraph->Connect(avisplitOut, myInputPin);
    //END//



    ///AVMUX
    IBaseFilter *avmux;
    CoCreateInstance(CLSID_AVIDec, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **) &avmux);
    IPin* avmuxIn;
    IPin* avmuxOut;
    avmuxIn = GetPin(avmux, PINDIR_INPUT);
    avmuxOut = GetPin(avmux, PINDIR_OUTPUT);
    pGraph->AddFilter(avmux, L"AVmux");
    pGraph->Connect(myOutPutPin, avmuxIn);


    //END
    //get writer inpin
    IPin *writerPin;
    writerPin = GetPin(pFileWritter, PINDIR_INPUT);


    //connect pins
    pGraph->Connect(SourcePin, writerPin);

    //render
    HRESULT hr S_OK;
    if(SUCCEEDED(hr))
    {
        hr = pControl->Run();
        if(SUCCEEDED(hr))
        {
            long evCode;
            pEvent->WaitForCompletion(INFINITE, &evCode);
            myfilterinterface->StopRecording();
            myFilter->Release();
                   CoUninitialize();

        }
    }






}

编译并运行正常,但不会生成任何文件。

4 个答案:

答案 0 :(得分:1)

引脚连接过滤器以使它们能够将数据传递到另一个。文件编写器没有任何东西可以将数据流传输到 - 而只是文件编写者。因此,没有输出引脚。

要指定文件名,请使用IFileSinkFilter::SetFileName界面(请参阅When changing a file name, Recording Start is overdue for 3 seconds. OnTimer代码段)。

答案 1 :(得分:0)

因此,如果我正确理解你想要渲染到屏幕并渲染到文件。

为此,您需要在AVI分离器和AVI多路复用器之间放置infinite pin tee。 tee的1个输出将继续转到AVI Mux,你可以使用另一个输出到视频渲染器(例如VMR9)。

答案 2 :(得分:0)

请在MSDN中阅读Render方法的功能,这不是您的想法。与你的想法最接近的是RenderStream(来自一个不同的界面,查找它)与FileWriter的最后一个参数。但请先了解一些DirectShow基础知识。

答案 3 :(得分:-1)

首先,FileWriter Filter只有输入引脚,因为它接收数据并写入文件。

其次,如果要播放文件,则应使用文件源(异步。)过滤器。因此,创建一个File Source(Async。)实例,获取它的输出引脚并传递给

pGraph->Render(FileSourceOutputPin);

第三,或者您可以像这样渲染文件:

pGraph->RenderFile("C:\\test.avi", "");