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

时间:2009-05-27 20:51:36

标签: c++ windows com directshow

实际上,它只会在第二次调用时失败。我正在使用无窗口控件来播放视频内容,当控件仍在屏幕上时,正在播放的视频可能会发生变化。在第一次构建图表后,我们通过停止播放,替换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是从DirectShow示例区域中的dshowutil.h借来的。

// 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 个答案:

答案 0 :(得分:0)

  1. 在删除源过滤器之前尝试调用IMediaControl::StopWhenReady
  2. 您何时直接调用QueryInterface?你可以使用CComQIPtr&lt;&gt;为你扭曲QI。这样您就不必调用Release,因为它会自动调用 语法如下所示:CComPtr<IMediaControl> mediaControl = pGraph;
  3. 在FindFilterByName()中,而不是传递实时指针传递CComPtr,这样您就不必显式调用release。

答案 1 :(得分:0)

从未得到过这方面的决议。生产解决方案只需调用IGraphBuilder::Release并从头开始重建整个图形。切换视频时会出现CPU峰值和轻微的重绘延迟,但它不如我们所担心的那么明显。