Глава 4(фрагмент). Режим предварительного просмотра
Основные интерфейсы, используемые для реализации режима предварительного просмотра.
Метод RenderStream [переход...]
Управление параметрами видеопотока на фильтре сбора [переход...]
Структура AM_MEDIA_TYPE [переход...]
Основные интерфейсы, используемые для реализации режима предварительного просмотра.
Прежде чем перейти непосредственно к построению ветви графа для реализации предварительного просмотра, оценим предстоящую задачу. Итак, мы имеем построенный граф до фильтра сбора включительно. Далее следует реализовать достройку графа от контакта предварительного просмотра фильтра сбора до фильтра отображения (Renderer). Определить наличие контакта VBI на фильтре сбора и построить ветвь графа для просмотра телетекста. Также необходимо оценить все возможные регулировки и настойки, которые предоставляются фильтром сбора и фильтром отображения, определить, какие из них следует предоставлять для управления пользователю, а какие можно оставить по умолчанию.
Достройка графа для предварительного просмотра имеет целый ряд особенностей, которые делают этот процесс многовариантным. Выбор способа реализации ветвей графа, определяется возможностями устройства, условиями задачи, текущим стандартом ТВ вещания. Для решения простой задачи отображения в минимальном варианте можно ограничиться применением методов "интеллектуального" построения ветвей графа. В остальных случаях необходимо комбинировать ручное построение графа с "интеллектуальным".
Начнем рассмотрение реализации предварительного просмотра с основных интерфейсов и их методов, необходимых для достройки графа.
Для построения отображающей ветви графа используются те же интерфейсы менеджера графа и построителя графа сбора, которые рассматривались ранее.
- Интерфейс построителя графа сбора ICaptureGraphBuilder2.
- Интерфейс менеджера графа IFilterGraph,.
- Интерфейс IFilterGraph2, расширяющий возможности IFilterGraph.
- Интерфейс построителя графа IGraphBuilder, производный от IFilterGraph.
Описание методов перечисленных интерфейсов приводится в главе 2. Здесь, прежде всего, рассмотрим методы этих интерфейсов, которые используют алгоритм "интеллектуального" соединения, позволяющий строить целые участки графа. Для реализации предварительного просмотра вполне возможно обойтись без трудоемкой работы по ручному построению графа. Или же максимально упростить задачу, используя эти методы. Из всех методов, указанных интерфейсов, для построения ветви графа предварительного просмотра можно использовать два метода, которые существенно влияют на реализацию собственных методов приложения. Конкретный выбор методов зависит от поставленной задачи и от особенностей поведения этих методов. Рассмотрим эти методы.
Метод IGraphBuilder::Render и IFilterGraph2::RenderEx подробно описан в главе 3. Он не имеет никаких параметров, которые могли бы управлять его поведением. Если используется этот метод, то Вы лишены любой возможности повлиять на процесс построения графа. Все решает алгоритм "интеллектуального" соединения.
Второй метод ICaptureGraphBuilder2::RenderStream имеет большие и разнообразные возможности по построению ветвей графа. Данный метод имеет несколько параметров, которые настраивают поведение метода при построении ветви графа. Он имеет возможности настройки своего поведения для специфических ветвей графа, таких как ветви, начинающиеся с выходных контактов фильтра сбора.
Метод RenderStream
Метод RenderStream производит построение участка графа от исходного фильтра до фильтра-приемника включительно. В типовом случае в качестве фильтра-приемника может быть отображающий или смешивающий фильтр. В процессе соединения метод может устанавливать дополнительные фильтры необходимые для отображения потока, а также промежуточный фильтр, указанный в отдельном параметре, например компрессор. Фильтр-источник (pSource) и промежуточный фильтр (pIntermediate) должны быть установлены в граф с помощью метода AddFilter до вызова метода
RenderStream. Исключение сделано для фильтра отображения потока (pSink), который может устанавливаться по умолчанию. По умолчанию метод устанавливает в качестве фильтра-приемника отображающий фильтр Video Renderer, который может использоваться для всех платформ и в настоящее время считается устаревшим. Для канала звука устанавливается по умолчанию фильтр DirectSound Renderer. Если параметр pSink указывает на фильтр, то он также должен быть предварительно установлен в граф с помощью метода AddFilter. Метод RenderStream обрабатывает многие дополнительные детали построения графа сбора.
Некоторые фильтры сбора не имеют контакта предварительного просмотра, а только контакт сбора (capture). В этом случае метод производит установку фильтра Smart Tee. Фильтр разделяет поток на две части, каждая часть общего потока обеспечивает характеристики и поведение в соответствии с имитируемым контактом. При установке Smart Tee метод возвращает значение VFW_S_NOPREVIEWPIN. В данном случае при решении стандартных задач можно не обращать внимания на отсутствие отдельного контакта предварительного просмотра, метод обрабатывает эту ситуацию автоматически, скрывая все детали. Следует отметить, что метод не делает различия между звуковым фильтром сбора и фильтром сбора видео. Он также устанавливает фильтр Smart Tee и для звукового фильтра сбора, что часто является излишним. Учитывая, что фильтр звука обычно имеет только контакт
Capture, применять метод для построения ветви записи звука не следует.
Также некоторые фильтры сбора могут обрабатывать данные, передаваемые на обратном ходе кадровой развертки (VBI). Данные, передаваемые на обратном ходе кадровой развертки, могут быть двух стандартов, американского и европейского. Для обработки данных американского стандарта метод должен вызываться дважды, один раз для контакта категории PIN_CATEGORY_VBI и второй раз для контакта категории PIN_CATEGORY_CC. Метод устанавливает в граф любые фильтры необходимые для использования данных VBI. Для европейского стандарта передачи телетекста контакт VBI на фильтре сбора не обрабатывается автоматически, метод не устанавливает необходимые фильтры, их нужно установить в граф вручную.
Существуют фильтры сбора, имеющие контакт видеопорта категории PIN_CATEGORY_VIDEOPORT вместо контакта предварительного просмотра. Для таких случаев метод устанавливает смешивающий оверлейный фильтр (Overlay Mixer), который обеспечивает как предварительный просмотр, так и запись файла. Категория контакта в этом случае указывается PIN_CATEGORY_PREVIEW или PIN_CATEGORY_CAPTURE, но не PIN_CATEGORY_VIDEOPORT.
Таким же образом некоторые фильтры формируют данные VBI, используя контакт видеопорта (PIN_CATEGORY_VIDEOPORT_VBI). В этом случае следует указывать категорию PIN_CATEGORY_VIDEOPORT, детали порт обрабатывает самостоятельно.
HRESULT RenderStream(
const GUID *pCategory,
const GUID *pType,
IUnknown *pSource,
IBaseFilter *pIntermediate,
IBaseFilter *pSink
);
Параметры
pCategory
[in]
Указатель на категорию контакта, являющийся членом структуры AMPROPERTY_PIN_CATEGORY или NULL при использовании контакта любого типа. Типовые значения величины следующие.
PIN_CATEGORY_CAPTURE
PIN_CATEGORY_PREVIEW
PIN_CATEGORY_CC
Все значения величин приводятся в приложении в разделе "Категории контактов" (Pin Property Set).
pType
[in]
Указатель на GUID главного медиа формата выходного контакта или NULL при использовании контакта любого медиа формата. Список значений приводится в приложении Главные типы (Major Types).
pSource
[in]
Указатель на стартовый фильтр, с которого начинается соединение или указатель на выходной контакт стартового фильтра. Если параметр pSource является указателем на фильтр, то производится поиск контакта на данном фильтре с использованием параметров pType и pCategory для ограничения поиска. Если параметр pSource является указателем на контакт, то параметры pType и pCategory не используются и должны быть установлены в NULL. Поиск производится для не соединенных контактов. Если не соединенных контактов, соответствующих критерию поиска несколько, то подключается первый найденный.
pIntermediate
[in]
Указатель на промежуточный фильтр, например компрессор. Может быть NULL.
pSink
[in]
Указатель на конечный фильтр. Для большинства применений параметр может указывать на отображающий или смешивающий фильтр. Если pSink равен NULL, тогда метод пытается установить в граф отображающий фильтр Video Renderer, обеспечивающий воспроизведение видеоданных для любых условий. Для звука устанавливается фильтр DirectSound Renderer. Описание фильтра Video Renderer приводится в приложении.
Возвращаемые значения
Возвращаемый код |
Описание |
S_OK |
Успешное завершение. |
VFW_S_NOPREVIEWPIN |
Предварительный просмотр осуществляется через фильтр Smart Tee. |
E_FAIL |
Ошибка. |
E_INVALIDARG |
Неправильные аргументы. |
E_POINTER |
Значение указателя NULL. |
VFW_E_NOT_IN_GRAPH |
Фильтра нет в графе. Эта ошибка может произойти, если не был вызван метод AddFilter или метод SetFiltergraph для подключения графа к объекту построителя графа сбора (Capture Graph Builder). В этом случае объект построителя графа сбора автоматически создает собственный граф. |
Метод RenderStream соединяет два или три фильтра в цепочку. Фильтр лучше всего работает при условии, что каждый фильтр имеет не более одного входного или выходного контакта определенного типа. Рассмотрим поведение фильтра при соединении трех фильтров А, В и С, где символы А, В и С означают указатели на фильтры (IBaseFilter). Первые два параметра пока не участвуют и равны нулю (NULL) и фильтры имеют один входной и один выходной контакт.
Допустим, что производится вызов метода в виде
RenderStream(NULL, NULL, A, B, C) . Метод соединит все три фильтра последовательно.
Если указатель на фильтр В установить равным NULL RenderStream (NULL, NULL, A, NULL, C), то используя алгоритм "интеллектуального" соединения метод добавит в граф фильтр В и соединит их в цепочку. Длинную цепочку фильтров можно создать, вызвав метод два раза.
RenderStream(NULL, NULL, A, B, C)
RenderStream(NULL, NULL, C, D, E)
При установке последнего параметра в NULL, метод автоматически установит отображающий фильтр по умолчанию. Для видеоканала это будет фильтр Video Renderer, для звукового канала фильтр DirectSound Renderer. Для подключения отображающего фильтра Video Mixing Renderer (VMR), он должен быть указан явно.
Если в третьем параметре передается указатель на фильтр, и он имеет не один контакт, а несколько с разными медиа типами, то тогда следует использовать первые два параметра, которые помогают локализовать выходной контакт на фильтре. Первый параметр используется только для фильтров сбора. Он указывает выходного категорию контакта (GUID). Список категорий контактов приводится в справочном разделе. Для любых фильтров сбора две категории контактом всегда справедливы:
PIN_CATEGORY_CAPTURE
PIN_CATEGORY_PREVIEW
Второй параметр идентифицирует медиа тип и для типовых случаев может иметь один из следующих типов:
- MEDIATYPE_Audio
- MEDIATYPE_Video
- MEDIATYPE_Interleaved (DV)
Этот параметр можно использовать, если выходные контакты фильтра поддерживают перечисление предопределенных медиа типов.
Управление параметрами видеопотока на фильтре сбора
Видеоданные на контактах фильтра сбора могут быть представлены в различных цветовых форматах, размеры изображения, частота кадров и другие параметры могут изменяться. Все параметры изображения определяются медиа форматом, который представлен на контакте фильтра.
Медиа формат описывается структурой AM_MEDIA_TYPE, которая кратко упоминалась ранее и будет подробно рассмотрена далее. Для WDM устройств управление медиа форматом производится с помощью интерфейса IAMStreamConfig. При установке нового медиа формата выходной контакт фильтра может быть, как подключен к следующему фильтру, так и отключен.
Если контакт отключен и фильтр поддерживает устанавливаемый формат, то метод IAMStreamConfig::SetFormat выполняется успешно. Установка формата происходит при последующем соединении фильтров. При этом производится согласование медиа форматов с подключаемым входным контактом следующего фильтра. Если медиа форматы не могут быть согласованы фильтрами, соединение не происходит. Для соединения фильтров может применяться метод, использующий алгоритм интеллектуального соединения. Тогда для согласования форматов автоматически устанавливается промежуточный трансформирующий фильтр. При других способах соединения установку промежуточного фильтра следует делать вручную.
Если контакт подключен, метод IAMStreamConfig::SetFormat пытается установить формат и произвести повторное соединение фильтров. Поскольку метод SetFormat не производит установку промежуточных фильтров при несогласованности форматов, то он заканчивает выполнение с ошибкой. В остальных случаях установка формата происходит успешно.
Структура AM_MEDIA_TYPE описывает формат медиа выборки, для видеоданных это один кадр изображения. Для изучения установки параметров изображения можно использовать изменение медиа формата на контакте предварительного просмотра (Preview). Контакт предварительного просмотра позволяет производить изменение медиа формата в более широких пределах, чем контакт записи и не нужно дополнительно организовывать запись файла.
Изменение медиа формата допустимо только в определенных пределах, которые определяются возможностями фильтра и описаны в соответствующих структурах для каждого медиа формата. Все поддерживаемые фильтром медиа форматы можно определить с помощью метода IAMStreamConfig::GetStreamCaps, применение, которого рассмотрим далее. Большое количество поддерживаемых фильтром медиа форматов и сложность структур, используемых при этом, делает процесс изменения медиа формата достаточно сложным.
Установку медиа формата можно производить раздельно для контактов предварительного просмотра и контакта записи (capture). Если в режиме предварительного просмотра размер изображения можно установить любым, вплоть до полного экрана, то при записи файлов предварительный просмотр может быть на экране не более чем номинального размера 352х288 (SEKAM). Это вполне понятно, поскольку нет смысла производить запись растянутого изображения, это можно сделать при воспроизведении.
Если для установки формата достаточно предопределенного формата, то можно в структуре указать GUID главного типа и подтипа при нулевых остальных данных. Формат будет дополнен остальными данными автоматически.
Для правильного использования структуры AM_MEDIA_TYPE и других, участвующих в установке медиа формата следует предварительно ознакомиться с ними и методами интерфейса IAMStreamConfig, с помощью которых производится изменение медиа формата. Также далее ознакомимся с принципами изменения размеров изображения и преобразования входного изображения в выходное изображение. Дальнейшая работа будет производиться с проектом в папке ProjectState6.
Структура AM_MEDIA_TYPE
typedef struct _MediaType {
GUID majortype;
GUID subtype;
BOOL bFixedSizeSamples;
BOOL bTemporalCompression;
ULONG lSampleSize;
GUID formattype;
IUnknown *pUnk;
ULONG cbFormat;
[size_is(cbFormat)] BYTE *pbFormat;
} AM_MEDIA_TYPE;
majortype
Главный тип (GUID), описывающий медиа выборку. Для нашего примера это MEDIATYPE_Video.
Subtype
Подтип (GUID), описывающий медиа выборку. Для видеоизображения определяет цветовые форматы, RGB, например, и другие. Из всего множества подтипов фильтр сбора может поддерживать ограниченное число подтипов. Определение поддерживаемых подтипов производится с помощью метода IAMStreamConfig::GetStreamCaps. Для некоторых форматов величина может иметь значение MEDIASUBTYPE_None, это означает, что подтип не нужен.
bFixedSizeSamples
Если значение равно TRUE, то выборка имеет фиксированный размер. Эта величина предназначена только для чтения. Для звука она всегда установлена в TRUE. Для не сжатого видеоизображения она также равна TRUE, а для сжатого FALSE.
bTemporalCompression
Значение TRUE указывает на применение межкадрового кодирования (временное сжатие). Эта величина предназначена только для чтения.
lSampleSize
Размер выборки в байтах. Для сжатых данных величина может быть равна нулю.
formattype
GUID, который указывает на тип блока форматирования, то есть указывается тип структуры, описывающей формат выборки.
Тип формата |
Тип структуры |
FORMAT_None |
None. |
FORMAT_DvInfo |
DVINFO |
FORMAT_MPEGVideo |
MPEG1VIDEOINFO |
FORMAT_MPEG2Video |
MPEG2VIDEOINFO |
FORMAT_VideoInfo |
VIDEOINFOHEADER |
FORMAT_VideoInfo2 |
VIDEOINFOHEADER2 |
FORMAT_WaveFormatEx |
WAVEFORMATEX |
GUID_NULL |
None |
Для фильтра сбора аналогового телевидения видеоизображение описывается структурой VIDEOINFOHEADER, а звук структурой WAVEFORMATEX.
pUnk
Не применяется.
cbFormat
Размер блока форматирования в байтах.
pbFormat
Указатель на блок форматирования. Структура формата должна быть представлена, если тип формата не GUID_NULL или не FORMAT_None. Может быть NULL. Для доступа к структуре определенного типа указатель должен быть преобразован в тип соответствующий типу структуры. В некоторых случаях можно установить указатель на блок формата в NULL и тип формата в GUID_NULL. Это позволит указать диапазон возможных форматов, например, указав MEDIASUBTYPE_RGB24, можно не указывать точно ширину и высоту изображения.
На рисунке 4.5 показано строение структуры AM_MEDIA_TYPE для типа формата FORMAT_VideoInfo...............
[в начало]