LINUX.ORG.RU

Нестандартные таймкоды в контейнерах

 


1

2

Приветствую. Я хочу рассказать о таком явлении, как нестандартные (нелинейные) таймкоды. Они возможны во всех современных контейнерах: MKV, MP4, MPG/VOB, TS и частично AVI (там только в видеопотоке средствами кодера). Если аудиодорожка или видеодорожка отсутствует в определенный промежуток времени, но при этом она должна быть, то информация об отсутствующих фреймах/кадрах пишется в таймкод контейнера, чтобы воспроизводящие устройства (плееры, конвертеры) их учли и на их месте сгенерировали тишину в звуке (или дубликаты кадров в случае видео) для поддержания синхронизации видео и звука. Такие участки еще называют gaps, но бывают еще overlaps (перекрытия). Чтобы было понятнее, gaps это тоже самое, что delay (информация для плеера), только находится в середине файла, поэтому MediaInfo его не показывает.

Причины их возниковения:
1. Записывающее устройство (со спутника или эфира) в случае, если не успевает закодировать кадр во время, может вставить информацию о пропущенных кадрах в контейнер.
2. При склейке двух файлов, если в каком-то из них видео и аудио имеют немного разную длину, на местах склейки могут образовываться пустоты.
3. При редактировании (резке) без пересжатия в программах типа VideRedo, SolveigMM из-за того, что фреймы видео и аудио потоков не совпадают по времени, невозможно разрезать, чтобы видео и звук заканчивались одновременно, а дальше см. п. 2
4. Растяжка средствами контейнера является их подвидом.
5. Иногда пофайловое открытие VOBов из DVD, содержащего несколько видеозаписей, приводит к подобному эффекту.
6. Поврежденный видеофайл.
7. Сознательная диверсия.

Как программы реагируют на нестандартные таймкоды:
Плееры:
Как правило все плееры, в том числе аппаратные, их учитывают и воспроизводят файл без рассинхрона. Так как таймкоды (в том числе delay) являются спецификацией контейнера. Некоторые плееры (SMPlayer) могут на время потерять синхронизацию, но уже со следующего GOP она восстанавливается.

Муксеры:
mkvtoolnix и ffmpeg копируют таймкоды как есть.
Исключения: при сохранении в AVI, из-за его ограничений, таймкоды звуковых дорожек теряются и появляется рассинхрон. Таймкоды видеодорожки переносятся в extradata кодера (например, mpeg4). Чтобы избежать рассинхрона у ffmpeg есть опции -vsync cfr -async 1 (действуют только при пересжатии видео и звука, а не copy). При полном пересжатии без этих опций в форматы, отличные от AVI, ffmpeg копирует таймкоды в новый файл (то есть вся аномалия переносится на плечи плееров).
mkvtoolnix не учитывает таймкоды в MPG/VOB контейнерах, но они там встречаются редко (в этих контейнерах он учитывает только delay). MPG/VOB нельзя в нем открывать (через промежуточный MKV, полученный в MakeMKV или ffmpeg, можно). Баг рапорт https://gitlab.com/mbunkus/mkvtoolnix/issues/2612
tsMuxer игнорирует таймкоды. Учитывает delay только для MPG и TS.
eac3to с опцией -demux показывает наличие gaps и overlaps (иногда драматизирует) и корректирует, но только для звуковых дорожек (для видео ему пришлось бы делать decode/encode, хотя, мог бы через обратные значения звука), причем только поддерживаемых (Vorbis, например, исправлять не будет и даже ничего не покажет), с ограниченной точностью из-за размеров фреймов аудиопотоков.
UPD: повторные исследования показали, что eac3to ничего не корректирует, ничего не показывает или показывает ерунду (завышенные значения длины gap).

Конвертеры:
Здесь все не так радужно. Множество конвертеров их игнорируют (в лучшем случае корректируется только начальный delay), как правило это те, кто обрабатывает звук и видео отдельно, то есть сначала извлекает потоки, при этом информация о таймкодах, естественно теряется.
MeGUI исправляет только delay, таймкоды игнорирует. XviD4PSP5 возможно тоже (у меня уже нет Windows, чтобы проверить).
ffmpeg копирует таймкоды как есть (кроме звуковых дорожек в AVI), см. раздел муксеры. Рекомендуется пользоваться им.
ConvertToDVD игнорирует.
Handbrake основан на ffmpeg и учитывает. У него есть настройки CFR/VFR, использующие опцию -vsync.
Sony Vegas и Edius уважают таймкоды (у звука по крайней мере) только в MPG/VOB контейнерах, но не MP4(H.264). Впрочем, новые версии я не проверял.
Avidemux учитывает (но надежно работает только с mkv).

