кодирование без потерь h264

Можно ли вообще кодировать без потерь в h264? Под без потерь я подразумеваю, что если я скормлю ему серию кадров и закодирую их, а затем, если я извлеку все кадры из закодированного видео, я получу точно такие же кадры, как и на входе, пиксель за пикселем, кадр за кадром . Это действительно возможно? Возьмите этот пример:

Я генерирую кучу кадров, затем кодирую последовательность изображений в несжатый AVI (с чем-то вроде virtualdub), затем применяю h264 без потерь (файлы справки утверждают, что параметр --qp 0 обеспечивает сжатие без потерь, но я не уверен, что это означает отсутствие потерь в любой точке процесса или просто квантование без потерь). Затем я могу извлечь кадры из получившегося видео h264 с помощью чего-то вроде mplayer.

Сначала я попробовал с Handbrake, но оказалось, что он не поддерживает кодирование без потерь. Я пробовал x264, но он вылетает. Это может быть связано с тем, что мой исходный файл AVI находится в цветовом пространстве RGB вместо YV12. Я не знаю, как передать серию растровых изображений YV12 и в каком формате для x264, поэтому я даже не могу попробовать.

Подводя итог, что я хочу знать, есть ли способ уйти от

Серия растровых изображений без потерь (в любом цветовом пространстве) -> некоторое преобразование -> кодирование h264 -> декодирование h264 -> некоторое преобразование -> исходная серия растровых изображений без потерь

Если есть способ добиться этого?

РЕДАКТИРОВАТЬ: есть ОЧЕНЬ веская точка зрения о том, что H264 без потерь не имеет особого смысла. Я прекрасно понимаю, что не могу сказать (только своими глазами) разницу между несжатым клипом и другим, сжатым с высокой скоростью в H264, но я не думаю, что это не бесполезно. Например, это может быть полезно для хранения видео для редактирования, не занимая при этом огромных объемов места, не теряя качества и не тратя слишком много времени на кодирование при каждом сохранении файла.

ОБНОВЛЕНИЕ 2: Теперь x264 не падает. Я могу использовать в качестве исходников либо avisynth, либо yv12 lagarith без потерь (чтобы избежать предупреждения о сжатии цветового пространства). Однако даже с --qp 0 и источником rgb или yv12 я все еще получаю некоторые различия, минимальные, но присутствующие. Это беспокоит, потому что вся информация, которую я нашел о прогнозирующем кодировании без потерь (--qp 0), утверждает, что все кодирование должно быть без потерь, но я не могу это проверить.


person cloudraven    schedule 15.07.2011    source источник
comment
Я даже не знал, что h.264 определяет схему без потерь...   -  person    schedule 15.07.2011
comment
Я не верю, что вы можете сделать h.264 в режиме без потерь. Почему вы хотите в любом случае?   -  person Brad    schedule 15.07.2011
comment
Что плохого в потере?   -  person    schedule 15.07.2011
comment
Студии компьютерной графики часто отправляют свои продукты (с транспортными компаниями) на самолетах, потому что это дешевле и быстрее, чем отправка через Интернет. Когда вы слышите подобные истории, такой вопрос внезапно обретает смысл. И да, для h.264 есть режим без потерь.   -  person Karoly Horvath    schedule 16.07.2011
comment
Этот вопрос кажется не по теме, поскольку он касается FFmpeg и лучше подходит либо для привилегированного пользователя, либо для Производство видео.   -  person Cole Johnson    schedule 28.12.2014


Ответы (8)


Я собираюсь добавить поздний ответ на этот вопрос, проведя весь день, пытаясь понять, как преобразовать YUV 4: 4: 4 пикселя в x264. Хотя x264 принимает необработанные пиксели 4: 2: 0 в файле, действительно довольно сложно передать пиксели 4: 4: 4. В последних версиях ffmpeg для кодирования и извлечения без потерь для проверки кодировки работает следующее.

