Compressing Grayscale 8-bit PNG Sequences with ffmpeg

1

I typically deal with many high-resolution PNG sequences, many of which are RGB (24-bit) or entirely grayscale (8-bit). Because adjacent frames in the sequences are very similar, it is important that I compress them losslessly using a codec that supports inter-frame compression. I've used libx264 to compress the RGB 24 bit sequences with decent success (specifically ffmpeg -framerate 60 -i out%04d.png -c:v libx264rgb -qp 0 out.mp4), and while I can do the same for the grayscale images, I'm wondering if there's a better codec to use in that case given that there's only one channel instead of three.

Is there a better alternative codec than libx264 for grayscale png sequences specifically? If so, why is it better? If not, why is libx264 the best in both cases?

jippyjoe4

Posted 2020-01-06T08:10:53.617

Reputation: 630

1What's your primary requirement - file size, encoding speed, compatibility? – Gyan – 2020-01-06T13:08:42.650

@Gyan, I'd like to reduce file size as much as possible. – jippyjoe4 – 2020-01-06T19:08:00.783

Answers

0

libx264 and libx265 both have lossless modes, are inter-frame, and support the gray pixel format.

libx264

libx264 supports the gray pixel format (see ffmpeg -h encoder=libx264), so using that instead of libx264rgb may be a more appropriate choice for the grayscale inputs:

ffmpeg -framerate 60 -i out%04d.png -c:v libx264 -qp 0 -preset veryslow out.mp4

libx265

Worth trying to compare with libx264, but it will be much slower to encode (especially if you use a slow preset):

ffmpeg -framerate 60 -i out%04d.png -c:v libx265 -x265-params lossless=1 out.mp4

others

ffv1, huffyuv, ffvhuff, qtrle are all lossless and support gray pixel format(s), but these are are all intra-frame.

llogan

Posted 2020-01-06T08:10:53.617

Reputation: 31 929

Compressing the following files with your first libx264 command doesn't seem lossless. When I extract them with ffmpeg -i out.mp4 -start_number 0 out_depth%04d.png, the resulting files I get have different pixel values (also, the output is 24bit instead of 8bit). Am I doing something wrong? https://drive.google.com/open?id=1YnnJgTT-YTcmxBhFEitr63n2fxZrQrCN

– jippyjoe4 – 2020-01-11T19:37:30.857

@jippyjoe4 You forgot to enable lossless mode with -crf 0 or -qp 0. – llogan – 2020-01-13T18:45:37.167

I did use -qp 0 in the encoding command (I ran your line exactly as in your answer). Using it in the decoding command I specified in my comment (ffmpeg -i out.mp4 -qp 0 -start_number 0 out_depth%04d.png) results in the following warning: Codec AVOption qp (Constant quantization parameter rate control method) specified for output file #0 (out_depth%04d.png) has not been used for any stream. The most likely reason is either wrong type (e.g. a video option with no video streams) or that it is a private option of some encoder which was not actually used for any stream.. – jippyjoe4 – 2020-01-14T00:32:55.710

Also, running ffmpeg -qp 0 -i out.mp4 -start_number 0 out_depth%04d.png results in Codec AVOption qp (Constant quantization parameter rate control method) specified for input file #0 (out.mp4) is not a decoding option., so I really don't understand what I'm doing wrong. – jippyjoe4 – 2020-01-14T00:37:28.663

@jippyjoe4 1) The -qp 0 is intended for MP4 output when encoding with libx264, not for the PNG outputs. 2) Option placement matters. You are attempting to apply -qp 0 to the input. Placement should be as follows ffmpeg [global options] [input options] input [output options] output – llogan – 2020-01-14T18:20:18.523

I'm sorry, but I still don't understand. I made a video here showing exactly what I'm doing. https://www.youtube.com/watch?v=ezurM5y-rfE&feature=youtu.be I don't understand why the output files aren't the same as the inputs.

– jippyjoe4 – 2020-01-14T19:56:15.317

@jippyjoe4 Looks like pixel format conversion is possibly occurring, although I am unable to try it myself right now. Seeing gray in the list of supported pixel formats I assumed it would stay within gray. Try libx265 instead. – llogan – 2020-01-14T20:33:44.490

Thank you, I should have tried that sooner. libx265 seems to work perfectly. The output is 8-bit and the files are identical. Although I still don't know why libx264 wouldn't work. – jippyjoe4 – 2020-01-15T01:52:01.227