Демуксеры:
При извлечении дорожек из файла, таймкоды почти всегда теряются и появляется риск рассинхрона. Некоторые демуксеры умеют корректировать только delay.
Из mkvextract можно извлечь такой командой
mkvextract tracks input.mkv 1:output.ac3
mkvextract timecodes_v2 input.mkv 1:timecodes.txt
Потом при муксе в mkvtoolnix файл timecodes.txt нужно указать в соответствующем поле. При этом с извлеченной дорожкой ничего делать нельзя (кроме может быть пересжатия и простые операции, типа изменения громкости, цветокоррекция). То есть, ключевые параметры (fps, длительность) при миграции без пересжатия должны сохраняться.

Распространенные мифы:
Видео и звук надо обрабатывать отдельно.
На самом деле это чревато рассинхроном. Единственным надежным способом его избежать для звуковых дорожек, это излекать в ffmpeg с параметрами
ffmpeg -drc_scale 0 -i input.mkv -map 0:1 -c:a pcm_f32le -ac 2 -async 1 output.wav
-drc_scale отключает DRC компрессию в AC3, -ac 2 микширует в два канала. При необходимости убрать.

При перепаковке из контейнера X в контейнер Y, надо сначала излекать элементарные потоки и муксить с нуля.
На самом деле это чревато рассинхроном. Переносить потоки из одного контейнера в другой желательно напрямую, чтобы таймкоды скопировались. Или самостоятельно принимать методы по их ликвидации (по силам только для звука). tsMuxer'ом пользоваться нельзя.

GUI конвертеры лучше командной строки
Графические конвертеры имеют ограниченные настройки и как правило прячут от пользователя полезную служебную информацию. А, если не прячут, то она проскакивает слишком быстро и с ненужными строками (ffmpeg GUI).

Еще несколько замечаний:
1.При звуковой PAL-NTSC растяжке средствами контейнера, ffmpeg с опцией -async 1 хоть и не наделает рассинхрона, но звук будет испорчен постоянными микропаузами для поддержания синхронизации. В этом случае единственный вариант извлекать звуковую дорожку без учета таймкодов и самому перетягивать, при этом о fps перетяжки придется только догадываться и сравнивать в аудиоредакторе.
2. Опция -vsync cfr на файлах с переменной частотой кадров, полученных со смартфонов, породит дубли.

Как детектировать нестандартные таймкоды:
1.eac3to -demux покажет (не для всех аудиодорожек). UPD: полагаться на eac3to нельзя.
2. Долгий ручной вариант. Сделать перекодирование в легкий формат в AVI. В одном случае без опций -vsync -async (и лучше сначала распаковать на элементарные потоки, а потом упаковать для надежности и пережать), в другом случае напрямую с этими опциями. Потом в видеомонтажке сравнивать покадрово и по звуковой волне получившиеся два файла. Если таймкоды стандартные, файлы будут идентичны (вплоть до совпадения хэш суммы, если использовать опции -map_metadata -1 -map_chapters -1). Важно, чтобы это был именно AVI, чтобы монтажка не занималась излишней самодеятельностью с таймкодами сама.

Я хочу использовать мою любимую программу XviD4PSP5 для обработки видео
Если нестандартные таймкоды только в аудиодорожке, их может исправить ffmpeg с пересжатием. Если в видеодорожке, можно скормить XviD4PSP5 временный lossless файл:
ffmpeg -drc_scale 0 -i input.mkv -map 0:0 -map 0:1 -c:v libx264 -preset ultrafast -qp 0 -g 12 -vsync cfr -c:a pcm_s16le -af volume=-2dB -async 1 output.mkv

