0

实际上,它只会在第二次调用时失败。我正在使用无窗口控件来播放视频内容,当控件仍在屏幕上时,正在播放的视频可能会发生变化。第一次构建图表后,我们通过停止播放、更换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);

当我们决定播放一部电影时,这就是我们所做的。是从DirectShow 示例区域RenderFileToVideoRenderer中借来的。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);
}

有人知道这里发生了什么吗?

4

2 回答 2

0
  1. 在删除源过滤器之前尝试调用IMediaControl::StopWhenReady 。
  2. 你什么时候直接调用QueryInterface?您可以使用 CComQIPtr<> 为您扭曲 QI。这样您就不必调用 Release,因为它会被自动调用。
    语法如下所示:CComPtr<IMediaControl> mediaControl = pGraph;
  3. 在 FindFilterByName() 中,不是传递实时指针,而是传递一个 CComPtr,因此您不必显式调用 release。
于 2009-05-27T21:57:48.690 回答
0

从来没有解决这个问题。IGraphBuilder::Release生产解决方案是从头开始调用和重建整个图表。切换视频时会出现 CPU 峰值和轻微的重绘延迟,但它没有我们担心的那么明显。

于 2009-05-28T17:46:21.617 回答