h264 settings for large flat areas of slowly changing colour I'm doing an animation for a projection mapping that simulates the sun casting shadows on a structure as it moves through the sky. Basically it's just big flat areas of colour that change over about five minutes as the "sun" rises and sets (in another projection). It's played off a Brightsign playback gizmo, and I'm using h.264 main profile as the codec in an mp4.

The problem I'm having is that the encoding isn't dealing very well with the content. Even though the colour is completely flat, when the pixels all change value over time I'm getting bands of noise and blocks appearing. They're subtle, but they're annoying.

Is there any tuning I can do using libx264 to optimise it for large flat areas of colour where all the pixels simultaneously change over time? There is absolutely no movement in the frame, just the colour of the whole area changing, quite slowly.

My current ffmpeg command is pretty generic:

ffmpg -i input.mov -c:v libx264 -preset slow -profile main -crf 20 -pix_fmt yuv420p -an output.mp4
The bands you're referring to could well just be a limitation of the 8-bit colour space.

In theory the way to solve this is to use 10- or 12-bit colour space through every stage from rendering, to editing and mastering, through to output and even in the screen or projector.  However your final output is probably going to be displayed in an 8 bits per channel space whether you like it or not.

So the practical way to do this is to render at 10- or 12-bit colour and dither down to 8-bit from the master.  The dithering will prevent the visual appearance of banding when displayed at 8 bits per channel.

Note that this is not a limitation of h.264 or any encoder but of the colour space used and the noise-free nature of the rendered animation; if real life was this noise-free it would also show this banding in 8-bit colour spaces.  There is unlikely to be any setting you could choose in your encoder in order to solve this.  To confirm, render to an uncompressed format and you will probably still see the banding.

Note: dithering from a 10- or 12-bit render is not the same as just adding some noise to an existing 8-bit dither - while this may disguise the banding a little bit simply by making it less distinct it doesn't solve it.  But you could do it in a pinch.