В 16 бит может быть клиппинг, -af volume для его предотвращения. С 32 bit PCM в MKV могут быть проблемы. В случае использования fixed point (16, 24 бита) при декоде или энкоде ffmpeg использует тихую матрицу микширования 5.1>2.0 (-ac 2).

Файлы для тестирования:
https://www.mediafire.com/file/ice1p92m21gzp98/gaps.7z/file

Как я обнаружил это явление:
Очень давно
При распаковке MKV появляется рассинхрон
http://forum.ixbt.com/topic.cgi?id=29:34519

Вывод:
Чтобы избежать проблем, пользуйтесь только ffmpeg, где все предусмотрено. Не сохраняйте в AVI. Для экспорта аудиоредакторам и видемонтажкам пользуйтесь опциями -vsync cfr -async 1

Enjoy.

Хотя от прочитанного пользы для себя не вижу(возможно пока не вижу), но одна вещь обратила на себя внимание... Это -preset ultrafast -qp 0 Я часто ипользую -preset ultrafast -qp 8÷12. Для чего я это использую? К примеру, для создания так называемых 'релакс каналов'. Это кусок зацикливаемого видео с добавлением бесконечной звук-дороги, как правило это радио, чтобы мне хватило скорости для трансляции видео вживу в 1920х1080 с неутраченным визуально качеством. Если прописать -preset ultrafast -crf 20, который по качеству совпадает с -qp 10, однако скорость падает на 15÷25%. Версия ffmpeg'а 3.2.4, и проблем здесь нет. Но версия, как видно, уже довольно старая и я решил в своё время обновить ffmpeg. И вот те на! Одна и та же опция кодирования с использованием -preset ultrafast -qp 10 чуть ли не хуже, чем -crf 20 по скорости, во всех версиях, начиная как минимум с 4.0.1. Я извиняюсь в нарушении темы, но могли бы Вы как-то прокомментировать изложенное, чувствуя Ваш высокий потенциал в ffmpeg'е.

xradio ()
Ответ на: комментарий от xradio

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

Может, это кризис среднего возраста, старею. А кругом одни максималисты.

anonymous ()
Ответ на: комментарий от xradio

у меня между 2.8, 3.3 и 4.2 разница не больше 1fps при похожем битрейте на ultrafast qp 10. и настройки кодирования у них абсолютно идентичны.

может быть виноват aac encoder? в новых версиях его улучшили, но вместе с тем, он стал очень медленным, особенно на больших битрейтах звука. но изменения были в версиях 3.0+, что-то не сходится.

чтобы найти причину надо бы проверить:
1. параметры кодирования (mediainfo)
2. битрейт
3. загрузка процессора (threads)
4. используемые оптимизации (пишется в консоли)
5. отключить лишние фильтры и звук
6. тест декодирования в /dev/null чтобы исключить вину декодера

anonymous ()
Ответ на: комментарий от anonymous

Возможно разночтение оттого, что я не указал - скорость ниже при рекодировании живого потока. Пример: Мой довольно старый телеСамсунг не может воспроизвести живой телеканал 1920х1080 50Гц. Чтобы посмотреть в этом разрешении, я этот поток должен ретранслируя вживую рекодировать ему в 25Гц. Опция: -i тв-канал -c h264 -preset ultrafast -qp 15 -vf fps=25 -c:a copy -listen 1 -f mpegts выход на Самсунг ( видно, что звук- энкодер здесь не используется) Версия 3.2.4 справляется элементарно, версия 4.2 нет и 4.1.2 нет! А при кодировании в конечный файл я либо не обращал внимания на +/- 5-10 мин, либо разницы нет. Так это можно проверить - дам адрес тв-канала, если подтвердится косяк, можно совместными усилиями написать разрабам... *Косяки в версиях не редкость.

xradio ()
Ответ на: комментарий от anonymous

У всех свои параметры компиляции. Например, в линуксовый static так и не завезли av1 кодек, а в виндовой сборке есть https://ffmpeg.zeranoe.com/builds/ (даже под xp, позор).

anonymous ()
Ответ на: комментарий от anonymous

В том то и дело, что сборщики ffmpeg'а разные, но номера версий те же и результат один и тот же. Причём здесь threads? Опция кодирования та же самая, что для 3.2.4, что для 4.1.2 и 4.2.

xradio ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.