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


Доставка примеров

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

В этой статье описывается, как фильтр предоставляет пример. В нем описывается модель отправки с использованием методов IMemInputPin и модель извлечения с помощью IAsyncReader.

Принудительная модель: доставка примера

Выходной контакт доставляет пример путем вызова метода IMemInputPin::Receive или метода IMemInputPin::ReceiveMultiple , который эквивалентен, но предоставляет массив примеров. Входной контакт может блокироваться внутри Receive (или ReceiveMultiple). Если закрепление может блокироваться, метод IMemInputPin::ReceiveCanBlock должен возвращать S_OK. Если закрепление гарантирует, что он никогда не будет блокироваться, ReceiveCanBlock должен вернуть S_FALSE. Возвращаемое значение S_OK не означает, что функция Receive всегда блокируется.

Несмотря на то, что функция Получения может блокировать ожидание доступности ресурса, она не должна блокировать ожидание дополнительных данных из фильтра вышестоящий. Это может привести к взаимоблокировке, в которой фильтр вышестоящий ожидает освобождения нижестоящего фильтра, что никогда не происходит, так как подчиненный фильтр ожидает вышестоящий фильтра. Однако если фильтр содержит несколько входных контактов, один контакт может ждать, пока другой контакт получит данные. Например, фильтр AVI Mux делает это, чтобы он смог чередовать аудио- и видеоданные.

Закрепление может отклонить выборку по ряду причин:

  • Закрепление очищается (см. раздел Очистка).
  • Контакт не подключен.
  • Фильтр остановлен.
  • Произошла другая ошибка.

Метод Receive должен возвращать S_FALSE в первом случае, а в других — код сбоя. Фильтр вышестоящий должен прекратить отправку примеров, если код возврата отличается от S_OK.

Первые три случая можно считать "ожидаемыми" сбоями в том смысле, что фильтр был в неправильном состоянии для получения примеров. Непредвиденная ошибка приведет к тому, что закрепление отклоняет образец, даже если контакт находится в принимающем состоянии. Если возникает ошибка этого типа, пин-код должен отправить оповещение об окончании потока вниз и отправить событие EC_ERRORABORT в диспетчер фильтров Graph.

В базовых классах DirectShow метод CBaseInputPin::CheckStreaming проверяет общие случаи сбоя — очистку, остановку и т. д. Производный класс должен проверка для сбоев, относящихся к фильтру. В случае ошибки метод CBaseInputPin::Receive отправляет уведомление о завершении потока и событие EC_ERRORABORT.

Модель по запросу: запрос примера

В интерфейсе IAsyncReader входной пин-код запрашивает примеры из выходного закрепления путем вызова одного из следующих методов:

Метод Request является асинхронным; входной пин-код вызывает IAsyncReader::WaitForNext , чтобы дождаться завершения запроса. Два других метода являются синхронными.

Когда следует доставлять данные

Фильтр всегда предоставляет образцы, пока он находится в состоянии выполнения. В большинстве случаев фильтр также предоставляет образцы в приостановленном режиме. Это позволяет графу подсказывать данные, чтобы воспроизведение начиналось сразу при вызове метода Run (см. раздел Состояния фильтра). Если фильтр не доставляет данные во время приостановки, метод IMediaFilter::GetState фильтра должен возвращать VFW_S_CANT_CUE в приостановленном состоянии. Этот код возврата сигнализирует графу фильтра не ждать данных из фильтра, прежде чем он завершит переход приостановки. В противном случае метод Pause будет блокироваться на неопределенный срок. Пример кода см. в разделе CBaseFilter::GetState.

Ниже приведены некоторые примеры того, когда фильтру может потребоваться вернуть VFW_S_CANT_CUE:

  • Динамические источники, такие как фильтры записи, не должны отправлять данные во время приостановки. См . раздел Создание данных в фильтре отслеживания.
  • Фильтр разбиения может отправлять данные во время приостановки в зависимости от реализации. Если фильтр использует отдельные потоки для постановки данных в очередь на каждом выходном контакте, он может отправлять данные во время приостановки. Но если фильтр использует один поток для каждого выходного контакта, первый контакт может заблокировать поток при вызове Receive, что не позволит другим контактам отправлять данные. В этом случае необходимо вернуть VFW_S_CANT_CUE.
  • Фильтр может периодически доставлять данные. Например, он может проанализировать пользовательский поток данных и отфильтровать некоторые пакеты при доставке других. В этом случае фильтр может не гарантировать доставку данных во время приостановки.

Исходный фильтр (с использованием модели принудительной отправки) или фильтр синтаксического анализа (с использованием модели push-извлечения) создает один или несколько потоков потоковой передачи, которые доставляют образцы как можно быстрее. Подчиненные фильтры, такие как декодеры и преобразования, обычно отправляют данные только при вызове метода Receive для входных контактов.

Получение и доставка примеров