DirectShow - Как прочитать файл из фильтра источника - PullRequest
2 голосов
/ 20 марта 2012

Я пишу исходный фильтр DirectShow, который зарегистрирован как CLSID_VideoInputDeviceCategory, так что его можно рассматривать как устройство захвата видео (например, в Skype его рассматривают как другую веб-камеру).Мой исходный фильтр основан на примере VCam из здесь , и на данный момент фильтр выдает точный выходной сигнал, как в этом примере (случайные цветные пиксели с одним выводом видеосигнала, звука пока нет), все реализовано вметод FillBuffer () единственного выходного вывода.

Теперь реальный сценарий будет немного сложнее - фильтр использует дескриптор файла для аппаратного устройства, открытый с помощью вызова API CreateFile () (открытие устройства вне моего контроля и выполняется библиотекой 3Party).Затем он должен прочитать порции данных из этого дескриптора (обычно это порции размером 256-512 байт).Это устройство WinUSB, а инфраструктура 3Party просто «дает» мне дескриптор открытого файла для чтения фрагментов.Данные, считываемые фильтром, представляют собой файл * .mp4, который передается с устройства на «дескриптор».

Этот сценарий эквивалентен чтению исходного фильтра из файла * .mp4 на диске (в виде «кусков») и переносу его данных в граф DirectShow, но без возможности полностью прочитать файл с самого началаВ итоге размер файла неизвестен (правильно?).

Я довольно новичок в DirectShow и чувствую, что мне не хватает некоторых базовых понятий.Я буду рад, если кто-нибудь сможет направить меня к решениям \ ресурсам \ объяснениям по следующим вопросам:

1) Из различных источников в Интернете и примеров Microsoft SDK (v7.1) я понял, что дляПриложение (такое как Skype) для построения правильного и действительного графа DirectShow (чтобы оно успешно отображало видео и аудио), вывод фильтра источника (наследуется от CSourceStream) должен реализовать метод «GetMediaType».В зависимости от возвращаемого значения из этой реализованной функции, приложение сможет построить правильный график для отображения данных, таким образом, построить правильный порядок фильтров.Если это правильно - Как бы я реализовал это в моем случае, чтобы график был построен так, чтобы отображать входные данные в формате * .mp4 порциями (мы можем предполагать постоянные размеры порций)?

2) Я заметилметод FillBuffer () должен вызывать SetTime () для объекта IMediaSample, который он получает (и заполняет).Я читаю сырые * .mp4 данные с устройства.Придется ли мне анализировать данные и извлекать кадры и значения времени из потока?Если да - пример был бы великолепен.

3) Должен ли я разделить данные, полученные из дескриптора файла («чанки»), на видео и аудио, или данные могут быть перенесены на график без необходимости манипулировать ими в исходном фильтре?Если требуется разделение - как это можно сделать (данные не являются непрерывными и разбиваются на куски) и повлияет ли это на требуемую реализацию «GetMediaType»?

Пожалуйста, не стесняйтесь исправлять меня, если я 'используя неверную терминологию.

Спасибо: -)

1 Ответ

3 голосов
/ 21 марта 2012

Это хороший вопрос.С одной стороны, это выполнимо, но есть некоторые специфические аспекты.

Прежде всего, ожидается, что ваш фильтр, зарегистрированный в категории CLSID_VideoInputDeviceCategory, будет работать как источник живого видео.Тем самым вы делаете его доступным для обнаружения приложениями (такими как Skype, как вы упомянули), и эти приложения будут пытаться настроить разрешение видео, они ожидают, что видео будет передаваться в реальном времени, некоторые приложения (такие как Skype) не ожидают сжатиевидео такое H.264 есть или просто отвергнет такое устройство.Вы также не можете прикрепить аудио прямо к этому фильтру, поскольку приложения даже не будут искать его там (не уверен, что в вашем фильтре есть звук, но вы упомянули файл .MP4, поэтому звук может быть там).

Вкл.ваши вопросы:

1 - вы бы лучше поняли требования к приложениям, проверив, какие методы интерфейса приложения вызывают в вашем фильтре.Большинство методов реализованы в BaseClasses и преобразуют вызовы во внутренние методы, такие как GetMediaType.Да, вам необходимо реализовать его, и тем самым вы, среди прочего, позволите своему фильтру соединяться с выводами нижестоящих фильтров, пытаясь использовать определенные типы носителей, которые вы поддерживаете.

Опять же, эти блоки не могут быть использованы для блоков MP4, даже еслитакой подход может работать в других графах DirectShow.Реализуя устройство захвата видео, вы должны доставлять именно видеокадры, предпочтительно распакованные (хорошо, они тоже могут быть сжаты, но у вас сразу же возникнет проблема совместимости с приложениями).

Решение, о котором вы могли бы подумать, эточтобы встроить полнофункциональный график внутри, в который вы вставляете свои фрагменты MP4, затем конвейеры анализируют их, декодируют и доставляют в ваш пользовательский рендер, принимая кадры, на которых вы повторно выставляете их с вашего виртуального устройства.Это может быть хорошим дизайном, хотя предполагает определенное понимание того, как фильтры работают внутри.

2 - Ваше устройство обычно рассматривается как / ожидается, что оно является живым источником, что означает, что вы доставляете видео в реальном времени, а кадрыне обязательно с отметкой времени.Таким образом, вы можете указывать время там, и да, вам определенно необходимо извлечь метки времени из исходного носителя (или сделать это с помощью внутреннего графика, как указано в пункте 1 выше), однако будьте готовы к тому, что приложения удаляют метки времени специально для предварительного просмотра, посколькуисточник "живой".

3 - Возвращаясь к аудио, вы не можете реализовать аудио на одном виртуальном устройстве.Ну, вы можете, и этот фильтр может даже работать в специально построенном графике, но это не будет работать с приложениями.Они будут искать отдельное аудиоустройство, и если вы реализуете такое, они будут создавать его отдельно.Таким образом, ожидается, что вы реализуете как виртуальное видео, так и виртуальный аудиоисточник, и будете осуществлять внутреннюю синхронизацию за сценой.Именно здесь отметки времени будут важны, предоставляя их правильно, вы будете поддерживать синхронизацию губ в сеансе в реальном времени с тем, что было изначально в медиафайле, из которого вы транслируете.

...