Video Mixing Renderer

Использование Video Mixing Renderer’а

С точки зрения и выполнения, и богатства возможностей, фильтр VMR представляет собой следующее поколение в видеоотображении на Windows-платформах. VMR заменяет собой и Overlay Mixer, и Video Renderer, и добавляет множество новых возможностей смешивания (микширования; нужен лучший синоним).

VMR вначале был доступен только на платформе Windows XP. Начиная с версии DirectX9.0, отдельная версия VMR, которая называется VMR-9, доступна для перераспространения ( redistibution ) на все платформы, поддерживаемые DirectX'ом. Два VMR-фильтра очень похожи в своей реализации и предствляемых ими интерфейсах. Главным отличием есть то, что исходный VMR (который называется VMR-7), внутренне использует DirectDraw 7 для управления аппаратным обеспечением видео, тогда как новая версия VMR (которая называется VMR-9), использует Direct3D 9.

VMR-9 имеет свой собственный CVSID и свой собственный набор интерфейсов, структур и перечислимых типов, которые не всегда тождественны соответствующим типам данных для VMR-7, что вытекает из лежащей в этом разнице между DirectDraw7 и Direct3D 9. Все интерфейсы VMR-9 заканчиваются на "9", а все структуры и перечислимые типы имеют в своих именах "VMR-9" для отличия от типов данных, используемых в VMR-7.

Для обеспечения обратной совместимости VMR-9 ни для какой системы не является фильтром отображения, задаваемым по умолчанию. Для его использования нужно явно добавить его к графу фильтров, используя метод IFilterGraph::AddFilter, а также отконфигурировать перед соединением с вышележащими фильтрами. Информация, приведенная далее, если особо не указано, применима и к VMR-7, и к VMR-9.

Особенности VMR

VMR-7 поддерживает следующие новые возможности:

  • Смешение многих видеопотоков с использованием возможностей смешения по яркости аппаратных устройств, поддерживающих Direct3D.
  • Возможность подключения пользовательских компонентов для реализации эффектов и переходов между многими видеопотоками, входящими в VMR.
  • Безоконное воспроизведение. It is no longer necessary to make the video playback window a child of the application's window in order to contain video playback. The VMR's new windowless rendering mode allows applications to easily host video playback within any window without having to forward window messages to the renderer for renderer-specific processing.
  • Новый режим безотображаемого проигрывания, в котором приложения могут поддерживать свои собственные компоненты распределителей для получения доступа к декодированному видеоизображению до того, как оно будет воспроизведено на экране.
  • Улучшенная поддержка PC, оснащенных несколькими мониторами.
  • Поддержка новой архитектуры Microsoft DirectX Video Acceleration.
  • Поддержка параллельного высококачественного видеовоспроизведения в нескольких окнах.
  • Поддержка эксклюзивного режима DirectDraw.
  • 100%-ная обратная совместимость для уже существующих приложений.
  • Поддержка покадрового прохода и надежный путь для захвата текущего изображения перед его показом.
  • Возможность для приложений легко смешивать свои статические картинки (такие, например, как эмблему канала (logos) или изображения компонентов графического интерфейса) с видео плавно и без мигания.

VMR-9 поддерживает, кроме уже перечисленного, еще и:

  • Возможность обрабатывать видеоданные напрямую через Direct3D API для, например, затемнения пикселов.
  • Улучшенная поддержка интерлейсного видео.
  • Поддержка на всех платформах, поддерживаемых DirectX'ом.

Сравнение VMR’а с предыдущими версиями DirectShow-фильтров

Старые фильтры видеоотображения предъявляли разные требования к графу (видимо, в первую очередь к вышележащему фильтру ?) в зависимости от аппаратной конфигурации.

Фильтр Video Renderer использовался для отображения одного видеопотока в случаях отсутствия видеопортов. Он базировался на давно устаревшей технологии графического аппаратного обеспечения и старой версии DirectDraw. В отдельных случаях для отображения использовался GDI. Это делалось также для экономии видеоресурсов, которые раньше были более чем ограниченными, а еще для преодоления ограничений DirectDraw, связанных с многомониторной поддержкой. Ни VMR-7, ни VMR-9 никогда не используют для отображения GDI; VMR-7 полностью основан на DirectDraw 7, а VMR-9 - на Direct3D 9.

