2009-05-27 14 views
0

実際には、呼び出されるのは2回目に失敗します。私はウィンドウレスのコントロールを使ってビデオコンテンツを再生していますが、コントロールがまだ画面に表示されている間に再生されるビデオが変更される可能性があります。グラフが初めて作成されると、再生を停止し、SOURCEフィルタを置き換えてグラフを再度実行して、メディアを切り替えます。 Vistaではうまく動作しますが、XPで動作している場合、Run()への2回目の呼び出しはE_UNEXPECTEDを返します。Windows XPではIMovieControl :: Runが失敗しますか?

// 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); 
} 

ここで何が起こっているのか分かりませんか?

答えて

0

解決方法はありません。生産ソリューションは、IGraphBuilder::Releaseを呼び出し、グラフ全体を最初から再構築することでした。ビデオを切り替えるときにCPUスパイクとわずかな再描画の遅延がありますが、私たちが恐れていたよりもそれほど顕著ではありません。

0
  1. ソースフィルタを削除する前にIMediaControl::StopWhenReadyに電話してみてください。
  2. いつQueryInterfaceを直接呼び出していますか? CComQIPtr <>を使用してQIをワープすることができます。これにより、自動的に呼び出されるReleaseを呼び出す必要がなくなります。
    構文は次のようになります。CComPtr<IMediaControl> mediaControl = pGraph;
  3. ライブポインタを渡す代わりにFindFilterByName()でCComPtrを渡すので、リリースを明示的に呼び出す必要はありません。
+0

1.ソースフィルタを削除する前にIMediaControl :: Stopを呼び出しています。IMediaControl :: GetStateを呼び出すと、再生状態はState_Stoppedになります。他のアイデア? 2/3。良い提案は、これはコードをかなり整理します。 –

関連する問題