Has anyone done or seen any tests comparing Apple ProRes 422 with high-bitrate H.264?
No, but I can tell you that x264 can get as close to lossless as you want (or even mathematically lossless, with -qp 0
). x264 can produce h.264 streams in 4:2:0, 4:2:2, or 4:4:4 YUV colorspaces, at 8 or 10 bits per component. (It can also do RGB, but unless you're doing lossless, you'll probably get better quality per bitrate from YUV.)
Decoder support for anything other than 4:2:0 8bit isn't as widespread. (e.g. video cards have hardware decoders that can only accelerate 4:2:0 8bit).
Note that x264 has to be compiled for either 8 or 10bit output. You need a separate build of libx264 (or a whole separate static build of ffmpeg) for 8bit and 10bit. Either can handle any input bit depth you want to throw at it, but will always output the bit depth it was compiled for.
The Hi444PP h.264 profile supports up to 14bit depth for lossy or lossless operation, but x264 still only supports 8 or 10bit. (Also 9bit, if you compile it with bit depth = 9, but there's really no point in doing that. The speed hit comes as soon as you go beyond 8)
BTW, even if your input is 8bit and your final display is 8bit RGB, 10bit h.264 looks better for the same bitrate. 8bit h.264 is a speed vs. quality tradeoff. (and obviously decoder compat.) Google should find some threads on doom9, and a PDF from ateme, to back up this assertion.
To understand it, remember that lossy codecs aren't trying to reproduce all the input bits, just something that looks similar. 10bit allows more internal precision for motion prediction, and lets the encoder tweak the least-significant bits for better CABAC efficiency (trellis) without producing a visible difference. So you get less banding of gradients.
We are wondering if it is possible to reach adequate quality with
H.264. Say, with bitrates of 50-100mbps, and tweaking the GOP
size/structure. (E.g., only using "I" frames.)
Forcing more I frames, or I frames only, does NOT increase quality. h.264 encoders "know" how their output differs from their input, and will use I macroblocks where they're a better choice.
Short GOPs are useful for seeking, or error recovery in realtime streaming use cases. For video production, a short GOP lets you frame step backwards without having to decode very many frames from the previous keyframe. So you can scrub with more precision.
If seeking isn't a concern at all, you could set keyint=1000, and then x264 could use almost as long a GOP as it wanted. (Scenecut detection is on in every preset except ultrafast, so x264 will use an IDR (key frame) every time a scene cut makes an I frame a good idea anyway.)
Update 2: I did some more testing ... with Adobe Media Encoder, using
MPEG2, and the "4:2:2" profile, the ProRes file went from 1,920MB to
290MB! And I would say, subjectively, that is is 99% as good. This is
remarkable. (With H264 I was down to 500-700MB)
If you got results that good with MPEG2, you should easily get even smaller files with a decent h.264 encoder. Your content probably compresses pretty well (low grain, some areas with lots of similarity).
If you have your input in a file that ffmpeg can read (i.e. almost any format),
ffmpeg -i in.mp4 -c:a copy -c:v libx264 -preset medium -tune film -crf 10 -movflags +faststart out.mp4
CRF 10 is way beyond visually lossless. ffmpeg defaults to the same colorspace as the input, if the output codec supports it. If your input is 4:4:4, but you want to subsample your chroma, use something like:
ffmpeg -i in ... -sws-flags lanczos+print_info -pix_fmt yuv422p out
...
[swscaler @ 0x33be0c0] Lanczos scaler, from rgb24 to yuv422p using MMXEXT
Update 1: How would one "test" the difference technically? Or measure
the color information?
Measure the output color depth? maybe with mediainfo.
To compare quality of different encodes of the same source, measure the SSIM or PSNR of each encode relative to the source. x264 can measure both those metrics during the encode process. There are other tools for comparing two already-made video files, to measure those quality metrics, but I haven't used them.
For ffmpeg, use -ssim 1 -psnr -tune ssim
. (Don't use -tune ssim
except when benchmarking that metric. It defaults to enabling psychovisual optimizations that produce output that looks better to humans, but is mathematically less similar according to that metric.)
SSIM and PSNR are about the only thing you can use when you're working with bitrates that go way beyond visually transparent. Google on these for more info.
To test losslessness, you can use ffmpeg's -f framemd5
codec to make sure the h.264 decodes bit-identically to the input. (see this question for an example. Make sure you use the same -pix_fmt for all tests, because different decoders might pack the same data differently.)
Oh, just read Prof Sparkles' answer. Didn't realize that you were eventually outputting to lossless. You're just shooting yourself in the foot if you use any lossy codecs along the way. The lossless codec will have to encode all the invisible blocking / ringing artifacts left by the lossy codecs, so you'll typically get bigger files from your lossless codec if you feed it input that's been through a lossy codec, instead of the original source.
So if you want to use h.264, use lossless. (ffmpeg -i in -preset ultrafast -qp 0 out
). (slower presets give only a tiny compression improvement for lossless. Never use ultrafast for anything except lossless, though.)