h264无损编码

发布于 2024-11-19 22:13:12 字数 880 浏览 4 评论 0原文

h264 是否可以进行完全无损编码?所谓无损,我的意思是,如果我向它提供一系列帧并对它们进行编码,然后如果我从编码视频中提取所有帧,我将得到与输入中完全相同的帧,逐像素、逐帧。这实际上可能吗? 举个例子:

我生成一堆帧,然后将图像序列编码为未压缩的 AVI(使用 virtualdub 之类的东西),然后应用无损 h264(帮助文件声称设置 --qp 0 可以进行无损压缩,但我我不确定这是否意味着过程的任何点都没有损失,或者只是量化是无损的)。然后我可以使用 mplayer 之类的工具从生成的 h264 视频中提取帧。

我先尝试使用 Handbrake,但结果发现它不支持无损编码。我尝试了 x264 但它崩溃了。这可能是因为我的源 AVI 文件采用 RGB 色彩空间而不是 YV12。我不知道如何将一系列 YV12 位图以及以什么格式提供给 x264,所以我什至无法尝试。

总之,我想知道是否有办法从

一系列无损位图(在任何色彩空间中) - >一些转变 -> h264 编码 -> h264解码->一些转变 ->原系列无损位图

是否有办法实现?

编辑:关于无损 H264 有一个非常有效的观点,但没有太大意义。我很清楚,我无法(仅用我的眼睛)分辨出未压缩的剪辑和另一个在 H264 中以高速率压缩的剪辑之间的区别,但我认为它并非没有用处。例如,它对于存储视频进行编辑可能很有用,而不会占用大量空间,也不会损失质量,也不会在每次保存文件时花费太多编码时间。

更新 2:现在 x264 不会崩溃。我可以使用 avisynth 或无损 yv12 lagarith 作为源(以避免色彩空间压缩警告)。然而,即使使用 --qp 0 和 rgb 或 yv12 源,我仍然得到一些差异,最小但存在。这很令人不安,因为我在无损预测编码(--qp 0)上找到的所有信息都声称整个编码应该是无损的,但我无法验证这一点。

Is it possible to do completely lossless encoding in h264? By lossless, I mean that if I feed it a series of frames and encode them, and then if I extract all the frames from the encoded video, I will get the exact same frames as in the input, pixel by pixel, frame by frame. Is that actually possible?
Take this example:

I generate a bunch of frames, then I encode the image sequence to an uncompressed AVI (with something like virtualdub), I then apply lossless h264 (the help files claim that setting --qp 0 makes lossless compression, but I am not sure if that means that there is no loss at any point of the process or that just the quantization is lossless). I can then extract the frames from the resulting h264 video with something like mplayer.

I tried with Handbrake first, but it turns out it doesn't support lossless encoding. I tried x264 but it crashes. It may be because my source AVI file is in RGB colorspace instead of YV12. I don't know how to feed a series of YV12 bitmaps and in what format to x264 anyway, so I cannot even try.

In summary what I want to know if that is there a way to go from

Series of lossless bitmaps (in any colorspace) -> some transformation -> h264 encode -> h264 decode -> some transformation -> the original series of lossless bitmaps

If there a way to achieve this?

EDIT: There is a VERY valid point about lossless H264 not making too much sense. I am well aware that there is no way I could tell (with just my eyes) the difference between and uncompressed clip and another compressed at a high rate in H264, but I don't think it is not without uses. For example, it may be useful for storing video for editing without taking huge amounts of space and not losing quality and spending too much encoding time every time the file is saved.

UPDATE 2: Now x264 doesn't crash. I can use as sources either avisynth or lossless yv12 lagarith (to avoid the colorspace compression warning). Howerver, even with --qp 0 and a rgb or yv12 source I still get some differences, minimal but present. This is troubling, because all the information I have found on lossless predictive coding (--qp 0) claims that the whole encoding should be lossless, but I am unable to verifiy this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

提笔落墨 2024-11-26 22:13:12

在花了一整天的时间试图找出如何将 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 值进行任何转换!

