Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

h264 lossless coding

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.

like image 891
cloudraven Avatar asked Jul 15 '11 01:07

cloudraven


People also ask

Is CRF 0 lossless?

The range of the CRF scale is 0–51, where 0 is lossless (for 8 bit only, for 10 bit use -qp 0), 23 is the default, and 51 is worst quality possible. A lower value generally leads to higher quality, and a subjectively sane range is 17–28.

Is H.264 codec good?

Benefits of using H. H. 264 was created to provide high-quality transmission of full-motion video with lower bandwidth requirements and lower latency traditional video standards, such as MPEG-2. H. 264 uses a very efficient codec that provides high-quality images and uses a minimal amount of bandwidth.

Is H.264 a codec?

A codec based on the H. 264 standard compresses a digital video file (or stream) so that it only requires half of the storage space (or network bandwidth) of MPEG-2. Through this compression, the codec is able to maintain the same video quality despite using only half of the storage space.

Which codec is better H.264 or H 265?

The H. 265 codec compresses information more efficiently than H. 264, resulting in files of comparable video quality that are about half the size.


1 Answers

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!

like image 144
MoDJ Avatar answered Sep 25 '22 10:09

MoDJ