Обработка данных в 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.
Обработка данных
Чтобы обработать данные, сделайте следующее:
- Для каждого входного потока заполните буфер входными данными.
- Вызовите метод IMediaObject::P rocessInput , чтобы доставить каждый буфер.
- Вызовите метод IMediaObject::P rocessOutput для обработки данных. Этот метод принимает массив буферов, по одному для каждого выходного потока.
- Повторяйте, пока не будет больше входных данных.
Метод 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 удаляет все буферы, которые он удерживает внутри.
Связанные темы