视频渲染器在Directshow中挂起

时间:2011-12-14 06:42:43

标签: directshow

我在Directshow实验中手动创建了一个过滤器图形。在这里,我添加了一个视频源过滤器和一个VMR-9渲染器。渲染器的视频窗口在视频到达文件末尾之前不会移动,最小化,关闭。如果我直接渲染源过滤器,则不会发生这种情况。我需要一个解决方案。

while(1)
{

    IGraphBuilder *pGraph = NULL;
    IMediaControl *pControl = NULL;
    IMediaEvent   *pEvent = NULL;
    IBaseFilter   *pInputFileFilter = NULL;
    IBaseFilter   *pVideoRenderer = NULL;
    IPin          *pFileOut = NULL, *pVidIn = NULL;
    IVideoWindow *VidWindow=NULL;


    string s=openfilename();
    wstring ws;
    ws.assign (s.begin (), s.end ());



     // Initialize the COM library.
     HRESULT hr = CoInitialize(NULL);
     if (FAILED(hr))
     {
         printf("ERROR - Could not initialize COM library");
        return 1;
     }

    // Create the filter graph manager and query for interfaces.
     hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                        IID_IGraphBuilder, (void **)&pGraph);
    if (FAILED(hr))
    {
       printf("ERROR - Could not create the Filter Graph Manager.");
       return 1;
    }

    hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
    hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
    // And add the filter to the filter graph
            // using the member function AddFilter.
    hr = pGraph->AddSourceFilter(ws.c_str(), ws.c_str(), &pInputFileFilter);
    if (SUCCEEDED(hr))
    {

        // Now create an instance of the video renderer
        // and obtain a pointer to its IBaseFilter interface.
        hr = CoCreateInstance(CLSID_VideoMixingRenderer9,NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, 
                          (void **)&pVideoRenderer);
        if (SUCCEEDED(hr)) 
        {
            hr = pGraph->AddFilter(pVideoRenderer, L"Video Renderer");
            //pVideoRenderer->QueryInterface(IID_IVideoWindow,(void**)&VidWindow);
            if (SUCCEEDED(hr)) 
            {
                // Now we need to connect the output pin of the source 
            // to the input pin of the renderer.
            // Obtain the output pin of the source filter.
            // The local function GetPin does this.
                 pFileOut = GetPin(pInputFileFilter, PINDIR_OUTPUT);

                 if (pFileOut != NULL) 
                {  // Is the pin good?

                      // Obtain the input pin of the WAV renderer.
                        // Obtain the input pin of the WAV renderer.
                        pVidIn = GetPin(pVideoRenderer, PINDIR_INPUT);
                        if (pVidIn != NULL) 
                        {  // Is the pin good?

                            // Connect the pins together:
                            // We use the Filter Graph Manager's
                    // member function Connect,
                    // which uses Intelligent Connect.
                    // If this fails, DirectShow couldn't 
                    // render the media file.
                             hr = pGraph->Connect(pFileOut, pVidIn);
                         }
                 }
            }
        }
    }





    if (SUCCEEDED(hr))
    {
        //VidWindow->put_FullScreenMode(OATRUE);
        //VidWindow->put_Owner(NULL);
      // Run the graph.
        hr = pControl->Run();

        if (SUCCEEDED(hr))
        {

            // Wait for completion.
            long evCode;
             pEvent->WaitForCompletion(INFINITE, &evCode);

            // Note: Do not use INFINITE in a real application, because it
         // can block indefinitely.
        }
        hr = pControl->Stop();

    }
     // Now release everything we instantiated--
    // that is, if it got instantiated.
    if(pFileOut) 
    {                // If it exists, non-NULL
        pFileOut->Release();    // Then release it
    }
    if (pVidIn) 
    {
        pVidIn->Release();
    }
    if (pInputFileFilter) 
    {
        pInputFileFilter->Release();
    }
    if (pVideoRenderer)
    {
        pVideoRenderer->Release();
    }

    //VidWindow->Release();
    pControl->Release();
    pEvent->Release();
    pGraph->Release();
    CoUninitialize();

}

1 个答案:

答案 0 :(得分:0)

在片段中查看您的代码:

// Do not use INFINITE in a real application, because it
// can block indefinitely.

这是您需要添加消息循环和分派消息的位置。这将为您的应用程序带来一些期待的生命。您可以轮询完成或注册窗口以在完成此类操作时收到消息。