В случаях, когда присутствовали видеопорты или несколько входящих видеопотоков, предшественником VMR'ов был фильтр Overlay Mixer. Этот фильтр только лишь использует аппаратный оверлей видеокарты и поэтому ограничен одной оверлейной поверхностью, предоставляемой большинством видеокарт. The Overlay Mixer performs destination color keying, but it is not capable of alpha blending. Поскольку у него нет оконного менеджера, он должен использовать другой фильтр, Video Renderer, в качестве такового. VMR поддерживает настоящее смешение интенсивностей и может создавать множество оверлеев программно вдобавок к аппаратным оверлеям.

В случаях с видеопортами, когда приложения перекрывают closed captioning или другие VBI-данные на видео, требуется иной дополнительный фильтр, VBI Surface Allocator для выделения дополнительной видеопамяти для VBI-текста. Для независимых поставщиков программного обеспечения VMR-7 упрощает разработку приложений путем объединения функциональности распределения и отображения в один фильтр, используемый во всех случаях. Для VMR фильтр VBI Surface Allocator больше не нужен. Этот фильтр в Windows XP заменен на новый фильтр Video Port Manager, на который возложено выпрлнение всех задач с видеопортами, которые прежде выполнял Overlay Mixer.

Замечание

VMR-9 не поддерживает видеопортов.

VMR более устойчив, чем предыдущие фильтры отображения, в частности, из-за того, что он только использует интерфейсы DirectDraw 7 (или Direct3D 9 при использовании VMR-9), в отличии от старых фильтров отображения, которые использовали смесь интерфейсов старых и новых версий DirectDraw. VMR использует также новый механизм представления изображения, разработанного для настоящего и новых поколений адаптеров, поддерживающих Direct3D, increased VRAM and video memory bandwidth, and hardware acceleration features. С VMR главное внимание можно перенести на "front-end" обработку, и уменьшить зависимость от видеопортов и оверлеев. Но, имея все эти новые элементы функциональности, VMR, тем не менее, разработан с учетом обеспечения максимальной совместимомти с уже существующими приложениями.

VMR расширяем. Приложения могут предоставлять свои собственные подкомпоненты для выполнения пользовательской обработки видео и/или обеспечении контроля над процессом распределения и воспроизведения.

Системные требования для использования VMR

VMR использует исключительно возможности компьютерной графической карты для обработки видео; VMR не использует главный процессор ни для смешивания, ни для отображения, т.к. это существенно влияет на скорость и качество отображения видео. Если взять преимущества новых возможностей, предлагаемых VMR'ом, такие как смешивание, поддержка нескольких видеопотоков и/или изображений, предоставляемых приложением, общее выполнение будет существенно зависеть от свойств видеокарты, используемой в компьютере. Графические карты, хорошо работающие с VMR'ом, должны аппаратно поддерживать следующие возможности:

  • Поддерживать YUV и "не-степенной двойки" ("non-power of 2") текстурные поверхности Direct3D.
  • The ability to StretchBlt from YUV to RGB DirectDraw surfaces.
  • Не менее 16 MB видеопамяти в случае необходимости смешения нескольких видеопотоков. Действительное количество требуемой памяти зависит от размера изображения видеопотоков и разрешения испрользуемого видеорежима.
  • Поддерживать RGB-оверлей или возможность смешивания для оверлейной поверхности YUV.
  • Аппаратный акселератор видеодекодирования (поддерживающий DirectX).
  • Высокую скорость заливки пикселей.

Замечание

VMR требует, чтобы глубина цвета была, как минимум, 16-ти битной. VMR нельзя запустить, если текущая глубина цвета - 256 цветов. Некоторые видеокарты не могут выполнять операций Direct3D, если глубина цвета составляет 24 бита на пиксел.

Правильный выбор фильтра отображения

При наличии DirectX 9, DirectShow предоставляет четыре разных фильтра видеотображения: старый Video Renderer, Overlay Mixer, VMR-7 и VMR-9. По разным причинам, не существует какого-то одного фильтра, предпочтительного во всех ситуациях. Сделать выбор помогут следующие руководящие принципы:

  • Существующие приложения, требующие только лишь базовой основы для видеоотображения, без использования смешивания.