I am going to add a late answer to this one after spending all day trying to figure out how to get YUV 4:4:4 pixels into x264. While x264 does accept raw 4:2:0 pixels in a file, it is really quite difficult getting 4:4:4 pixels passed in. With recent versions of ffmpeg, the following works for completely lossless encoding and extraction to verify the encoding.

First, write your raw yuv 4:4:4 pixels to a file in a planar format. The planes are a set of Y bytes, then the U and V bytes where U and V use 128 as the zero value. Now, invoke ffmpeg and pass in the size of the raw YUV frames as use the "yuv444p" pixel format twice, like so:

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

Once the encoding to h264 and wrapping as a Quicktime file is done, one can extract the exact same bytes like so:

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

Finally, verify the two binary files with diff:

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

Just keep in mind that you need to write the YUV bytes to a file yourself, do not let ffmpeg do any conversion of the YUV values!

鹿童谣 2024-11-26 22:13:12

如果 x264 进行无损编码但不喜欢您的输入格式,那么您最好的选择是使用 ffmpeg 来处理输入文件。尝试从类似的内容开始

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

,然后从那里添加选项。 YUV4MPEG是一种无损未压缩格式,适用于不同视频工具之间的管道传输; ffmpeg 知道如何编写它,x264 知道如何读取它。

If x264 does lossless encoding but doesn't like your input format, then your best bet is to use ffmpeg to deal with the input file. Try starting with something like

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

and adding options from there. YUV4MPEG is a lossless uncompressed format suitable for piping between different video tools; ffmpeg knows how to write it and x264 knows how to read it.

逐鹿 2024-11-26 22:13:12

FFmpeg 对于 x264 有一个“无损”模式,请参阅FFmpeg 和 x264 编码指南


§ Lossless H.264

本质上它是 -qp 0

FFmpeg has a "lossless" mode for x264, see FFmpeg and x264 Encoding Guide


§ Lossless H.264

in essence it's -qp 0

感情废物 2024-11-26 22:13:12

我不知道您对压缩和解压缩的要求,但通用存档器(例如带有 LZMA2 的 7-zip)应该能够压缩得与无损视频编解码器一样小,或者在某些情况下甚至明显小于无损视频编解码器。而且它比整个视频处理链更简单、更安全。缺点是速度慢很多,而且必须先解压才能看到。但对于图像,我认为你应该尝试一下。

还有无损图像格式,例如 .png。

要使用 x264 编码无损 RGB,您应该使用 x264 的命令行版本(在这种边缘情况下您不能信任 GUI,它们可能会搞砸)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

编辑:
我不知道为什么我被否决了。当您这样做时请发表评论。

I don't know your requirements for compression and decompression, but a general purpose archiver (like 7-zip with LZMA2) should be able to compress about as small or, in some cases, even significantly smaller than a lossless video codec. And it is much simpler and safer than a whole video processing chain. The downside is the much slower speed, and that you have to extract before seeing it. But for images, I think you should try it.

There is also lossless image formats, like .png.

