-2

THe filter graphs renderer method takes a reference of a output pin. But the FileWriter Filter has no output pin. So how do i make the filter graph render itself?

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

This is my code that builds the graph with its filters:

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();

        }
    }






}

This compiles and runs fine but doesn't produce any file.

Luke
  • 5,771
  • 12
  • 55
  • 77
  • Please Luke, stop posting thousands of basic questions about DirectShow. Read a book or a [tutorial](http://stackoverflow.com/questions/2077997/where-can-i-find-a-thorough-directshow-tutorial) about how DirectShow works. For basic questions try a directshow mailinglist or chat or forum. – CPlusSharp Mar 03 '14 at 15:31

4 Answers4

1

Pins connect filter to enable them pass data one to another. File writer does not have anything to stream data to - instead it just writers to file. Hence, no output pin.

To specify the file name you use IFileSinkFilter::SetFileName interface (see When changing a file name, Recording Start is overdue for 3 seconds. OnTimer code snippet using it).

Community
  • 1
  • 1
Roman R.
  • 68,205
  • 6
  • 94
  • 158
1

So if Im understanding correctly you want to render to screen AND render to file.

To do this you need to place an infinite pin tee in between your AVI splitter and your AVI mux. 1 output of the tee would continue to go to the AVI Mux and you can use another to stream to a video renderer (e.g a VMR9).

Goz
  • 61,365
  • 24
  • 124
  • 204
0

Please read in MSDN what Render method does, it's not what you think. The closest thing to your idea is RenderStream (from a bit different interface, look it up) with the FileWriter in its last parameter. But please learn some DirectShow basics first.

Dee Mon
  • 1,016
  • 6
  • 7
-1

First, FileWriter Filter only has input pin because it receives data and writes to a file.

Second, if you want to play a file you should use File Source (Async.) filter. So, create a instance of File Source (Async.), get it's output pin and pass to

pGraph->Render(FileSourceOutputPin);

Third, alternatively you can render file like this:

pGraph->RenderFile("C:\\test.avi", "");
Mustafa Chelik
  • 2,113
  • 2
  • 17
  • 29