Обработка изменений потока

В этом разделе описывается, как преобразование Media Foundation (MFT) должно обрабатывать изменения формата во время потоковой передачи.

Важно!

Этот раздел не относится к кодировщикам. Кодировщики не должны распространять изменения формата, как описано в этом разделе. Кодировщики должны принимать только тип входных данных, соответствующий текущему настроенному типу вывода.

 

Общие сведения об изменениях формата

Как правило, формат может измениться во время потоковой передачи по двум причинам.

  • Клиент может переключиться на поток с новым форматом. Например, в цифровом телевидении это может произойти из-за изменения канала.
  • В некоторых форматах видео, таких как H.264, битовый поток может сигнализировать об изменении формата. Такие изменения могут включать изменения в доминировании поля, разрешении видео или пропорции пикселей.

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

При изменении формата MFT может потребоваться новый тип входных данных, новый тип вывода или и то, и другое.

  • Изменения в типе входных данных инициируются клиентом. MFT никогда не изменяет собственный тип входных данных.
  • Изменения в типе выходных данных инициируются MFT. MFT сигнализирует о том, что требуется новый тип выходных данных, и клиент согласовывает новый тип выходных данных с MFT.

Таким образом, возможны три отдельных варианта:

  • Клиент задает новый тип входных данных. MFT использует новый формат без изменения типа выходных данных.
  • Клиент задает новый тип входных данных, и это активирует изменение в типе вывода.
  • Тип входных данных не меняется, но MFT обнаруживает изменение формата в битовом потоке, что требует нового типа вывода.

Реализация изменений формата

В оставшейся части этого раздела описывается, как клиент должен обработать изменение формата и как реализовать изменения формата в MFT.

Тип выходных данных

Любой MFT может инициировать изменение своего типа выходных данных следующим образом:

  1. Клиент вызывает IMFTransform::P rocessOutput. MFT отвечает следующим образом:
    1. MFT не создает выходную выборку в ProcessOutput.
    2. MFT задает флаг MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE в элементе dwStatus структуры MFT_OUTPUT_DATA_BUFFER .
    3. Метод ProcessOutput возвращает код ошибки MF_E_TRANSFORM_STREAM_CHANGE.
  2. Клиент вызывает IMFTransform::GetOutputAvailableType. Этот метод возвращает обновленный набор типов выходных данных.
  3. Клиент вызывает SetOutputType , чтобы задать новый тип вывода.
  4. Клиент возобновляет вызов ProcessInput/ProcessOutput.

Тип входных данных

Изменения в типе входных данных инициируются клиентом, а не MFT. Если тип входных данных изменяется, это может привести к изменению выходного типа.

Точная последовательность событий зависит от значения атрибута MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE .

Значение Описание
FALSE Прежде чем клиент установит новый тип входных данных, он должен очистить MFT.
TRUE Клиент может задать новый тип входных данных без очистки MFT.

 

MFT предоставляет этот атрибут с помощью метода IMFTransform::GetAttributes . Значение этого атрибута по умолчанию — FALSE; Если MFT не задает атрибут , то значение следует рассматривать как FALSE.

MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE имеет значение FALSE

  1. Клиент отправляет сообщение MFT_MESSAGE_COMMAND_DRAIN .
  2. Клиент истощает MFT, вызывая IMFTransform::P rocessOutput , пока ProcessOutput не вернет MF_E_TRANSFORM_NEED_MORE_INPUT.
  3. Клиент вызывает IMFTransform::SetInputType , чтобы задать новый тип входных данных.
  4. MFT проверяет тип входных данных. Если тип является недопустимым, SetInputType возвращает MF_E_INVALIDMEDIATYPE или другой код ошибки. В противном случае SetInputType возвращает S_OK.
  5. При условии, что входной тип является допустимым, MFT оценивает, меняется ли тип выходных данных. В противном случае потоковая передача продолжается, и дальнейшие действия не требуются.
  6. Если тип выходных данных изменяется:
    1. MFT делает недействительным текущий тип выходного носителя и обновляет список доступных типов выходных носителей.
    2. Следующий вызов ProcessOutput возвращает MF_E_TRANSFORM_STREAM_CHANGE, как описано в предыдущем разделе.
    3. Клиент вызывает IMFTransform::GetOutputAvailableType , чтобы получить обновленный список типов выходных данных.
    4. Клиент вызывает SetOutputType.

MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE имеет значение TRUE

  1. Клиент вызывает IMFTransform::SetInputType , чтобы задать новый тип входных данных.
  2. MFT проверяет тип входных данных. Если тип является недопустимым, SetInputType возвращает MF_E_INVALIDMEDIATYPE или другой код ошибки. В противном случае SetInputType возвращает S_OK.
  3. При условии, что входной тип является допустимым, MFT оценивает, меняется ли тип выходных данных. В противном случае потоковая передача продолжается, и дальнейшие действия не требуются.
  4. Перед изменением типа выходных данных MFT должен обработать все кэшированные входные примеры следующим образом:
    1. MFT не делает недействительным текущий тип выходных данных.
    2. MFT создает столько выходных данных, сколько может получиться из кэшированных входных примеров.
    3. Необязательно, принимает ли MFT новые входные примеры во время обработки кэшированных примеров. В этом случае новые входные примеры будут использовать новый формат входных данных, поэтому MFT должен отслеживать точку при изменении формата.
  5. После обработки MFT всех выборок, полученных до изменения типа входных данных, функция IMFTransform::P rocessOutput возвращает MF_E_TRANSFORM_STREAM_CHANGE.
  6. MFT делает недействительным текущий тип выходных данных и обновляет список доступных типов выходных носителей.
  7. Клиент согласовывает новый тип выходных данных, как описано выше.

Асинхронные MFT должны возвращать значение TRUE для атрибута MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE . При использовании асинхронного MFT клиент может предположить, что атрибут MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE имеет значение TRUE.

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

Предыдущий абзац относится в первую очередь к декодерам видео, которые могут получать межкодированные кадры из темпорального порядка и, следовательно, должны кэшировать их. Если MFT не кэшируют входные образцы, очистка по сути не выполняется. В этом случае MFT может присвоить MFT_SUPPORT_DYNAMIC_FORMAT_CHANGEзначение FALSE (или оставить атрибут ненастроенным).

Кроме того, обратите внимание, что каждый MFT должен правильно обрабатывать изменения формата после очистки. Атрибут MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE указывает, поддерживает ли MFT изменение формата без очистки.

Изменение в режиме чередование

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

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

Дополнительные сведения см. в разделе Чередование флагов в примерах.

Написание пользовательского MFT