Сначала запишите необработанные пиксели yuv 4:4:4 в файл в плоском формате. Плоскости представляют собой набор байтов Y, затем байты U и V, где U и V используют 128 в качестве нулевого значения. Теперь вызовите ffmpeg и передайте размер необработанных кадров YUV, поскольку дважды используйте формат пикселей «yuv444p», например:

ffmpeg -y -s 480x480 -pix_fmt yuv444p -i Tree480.yuv \
-c:v libx264 -pix_fmt yuv444p -profile:v high444 -crf 0 \
-preset:v slow \
Tree480_lossless.m4v

После кодирования в h264 и переноса в файл Quicktime можно извлечь точно такие же байты следующим образом:

ffmpeg -y -i Tree480_lossless.m4v -vcodec rawvideo -pix_fmt yuv444p \
Tree480_m4v_decoded.yuv

Наконец, проверьте два бинарных файла с помощью diff:

$ diff -s Tree480.yuv Tree480_m4v_decoded.yuv
Files Tree480.yuv and Tree480_m4v_decoded.yuv are identical

Просто имейте в виду, что вам нужно самостоятельно записывать байты YUV в файл, не позволяйте ffmpeg выполнять какое-либо преобразование значений YUV!

person MoDJ    schedule 29.08.2013
comment
более простая команда ffmpeg: ffmpeg -i Frame_03d.png -vcodec rawvideo -pix_fmt yuv444p Output.y4m (измените 3 на количество цифр в вашем файле) - person MarcusJ; 01.05.2015
comment
наконец кто-то проверяет! - person n611x007; 07.09.2015
comment
Нет, это просто сбросит необработанные пиксели в файл y4m (rawvideo). Первоначальный вопрос был о том, как кодировать как без потерь h.264. Ваша более простая команда не сжимает данные, а просто преобразует их в необработанные несжатые пиксели. - person MoDJ; 07.09.2015
comment
Первая команда - преобразовать его. Вторые - распаковать его для сравнения :) - person rogerdpack; 20.12.2019

Если x264 выполняет кодирование без потерь, но вам не нравится ваш входной формат, то лучше всего использовать ffmpeg для работы с входным файлом. Попробуйте начать с чего-то вроде

ffmpeg -i input.avi -f yuv4mpegpipe -pix_fmt yuv420p -y /dev/stdout \
  | x264 $OPTIONS -o output.264 /dev/stdin

и добавление опций оттуда. YUV4MPEG — это несжатый формат без потерь, подходящий для передачи между различными видеоинструментами; ffmpeg знает, как его записать, а x264 знает, как его прочитать.

person hobbs    schedule 15.07.2011
comment
Спасибо! До сих пор мне не удавалось вернуться к своим оригинальным видео с x264 (теперь ему нравится мой входной формат). Всегда есть затяжные (очень-очень тонкие) артефакты, так что, возможно, ffmpeg может мне помочь. Потеряю ли я информацию о цвете из оригинального avi при конвертации в yuv420p? Даже если это так, есть ли способ извлечь отдельные кадры из несжатого потока yuv4mpeg, чтобы я мог сравнить их с кадрами в потоке x264 или, по крайней мере, декодировать yuv4mpeg обратно из потока x264. Если h264 может быть действительно без потерь, они должны быть идентичными. - person cloudraven; 16.07.2011
comment
Вероятно, есть небольшая потеря точности при преобразовании из RGB в YUV, но я считаю, что это неизбежно, поскольку YUV является родным цветовым пространством H.264. Однако я забыл, что YUV420P на самом деле не является полностью пиксельным форматом без потерь - он несколько уменьшает информацию о цветности, которую он хранит. Попробуйте выбрать другие параметры из ffmpeg -pix_fmts и посмотрите, примет ли их x264. yuv444p было бы хорошим началом; это YUV, но с полной информацией о цветности на пиксель. - person hobbs; 16.07.2011
comment
Это то, о чем я думал. Я попытался сделать следующее, чтобы отказаться от уменьшения цветового пространства: кодировать видео с использованием лагарита (без потерь yv12), чтобы мои изображения были в цветовом пространстве, подходящем для h264. Я извлек все кадры из этого видео и сохранил копию. Я закодировал видео с помощью x264 --qp0 (на этот раз преобразования цветов не произошло), а затем извлек кадры из полученного видео. Они не соответствовали моей резервной копии. Не должно быть потери информации при переходе от YV12 к RGB, верно? Я делаю что-то неправильно? - person cloudraven; 16.07.2011