Следует использовать VMR-9 для улучшения деинтерлейсинга и поддержки ProcAmp (что за ProcAmp и почему его нужно поддерживать?). Если же заранее известно, что аппаратные средства не поддерживают VMR-7 или VMR-9, то следует использовать старый фильтр видеоотображения, задаваемый по умолчанию.

  • Приложения для работы с устройствами, использующие видеопорты.

Если необходима работа на платформах, более ранних, чем Windows XP, то нужно использовать Overlay Mixer. Для работы на Windows XP лучше использовать VMR-7. В VMR-9 видеопорты не поддерживаются.

  • Приложения, требующие любые специфические возможности VMR.

Лучше использовать VMR-9, а не VMR-7, поскольку VMR-9 поддерживается последними возможностями Direct3D на всех платформах, поддерживаемых DirectX'ом. При использовании VMR-7 приложение сможет работать только на Windows XP.

Компоненты VMR

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


Рис. 1. Компоненты VMR

Mixer: Микшер - это COM-объект, который загружается VMR'ом при обнаружении нескольких входящих потоков. Микшер собирает информацию о каждом входящем потоке и упорядочивает их в правильном Z-порядке. Он ответственен за определение того, когда каждый входящий контакт получает сэмпл и для указания составителю изображений (image compositor ) времени, когда пора производить смешение. Микшер вычисляет также временную отметку, присваиваемую каждому исходящему изображению. When the application is supplying a bitmap to be displayed on top of the composited image, the mixer is responsible for ensuring that the bitmap is displayed on top even if the Z-order of the input streams is modified.

Image Compositor: Это - COM-объект, выполняющий смешение входящих потоков на одной DiurectDraw или Direct3D поверхности, предоставляемой распределителем-подателем (by allocator-presenter). VMR предоставляет image compositor, задаваемый по умолчанию, который позволяет приложением выполнять эффекты по 2-D-смешиванию. Приложения могут предоставлять пользовательские image compositor'ы для выполнения каки-либо других 2D или 3D операций, таких как, например, использование текстур для участков изображений, по-пиксельному смешению, отображение рисунков на стационарные или движущиеся 3-D объекты и т.д.

Allocator-Presenter: Это COM-объект, дающий возможность DirectDraw или Direct3D-объекту управлять связью с графической картой. Рисование может выполняться как flip или как blit. Можно подставить собственный аллокатор-презентер лоя того, чтобы создавать и управлять DirectDraw и Direct3D-объектами, и/или получения доступа к видеобитам времени представления (presentation time).

Core Synchronization Unit (основное устройство синхронизации): Это COM-объект, удостоверивающийся, что время отображения каждого кадра корректно. Он использует интерфейс IReferenceClock, предоставляемый МГФ, и выполняет функции слежения за качеством и кадрами.

Window Manager: Оконный менеджер используется только в оконном режиме. Он реализован в виде статической библиотеки и поддерживает старые интерфейсы DirectShow -IVideoWindow и IBasicVideo для обеспечения обратной совместимости.

Режимы операций VMR

Компонентная архитектура VMR'а позволяет приложениям конфигурировать его разными способами в зависимости от того, как предполагается производить отображение. Следующая таблица показывает три режима представления и два режима смешивания, а также компоненты, присутствующие в каждой из конфигураций:

РежимОдин потокНесколько потоков (режим смешивания)
ОконныйAllocator-presenterCore Synchronization UnitWindow ManagerМикшерCompositor*Allocator-presenterCore Synchronization UnitWindow Manager
БезоконныйAllocator-presenterCore Synchronization UnitМикшерCompositor*Allocator-presenterCore Synchronization Unit
Без отображенияAllocator-presenter (предоставляемый приложением)Core Synchronization UnitМикшерCompositor*Allocator-presenter (предоставляемый приложением)Core Synchronization Unit

* Указывает, что приложение имеет выбор - использовать собственный компонент или компонет, задаваемый по умолчанию.

Во всех этих конфигурациях нужно помнить, что при создании графа фильтров с VMR'ом последний нужно отконфигурировать перед его подключением к другому фильтру.