For encoding lossless RGB with x264, you should use the command line version of x264 (you can't trust GUIs in this edge case, they will probably mess-up) r2020 or newer, with something like that:

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

Any losses/differences between the input and output should be from some colour space conversion (either before encoding, or at playback), wrong settings or some header/meta-data that was lost. x264 don't supports RGBA, but RGB is ok. YUV 4:4:4 compression is more efficient, but you will lose some data in colour space conversion as your input is RGB. YV12/i420 is much smaller, and by far the most common colour space in video, but you have less chroma resolution.

More information on x264 settings:
http://mewiki.project357.com/wiki/X264_Settings

Also, avoid lagarith. It uses x87 floating point... and there are better alternatives.
http://codecs.multimedia.cx/?p=303
http://mod16.org/hurfdurf/?p=142

EDIT:
I don't know why I was donwvoted. Please leave a comment when you do that.

酷到爆炸 2024-11-26 22:13:12

我同意有时数据丢失是可以接受的,但这不仅仅是压缩后的外观问题。

即使是视觉上难以察觉的颜色数据丢失也会降低素材质量,从而使颜色校正、绿屏抠像、跟踪和其他后期任务变得更加困难或不可能,从而增加制作成本。

这实际上取决于您在管道中压缩的时间和方式,但最终归档原始质量是有意义的,因为存储通常比重新拍摄便宜得多。

I agree that sometimes the loss in data is acceptable, but it's not simply a matter of how it looks immediately after compression.

Even a visually imperceptible loss of color data can degrade footage such that color correction, greenscreen keying, tracking, and other post tasks become more difficult or impossible, which add expense to a production.

It really depends when and how you compress in the pipeline, but ultimately it makes sense to archive the original quality, as storage is usually far less expensive than reshooting.

五里雾 2024-11-26 22:13:12

要使用 HandBrake GUI 生成无损 H.264,请设置视频编解码器:H.264、恒定质量、RF:0、H.264 配置文件:自动。尽管 Apple 本身不支持此文件,但可以将其重新编码为近乎无损的格式以便播放。

HandBrake GUI 的活动窗口:

H.264 配置文件:自动; 以恒定 RF 0.000000 进行编码...profile High 4:4:4 预测,级别 3.0,4:2:0 8 位

H.264 Profile:高; 以恒定 RF 0.000000 进行编码...无损需要 high444 配置文件,禁用...配置文件高,级别 3.0

To generate lossless H.264 with HandBrake GUI, set Video Codec: H.264, Constant Quality, RF: 0, H.264 Profile: auto. Though this file is not supported natively by Apple, it can be re-encoded as near-lossless for playback.

HandBrake GUI's Activity Window:

H.264 Profile: auto; Encoding at constant RF 0.000000...profile High 4:4:4 Predictive, level 3.0, 4:2:0 8-bit

H.264 Profile: high; Encoding at constant RF 0.000000...lossless requires high444 profile, disabling...profile High, level 3.0

蛮可爱 2024-11-26 22:13:12

如果您无法使用 h.264 编码器和解码器获得无损压缩,
也许您可以考虑两种替代方案:

(1) 有些人不是以 h.264 格式传递所有数据,而是尝试使用 剩余“侧通道”

  • (h.264文件)-> h264解码->一些转变 ->原始位图系列的有损近似
  • (压缩残留文件)-->解码器->一系列无损残差位图
  • 对于每个位图中的每个像素,approximate_pixel +residual_pixel = 逐位等于原始像素的像素。

(2) 在“无损”模式下使用Dirac视频压缩格式。

If you can't get lossless compression using a h.264 encoder and decoder,
perhaps you could look into two alternatives:

(1) Rather than passing all the data in h.264 format, some people are experimenting with transmitting some of the data with a residual "side channel":

  • (h.264 file) -> h264 decode -> some transformation -> a lossy approximation of the original series of bitmaps
  • (compressed residual file) --> decoder -> a series of lossless residual bitmaps
  • For each pixel in each bitmap, approximate_pixel + residual_pixel = a pixel bit-for-bit equal to the original pixel.

(2) Use Dirac video compression format in "lossless" mode.

絕版丫頭 2024-11-26 22:13:12

将 FFmpeg 与 PowerShell 结合使用。输入 ffmpeg -h编码器=libx264rgb 。
您可以看到支持的像素格式:bgr0 bgr24 rgb24
当您将 RGB 编码为 YUV 或反之亦然时,您总是会损失质量。
但如果你使用 -pix_fmt yuv444p -profile:v high444p ,你的损失是最小的。
但是,如果您使用 ffmpeg 编码器 libx264rgb 的 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 中这是可能的。

Use FFmpeg with PowerShell. Type ffmpeg -h encoder=libx264rgb.
You can see Supported pixel formats: bgr0 bgr24 rgb24
When you encoding RGB to YUV or vice versa, you always loose quality.
But if you use -pix_fmt yuv444p -profile:v high444p your losses are least.
But if you use libx264rgb of ffmpeg encoder libx264rgb with format of pixel rgb24 you don't have any loss of quality.
A lot of application (for example Davinci Resolve) cannot read rgb 24 format of pixel.
I reccomend you to use:

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"

Unfortunately, I don't know how to create sequence. But it is possible in FFmpeg.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文