FFmpeg имеет режим "без потерь" для x264, см. Руководство по кодированию FFmpeg и x264

H.264 без потерь

по сути это -crf 0

person rogerdpack    schedule 06.09.2012
comment
вы должны внимательно прочитать OP, единственная команда, которая уже содержится, это -qp 0 - person n611x007; 07.09.2015
comment
Опечатка: crf, а не crt. - person llogan; 20.12.2019

Я не знаю ваших требований к сжатию и распаковке, но архиватор общего назначения (например, 7-zip с LZMA2) должен сжимать примерно так же мало или, в некоторых случаях, даже значительно меньше, чем видеокодек без потерь. И это намного проще и безопаснее, чем целая цепочка обработки видео. Недостатком является гораздо более низкая скорость, и вы должны извлечь ее, прежде чем увидеть ее. Но для изображений, я думаю, вы должны попробовать это.

Существуют также форматы изображений без потерь, такие как .png.

Для кодирования RGB без потерь с x264 вы должны использовать версию командной строки x264 (вы не можете доверять графическим интерфейсам в этом крайнем случае, они, вероятно, испортятся) r2020 или новее, с чем-то вроде этого:

x264 --qp 0 --preset fast --input-csp rgb --output-csp rgb --colormatrix GBR --output "the_lossless_output.mkv" "someinput.avs"

Любые потери/различия между входом и выходом должны быть связаны с некоторым преобразованием цветового пространства (либо перед кодированием, либо при воспроизведении), неправильными настройками или некоторыми потерянными заголовком/метаданными. x264 не поддерживает RGBA, но с RGB все в порядке. Сжатие YUV 4:4:4 более эффективно, но вы потеряете некоторые данные при преобразовании цветового пространства, так как ваш входной сигнал — RGB. YV12/i420 намного меньше и, безусловно, является наиболее распространенным цветовым пространством в видео, но у вас меньше разрешение цветности.

Дополнительные сведения о настройках x264: http://mewiki.project357.com/wiki/X264_Settings.

Кроме того, избегайте лагарита. Он использует x87 с плавающей запятой... и есть лучшие альтернативы. http://codecs.multimedia.cx/?p=303 http://mod16. org/hurfdurf/?p=142

РЕДАКТИРОВАТЬ: я не знаю, почему за меня не проголосовали. Пожалуйста, оставьте комментарий, когда вы это сделаете.

person ReneSac    schedule 19.01.2012
comment
Алгоритмы сжатия общего назначения не очень хорошо справляются с видео, аудио и т. д. Специализированные алгоритмы (если они существуют) почти всегда лучше. Исключениями из этого правила являются некоторые очень старые алгоритмы +, возможно, специально созданные входные данные, предназначенные для обмана кодировщика. - person Display Name; 03.06.2013
comment
@Sarge: я не согласен с видеокодеками без потерь, потому что лучше не имеет смысла без определения статистики для сравнения. Многие видеокодеки без потерь предназначены для захвата в реальном времени, поэтому используйте только легкое сжатие. Общие компрессоры часто приводят к меньшему размеру файла. - person John Smith; 06.08.2013
comment
@JohnSmith в этом случае они быстрее. - person Display Name; 06.08.2013
comment
Основным преимуществом является отсутствие необходимости распаковки всего файла перед его просмотром/использованием. И да, большинство видеокодеков без потерь предназначены для захвата в реальном времени и, следовательно, являются быстрыми и обычно сжимают естественные кадры лучше, чем архиваторы общего назначения, но ненамного. Но для некоторых материалов, таких как захват 2D-экрана, даже специализированные кодеки не могут сравниться со сжатием LZMA с большим словарем. И у вас всегда будет точная побитовая копия вашего входного видео, без шансов испортить преобразование цвета, метаданные и т. Д. В зависимости от потребностей OP они могут быть лучшим вариантом. - person ReneSac; 27.11.2013

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

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

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