Для всех конфигураций контакты не могут быть динамически добавлены или удалены после того, как VMR подключится к вышележащему фильтру, но их можно подсоединить и отсоединить. Если приложение неуверено в количестве необходимых контактов, оно должно отконфигурировать VMR с учетом их максимального количества. Присутствие неиспользуемых входящих контактов на фильтре не ухудшает свойств воспроизведения. В отличие от старого Overlay Mixer'а, у VMR'а нет исходящего контакта, т.к. ему не нужен отдельный фильтр для управления окном.

Следующие разделы описывают конфигурирование VMR'а для указанных режимов.

VMR Windowed (compatibility) Mode

VMR Windowless Mode

VMR with Multiple Streams (Mixing Mode)

VMR Renderless Plauback Mode (Custom Allocator-Presenters)

DirectDraw Exclusive Mode

Построение графа фильтров, содержащего VMR-9

Поскольку фильтр VMR-9 не является фильтром видеоотображения по умолчанию, приложения, использующие его, должны явно добавить к графу и соединить его с другими фильтрами. Ниже представлено два разных способа построения графа фильтров с VMR-9.

Использование построителя графа захвата (Capture Graph Builder).

Capture Graph Builder - это вспомагательный объект для построения графов фильтров. Его можно использовать для построения графа, содержащего VMR-9, следующим образом:

  1. Создать и проинициализировать Capture Graph Builder.
  2. Вызвать CoCreateInstance для создания VMR-9:
IBaseFilter *pVmr = NULL;
hr = CoCreateInstance(CLSID_VideoMixingRenderer9, 0, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&pVmr);
  1. Вызвать метод IFilterGraph::AddFilter на МГФ для добавления фильтра VMR-9 к графу фильтров:
hr = pGraph->AddFilter(pVmr, L"VMR9");
  1. Вызвать метод IGraphBuilder::AddSourceFilter для добавления фильтра источника для видеофайла:
IBaseFilter *pSource;
hr = pGraph->AddSourceFilter(L"C:\\Example.avi", L"Source1", &pSource);
  1. Вызвать метод ICaptureGraphBuilder2::RenderStream для отображения видеопотока с использованием VMR'а:
hr = pBuild->RenderStream(0, 0, pSource, 0, pVmr); 
  1. Опционально снова вызвать RenderStream для воспроизведения аудиопотока:
hr = pBuild->RenderStream(0, &MEDIATYPE_Audio, pSource, 0, NULL);

Можно смешать несколько видеопотоков, вызывая методы AddSourceFilter и RenderStream для каждого фильтра источника.

Использование Менеджера Графа Фильтров

Если вы не хотите использовать Capture Graph Builder, вы можете построить граф фильтров, содержащий VMR-9, просто используя следующие методы МГФ:

  1. Создайте VMR-9 и добавьте его в граф, как это показано в предыдущем способе.
  2. Используйте метод AddSourceFilter для добавления фильтра источника для видеофайла, как показано в предыдущем способе.
  3. Если вы хотите воспроизводить аудио, создайте экземпляр фильтра DirectSound Renderer  и добавьте его в граф фильтров.
  4. Используйте метод IBaseFilter::EnumPins для поиска исходящего контакта фильтра источника. 
  5. Запросите у МГФ интерфейс IFilterGraph2.
  6. Вызовите метод IFilterGraph2::RenderEx с флагом AM_RENDEREX_RENDERTOEXISTINGRENDERERS. Этот вызов приведет к отображению исходящего контакта с использованием только уже присутствующих в графе фильтров отображения, - в нашем случае фильтров VMR-9 и DirectSound Renderer'а. Это помешает логике выполнения Intelligent Connect, которая в другом случае добавит в граф фильтр видеоотображения, заданный по умолчанию, что оставит VMR-9 в несвязанном виде.

Отображение на составном рисунке предоставляемых приложением изображений

Приложения могут использовать возможность VMR'а "Mixer-Bitmap" для отображения logos'ов каналов (смешанных с видеопотоком), пользовательских интерфейсов или рекламы, частично или полностью находящейся внутри прямоугольника видеоотображения. Поскольку смешивание выполняется аппаратно графическим процессором, оно оказывает минимальное влияние на выполнение проигрывания видеопотока, а артефакты мерцания или разрыва отсутствуют. Приложения могут изменять отображаемое изображение настолько часто, насколько им это нужно. Нужно отметить, что все изменения будут отображаться на экране, когда граф фильтров DirectShow будет запущен.

