代码之家  ›  专栏  ›  技术社区  ›  Ben Straub

iMovieControl::在Windows XP上运行失败?

  •  0
  • Ben Straub  · 技术社区  · 15 年前

    实际上,它只在第二次被调用时失败。我正在使用无窗口控件播放视频内容,在该控件仍在屏幕上时,正在播放的视频可能会发生更改。一旦第一次建立图形,我们就通过停止播放来切换媒体,替换 SOURCE 过滤,然后再次运行图表。这在Vista下工作正常,但是在XP上运行时,第二个调用 Run() 收益率 E_UNEXPECTED .

    初始化过程如下:

    // Get the interface for DirectShow's GraphBuilder
    mGB.CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER);
    
    // Create the Video Mixing Renderer and add it to the graph
    ATL::CComPtr<IBaseFilter> pVmr;
    pVmr.CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC);
    mGB->AddFilter(pVmr, L"Video Mixing Renderer 9");
    
    // Set the rendering mode and number of streams
    ATL::CComPtr<IVMRFilterConfig9> pConfig;
    pVmr->QueryInterface(IID_IVMRFilterConfig9, (void**)&pConfig);
    pConfig->SetRenderingMode(VMR9Mode_Windowless);
    pVmr->QueryInterface(IID_IVMRWindowlessControl9, (void**)&mWC);
    

    这就是我们决定放电影时要做的。 RenderFileToVideoRenderer 是从 dshowutil.h 在DirectShow示例区域中。

    // Release the source filter, if it exists, so we can replace it.
    IBaseFilter *pSource = NULL;
    if (SUCCEEDED(mpGB->FindFilterByName(L"SOURCE", &pSource)) && pSource)
    {
        mpGB->RemoveFilter(pSource);
        pSource->Release();
        pSource = NULL;
    }
    
    // Render the file.
    hr = RenderFileToVideoRenderer(mpGB, mPlayPath.c_str(), FALSE);
    
    // QueryInterface for DirectShow interfaces
    hr = mpGB->QueryInterface(&mMC);
    hr = mpGB->QueryInterface(&mME);
    hr = mpGB->QueryInterface(&mMS);
    
    // Read the default video size
    hr = mpWC->GetNativeVideoSize(&lWidth, &lHeight, NULL, NULL);
    if (hr != E_NOINTERFACE)
    {
        if (FAILED(hr))
        {
            return hr;
        }
    
        // Play video at native resolution, anchored at top-left corner.
        RECT r;
        r.left = 0;
        r.top = 0;
        r.right = lWidth;
        r.bottom = lHeight;
        hr = mpWC->SetVideoPosition(NULL, &r);
    }
    
    // Run the graph to play the media file
    if (mMC)
    {
        hr = mMC->Run();
        if (FAILED(hr))
        {
            // We get here the second time this code is executed.
            return hr;
        }
        mState = Running;
    }
    
    if (mME)
    {
        mME->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0);
    }
    

    有人知道这是怎么回事吗?

    2 回复  |  直到 15 年前
        1
  •  0
  •   Shay Erlichmen    15 年前
    1. 尝试呼叫 IMediaControl::StopWhenReady 删除源筛选器之前。
    2. 您什么时候直接调用QueryInterface?您可以使用ccomqiptr<gt;为您扭曲qi。这样,您就不必调用release,因为它将被自动调用。
      语法如下: CComPtr<IMediaControl> mediaControl = pGraph;
    3. 在findFilterByName()中,不要传递活动指针,而是再次传递一个ccomptr,这样您就不必显式调用release。
        2
  •  0
  •   Ben Straub    15 年前

    这件事从来没有得到解决。生产解决方案是 IGraphBuilder::Release 重新构建整个图形。在切换视频时,有一个CPU峰值和一个轻微的重绘延迟,但是它没有我们担心的那么明显。