Pull to refresh

Comments 21

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

Вообще, кодирование каждой сцены по отдельности - это своего рода bleeding edge. Ну, был в 2017. Но это жуткий геморрой, и заниматься таким серьезно стоит только если большие бабки на кону.

Note that Netflix proposes using fixed-QP encoding for its per-shot encoding optimization to achieve optimal encodes for each scene. This however requires a lot of processing and careful assembly of the individual encoded shots, so it’s not a “one size fits all” method you should use unless you have the whole framework implemented.

https://slhck.info/video/2017/03/01/rate-control.html

своего рода bleeding edge.

жуткий геморрой

серьезно стоит только если большие бабки на кону

Можно разбить задачу на три части:

  • Научиться резать, кодировать кусками и склеивать

  • Перебирать параметры для максимизации метрики качества (VMAF). Кодируем кусок, смотрим на VMAF, повторяем с другими настройками (QP в статье netflix)

  • Повторять для разных разрешений, выбирать куски по разным критериям ("minimizing bitrate for a given average quality or maximizing quality for a given average bitrate")

Первые два пункта реализованы в av1an, а третий вроде бы нужен только видеохостингу.

Будем честны: первые два нужны тоже только видеохостингу, дома никто не будет перебирать десятки вариантов кодирования сцен :)

Первый нужен, если вдруг энкодер плохо параллелится.

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

Не-не-не, истина где-то рядом посередине.

TL;DR: резать видео на куски - это нормальный подход, который должен хорошо работать в CRF-режимах и который используется для распараллеливания кодирования AV1. Только резать не по ключевым кадрам, а по scenecut'ам, как это делает утилита av1an.

___

Если при кодировании целиться в определённый уровень качества, а не в размер файла (не в средний битрейт), то тогда алгоритмы rate control'а не должны делать ничего важного на длинных промежутках.

Допустим, кодируем по отдельности 2 сцены с разной сложностью по 5 минут каждая.

  • Хотим получить файл в X мегабайт - придётся сцены кодировать в файлы X/2 мегабайт - битрейт распределяется неоптимально (сложная сцена недополучает, лёгкая - получает избыточный).

  • Хотим получить X единиц качества (--crf, --cq-level, VMAF) - тогда сцены друг от друга почти не зависят, раздельное кодирование почти никак не вредит.

Примерно поэтому разработчики x264 настаивали на том, что в их энкодере однопроходный CRF-режим - лучший по качеству. 2pass чуть-чуть выигрывает от того, что алгоритмы алгоритмы rate control'а видят весь файл (словно у нас CRF + ‑-rc‑lookahead ∞), но время, затраченное на второй проход, в x264 выгоднее потратить иначе (вместо 2pass выбрать CRF с более медленным пресетом).

Другая часть истории - гугл. Он стал делать кодеки. И эти его кодеки плохо параллелятся на все ядра. Поэтому в AV1 кодирование кусками (chunking) и склеивание - это чуть ли не ожидаемый сценарий использования. Поэтому появилась утилита av1an - она режет видео на куски по scenecut'ам и запускает пул из N штук ffmpeg'ов (ну и делает вид, что её работа гораздо сложнее, чем на самом деле).

___

Разрезание по ключевым кадрам автоматически достигается в ffmpeg через -noaccurate_seek: Previous behavior (seek only to nearest preceding keyframe, despite inaccuracy) can be restored with "-noaccurate_seek" - https://trac.ffmpeg.org/wiki/Seeking

___

Чтобы меньше вредить качеству, режут по переходам между сценами и shot'ами. Дальше можно выбирать наиболее резкие переходы и наложить ограничение на минимальную длину куска. Методы: использовать выхлоп встроенного ффмпеговского scene detector'а или использовать сторонний, как делает av1an.

___

А если мы в месте склейки вылезем за ограничения, которые важны аппаратным декодерам? Если мы заморачивались со всякими --level, --bluray-compat, --vbv-maxrate и хотим сохранить гарантии совместимости? То мы слишком много хотим, то это тонкие материи, наверное, есть платные инструменты для точного контроля совместимости. Нас бы и без склейки мог, например, обломать один из многочисленных багов с упоминанием VBV в истории версий x265.

