MS Media Foundation Session по умолчанию - неправильное соотношение сторон видео
Научиться (мучительно), как использовать топологию и сессию, чтобы представить захваченное видео. Ничего особенного - просто выберите веб-камеру, перечислите ее режимы, выберите формат видео и нажмите "перейти". В общем, вот шаги, которые я предпринимаю, чтобы представить захват видео:
- Перечислите доступные устройства с помощью
MFEnumDeviceSources()
фильтруетсяMF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
и позволить пользователю выбрать один - Список потоков на основе
GetStreamDescriptorCount()
после активации источника и создания дескрипторов презентации сCreatePresentationDescriptor()
и позволить пользователю выбрать поток (если доступно несколько потоков) - Показать все поддерживаемые форматы видео на основе списка
IMFMediaType
доступны черезGetMediaTypeByIndex()
и позволить пользователю выбрать один
После выбора точного формата я строю топологию следующим образом:
- вызов
MFCreateTopology()
создать новыйIMFTopology
объект - создать активацию мультимедийного приемника с помощью
MFCreateVideoRendererActivate()
- убедившись, что позвонил
SetCurrentMediaType()
наIMFMediaTypeHandler
объект выбранного в данный моментIMFStreamDescriptor
- убедившись, что позвонил
- создать исходный узел с
MFCreateTopologyNode()
, установка его представления и потоковых дескрипторов с вызовомSetUnknown()
и добавив этот узел в топологию- удостоверился, чтобы установить его текущий
IMFMediaType
к выбранному пользователем сSetCurrentMediaType()
- удостоверился, чтобы установить его текущий
- создать выходной узел и вызвать
SetObject()
предоставление ранее созданного объекта активации медиа-приемника (из шага 5 выше) - подключите источник к выходу с
ConnectOutput()
предоставив его с идентификатором узла0
При нажатии кнопки "Предварительный просмотр" сеанса IMFMediaSession
объект (созданный при запуске приложения) устанавливается с новой топологией
m_session->SetTopology(MFSESSION_SETTOPOLOGY_IMMEDIATE, pTopo);
И здесь я вижу что-то странное. Я установил размер видео для предварительного просмотра на основе размеров кадра, предоставленных IMFMediaType
что пользователь выбрал, и источник, кажется, производит видео в этом формате. Однако средство рендеринга неправильно обрабатывает пропорции пикселя и создает видеоизображение в виде почтового ящика / столбика, в то время как изображение представляется растянутым либо вертикально, либо горизонтально.
Из жизни я не могу найти способ заставить рендерер настроить правильное соотношение сторон пикселя (для которого было установлено правильное значение в шаге 5.1 выше)
Пример SDK для MS показывает, как представить захваченное видео для несжатых форматов - он не использует IMFMediaSession
объект и прекрасно работает для YUV2
формат, но не для MJPG
, На самом деле это сработало настолько хорошо, что я подумал, что перейти на сессию будет легко:)
С использованием IMFMediaSession
кажется наименее громоздким способом поддержки форматов сжатого видео, особенно H.264
это в новее UVC 1.5
стандартная и любая новая (H.265
?) форматы, которые появятся в будущем.
1 ответ
Дальнейшие исследования показали, что можно получить доступ к объекту рендеринга, запросив сеанс для получения сервиса, а затем использовать этот сервис для получения управления отображением видео. Тот IMFVideoDisplayControl
это объект, который позволяет вам управлять различными аспектами рендеринга видео, включая соотношение сторон изображения.
Вот как это сделать IMFVideoDisplayControl
объект:
получить
IMFGetService
:hr = m_session->QueryInterface<IMFGetService>(&service);
получить
IMFVideoDisplayControl
:hr = service->GetService(MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl, (void**)&control);
Если у вас есть объект управления отображением, вы можете достичь остальных. В моем случае (так как я знал реальную геометрию ожидаемого видео), решение было установить режим соотношения сторон MFVideoARMode_None