Я использую 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 ошибкой?