VMR использует компонет микширования (mixer) для перекрытия картинкой составного изображения (to overlay the bitmap onto the composited image). Используя VMR-7, приложение должно его заставить загрузить свой миксер, даже если в наличии есть только один поток. Этого можно не делать для VMR-9, поскольку он загружает свой миксер по умолчанию.

Для смешивания статической картинки с видеопотоком приложение создает VMR и добавляет его в граф фильтров, а затем вызывает метод IVMRFilterConfig::SetNumberOfStreams.  Значение, переданное этой функции, указывает количество входящих контактов, которые должен будет создать VMR. Приложения могут указать любое значение от 1 до MAX_MIXER_STREAMS (16); указание значения 1 нужно делать, если приложение собирается отображать только один видеопоток. Хотя VMR-7 и имеет один входящий контакт по умолчанию, этот метод все равно нужно вызвать для того, чтобы заставить VMR-7 загрузить свой компонент микширования. (VMR-9 загружает свой микшер и устанавливает по умолчанию четыре входящих контакта.)

Битмэп может также быть задан хэндлом контекста устройства GDI (GDI Device Context) или интерфейсом поверхности DirectDraw. Если приложение хочет, чтобы изображение содержало вложенную информацию о яркости (известную также как per pixel alpha), оно должно положить данные изображения на интерфейс поверзности DirectDraw. Дело в том, что в контексте устройства GDI невозможно невозможно использовать вложенную информацию о яркости (per-pixel alpha information). Поверхность DirectDraw должна быть RGB32 или ARGB32, and should preferably be a system memory surface. Размеры поверхности не обязаны быть равными степени двойки.

VMR позволяет приложениям указывать позицию и общее значение прозрачности для изображения. Следующий код показывает как передавать данные VMR'у для последующего смешивания:

HRESULT BlendApplicationImage( 
HWND hwndApp,
IVMRWindowlessControl* pWc,
HBITMAP hbm
)
{
LONG cx, cy;
HRESULT hr;
hr = pWc->GetNativeVideoSize(&cx, &cy, NULL, NULL);
if (FAILED(hr))
return hr;

HDC hdc = GetDC(hwndApp);
if (hdc == NULL)
{
return E_FAIL;
}

HDC hdcBmp = CreateCompatibleDC(hdc);
ReleaseDC(hwndApp, hdc);

if (hdcBmp == NULL)
{
return E_FAIL;
}

BITMAP bm;
if (0 == GetObject(hbm, sizeof(bm), &bm))
{
DeleteDC(hdcBmp);
return E_FAIL;
}

HBITMAP hbmOld = (HBITMAP)SelectObject(hdcBmp, hbm);
if (hbmOld == 0)
{
DeleteDC(hdcBmp);
return E_FAIL;
}

VMRALPHABITMAP bmpInfo;
ZeroMemory(&bmpInfo, sizeof(bmpInfo) );
bmpInfo.dwFlags = VMRBITMAP_HDC;
bmpInfo.hdc = hdcBmp;

// Show the entire bitmap in the top-left corner of the video image.
SetRect(&bmpInfo.rSrc, 0, 0, bm.bmWidth, bm.bmHeight);
bmpInfo.rDest.left = 0.f;
bmpInfo.rDest.top = 0.f;
bmpInfo.rDest.right = (float)bm.bmWidth / (float)cx;
bmpInfo.rDest.bottom = (float)bm.bmHeight / (float)cy;

// Set the transparency value (1.0 is opaque, 0.0 is transparent).
bmpInfo.fAlpha = 0.2f;

IVMRMixerBitmap* pBmp;
hr = pWc->QueryInterface(IID_IVMRMixerBitmap, (LPVOID *)&pBmp);
if (SUCCEEDED(hr))
{
pBmp->SetAlphaBitmap(&bmpInfo);
pBmp->Release();
}

DeleteObject(SelectObject(hdcBmp, hbmOld));
DeleteDC(hdcBmp);
return hr;
}

Поддержка нескольких мониторов

VMR поддерживает интерфейс IVMRMonitorConfig, который позволяет приложениям управлять поведением VMR'у на многомониторной системе. При VMR-7 мониторы идентифицируются GUID'ами, тогда как с VMR-9 an integer is used for this purpose.

