Поделиться через


Поддержка изменений динамического формата в кодеках AVStream

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

Следующая последовательность событий возникает, когда динамическое изменение формата происходит из источника мультимедиа:

  1. Драйвер получает запрос KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT , чтобы определить, поддерживает ли входной пин-код KS новый тип носителя. Драйверы должны поддерживать это свойство.

  2. Если входной контакт поддерживает новый тип носителя, обработчик KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT должен возвращать STATUS_SUCCESS. Затем драйвер определяет, может ли он возобновить поток, используя предлагаемые входные данные вместе с выбранными в настоящее время типами выходных носителей. Если да, поток возобновляется.

  3. Если входной контакт не поддерживает только что предложенный тип носителя, обработчик KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT должен возвратить ошибку. Затем HW MFT пересматривает тип носителя с подключенным компонентом.

  4. Если контакт ввода поддерживает новый тип входных данных мультимедиа, но для фильтра KS требуется другой тип выходного носителя, драйвер должен создать событие KSEVENT_DYNAMIC_FORMAT_CHANGE , как описано далее в этом разделе, чтобы уведомить HW MFT об изменении типа носителя.

  5. Когда HW MFT получает уведомление KSEVENT, он перемещает выходной пин-код с KSSTATE_RUN на KSSTATE_STOP.

  6. Затем HW MFT запрашивает у драйвера доступные типы мультимедиа, что преобразуется в вызов обработчика пересечения AVStrMiniIntersectHandlerEx драйвера. Драйвер должен сообщать предпочтительные типы выходных носителей в порядке предпочтения.

  7. Клиент пользовательского режима выбирает тип носителя и задает новый тип носителя на выходном контакте HW MFT. Это приводит к вызову подпрограммы диспетчеризации AVStrMiniPinSetDataFormat драйвера. Если драйвер принимает формат, возвращая STATUS_SUCCESS, потоковая передача возобновляется с новым типом мультимедиа. Если вызов завершается сбоем, компоненты, участвующие в изменении формата, должны пересмотреть тип носителя.

  8. HW MFT проверяет, есть ли какие-либо изменения в подключенном носителе. Если изменений нет, он устанавливает выбранный тип носителя на контакте и помещает его в KSSTATE_RUN. Если в подключенном носителе произошло изменение, HW MFT уничтожает контакт и повторно создает его с новым типом носителя и носителем. Затем MFT помещает контакт в KSSTATE_RUN.

  9. Возобновление потоковой передачи.

В некоторых ситуациях источник мультимедиа может не обнаружить изменение формата. Например, декодер 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.