MS Media Foundation Session по умолчанию - неправильное соотношение сторон видео

Научиться (мучительно), как использовать топологию и сессию, чтобы представить захваченное видео. Ничего особенного - просто выберите веб-камеру, перечислите ее режимы, выберите формат видео и нажмите "перейти". В общем, вот шаги, которые я предпринимаю, чтобы представить захват видео:

  1. Перечислите доступные устройства с помощью MFEnumDeviceSources() фильтруется MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID и позволить пользователю выбрать один
  2. Список потоков на основе GetStreamDescriptorCount() после активации источника и создания дескрипторов презентации с CreatePresentationDescriptor() и позволить пользователю выбрать поток (если доступно несколько потоков)
  3. Показать все поддерживаемые форматы видео на основе списка IMFMediaTypeдоступны через GetMediaTypeByIndex() и позволить пользователю выбрать один

После выбора точного формата я строю топологию следующим образом:

  1. вызов MFCreateTopology() создать новый IMFTopology объект
  2. создать активацию мультимедийного приемника с помощью MFCreateVideoRendererActivate()
    1. убедившись, что позвонил SetCurrentMediaType() на IMFMediaTypeHandler объект выбранного в данный момент IMFStreamDescriptor
  3. создать исходный узел с MFCreateTopologyNode(), установка его представления и потоковых дескрипторов с вызовом SetUnknown() и добавив этот узел в топологию
    1. удостоверился, чтобы установить его текущий IMFMediaType к выбранному пользователем с SetCurrentMediaType()
  4. создать выходной узел и вызвать SetObject() предоставление ранее созданного объекта активации медиа-приемника (из шага 5 выше)
  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 объект:

  1. получить IMFGetService:

    hr = m_session->QueryInterface<IMFGetService>(&service);

  2. получить IMFVideoDisplayControl:

    hr = service->GetService(MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl, (void**)&control);

Если у вас есть объект управления отображением, вы можете достичь остальных. В моем случае (так как я знал реальную геометрию ожидаемого видео), решение было установить режим соотношения сторон MFVideoARMode_None

Другие вопросы по тегам