Общий обзор подключения и управления DirectShow фильтрами

В общих чертах понять как работать с DirectShow фильтрами и принципы построения графа фильтров помогает утилита GraphStudo.
Вот так должно выглядеть окно приложения:

MONOGRAM GrapStudio

(Рис.1. Окно MONOGRAM GraphStudio)

Проигрывание видеофайла

Жмем File->Render Media File ... - появляется окно с приглашением выбрать media-файл. Рекомендую для начала выбрать avi-файл и нажимаем OK.
У меня получилось вот что:

MONOGRAM GrapStudio

(Рис.2. Построенный граф фильтров)

Давайте в общих чертах разберемся, что здесь нарисовано. Картинка состоит из синних прямоугольников, соединенных стрелочками. Первый прямоугольник символизирует, наш исходный файл. Далее, по ходу стрелочки, видим следующий прямоугольник, в котором написано "AVI Splitter", а также по двум исходящим из него стрелкам, он предназначен для того, чтобы взять данные от первого прямоугольника и разделить их на два потока - нетрудно сообразить, что это - аудио- и видео- потоки. Входы и выходы в прямоугольнички в терминологии DirectShow представляют собой входящие и исходящие контакты (InputPin и OutputPin), а сами прямоугольники - собственно фильтры (теперь мы сможем догадаться о причине ошибки, если увидим где-то сообщение о ней вроде "Действие не может быть выполнено, поскольку контакты не подключены" - речь идет именно об этих контактах). Вся же эта схема и есть так называемый граф фильтров. Дальнейший анализ нашей картинки не должен представлять трудностей. 

Теперь попробуем понять почему граф фильтров построился  именно так, а не иначе.
Перед открытием файла загрузчик Windows проверяет раздел реестра HKEY_CLASSES_ROOT\Media Type\ в котором находится список расширений файлов (Extensions) и медиатипов в разделе MEDIATYPE_Stream (e436eb83-524f-11ce-9f53-0020af0ba770).
Как видно из названия, в разделе Extensions хранятся сопоставления: расширение файла -> SourceFilter. С разделом реестра e436eb83-524f-11ce-9f53-0020af0ba770 - немного сложнее, в нем находятся GUID*ы медиатипов (например для avi-файла: e436eb88-524f-11ce-9f53-0020af0ba770) и так-же как в Extensions поддерживающий медиатип SourceFilter.

В примере на рис.2 для файла с расширением .avi Windows не нашла нужного SourceFilter*а, поэтому файл открыл дефолтный File Source (Async.) (возможно что для открытия avi-файлов в реестре может быть указан именно дефолтый сурс фильтр). Далее построитель графа (GraphBuilder) строит граф по двум параметрам: поддерживаемый на входном контакте медиатип и MERIT (приоритет фильтра), так получилось что подходящим сплиттером у меня оказался системный AVI Splitter, а декодером Mpeg4s Decoder DMO.
В Windows 7 поиск нижележащего фильтра начинается с раздела реестра: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectShow\Preferred где находятся сопоставления - GUID медиатипа и CLSID фильтра.

Теперь поуправляем построением графа фильтров, для примера возьмем тот-же avi-файл.
Попробуем построить граф такого вида: AV Splitter -> ffdshow video decoder -> Video Render.
Первым делом создадим раздел в реестре для расширения avi и пропишем SourceFilter вот так:
[HKEY_CLASSES_ROOT\Media Type\Extensions\.avi] "Source Filter"="{D8980E15-E1F6-4916-A10F-D7EB4E9E10B8}" 
{D8980E15-E1F6-4916-A10F-D7EB4E9E10B8} это CLSID AV Source.
Теперь все avi-файлы  будут открыватся AV Source фильтром.

Подключить  ffdshow video decoder в Windows 7 немного сложнее, хотя  у ffdshow при регистрации задается запредельный merit, GraphStudio подключает системный Mpeg4s Decoder DMO, для исправления этой неприятности требуется внести изменения в реестр, для этого делаем следующие шаги:
В  GraphStudio жмем Ctrl+F в списке DirectShow фильтров выбираем AV Source, открываем наш sample.avi.
У меня получилось вот так:

MONOGRAM GrapStudio

(Рис.3. Загруженный в граф фильтров AV Source)

Теперь смотрим свойства Video контакта сплиттера, (двойной щелчок мышью по контакту или св-ва фильтра) нас интересует значение GUID subtype:

 
(Рис.4. Свойства видео контакта)

В моем avi-файле значение GUID subtype получилось {44495658-0000-0010-8000-00AA00389B71} (кодек XVID) 

В реестре по адресу HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectShow\Preferred, по крайней мере у меня, уже есть параметр  {44495658-0000-0010-8000-00AA00389B71} со значением {2A11BAE2-FE6E-4249-864B-9E9ED6E8DBC2} (это CLSID Mpeg4s Decoder DMO), меняем его на CLSID ffdshow Video Decoder {04FE9017-F873-410E-871E-AB91661A4EF7}.
На этом настройки необходимые для выполнения поставленной задачи можно считать законченными, можете проверить как теперь будет строится граф фильтров.В утилите GraphStudio повторите RenderMediaFile описанный в начале статьи и если вы решились на эксперимент и правильно выполнили все действия у вас должно получится так-же как и у меня:

MONOGRAM GraphStudio

(Рис.5. Построенный граф фильтров)

Все описанные выше действия крайне утомительны и требуют определенной подготовки у пользователя. С AV Splitter все это делается намного проще. На каждом этапе построения графа фильтров правильно настроенный AV Splitter вносит необходимые коррективы и без изменений системного реестра позволяет добится желаемого результата.

Настроить сплиттер для подключения заданного фильтра можно тремя разными способами:

1. Медиатип на вкладке Output. (для аудио не работает)
2. Загрузка выбранного фильтра на вкладке Graph Builder.
3. Принудительное подключение к фильтру на вкладке Connections.
В большинстве случаев одну и туже задачу можно решить используя по отдельности любой из перечисленных механизмов.

На вкладке Output можно сформировать нужный медиатип в зависимости от типа контента.

Как показывает практика в основном требуется изменить стандартный subtype wvc1 на совместимый с декодерами ArcSoft и CyberLink, для h264/AVC на вкладке Output чаще всего ничего делать не нужно.

Стандартный subtype WVC1 {31435657-0000-0010-8000-00AA00389B71} 
Subtype WVC1 ArcSoft  {629B40AD-AD74-4EF4-A985-F0C8D92E5ECA} 
Subtype WVC1 CyberLink  {D979F77B-DBEA-4BF6-9E6D-1D7E57FBAD53}
Стандартный subtype AVC {31435641-0000-0010-8000-00AA00389B71}

Второй в арсенале сплиттера Graph Builder, загружает в граф нужный фильтр еще до того как система начинает подбирать и загружать в граф совместимые фильтры, т.е. вероятность того что подцепится фильтр прописанный в сплиттере практически равна 100%. Коннект может не получится только в случае если фильтр откажется сцеплятся по причине несовместимого медиатипа или при использвании сплиттера в плеере типа мрс-нс. Встроенный Graph Builder полезно использовать если у фильтра мерит MERIT_DO_NOT_USE или вообще не зарегестрирован в системе.

В заключение принудительное подключение к фильтру Connections.
Подключает надежно и без вариантов если нижележащий фильтр не будет против. В выпадающем списке "Media Subtype" для н264 или VC-1 следует прописать один из перечисленных выше subtype и в списке "Filter" выбрать нужный фильтр.

Подробно о настройках AV Splitter смотрите соответствующие разделы справки.