Оптимизация операций смешивания

Важно. Оптимизация, описываемая ниже, очень сильно зависит от используемого аппаратного обеспечения. Если вы неможете гарантировать, что будет использоваться соответствующий тип аппаратного обеспечения, установка описываемых ниже флагов инициализации может привести к серьезного ухудшению производительности при отображении изображений.

High Definition Television (HDTV) - высококачественное телевидение (???) требует много процессорной мощности, которая на новых системах обеспечивается, в первую очередь, графической картой. Но даже если видеокарта и декодер поддерживают разрешение 1920 на 1080, пользователь не всегда сможет выставить такое разрешение на своем мониторе. В этом случае графическая микросхема создаст изображение 1920 на 1080, но уменьшит его перед посылкой в кадровый буфер.

Since this is a waste of processing power, the VMR provides a way to decimate (reduce) the image at the time it is being rendered onto the DirectDraw surface. Этим устраняется чрезмерное копирование памяти, требуемое в том случае, если изображение нужно отмасшибировать перед отображением. Метод, предоставляющий такую оптимизацию, называется IVMRMixerControl::SetMixingPrefs, который должен быть вызван перед тем, как VMR будет соединен. Пока граф запущен, флаги смешивания изменены быть не могут. SetMixingPrefsмогут также использоваться для конфигурирования типа фильтрации и цветового пространства поверхности назначения.

Настройка деинтерлейсных свойств

VMR поддерживает аппаратно ускоренный деинтерлейс, который улучшает качество воспроизведения интерлейсного видео. Точные характеристики зависят от используемого оборудования. Приложение может узнать свойства аппаратного деинтерлейса и установить установки деинтерлейса через вызовы интерфейсов IVMRDeinterlaceControl  (VMR-7) или IVMRDeinterlaceControl9  (VMR-9). Deinterlacing is performed on a per-stream basis. (Деинтерлейсинг выполняется для каждого потока отдельно?)

Замечание. Далее описываются методы IVMRDeinterlaceControl9, но методы VMR-7 им практически идентичны.

Для того, чтобы получить деинтерлейсные свойства видеопотока, нужно сделать следующее:

  1. Залить структуру VMR9VideoDesc с описанием видеопока. Как это сделать, будет описано ниже.
  2. Передать эту структуру методу IVMRDeinterlaceControl9::GetNumberOfDeinterlaceModes. Его нужно вызвать дважды. Первый вызов вернет количество деинтерлейсных режимов, поддерживаемых аппаратно, для указанного формата. Затем нужно распределить массив GUID'ов этого размера, и вызвать метод опять, передав алрес массива. Второй вызов зальет массив GUID'ами. Каждый из GUID'ов идентифицирует деинтерлейсный режим.
  3. Для получения свойств конкретного режима нужно вызвать метод IVMRDeinterlaceControl9::GetDeinterlaceModeCaps, передав в него структуру VMR9VideoDesc вместе с одним из GUID'ов из массива. Метод заполнит структуру VMR9DeinterlaceCaps свойствами режима.

Эти шаги можно продемонстрировать следующим кодом:

VMR9VideoDesc VideoDesc; 
DWORD dwNumModes = 0;
// Fill in the VideoDesc structure (not shown).
hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc,
&dwNumModes, NULL);
if (SUCCEEDED(hr) && (dwNumModes != 0))
{
// Allocate an array for the GUIDs that identify the modes.
GUID *pModes = new GUID[dwNumModes];
if (pModes)
{
// Fill the array.
hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc,
&dwNumModes, pModes);
if (SUCCEEDED(hr))
{
// Loop through each item and get the capabilities.for (int i = 0; i < dwNumModes; i++)
{
VMR9DeinterlaceCaps Caps;
hr = pDeinterlace->GetDeinterlaceModeCaps(pModes + i,
&VideoDesc, &Caps);
if (SUCCEEDED(hr))
{
// Examine the Caps structure.
}
}
}
delete [] pModes;
}
}

