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


Обработка данных в DMO

[Функция, связанная с этой страницей DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngine, и аудио/ видео захвата в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать в новом коде MediaPlayer, IMFMediaEngine и аудио/видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает переписать существующий код, в котором используются устаревшие API, чтобы по возможности использовать новые API.]

В этом разделе объясняется, как обрабатывать поток данных с помощью DMO. Шаги, перечисленные в этом разделе, являются поведением по умолчанию; все МДО должны поддерживать описанные здесь методы. Эти методы используют отдельные буферы для входных и выходных данных. Некоторые МДО также поддерживают обработку на месте с использованием одного буфера. Дополнительные сведения об обработке на месте см. в разделе Обработка на месте.

Выделение буферов

Клиент отвечает за все выделение буфера. Задавая типы мультимедиа в DMO, запросите объект DMO для требований к буферу каждого потока. Они могут изменяться в зависимости от типа носителя. Для каждого потока вызовите метод IMediaObject::GetInputSizeInfo или IMediaObject::GetOutputSizeInfo . Эти методы возвращают следующие сведения:

  • Минимальный размер буфера в байтах.
  • Требования к выравниванию, если таковые есть. Буфер выравнивается, если начальный адрес является кратным некоторым указанным целым числом.
  • Максимальный объем данных, которые DMO будет хранить для lookahead. Это число применяется только к входным потокам. Для некоторых типов данных (например, кодировки MPEG) DMO может потребоваться заглянуть в поток. Значение lookahead указывает, сколько входных данных потребуется DMO, прежде чем он сможет создать выходные данные.

Клиент должен выделить буферы, соответствующие этим требованиям. Кроме того, DMO может иметь требования к тому, как клиент упаковывая входные данные. Например, для DMO может потребоваться, чтобы каждый буфер содержал ровно один образец (или видеокадр). Чтобы определить эти требования, вызовите метод IMediaObject::GetInputStreamInfo . Метод IMediaObject::GetOutputStreamInfo возвращает аналогичные сведения о потоке вывода.

В модели потоковой передачи по умолчанию клиент не передает необработанные указатели буфера в DMO. Вместо этого он использует упрощенный COM-объект, который предоставляет интерфейс IMediaBuffer . Интерфейс IMediaBuffer выступает в качестве com-оболочки для блока памяти. Так как это COM-объект, он поддерживает подсчет ссылок, что помогает гарантировать, что буферы не освобождаются во время использования.

Примечание

Интерфейс IMediaBuffer выполняет функцию, аналогичную интерфейсу IMediaSample в DirectShow.

 

Клиент должен реализовать объект IMediaBuffer . Дополнительные сведения см. в разделе Реализация IMediaBuffer.

Обработка данных

Чтобы обработать данные, сделайте следующее:

  1. Для каждого входного потока заполните буфер входными данными.
  2. Вызовите метод IMediaObject::P rocessInput , чтобы доставить каждый буфер.
  3. Вызовите метод IMediaObject::P rocessOutput для обработки данных. Этот метод принимает массив буферов, по одному для каждого выходного потока.
  4. Повторяйте, пока не будет больше входных данных.

Метод ProcessInput принимает входные данные для одного потока за раз. Как правило, метод возвращает немедленно, а DMO содержит счетчик ссылок на объект IMediaBuffer . Он освобождает объект после обработки всех данных в буфере или при очистке DMO приложением. Не используйте буфер повторно, пока DMO не освободит его. Чтобы определить, может ли входной поток принимать дополнительные данные, вызовите метод IMediaObject::GetInputStatus . Этот метод возвращает флаг DMO_INPUT_STATUSF_ACCEPT_DATA, если поток может принимать дополнительные входные данные.

Метод ProcessOutput создает выходные данные для всех потоков вывода одновременно. Приложение передает массив DMO_OUTPUT_DATA_BUFFER структур, по одной для каждого выходного потока. Каждая структура в массиве имеет указатель на объект IMediaBuffer . DMO записывает в буферы столько выходных данных, сколько может. Он также устанавливает различные флаги для отчета о состоянии операции. Флаг DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE указывает, что DMO может создавать дополнительные выходные данные из существующих входных данных. В этом случае клиент может снова вызвать ProcessOutput . В противном случае он должен вызвать ProcessInput с дополнительными входными данными. DMO никогда не изменяет данные во входных буферах; он записывает только в выходные буферы.

После доставки всех данных во входной поток вызовите метод IMediaObject::D iscontinuity . DMO не принимает дальнейшие входные данные в этот поток, пока вы не обработаете остальные выходные данные (или не очистите DMO).

В любой момент после начала потоковой передачи DMO может принимать входные данные или создавать выходные данные, или и то, и другое. Поэтому либо GetInputStatus возвращает DMO_INPUT_STATUSF_ACCEPT_DATA, либо ProcessOutput возвращает DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE. Приложение поддерживает поток данных, проверяя наличие этих флагов и вызывая ProcessInput или ProcessOutput соответствующим образом. Чтобы прервать поток данных, вызовите метод IMediaObject::Flush . Этот метод приводит К тому, что DMO удаляет все буферы, которые он удерживает внутри.

Непосредственное размещение объектов DMO

Обработка на месте