IMovieControl :: Выполнить не удалось в Windows XP? - PullRequest
0 голосов
/ 28 мая 2009

На самом деле, происходит сбой только при втором вызове. Я использую безоконный элемент управления для воспроизведения видеоконтента, где воспроизводимое видео может измениться, пока элемент управления все еще находится на экране. Как только график будет построен в первый раз, мы переключаем мультимедиа, останавливая воспроизведение, заменяя фильтр 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 ]

0 голосов
/ 28 мая 2009

Никогда не получил разрешение по этому вопросу. Производственным решением было просто позвонить IGraphBuilder::Release и перестроить весь график с нуля. При переключении видео наблюдается всплеск процессора и небольшая задержка перерисовки, но она менее выражена, чем мы опасались.

0 голосов
/ 28 мая 2009
  1. Попробуйте вызвать IMediaControl :: StopWhenReady перед удалением фильтра источника.
  2. Когда вы вызываете QueryInterface напрямую? Вы можете использовать CComQIPtr <> для деформации QI для вас. Таким образом, вам не нужно будет вызывать Release, поскольку он будет вызываться автоматически.
    Синтаксис выглядит следующим образом: CComPtr<IMediaControl> mediaControl = pGraph;
  3. В FindFilterByName () вместо передачи живого указателя передайте CComPtr, чтобы вам не пришлось явно вызывать release
...