<p>The bands you're referring to could well just be a limitation of the 8-bit colour space.</p>

<p>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.</p>

<p>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.</p>

<p>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.</p>

<p>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.</p>

CC BY-SA 3.0
2014-04-01T02:40:22.777Z
thanks, but it's probably not the limitations of the 8-bit output. Banding occurs with gradients. These are flat areas of colour, with every pixel the same value. The compression is introducing the banding as the the pixels change in time.
stib
CC BY-SA 3.0
2014-04-01T23:51:52.753Z
In that case have you played with lower CRF values?  20 may not be transparent in mostly flat areas of color with animation.  With rendered animation you should be able to get away with much lower CRF values (such as 16).  You can test with something very high quality like 10 or even lossless just as a point of troubleshooting to see if the quantization is a factor at all.
thomasrutter
CC BY-SA 3.0
2014-03-31T05:04:19.703Z
2014-03-31T05:04:19.703Z
thomasrutter
<p>The first thing I would try is to add <code>-force_key_frames</code> to your original command, drop the preset and lower the <code>-crf</code> value. The following example sets a key frame every second.</p>

<pre><code>ffmpg -i input.mov -c:v libx264 -profile main \
    -force_key_frames expr:gte(t,n_forced*1) \
    -crf 15 -pix_fmt yuv420p -an output.mp4
</code></pre>

<p>As a second resort I would use a series of png images (instead of mov) as the input and use a very low crf. This way you can really make sure that there is no banding in your input and the highest quality in the end material. If you can't directly render to png, then convert the original material.</p>

<p>Here is an example:</p>

<pre><code># turn the original into pngs
ffmpeg -i input.mov -f image2 -threads 0 /tmp/%05d.png

# turn the pngs back into mp4 (assuming 25 fps)
ffmpeg -ar 48000 -ac 2 -f s16le -i /dev/zero -r 25/1 -f image2 \
  -i /tmp/%05d.png -c:a libfdk_aac -c:v libx264 \ 
  -profile main -vf "fps=fps=25" -force_key_frames expr:gte(t,n_forced*1) \
  -crf 10 -threads 0 -pix_fmt yuv420p output.mp4
</code></pre>

<p>ps. You should get in the habit of including a silent audio track for media device playback because of syncing issues.</p>

CC BY-SA 3.0
2014-08-29T09:44:01.373Z
2014-08-29T09:44:01.373Z
denjello
<p>Depending how the content was made, the banding might be introduced when you're converting your content from RGB colorspace to YUV. You can try to make an h264 while keeping RGB colorspace, although I've read it's not easy. Are you able to use another codec?</p>

CC BY-SA 3.0
2014-04-01T19:23:46.310Z
2014-04-01T19:23:46.310Z
elburzs
<p>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.</p>

<p>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.</p>

<p>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.</p>

<p>My current ffmpeg command is pretty generic:</p>

<pre><code>ffmpg -i input.mov -c:v libx264 -preset slow -profile main -crf 20 -pix_fmt yuv420p -an output.mp4
</code></pre>

CC BY-SA 3.0
2014-03-27T17:44:30.263Z
Please include the complete `ffmpeg` console output. Can you provide a short input sample? Does reducing `-crf` to ~18 help? Does `-tune animation` make a difference? If nothing helps you can look into using the [`gradfun` video filter](http://ffmpeg.org/ffmpeg-filters.html#gradfun) upon playback.
llogan
<ffmpeg><encoding><libx264><h.264>
h264 settings for large flat areas of slowly changing colour
stib
# h264 settings for large flat areas of slowly changing colour

(Asked by: username_0 on 2014-03-27)

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

**Tags:** ffmpeg, encoding, libx264, h.264

> **Comments:**
> **username_1**: Please include the complete `ffmpeg` console output. Can you provide a short input sample? Does reducing `-crf` to ~18 help? Does `-tune animation` make a difference? If nothing helps you can look into using the [`gradfun` video filter](http://ffmpeg.org/ffmpeg-filters.html#gradfun) upon playback.  

---

## 3 answers

### Answer by username_2 on 2014-03-31. Score: 2

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.

> **Comments:**
> **username_0**: thanks, but it's probably not the limitations of the 8-bit output. Banding occurs with gradients. These are flat areas of colour, with every pixel the same value. The compression is introducing the banding as the the pixels change in time.  
> **username_2**: In that case have you played with lower CRF values?  20 may not be transparent in mostly flat areas of color with animation.  With rendered animation you should be able to get away with much lower CRF values (such as 16).  You can test with something very high quality like 10 or even lossless just as a point of troubleshooting to see if the quantization is a factor at all.  

---

### Answer by username_3 on 2014-08-29. Score: 2

The first thing I would try is to add -force_key_frames to your original command, drop the preset and lower the -crf value. The following example sets a key frame every second.
ffmpg -i input.mov -c:v libx264 -profile main \
    -force_key_frames expr:gte(t,n_forced*1) \
    -crf 15 -pix_fmt yuv420p -an output.mp4

As a second resort I would use a series of png images (instead of mov) as the input and use a very low crf. This way you can really make sure that there is no banding in your input and the highest quality in the end material. If you can't directly render to png, then convert the original material.
Here is an example:
# turn the original into pngs
ffmpeg -i input.mov -f image2 -threads 0 /tmp/%05d.png

# turn the pngs back into mp4 (assuming 25 fps)
ffmpeg -ar 48000 -ac 2 -f s16le -i /dev/zero -r 25/1 -f image2 \
  -i /tmp/%05d.png -c:a libfdk_aac -c:v libx264 \ 
  -profile main -vf "fps=fps=25" -force_key_frames expr:gte(t,n_forced*1) \
  -crf 10 -threads 0 -pix_fmt yuv420p output.mp4

ps. You should get in the habit of including a silent audio track for media device playback because of syncing issues.


---

### Answer by username_4 on 2014-04-01. Score: 2

Depending how the content was made, the banding might be introduced when you're converting your content from RGB colorspace to YUV. You can try to make an h264 while keeping RGB colorspace, although I've read it's not easy. Are you able to use another codec?


---