Теперь приложение может установить деинтерлейсный режим для потока, используя следующие методы:

  1. Метод  SetDeinterlaceMode устанавливает предпочитаемый режим. GUID_NULL используется для отключения деинтерлейсинга.
  2. Метод SetDeinterlacePrefs  задает поведение, если требуемый режим недоступен.
  3. Метод GetDeinterlaceMode  возвращает ранее установленный предпочитаемый режим.
  4. Метод GetActualDeinterlaceMode  действительно используемый режим, который может быть аварийным режимом, если предпочитаемый режим недоступен.

Для прлучения более детальной информации следует смотреть описания этих методов.

Использование структуры VMR9VideoDesc

В описанных выше процедурах первым шагом есть заполнение структуры VMR9VideoDesc описанием видеопотока. Начнем с получения видеотипа медиапотока. Это можно сделать, вызвав метод IPin::ConnectionMediaType  на входящем контакте VMR-фильтра. Затем нужно убедиться, что видеопоток действительно интерлейсный. Таковыми могут быть только форматы VIDEOINFOHEADER2.  Если тип формата - FORMAT_VideoInfo, то это прогрессивный кадр. Если тип формата - FORMAT_VideoInfo2, то тогда нужно проверить поле dwInterlaceFlags флага AMINTERLACE_IsInterlaced. Наличие этого флага свидетельствует об интерлейсном видео.

Допустим, что переменная pBMI есть указатель на структуру BITMAPINFOHEADER форматного блока. Установим следующие значения для структуры VMR9VideoDesc:

  • dwSize: Устанавливаем это значение в sizeof(VMR9VideoDesc)
  • dwSamplesWidth: Устанавливаем это поле в pBMI->biWidth
  • dwSamplesHeight: Устанавливаем это поле в abs(pBMI->biHeight)
  • SampleFormat: Это поле описывает интерлейсные свойства медиатипа. Нужно проверить поле dwInterlaceFlags в структуре VIDEOINFOHEADER2 и установить SampleFormat в значение, эквивалентное флагу VMR9_SampleFormat. Вспомагательная функция для этого приведена ниже.
  • InputSampleFreq: Это поле дает входящую частоту, которая может быть вычислена, исходя из значения поля AvgTimePerFrame структуры VIDEOINFOHEADER2. В общем случае нужно установить dwNumerator в 10000000, а dwDenominator в AvgTimePerFrame. Но, однако, можно также отметить следующие хорошо известные частоты:
Average time per frameFrame rate (fps)NumeratorDenominator
16683359.94 (NTSC)600001001
33366729.97 (NTSC)300001001
41718823.97 (NTSC)240001001
20000050.00 (PAL)501
40000025.00 (PAL)251
41666724.00 (Film)241
  • OutputFrameFreq: Это поле дает исходящую частоту, которая вычисляется исходя из значения InputSampleFreq и интерлейсных свойств входящего потока:
  • Установить OutputFrameFreq.dwDenominator равным InputSampleFreq.dwDenominator.
  • Если входящее видео - интерлейсное, нужно установить OutputFrameFreq.dwNumerator в 2 x InputSampleFreq.dwNumerator. (После деинтерлейсинга скорость кадров удваивается.) В противном случае это значение нужно установить в InputSampleFreq.dwNumerator.
  • dwFourCC: Устанавливаем это поле в pBMI->biCompression.

Следующая вспомагательная функция конвертирует флаги AMINTERLACE_X в значения VMR9_SampleFormat:

#define IsInterlaced(x) ((x) & AMINTERLACE_IsInterlaced)
#define IsSingleField(x) ((x) & AMINTERLACE_1FieldPerSample)
#define IsField1First(x) ((x) & AMINTERLACE_Field1First)

VMR9_SampleFormat ConvertInterlaceFlags(DWORD dwInterlaceFlags)
{
if (IsInterlaced(dwInterlaceFlags)) {
if (IsSingleField(dwInterlaceFlags)) {
if (IsField1First(dwInterlaceFlags)) {
return VMR9_SampleFieldSingleEven;
}
else {
return VMR9_SampleFieldSingleOdd;
}
}
else {
if (IsField1First(dwInterlaceFlags)) {
return VMR9_SampleFieldInterleavedEvenFirst;
}
else {
return VMR9_SampleFieldInterleavedOddFirst;
}
}
}
else {
return VMR9_SampleProgressiveFrame; // Not interlaced.
}
}

Comments