Поддержка изменений динамического формата в кодеках AVStream
При изменении динамического формата в работающем потоке мультимедиа модуль Devproxy, предоставляемый системой, согласовывает с контактом захвата, чтобы определить, будет ли новый формат приемлемым.
Следующая последовательность событий возникает, когда динамическое изменение формата происходит из источника мультимедиа:
Драйвер получает запрос KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT , чтобы определить, поддерживает ли входной пин-код KS новый тип носителя. Драйверы должны поддерживать это свойство.
Если входной контакт поддерживает новый тип носителя, обработчик KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT должен возвращать STATUS_SUCCESS. Затем драйвер определяет, может ли он возобновить поток, используя предлагаемые входные данные вместе с выбранными в настоящее время типами выходных носителей. Если да, поток возобновляется.
Если входной контакт не поддерживает только что предложенный тип носителя, обработчик KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT должен возвратить ошибку. Затем HW MFT пересматривает тип носителя с подключенным компонентом.
Если контакт ввода поддерживает новый тип входных данных мультимедиа, но для фильтра KS требуется другой тип выходного носителя, драйвер должен создать событие KSEVENT_DYNAMIC_FORMAT_CHANGE , как описано далее в этом разделе, чтобы уведомить HW MFT об изменении типа носителя.
Когда HW MFT получает уведомление KSEVENT, он перемещает выходной пин-код с KSSTATE_RUN на KSSTATE_STOP.
Затем HW MFT запрашивает у драйвера доступные типы мультимедиа, что преобразуется в вызов обработчика пересечения AVStrMiniIntersectHandlerEx драйвера. Драйвер должен сообщать предпочтительные типы выходных носителей в порядке предпочтения.
Клиент пользовательского режима выбирает тип носителя и задает новый тип носителя на выходном контакте HW MFT. Это приводит к вызову подпрограммы диспетчеризации AVStrMiniPinSetDataFormat драйвера. Если драйвер принимает формат, возвращая STATUS_SUCCESS, потоковая передача возобновляется с новым типом мультимедиа. Если вызов завершается сбоем, компоненты, участвующие в изменении формата, должны пересмотреть тип носителя.
HW MFT проверяет, есть ли какие-либо изменения в подключенном носителе. Если изменений нет, он устанавливает выбранный тип носителя на контакте и помещает его в KSSTATE_RUN. Если в подключенном носителе произошло изменение, HW MFT уничтожает контакт и повторно создает его с новым типом носителя и носителем. Затем MFT помещает контакт в KSSTATE_RUN.
Возобновление потоковой передачи.
В некоторых ситуациях источник мультимедиа может не обнаружить изменение формата. Например, декодер MPEG2 должен декодировать каждый пакет, чтобы найти любое изменение формата.
В таком случае, если драйвер обнаруживает изменение формата, драйвер оборудования должен создать динамическое изменение формата KSEVENT. Затем HW MFT запрашивает у контакта поддерживаемые типы носителей. Закрепление должно возвращать предпочтительные типы мультимедиа в порядке предпочтения. Затем HW MFT следует последовательности событий, описанных в шагах 4–9 предыдущего раздела.
Если драйвер не может обработать такое изменение формата, он должен вернуть ошибку потоковой передачи, которая затем распространяется на MF.
В следующем примере кода показано, как определить новое динамическое изменение формата с помощью KSEVENT:
// {162AC456-83D7-4239-96DF-C75FFA138BC6}
#define STATIC_KSEVENTSETID_DynamicFormatChange\
0x162ac456, 0x83d7, 0x4239, 0x96, 0xdf, 0xc7, 0x5f, 0xfa, 0x13, 0x8b, 0xc6 DEFINE_GUIDSTRUCT("162AC456-83D7-4239-96DF-C75FFA138BC6", KSEVENTSETID_ DynamicFormatChange);
#define KSEVENTSETID_DynamicFormatChange DEFINE_GUIDNAMED(KSEVENTSETID_ DynamicFormatChange)
typedef enum {
KSEVENT_DYNAMIC_FORMAT_CHANGE = 0
};
DEFINE_KSEVENT_TABLE(DynamicFormatChangeEventTable) {
DEFINE_KSEVENT_ITEM
(
KSEVENT_DYNAMIC_FORMAT_CHANGE,
sizeof(KSEVENTDATA),
0,
NULL,
NULL,
NULL
)
};
KSEVENT_SET PinEventTable[] =
{
DEFINE_KSEVENT_SET
(
&KSEVENTSETID_DynamicFormatChange,
SIZEOF_ARRAY(DynamicFormatChangeEventTable),
DynamicFormatChangeEventTable
)
};
Каждое закрепление должно предоставлять это событие в своем дескрипторове контактов. Событие имеет тип KSEVENTF_EVENT_HANDLE.
Прежде чем драйвер создаст это событие, он должен задать предпочтительные типы носителей для контакта KS на основе выбранного в данный момент типа входного носителя. Это можно сделать с помощью функции _KsEdit в дескрипторе контакта.
Чтобы создать событие, драйверы должны вызывать KsGenerateEvents.