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


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

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

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

Модель Push: доставка образца

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

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

Штырь может отклонить образец по нескольким причинам:

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

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

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

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

модель извлечения : запрос примера

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

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

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

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

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

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

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

Получение и доставка образцов