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


Каналы и каналы AVStream

Канал — это набор фильтров AVStream, которые совместно используют общий распределител.

На следующем рисунке показан канал, состоящий из трех фильтров AVStream: исходного фильтра, фильтра преобразования на месте и фильтра отрисовщика.

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

В этом примере KSProxy (не показан) выбрал распределителя, представленный блоком Alloc на схеме.

AVStream создает внутренний объект инициатора запроса, связанный с исходным фильтром. На схеме инициатор запроса отображается как Req. Мини-отвертка указывает в элементе AllocatorFramingKSPIN_DESCRIPTOR_EX тип памяти и объем непрерывной памяти для назначения кадру. Соответственно, инициатор запроса получает кадры из распределителя и передает их следующему компоненту в цепи.

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

Наконец, данные передаются в фильтр отрисовщика, реализованный третьим фильтром AVStream.

Так как все контакты в этом графе являются контактами AVStream, AVStream использует собственные внутренние транспортные интерфейсы вместо отправки IRP с помощью IoCallDriver, что сокращает задержку и повышает производительность.

В частности, когда приложение приводит к переходу графа к KSSTATE_ACQUIRE (например, когда пользователь нажимает кнопку Воспроизвести в GraphEdit), AVStream напрямую подключает очереди фильтров, как показано выше.

Таким образом, отправляемые нижестоящим образом кадры возвращаются инициатору запроса, где их можно перезапустить после завершения отрисовки. Этот путь к данным AVStream является каналом.

Рассмотрим второй пример, показанный на рисунке ниже, в котором фильтр преобразования не является фильтром AVStream, но по-прежнему является фильтром в режиме ядра.

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

Как и в первом примере, этот пример включает три фильтра: источник AVStream, преобразование KS (это может быть драйвер, использующий KS напрямую, или мини-драйвер в классе потока) и отрисовщик AVStream.

Как показано на первом рисунке, контакты сначала соединены между собой. Однако при переходе графа фильтра на KSSTATE_ACQUIRE фильтр Потоковой передачи ядра 1.0 не поддерживает транспортный интерфейс AVStream. В результате AVStream не обходит контакты; Вместо этого он должен использовать ввод-вывод для перемещения данных между фильтрами.

В частности, когда кадр покидает очередь исходного фильтра, AVStream вызывает IoCallDriver. В этом вызове параметр Irp содержит кадр для передачи из выходного закрепления источника в фильтр преобразования.

Когда входной контакт отрисовщика получает IRP, закрепление помещает IRP в очередь. Когда драйвер отрисовщика завершает кадр, он возвращает кадр во входной контакт отрисовщика, как показано во втором примере.

AVStream теперь вызывает IoCompleteRequest, чтобы вернуть вышестоящий кадра. Выходной контакт исходного фильтра получает уведомление о завершении. Подпрограмма обратного вызова процесса пин-кода мини-driver может затем вызвать KsStreamPointerUnlock и переместить кадры обратно инициатору запроса для повторной передачи в цепь.

Рассмотрим последний пример, в котором источник кадра находится в пользовательском режиме. (Кроме того, конечный кадр назначения может находиться в пользовательском режиме.)

На приведенном ниже рисунке фильтр преобразования в режиме ядра не на месте получает кадры из фильтра DirectShow пользовательского режима и отправляет преобразованный кадр в отрисовщик AVStream в режиме ядра:

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

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

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

Мини-накопитель может внедрять кадры в цепь, вызывая KsPinSubmitFrame или KsPinSubmitFrameMdl. Если мини-driver использует этот метод, запрашивающий AVStream получает кадры в результате этих вызовов, а не из распределителя в режиме ядра.