На самом деле это перепечатка моей собственной
темы на одном из форумов
Чему посвящён данный топик
Я постарался осветить процесс воспроизведения видеофайлов в Windows. Данная информация поможет решить некоторые проблемы, связанные с ошибками или полной невозможностью просмотра фильмов на PC.
Понятие кодека и контейнера
Рассмотрим на пальцах что представляет из себя типичный видеофайл с фильмом.
Во первых это видеоряд. Во вторых это одна или несколько аудиодорожек. И всё это некоторым образом смешано в одном файле.
Так вот, видео и аудио в общем случае зажато с помощью определённого
кодека - этакого архиватора. Таким образом формат отдельно взятого видео и аудио определяется кодеком. А то, каким именно образом это перемешано определяется
контейнером. Существует множество различных кодеков и множество различных контейнеров. Наиболее распространённым на данный момент является контейнер AVI (
Audio
Video
Interleave).
Как происходит воспроизведение фильма
В общем случае при воспроизведении видеофильма используется следующий (несколько упрощённый) механизм:
Специальный компонент называемый
сплитер принимает на вход данные из файла-контейнера. Сплитер, зная формат контейнера разделяет аудио и видео потоки. Аудиопоток поступает на вход декодеру аудио. Декодер аудио выполняет декодирование аудиопотока после чего декодированный аудиопоток поступает на аудиокарту. Видеопоток поступает на вход декодеру видео, в целом цепочка аналогична аудио.
Таким образом для успешного воспроизведения видеофайла необходимо иметь следующие компоненты:
- Сплитер, подходящий для данного контейнера
- Соответствующий декодер для видео
- Соответствующий декодер для аудио
А теперь давайте рассмотрим вышеописанный механизм воспроизведения видеофайла на примере. Для этого нем понадобится
GraphEdit и
работающий у вас AVI-файл.
Запускаем GraphEdt.exe. В меню выбираем [File]->[Render Media File]->
вашфайл.avi
Видим следующую картинку (или что-то вроде того):
[показать]
Эта картинка называется "
DirectShow граф" или просто "граф". А "квадратики", изображённые на графе называются "
DirectShow фильтр" или просто "фильтр"
Все три основных компонента перед глазами:
- Сплитер - AVI Splitter
- Видеодекодер - DivX Decoder Filter
- Аудиодекодер - MPEG Layer 3 Decoder
Вообще GraphEdit - замечательный инструмент, однако для диагностики более информативен
GSpot.
Давайте повторим наш опыт с использованием GSpot и посмотрим поподробнее на предоставляемую им информацию. Запускаем GSpot, ждём 30 секунд пока он соберёт информацио о нашей системе после чего выбираем в меню В меню выбираем [File]->[Open]->
вашфайл.avi
[показать]
Нажимаем на выделенную кнопочку и наблюдаем:
[показать]
Если внимательно присмотреться то выделеная красным прямоугольничком информация - это просто более компактная форма отображения графа которое мы наблюдали в GraphEdit-е
Что такое DirectShow фильтр. Как его установить или удалить.
Для тех кто знаком с программированием скажу что DirectShow фильтр это такой COM-компонент, реализующий набор интерфейсов, определяемых DirectShow. Если для Вас данная абракадабра лиш набор несвязных звуков не расстраивайтесь, не боги горшки обжигают...
Для удаления фильтра из системы достоточно выполнить команду
code:
regsvr32 /u полное_имя_файла_фильтра
Для установки фильтра обратно воспользуйтесь
code:
regsvr32 полное_имя_файла_фильтра
Для получения полного имени файла фильтра можно использовать GSpot. Например меня интересует полное имя файла фильтра DivX Decoder Filter:
Я навожу мышку на этот фильтр, щёлкаю правой кнопкой мыши, выбираю из меню [Details on This Filter] и вижу:
[показать]
Driver File это и есть полное имя файла фильтра.
Таким образом команда на удаление фильтра DivX будет выглядеть так:
[показать]
А для установки обратно так:
[показать]
Для получения списка всех фильтров, установленных в системе используйте пункт меню [System] -> [List Codecs and Other Filters] в GSpot
Подробнее про сплитеры
Итак, сплитер это DirectShow фильтр выполнящий следующие функции:
- разбор файла контейнера на отдельные потоки (видео, аудио, иногда субтитры) для дальнейшей обработки/декодирования
- предоставление информации о типе потока + разрешение и частота кадров у видео + частота дискретизации у аудио
- предоставление сервиса для перемотки видео
- предоставление информации для синхронизации аудио и видео
Некоторые сплитеры позволяют использовать информацию о "главах" для быстрой перемотки видео (как выбор сцены на DVD). Также некоторые сплиттеры позволяют выбирать один из нескольких аудиопотоков (аудиодорожек) при просмотре файла.
Самый распространенный сплитер это сплитер для AVI-файлов, он входит в состав DirectShow (а DirectShow входит в состав DirectX). Именно поэтому обычно не возникает проблем при просмотре AVI-файлов. Однако AVI контейнер имеет ряд серъёзных ограничений и недостатков, поэтому в последнее время набирают популярность контейнеры OGM, MKV и MP4.
Помимо стандартного сплитера от Microsoft есть ещё несколько различных реализаций AVI-сплиттера. Так как сплитер отвечает за синхронизацию аудио и видео то некорректный сплиттер может быть это одной из причин рассинхронизации. Стандартный сплиттер от Microsoft называется
quartz.dll. Если у вас возникли проблемы рассинхронизации при проигрывании AVI первым делом проверьте при помощи GSpot имя файла со сплитером. Попробуйте переключиться на стандартный сплитер выполнив команду
code:
regsvr32 %SYSTEMROOT%\System32\quartz.dll
Замечу что некоторые проигрыватели (например Crystal Player и Media Player Classic) имеют свои собственные встроенные парсеры. Эти парсеры можно попробовать отключить в настройках проигрывателя.
Что такое MEDIASUBTYPE, FourCC и TwinCC
Как было сказано выше сплитер предоставляет информацию о типе потока. В буквальном смысле слова он говорит "Вот это видео в DivX" и "Вот это аудио в MP3". Эта информация называется
MEDIASUBTYPE.
В AVI-контейере эта информация хранится как
FourCC для видео и
TwinCC для аудио.
TwinCC это число, соответствующая аудиокодеку
FourCC это 4-х буквенная строчка, соответствующая видеокодеку
[показать]
Список всех (ну или почти всех) известных FourCC и TwinCC можно посмотреть в GSpot выбрав в меню [Tables] -> [Audio Codecs] и [Tables] -> [Video Codecs]
Разница между спецификацией и реализацией. Применяем FourCC Changer на практике
Обратимся к примеру "на пальцах". Есть такой формат архивов, называется ZIP. Существует множество архиваторов которые могут с ним работать. Вы можете сжать архив используя WinZIP а распаковать его используя WinRAR и всё будет работать. Так вот, в приведённом примере ZIP это спецификация а WinZip, WinRar, PowerArchiver, 7-zip и.т.д. - реализация.
7-zip жмёт в Zip сильнее чем WinZIP, однако полученный в результате zip-файл без проблем распакуется WinZip-ом.
Аналогичный пример работает и для видео/аудиокодеков. Речь пойдёт о семействе DivX 5.1+, XviD 1.0+, 3ivX, Nero Digital. Реально все эти кодеки реализуют формат MPEG4 Part 2. Теоретически можно декодировать файл закодированный XviD-ом при помощи DivX-а и наоборот. Один из способов добиться такого поведения - заменить в AVI-файле строчку со значением FourCC. Для этой операции нам понадобится
AVI FourCC Changer.
Найдите у себя видео файл с FourCC = XviD. Откройте его с помощью AVI FourCC Changer и поменяйте FourCC
Было:
[показать]
Стало:
[показать]
Запустите полученный файл на проигрывание и убедитесь что он нормально воспроизводится. С помощью утилиты GSpot убедитесь что данный файл декодируется теперь с помощью DivX Decoder Filter
ВАЖНО
- Старые версии XviD и DivX не до конца соблюдали стандарт, поэтому не все файлы можно так "конвертировать".
- Из DivX в XviD можно конвертировать только файлы с FourCC DIVX и DX50
Почему DirectShow декодирует видео формата XXX используя фильтр YYY
Рассмотрим как DirectShow подбирает фильтр для декодирования. Для этого сначала обратим более пристальное внимание на фильтры. DirectShow обращается со своими фильтрами как с такими чёрными ящичками у которых есть входы и выходы (
пины). Каждый фильтр при своей установке записывает в реестр какие у него входы/выходы и что они принимают/отдают.
Рассмотрим на примере DivX Decoding Filter. Запускаем GSpot, выбираем в меню [System] -> [List Codecs and Other Filters]. Теперь найдём в списке DivX Decoding Filter. Щелкаем по нему правой кнопкой мыши и в выпадающем меню выбираем [View Mediatypes]. Видим такую картинку:
[показать]
Помимо описания пинов каждый фильтр имеет некоторую "волшебную" циферку, называемую
Merit, по русски д данном случае больше всего подходит "приоритет". На нашем многострадальном DivX Decoding Filter щелкаем правой кнопкой мыши и в выпадающем меню выбираем [Set Filter Merit]. Видим такую картинку:
[показать]
Теперь вооружённые знаниями посмотрим (несколько упрощённо), каким образом DirectShow подбирает подходящий фильтр. Благодаря GSpot-у мы можем даже наблюдать этот процесс. Для этого открываем им наш AVI-шничек, скриншоты будут по месту. Рассматривать будем на примере видеокодека, для аудио все происходит аналогично.
DirectShow знает какой MEDIASUBTYPE имеет наш поток (ему эту информацию поставляет сплитер, помните?). Первым делом DirectShow находит все фильтры которые имеют входной пин с таким-же MEDIASUBTYPE и приоритетом не ниже MERIT_NORMAL. Данный список сортируется по убыванию приоритета:
[показать]
Далее DirectShow пытается по порядку (начиная с высших приоритетов) соединить фильтр со сплитером . Если не удаётся соединить то DirectShow пытается использовать следующий фильтр из списка. Как только попадётся "сговорчивый" фильтр DirectShow прекращает дальнейшие попытки и использует этот фильтр как декодер. Если DirectShow не удалось найти фильтров или не удалось ни один из найденных фильтров соединить со сплитером возникает ошибка.
[показать]
"Волшебные" фильтры AVI Decompressor и ACM Wrapper
Иногда при построении графа DirectShow использует для декодирования видео фильтр
AVI Decompressor:
[показать]
А для декодирования аудио
ACM Wrapper (без скриншота).
Это универсальные фильтры, представляющие собой переходник между DirectShow и WfV. На самом деле это не есть хорошо, данные переходники выполняют лишнюю работу и зря кушают процессор. Рекомендую при помощи GSpot-а изучить процесс подбора декодера и постараться добиться использования другого DirectShow фильтра (если он есть) путём увеличения последнему Merit-а.
ВАЖНО Сами фильтры
AVI Decompressor и
ACM Wrapper от греха подальше лучше не трогать (а особенно не деинсталировать)
Как бороться с проблемами при воспроизведении
На самом деле после того как вы ознакомились с принципами работы DirectShow трудных проблем возникнуть не должно. Вот общие рекомендации:
Откройте проблемный файл GSpot-ом, ткните кнопочку, посмотрите какой получается граф
[показать]
Вот как ругается GSpot на отсутсвие сплитера:
[показать]
А вот так на отсуствие декодера
[показать]
Если декодеры обнаружены а видео/аудио воспроизводится некорректно возможно у вас используется неправильный декодер, проанализируйте GSpot-ом установленные декодеры, попробуйте использовать другие (посредством изменения Merit-а и/или удалением декодеров)
Иногда в графе могут присутствовать "посторонние" фильтры, такие как Morgan Stream Switcher, DivXG400, VobSub и прочее говно. Попробуйте их удалить.
В случае проблем с синхронизацией звука уделите внимание сплитерам.
Кодепаки - добро или зло
Вообще бытует мнение что кодепаки - зло. И в этом есть резон, поставят какое-то говно (читай фильтры всякие левые) - у юзера после этого ничего работать не будет нормально. Нередки случаи когда перепробовав множество кодепаков, пройдя через ад десятков install/uninstall в попытке "вылечить" систему пользователям приходилось переустанавливать Windows.
Однако нам теперь проблемы установки "левых" фильтров не страшны, в случае чего GSpot ( :worthy: ) в руки, чик-вжик и нет проблем. С другой строны кодепаки удобнее тем что в сравнительно небольшом объёме есть 99% всех нужных фильтров. Ну и в заключении добавлю что есть "хорошие" кодепаки, позволяющие выбрать какие конкретно фильтры/кодеки будут установлены. Лично я рекомендую
K-Lite Codec Pack FULL, при размере 8 мегабайт есть практически всё, в том числе видеоплеер и GSpot. Поэтому я обычно ставлю кодепак и особо не мучаюсь, вмешательство GSpot-ом бывают очень редко да и то чаще носят экспериментальный характер.
Если совсем всё плохо
Признаюсь честно - никогда не попадал в такую ситуацию, анализ используемых фильтров всегда спасал. Однако если совсем всё плохо не спешите переустанавливать Windows, можно попробовать сделать следующее:
- Снести все кодепаки и кодеки
- Используя GSpot найти и удалить всё оставшееся после (1)
- Переустановить самый свежий DirectX (он обновит вам DirectShow и установит стандартные фильтры)
- Аккуратно поставить свежий K-Lite Codec Pack FULL