Видеопроцессор MFT вызывает ошибку «Запрос недействителен в текущем состоянии» - PullRequest
0 голосов
/ 20 апреля 2020

Я использую Media Foundation для создания средства просмотра веб-камеры. Критическим для этого приложения является то, что поток веб-камеры имеет горизонтальное зеркальное отображение. Я использую Видеопроцессор MFT для достижения этой цели. Вот соответствующий код для добавления MFT:

void tryMirror(IMFPMediaPlayer* pPlayer) {
    IMFTransform* pMFT = NULL;
    IMFVideoProcessorControl* pVPC = NULL;

    HRESULT hr = CoCreateInstance(CLSID_VideoProcessorMFT, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pMFT));
    if (FAILED(hr)) {
        ShowHResultErrorMessage(L"CoCreateInstance(CLSID_VideoProcessorMFT, ...) failed", hr);
        goto done;
    }

    hr = pMFT->QueryInterface(&pVPC);
    if (FAILED(hr)) {
        ShowHResultErrorMessage(L"pMFT->QueryInterface(&pVPC) failed", hr);
        goto done;
    }

    hr = pVPC->SetMirror(MIRROR_HORIZONTAL);
    if (FAILED(hr)) {
        ShowHResultErrorMessage(L"pVPC->SetMirror(MIRROR_HORIZONTAL) failed", hr);
        goto done;
    }

    hr = pPlayer->InsertEffect(pMFT, FALSE);  // Not optional - critical functionality
    if (FAILED(hr)) {
        ShowHResultErrorMessage(L"m_pPlayer->InsertEffect(CLSID_VideoProcessorMFT) failed", hr);
        goto done;
    }

    done:
    SafeRelease(&pMFT);
    SafeRelease(&pVPC);
}

// class CPreview implements IMFPMediaPlayerCallback as follows

void STDMETHODCALLTYPE CPreview::OnMediaPlayerEvent(MFP_EVENT_HEADER* pEventHeader) {
    switch (pEventHeader->eEventType)
    {
        //...
        case MFP_EVENT_TYPE_MEDIAITEM_SET:
            OnMediaItemSet(MFP_GET_MEDIAITEM_SET_EVENT(pEventHeader));
            break;

        case MFP_EVENT_TYPE_PLAY:
            OnMfpPlay(MFP_GET_PLAY_EVENT(pEventHeader));
            break;
    }
}

// Called after I set the webcam media source
void CPreview::OnMediaItemSet(MFP_MEDIAITEM_SET_EVENT* /*pEvent*/)
{
    HRESULT hr = m_pPlayer->Play();
    if (FAILED(hr)) {
        ShowHResultErrorMessage(L"m_pPlayer->Play() failed", hr);
    }
}

void CPreview::OnMfpPlay(MFP_PLAY_EVENT* pEvent) {
    if (FAILED(pEvent->header.hrEvent)) {
        ShowHResultErrorMessage(L"OnMfpPlay failed", pEvent->header.hrEvent);
        WCHAR msg[1000];
        HRESULT hr = StringCbPrintf(msg, sizeof(msg), L"Event type: 0x%X", pEvent->header.eEventType);
        ShowErrorMessage(msg);
        return;
    }
}

void ShowHResultErrorMessage(PCWSTR errContext, HRESULT hrErr) {
    _com_error err(hrErr);
    LPCTSTR hrErrMsg = err.ErrorMessage();
    WCHAR msg[1000];
    HRESULT hr = StringCbPrintf(msg, sizeof(msg), L"%s (HRESULT=0x%X, %s)", errContext, hrErr, hrErrMsg);
    if (SUCCEEDED(hr)) {
        MessageBox(NULL, msg, L"Error", MB_ICONERROR);
    }
}

На моей машине для разработки эта программа работает без ошибок, точно так, как нужно. Однако на другом компьютере пользователя происходит сбой с этой ошибкой:

OnMfpPlay failed (HRESULT=0xC00D36B2, The request is invalid in the current state.)

То есть эта ошибка возникает при обратном вызове OnMediaPlayerEvent объекта IMFPMediaPlayerCallback.

I Знайте несколько вещей о машине, на которой происходит сбой:

  • Пользователь также запустил модифицированную версию с MFT, установленной на необязательную, например: pPlayer->InsertEffect(pMFT, TRUE). В этом случае программа запускается, но зеркалирование MFT не дает никакого эффекта. Ошибка определенно вызвана этим MFT.
  • Этот пользователь работает Windows 10, версия 1909. Видеопроцессор MFT явно доступен . Его API утверждает, что работает - все HRESULT успешно.

Эта ошибка "Запрос недействителен в текущем состоянии", может означать что угодно, и я не могу найти любой способ получить больше наблюдаемости. Что означает «Запрос недействителен в текущем состоянии»? Почему он создается добавлением видеопроцессора MFT только на некоторых компьютерах? Как я могу отладить это с более конкретной c ошибкой?

...