Разрезание по ключевым кадрам автоматически достигается в ffmpeg через -noaccurate_seek

Считайте, что я этого не говорил, это глупость.

Поизучать поведение можно на тестовом файле, где I/P/B-кадры стоят на удобных timestamp'ах и на видео наложен тип и номер кадра.

Опасно
ffmpeg                                                          ^
    -y                                                          ^
    -f lavfi -i color=0x402000:rate=10:duration=10:size=640x480 ^
    -f lavfi -i color=0x002040:rate=10:duration=10:size=640x480 ^
    -f lavfi -i color=0x004020:rate=10:duration=10:size=640x480 ^
    -f lavfi -i color=0x401040:rate=10:duration=10:size=640x480 ^
    -filter_complex "[0:v:0][1:v:0][2:v:0][3:v:0]concat=n=4:v=1:a=0[outv]"  ^
    -map "[outv]"                                               ^
    -x264-params scenecut=0:keyint=100:b-adapt=0:bframes=9      ^
    "temp.mkv"

:: 10 fps; 40 seconds; pts=0..39.9; I B*9 P B*9 P...; 
:: https://stackoverflow.com/a/21026862
    
ffmpeg                                                          ^
    -y                                                          ^
    -i "temp.mkv"                                               ^
    -vf "drawtext=text='%%{pict_type}':fontfile='swmono.ttf':fontcolor=black:fontsize=200:box=1:boxcolor=white:boxborderw=5:x=w-tw,drawtext=text='%%{frame_num}':fontfile='swmono.ttf':fontcolor=black:fontsize=200:box=1:boxcolor=white:boxborderw=5:x=w-tw:y=h-th,drawtext=text='%%{pts}':fontfile='swmono.ttf':fontcolor=black:fontsize=50:box=1:boxcolor=white:boxborderw=5" ^
    -x264-params scenecut=0:keyint=100:b-adapt=0:bframes=9      ^
    "test_vid.mkv"

Переносы (^) и экранирование (%->%%) виндовые, не для bash.

-vf накладывает на кадр свойства %{pict_type},%{frame_num},%{pts} через 3 вызова drawtext.

ffmpeg совсем не годится для такого, выглядит и отлаживается отвратительно, это работа для vapour/avisynth, но зато без лишних зависимостей

Если кратко:

  • интервал работает так: [-ss; -to), -t тоже задаёт открытый интервал

  • но только не с -c copy , тогда интервалы работают... как-то сложно

  • конец интервала с -c copy может быть P-кадром, может быть битым (выкинул 5 B-кадров перед последним P-кадром)

  • -noaccurate_seek -ss _ -i _ делает фигню (у меня добавление опции захватывает ещё один кадр перед -ss, независимо от типа кадра)

  • автопоиск ключевых кадров для обоих концов интервала есть разве что в -f segment -segment_times _,_,... -c copy

За инициативность плюс, но разве в ffmpeg не работает кнопка Pause/Break на клавиатуре? :)

Память это не освободит, на на ПК пригодном для конвертации видео ее все равно должно быть более чем. Не придется изобретать велосипед.

Нет конечно, а зачем перезагружать компьютер в середине процесса конвертации? Поставил на паузу, сделал дела, продолжил конвертацию.

В статье про перезагрузку тоже ничего не сказано.

Затем, что зачем мне её просто на паузу ставить? Чтобы что? Она ещё дольше бы выполнялась? Как правило, продолжать нужно по той причине, что она прервалась по не зависящим от тебя обстоятельствам (например, комп в перезагрузку ушёл или просто вырубился посреди процесса) и хотелось бы, чтобы работа не пропадала вхолостую.

Затем, что зачем мне её просто на паузу ставить? Чтобы что?

Например, кодирование какого-нибудь HEVC по медленному профилю может длиться сутками. Я нередко заряжал такие энкоды на время своего отсутствия, возвращался, делал свои дела с кодированием на паузе, а потом возобновлял процесс.

Она ещё дольше бы выполнялась?

В какой-то момент процесс становится настолько длительным, что несколько часов простоя банально не влияют на общую картину. В 3Д, например, тоже. Я вам больше скажу: если у вас кодирование длится 4 часа, то вам вообще велосипед из статьи ни к чему, проще перетерпеть.

