ffmpeg framemd5 — как добиться соответствия контрольных сумм между LPCM и FLAC?

ffmpeg framemd5 — как добиться соответствия контрольных сумм между LPCM и FLAC?

Я конвертирую сжатые без потерь видео и аудио файлы (Utvideo/LCPM) в кодеки FFV1/FLAC, используя MKV в качестве контейнера для экономии места на диске без ущерба качеству. Я использую функции framemd5 ffmpeg, чтобы гарантировать, что каждое преобразование будет 1:1 с исходным захватом с точки зрения вывода.

Пакетный скрипт выглядит следующим образом:

for %%a in ("*.avi") do ffmpeg -i "%%a" -f framemd5 "%%~na.framemd5"

Однако при использовании FLAC в качестве аудиокодека аудиочасть выходных данных framemd5 перестает совпадать.

Вот первые 1001 строка framemd5 примера записи:

https://pastebin.com/axcf3f0aоригинальный LPCM

https://pastebin.com/3n75YTMjКонвертация FLAC

Проблема, кажется, в том, чтоFLAC добавляет дополнительные метаданные и собственную контрольную сумму, так что хотя аудио предположительно 1:1, framemd5 не распознает его как таковой. Я не очень хорошо разбираюсь в файловой структуре FLAC, поэтому не могу проверить это сам или придумать обходной путь.

Можно ли как-то это согласовать? Могу ли я создать файлы framemd5, которые будут проверять контрольные суммы видео и аудио между Utvideo/LPCM и FFV1/FLAC как 1:1?

Это невероятно раздражает. Я хочу использовать FLAC для сжатия аудио, так как я и так пытаюсь сэкономить как можно больше места.

решение1

Это не имеет никакого отношения к метаданным потока FLAC.

ffmpeg-allна фреймхэше(framemd5 — это вариант framehash):

По умолчанию аудиокадры преобразуются в подписанный 16-битный необработанный звук, а видеокадры — в необработанное видео перед вычислением хэша.

(ПРИМЕЧАНИЕ: в случае более высокой битовой глубины вам необходимо будет указать соответствующуюкодер, например-c:a pcm_s24le после -f framemd5(В обоих случаях «A» и «B» для предотвращения вычисления контрольной суммы на «усеченных» аудиокадрах.)

Таким образом, контрольная сумма всегда выполняется для декодированных (а затем кодированных, несколько «фиктивным» способом, как в случаях PCM или нет) кадров, если только вы не указали что-то вроде -c copy. Таким образом, метаданные не будут «мешать» хешированию здесь.

Настоящая причина проблемы здесь в том, что в отличие от случая с видео, «кадр» в данном случае при применении к аудиопотоку относится не к одному сэмплу, а к сэмплам в целом, которые были сгруппированы в пакет. Пакеты могут иметь разные размеры (количество сэмплов) в зависимости от кодировщика/мультиплексора (значения по умолчанию в их коде) и, возможно, настроек пользователя.

Как видно из выходных строк, каждый пакет во входном аудиопотоке содержит 1024 сэмпла в случае PCM, тогда как в случае FLAC каждый пакет содержит 4608 сэмплов.

TL;DR. Решением здесь будет добавление -frame_size 1024после -c:a flacтого, как вы кодируете «сжатую версию».

PS Я понятия не имею, вызовет ли изменение размера кадра/пакета потока FLAC какие-либо проблемы (например, при воспроизведении) / нежелательные побочные эффекты, и вы можете задаться вопросом, можно ли вместо этого изменить размер кадра/пакета потока PCM. Все, что я могу сказать, это то, что в случае PCM это будет на уровне мультиплексора, а не на уровне кодировщика, как в случае FLAC, что более или менее подразумевает, что это вряд ли будет настраиваемым пользователем .

Хотя это может помочь, а может и нет, вы всегда можете попробовать выполнить мультиплексирование (из файлов необработанного потока или файлов WAVE/AIFF, если это PCM, вместо повторного мультиплексирования файла Matroska, поскольку задействованный процесс может отличаться) с другим мультиплексором Matroska в случае, если размер пакета/кадра PCM-in-Matroksa (т. е. 1024) в ffmpeg не работает должным образом при использовании для FLAC.

ОБНОВЛЕНИЕ: Очевидно, если вы используете WAVE-файл в качестве входных данных, вы можете использовать-max_size демультиплексоропция (WAVE dexmuer) для определения размера каждого пакета, когда поток подается в Matrokska muxer. Обратите внимание, что -max_sizeэто байты, а не образцы. Так что в этом случае вы можете использовать что-то вроде ffmpeg ... -max_size 9216 -i path/to/input.wav ...(убедитесь, что у вас есть-max_size до -i). Кажется, я не вижу подобной опции в демультиплексорах raw PCM (например s16le), поэтому вам сначала нужно будет сделать входной аудиофайл WAVE-файлом, если вы хотите использовать его.

Ссылка (расположение в коде значений по умолчанию):
https://github.com/FFmpeg/FFmpeg/blob/n5.1.2/libavcodec/flacenc.c#L314
https://github.com/FFmpeg/FFmpeg/blob/n5.1.2/libavformat/pcm.c#L27
https://github.com/FFmpeg/FFmpeg/blob/n5.1.2/libavformat/wavdec.c#L76

Связанный контент