person LDaly    schedule 12.07.2012
comment
Хороший вопрос, и я полностью согласен, но это скорее комментарий, чем ответ. Я предполагаю, что это было опубликовано из-за отсутствия привилегии комментировать? - person Camilo Martin; 03.04.2015

Чтобы сгенерировать H.264 без потерь с графическим интерфейсом HandBrake, установите видеокодек: H.264, постоянное качество, RF: 0, профиль H.264: авто. Хотя этот файл изначально не поддерживается Apple, его можно перекодировать практически без потерь для воспроизведения.

Окно активности HandBrake GUI:

Профиль H.264: авто; Кодирование при постоянной RF 0,000000...профиль Высокий 4:4:4 Предиктивный, уровень 3.0, 4:2:0 8-бит

Профиль H.264: высокий; Кодирование с постоянным значением RF 0,000000...без потерь требует профиля high444, отключение...профиль High, уровень 3.0

person Community    schedule 11.12.2013

Если вы не можете получить сжатие без потерь с помощью кодировщика и декодера h.264, возможно, вы могли бы рассмотреть две альтернативы:

(1) Вместо передачи всех данных в формате h.264 некоторые люди экспериментируют с передачей некоторых данных с остаточный "побочный канал":

  • (файл h.264) -> декодирование h264 -> некоторое преобразование -> аппроксимация исходной серии растровых изображений с потерями
  • (сжатый остаточный файл) --> декодер --> серия остаточных растровых изображений без потерь
  • Для каждого пикселя в каждом растровом изображении приблизительное_пиксель + остаточный_пиксель = пиксель, побитно равный исходному пикселю.

(2) Используйте формат сжатия видео Dirac в режиме «без потерь».

person David Cary    schedule 26.08.2011
comment
Да... на самом деле я сделал что-то очень похожее на это (вариант 1). Я также пробовал использовать кодек Lagarith, который, вероятно, похож на вариант 2. Плохо, что не написал об этом здесь. Спасибо большое за ответ. - person cloudraven; 27.08.2011
comment
Дает ли это вообще достойные результаты? Я помню, как однажды пробовал что-то подобное с остаточным сжатием MP3 + lzma, но это всегда было хуже, чем обычный FLAC (с очень небольшим отрывом). - person Camilo Martin; 03.04.2015

Используйте FFmpeg с PowerShell. Тип 1_. Вы можете видеть Supported pixel formats: bgr0 bgr24 rgb24 Когда вы кодируете RGB в YUV или наоборот, вы всегда теряете качество. Но если вы используете -pix_fmt yuv444p -profile:v high444p, ваши потери будут минимальными. Но если вы используете libx264rgb кодировщика ffmpeg libx264rgb с форматом пикселя rgb24, у вас не будет потери качества. Многие приложения (например, Davinci Resolve) не могут читать формат пикселей rgb 24. Я рекомендую вам использовать:

ffmpeg -i ["your sequence of rgb image.png"] -c:v libx264rgb -video_size [your size] -framerate [your fps] -r [your fps] -qp 0 -pix_fmt rgb24 -profile:v high444 -preset veryslow -level 6.2 "your_video.mov"

К сожалению, я не знаю, как создать последовательность. Но это возможно в FFmpeg.

person Andrew    schedule 22.04.2021