Как правило, продолжать нужно по той причине

Это все проблемы, которые нужно побороть на корню, и я объясню почему:

например, комп в перезагрузку ушёл

Нужно использовать ОС, которая сама не перезагружается. Или привыкнуть откладывать естественные процессы ОС (я сам виндузятник по большей части).

просто вырубился посреди процесса

Если он вырубился, то вы либо не прошли стресс-тест кодированием (и тогда вам нужно разобраться, что у вас в системе нестабильно, а не городить костыли), либо у вас проблема с электричеством (ее тоже можно и нужно решить, как минимум ИБП).

А все эти проблемы нужно решать не костылем из статьи по одной простой причине: вот это все городится исключительно под ffmpeg, но упомянутые выше проблемы вас будут преследовать буквально во всем софте. В какой-то момент костылей станет так много, что продираться через них уже будет сильно сложнее, чем просто решить проблему.

просто решить проблему

Правильно. В ffmpeg уже давно бы пора решить проблему (например, сохраняя (можно по флагу, у него уже флагов столько, что от ещё одного хуже не станет) промежуточные вычисления куда-то на диск (все эти таблицы квантования/Хаффмана или что там ещё используется). Ну а пока приходится довольствоваться костылями (ИБП — это тоже костыль, кстати, физический).

промежуточные вычисления куда-то на диск

ЕМНИП, log с 2-pass так и работает. Но он настолько никому не нужен, что я даже сейчас сходу не могу нагуглить синтаксис. Лет 10 назад пользовался.

(ИБП — это тоже костыль, кстати, физический).

ИБП - это еще и про защиту техники от инфаркта, при софтовом падении конкретно энкодера пострадает разве что гордость. На рабочих лошадках костылей будь здоров - тот же ECC. Но это как раз потому, что железные костыли лучше работают и универсальные.

Основная цель утилиты из статьи - это именно сохранить состояние, а не поставить на паузу. И да, она отлично переживает перезагрузку.

Более того, [путём переименований папок] можно хранить такое сохранённое состояние очень долго (просто сохранить до лучших времён) и в это время гонять другие конвертации или работу.

Из моей практики приведу несколько примеров, когда пауза может не сработать:

  • хочется выключить компьютер (ну чтобы не гудел или по другим причинам);

  • другая работа на компьютере приведёт к перезагрузке. Например, я разрабатываю модули ядра (windows: драйвера). Что-то можно сделать через виртуалку, что-то - нет. И вот когда "нет", любой kernel panic (windows: BSOD) может всё поломать (даже конвертация в виртуалке или докере может не спасти - поломается всё). Да, можно завести отдельный компьютер для конвертаций, но это как-то жирно.

  • сама конвертация по каким-то причинам поломалась. Например, у меня были случаи аварийного останова. Причём повторный прогон отрабатывал нормально.

Как я уже писал, все углы можно обойти. Но, например, для меня поднимать виртуалку или докер, чтобы сконвертировать видеофайл это неизи. Если есть другой способ (например, моя утилита) - то это гуд.

Не, я костыли уважаю и даже сам пишу. Ну как "сам" - с ChatGPT недавно сделал soundboard для Mumble, например.

Например, у меня были случаи аварийного останова.

Вот это вам нужно разобраться почему происходит, ffmpeg достаточно стабилен, чтобы не падать посреди процесса.

Мне с детства казалось, что если я в одном месте, то всякая дурацкая деятельность должна быть в другом. Повзрослев, я понял что лучшее место для работы, в смысле не для игр, в Windows - Parallels на Маке. Она тебе - не выключайте компьютер!!!, а ты ей не глядя - suspend, и домой с внешним диском в кармане.

Применительно к этой вашей ffmpeg - есть же Docker со товарищи…

Если любому человеку… молдаванин, женщина, не важно. Нужно… А человеку только надо было всего лишь один… Кампучия, да? Тридцать восьмой год. А? Красавцы… А он говорит: «нет»… а мы не хотим, а мы не хотим, мы хотим чтобы русский балет, чтобы он развивался... эскорт… она приехала да, пачка… все оп ух быль-были-были-у ууп, все… русский балет

Sign up to leave a comment.

Articles