Обработка изменений потока
В этом разделе описывается, как преобразование Media Foundation (MFT) должно обрабатывать изменения формата во время потоковой передачи.
Важный
Этот раздел не применяется к кодировщикам. Кодировщики не должны распространять изменения формата, как описано в этом разделе. Кодировщики должны принимать только входной тип, соответствующий текущему настроенному типу вывода.
Обзор изменений формата
Обычно существуют две причины, по которым формат может измениться во время потоковой передачи.
- Клиент может переключиться в поток с новым форматом. Например, в цифровом телевидении это может произойти из-за изменения канала.
- В некоторых форматах видео, таких как H.264, битовый поток может сигнализировать об изменении формата. Такие изменения могут включать изменения в доминировании полей, разрешении видео или пропорции пикселей.
Если тип кодирования изменяется, клиенту может потребоваться удалить MFT из конвейера и заменить его другим MFT. (Например, клиенту может потребоваться переключение в новый декодатор.) Этот раздел не охватывает эту ситуацию. В этом разделе рассматриваются только те случаи, когда текущий MFT может обрабатывать новый формат.
Если формат изменяется, MFT может потребовать нового типа ввода, нового типа вывода или обоих.
- Изменения входного типа инициируются клиентом. MFT никогда не изменяет собственный тип входных данных.
- Изменения типа выходных данных инициируются MFT. MFT сигнализирует о том, что он требует нового выходного типа, и клиент согласовывает новый тип вывода с MFT.
Таким образом, возможны три отдельных случая:
- Клиент задает новый тип входных данных. MFT использует новый формат без изменений в типе выходных данных.
- Клиент задает новый тип входных данных, и это активирует изменение типа выходных данных.
- Тип входных данных не изменяется, но MFT обнаруживает изменение формата в битовом потоке, для которого требуется новый тип вывода.
Реализация изменений формата
Остальная часть этого раздела описывает, как клиент должен обработать изменение формата и как реализовать изменения формата в MFT.
Тип вывода
Любой MFT может инициировать изменение типа выходных данных следующим образом:
- Клиент вызывает IMFTransform::ProcessOutput. MFT отвечает следующим образом:
- MFT не создает выходной пример в ProcessOutput.
- MFT задает флаг MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE в элементе dwStatus структуры MFT_OUTPUT_DATA_BUFFER.
- Метод ProcessOutput возвращает код ошибки MF_E_TRANSFORM_STREAM_CHANGE.
- Клиент вызывает IMFTransform::GetOutputAvailableType. Этот метод возвращает обновленный набор типов выходных данных.
- Клиент вызывает SetOutputType, чтобы задать новый тип вывода.
- Клиент возобновляет вызов ProcessInput/ProcessOutput.
Тип входных данных
Изменения типа входных данных инициируются клиентом, никогда не MFT. Если тип ввода изменяется, он может активировать изменение типа выходных данных.
Точная последовательность событий зависит от значения атрибута MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE.
Ценность | Описание |
---|---|
FALSE | Прежде чем клиент задает новый тип входных данных, он должен очистить MFT. |
ИСТИНА | Клиент может задать новый тип ввода без очистки MFT. |
MFT предоставляет этот атрибут через метод IMFTransform::GetAttributes. Значение по умолчанию этого атрибута — FALSE; если MFT не задает атрибут, следует считать значение FALSE.
MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE имеет значение FALSE
- Клиент отправляет сообщение MFT_MESSAGE_COMMAND_DRAIN.
- Клиент очищает MFT, вызывая IMFTransform::ProcessOutput, до тех пор, пока ProcessOutput не вернет MF_E_TRANSFORM_NEED_MORE_INPUT.
- Клиент вызывает IMFTransform::SetInputType, чтобы задать новый тип входных данных.
- MFT проверяет тип входных данных. Если тип недопустим, SetInputType возвращает MF_E_INVALIDMEDIATYPE или другой код ошибки. В противном случае SetInputType возвращает S_OK.
- Предполагая, что входной тип является допустимым, MFT оценивает, изменяется ли тип выходных данных. Если нет, потоковая передача продолжается, и дальнейшие действия не требуются.
- Если тип выходных данных изменяется:
- MFT делает недействительным текущий тип выходного носителя и обновляет список доступных типов выходных носителей.
- Следующий вызов ProcessOutput возвращает MF_E_TRANSFORM_STREAM_CHANGE, как описано в предыдущем разделе.
- Клиент вызывает IMFTransform::GetOutputAvailableType, чтобы получить обновленный список типов выходных данных.
- Клиент вызывает SetOutputType.
MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE — ИСТИНА
- Клиент вызывает IMFTransform::SetInputType, чтобы задать новый тип входных данных.
- MFT проверяет тип входных данных. Если тип недопустим, SetInputType возвращает MF_E_INVALIDMEDIATYPE или другой код ошибки. В противном случае SetInputType возвращает S_OK.
- Предполагая, что входной тип является допустимым, MFT оценивает, изменяется ли тип выходных данных. Если нет, потоковая передача продолжается, и дальнейшие действия не требуются.
- Перед изменением типа выходных данных MFT должен обрабатывать все кэшированные входные образцы, как показано ниже.
- MFT не аннулирует текущий тип выходных данных.
- MFT создает столько выходных данных, насколько это возможно из кэшированных входных данных.
- Необязательно, принимает ли MFT новые входные образцы во время обработки кэшированных примеров. В этом случае новые входные образцы будут использовать новый формат ввода, поэтому MFT должен отслеживать момент, когда изменился формат.
- После обработки всех образцов, полученных до изменения входного типа, IMFTransform::ProcessOutput возвращает MF_E_TRANSFORM_STREAM_CHANGE.
- MFT делает недействительным текущий тип выходных данных и обновляет список доступных типов выходных носителей.
- Клиент согласовывает новый тип вывода, как описано ранее.
асинхронные MFT должны возвращать значение TRUE для атрибута MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE. При использовании асинхронного MFT клиент может предположить, что атрибут MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE имеет значение TRUE.
Если MFT_SUPPORT_DYNAMIC_FORMAT_CHANGETRUE, основное различие заключается в том, что клиенту не требуется очистка MFT перед установкой нового типа ввода. В результате входной тип может измениться, пока MFT держится на входных образцах. Важно, чтобы MFT не просто сбрасывал эти образцы. Кроме того, выходной тип не может измениться, пока MFT не обрабатывает все кэшированные данные.
Предыдущий абзац особенно относится к декодерам видео, которые могут получать межкодированные кадры вне временного порядка, поэтому им необходимо их кэшировать. Если MFT не кэширует входные образцы, их очистка по сути аналогична no-op. В этом случае MFT может задать MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE значение FALSE (или оставить атрибут не задан).
Кроме того, обратите внимание, что каждый MFT должен правильно обрабатывать изменения формата после очистки. Атрибут MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE указывает, поддерживает ли MFT изменения формата без освобождения буфера.
Изменение в режиме переплета
Изменения в режиме чересстрочной развёртки видео являются особым случаем, так как они не делают недействительным текущий тип носителя. Вместо этого для каждого кадра видео задается режим переплета, задав атрибуты в образце мультимедиа. Видео MFT должен проверять каждый входной образец на наличие этих флагов.
Режим переплета может измениться, когда преобладание поля переключается с верхнего поля на нижнее поле или когда видео переключается между прогрессивными и переплетными изображениями.
Для получения дополнительной информации см. "Флаги чересстрочной развертки" в примерах.
Связанные разделы