Мне нужно отобразить поток локальной веб-камеры на экране, перевернутый горизонтально, чтобы экран выглядел как зеркало. У меня есть график DirectShow, который делает все это, кроме зеркального отображения изображения. Я пробовал несколько подходов для зеркального отображения изображения, но ни один из них не работал.
Подход A: VideoControlFlag_FlipHorizontal
Я пытался установить флаг VideoControlFlag_FlipHorizontal
на выходе вывод фильтра веб-камеры, например, так:
IAMVideoControl* pAMVidControl;
IPin* pWebcamOutputPin;
// ...
// Omitting error-handing for brevity
pAMVidControl->SetMode(pWebcamOutputPin, VideoControlFlag_FlipHorizontal);
Однако это не имеет никакого эффекта. Действительно, фильтр веб-камеры утверждает, что не имеет этой возможности или каких-либо других возможностей:
long supportedModes;
hr = pAMVidControl->GetCaps(pWebcamOutputPin, &supportedModes);
// Prints 0, i.e. no capabilities
printf("Supported modes: %ld\n", supportedModes);
Подход B: SetVideoPosition
Я попытался перевернуть изображение, перевернув прямоугольники, переданные SetVideoPosition
. (Я использую фильтр Enhanced Video Renderer в режиме без окон.) Есть два прямоугольника: исходный прямоугольник и целевой прямоугольник. Я попробовал оба. Вот подход B (i), переворачивающий исходный прямоугольник:
MFVideoNormalizedRect srcRect;
srcRect.left = 1.0; // note flipped
srcRect.right = 0.0; // note flipped
srcRect.top = 0.0;
srcRect.bottom = 0.5;
return m_pVideoDisplay->SetVideoPosition(&srcRect, &destRect);
В результате ничего не отображается. Это работает в других конфигурациях, но, кажется, не нравится srcRect.left > srcRect.right
.
Вот подход B (ii), переворачивающий прямоугольник назначения:
RECT destRect;
GetClientRect(hwnd, &destRect);
LONG left = destRect.left;
destRect.left = destRect.right;
destRect.right = left;
return m_pVideoDisplay->SetVideoPosition(NULL, &destRect);
Это также приводит к тому, что ничего не отображается. Это работает в других конфигурациях, но, кажется, не нравится destRect.left > destRect.right
.
Подход C: IMFVideoProcessorControl::SetMirror
IMFVideoProcessorControl::SetMirror(MF_VIDEO_PROCESSOR_MIRROR)
звучит так, как я хочу. Этот IMFVideoProcessorControl
интерфейс реализован Видеопроцессором MFT . К сожалению, это Media Foundation Transform, и я не понимаю, как использовать его в DirectShow.
Подход D: Video Resizer DSP
Video Resizer DSP это «COM-объект, который может действовать как DMO», поэтому теоретически я мог бы использовать его в DirectShow. К сожалению, у меня нет опыта работы с DMO, и в любом случае, документы для Video Resizer не говорят, поддерживает ли он переворачивание изображения.
Подход E: IVMRMixerControl9::SetOutputRect
Я нашел IVMRMixerControl9::SetOutputRect
, который явно говорит:
Поскольку этот прямоугольник существует в композиционном пространстве, не существует такого понятия, как «недопустимый» прямоугольник. Например, установите влево больше, чем вправо, чтобы отразить видео в направлении х.
Однако IVMRMixerControl9
представляется устаревшим, и я использую EVR, а не VMR, и нет никаких документов о том, как получить IVMRMixerControl9
в любом случае.
Подход F: Напишите мой собственный фильтр DirectShow
Я не хочу пробовать этот, если мне не нужно. Это будет серьезная инвестиция, и я не уверен, что она все равно будет достаточно эффективной.
Подход G: начните заново с Media Foundation
Media Foundation, возможно, позволит мне решить эту проблему , потому что это обеспечивает "Преобразование Фонда СМИ". Но даже не ясно, соответствует ли Media Foundation всем моим требованиям.
Я очень удивлен, что смотрю на такие радикальные решения для преобразования, которое кажется настолько стандартным. Какие еще существуют подходы? Есть ли что-то, что я упустил из виду в своих попытках? Как я могу зеркально отразить видео в DirectShow?