<p>For compression purposes, I am re‐encoding a grayscale video to the H.265/HEVC codec. Although the input video is more or less perfectly grayscale in aspect, it is provided in the <code>yuv420p</code> pixel format. So I thought that mapping the video to the <code>gray</code> pixel format would reduce file size further. I was expecting this, not only because <code>gray</code> uses 8 bits per pixel while <code>yuv420p</code> uses 12 (according to <code>ffmpeg -pix_fmts</code>), but also because stripping noisy data (irrelevant color information) would help compression.</p>

<p>To my surprise, the opposite happened: the output video in <code>gray</code> is about 14 % larger than the output video in <code>yuv420p</code>!</p>

<hr>

<p>As an example, I measured the byte size with a 60‐second footage, which I encoded as follows :</p>

<pre><code>ffmpeg -i in.h264 \
    -filter:V 'crop=960:720:160:0, format=gray, format=yuv420p' \
    -c:V libx265 -crf 26 -preset medium \
  out-gray-yuv.h265
</code></pre>

<p>I tried several filter chains (I was also cropping the video):</p>

<ul>
<li>nothing (output file <code>out.h265</code>),</li>
<li>turning the video to <code>gray</code> (output file <code>out-gray.h265</code>)</li>
<li>turning the video to <code>gray</code>, then back to <code>yuv420p</code> (output file <code>out-gray-yuv.h265</code>) — as hinted at by <a href="https://video.stackexchange.com/a/21642">that answer</a>.</li>
</ul>

<p>(I also tried the hue filter, like this: <code>hue=s=0</code>, but it is apparently subsumed by converting the video to <code>gray</code>. Also, using the <code>-pix_fmt</code> option appears to be equivalent to appending a format filter)</p>

<pre><code>BYTES      NAME                FFPROBE
14972779   in.h264             h264 (Main), yuv420p(tv, progressive), 1280x720 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 1200k tbn, 50 tbc
 3043717   out-gray.h265       hevc (Rext), gray(tv),                 960x720 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 1200k tbn, 25 tbc
 2670564   out.h265            hevc (Main), yuv420p(tv),              960x720 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 1200k tbn, 25 tbc
 2662991   out-gray-yuv.h265   hevc (Main), yuv420p(tv),              960x720 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 1200k tbn, 25 tbc
</code></pre>

<p>It appears that <code>out-gray-yuv</code> is very slightly smaller than <code>out</code>, which is not surprising (it could come from the input video not being perfectly grayscale yet). However, it is also about 14 % smaller than <code>out-gray</code>, which I cannot explain.</p>

<hr>

<p>Why do I observe these results? What should I do to benefit from grayscale compression with H.265?</p>

CC BY-SA 4.0
2020-05-30T10:27:35.263Z
Imna hazard a guess and say out-gray.h265 doesn’t use chroma sub sampling, and isn’t just the y’ component, maybe? Maybe it’s 411? I don’t understand why out-gray-Yuv would be 420, either; it shouldn’t have a chrominance component — it should just be black and white.
Jason Conrad
CC BY-SA 4.0
2021-02-09T22:41:04.150Z
encoding videos can be quirky. A different combination of preset and crf values might give you totally different results!

Also I imagine that the libx265 encoder was primarily optimized for yuv420/yuv420p10/color  formats. You might just be running into some slightly substandard behavior.

One thing you can try is keep the yuv420p format, but explicitly remove the chroma components with `lutrgb="g=0:b=0"` and see what happens.
Chris
CC BY-SA 4.0
2022-06-05T01:05:20.837Z
I consistently observe this. @JasonConrad the `gray` pixel format doesn’t even have a chroma to sub-sample. It’s really just the Y component (or Y', I don’t know exactly) at 8 bits per pixel. Whereas the `yuv420p` is 12 bits per pixel (Y at 8b/px, U at 8b/4px, V at 8b/4px). This is documented by `ffmpeg -pix_fmts`. As far as I understand, the encoding of `out-gray-yuv` is just the same as that of `out-gray` with four additional null bits per pixel. So I guess it’s just that H.265 compression algorithms/settings have not been optimized for 8bit-pixels. ¯\\_(ツ)_/¯
Maëlan
CC BY-SA 4.0
2022-06-05T01:08:13.260Z
@Chris The video filter `lutrgb=g=0:b=0` imposes RGB instead of YUV, and removes the green and blue components, leaving the picture in redscale. I guess you rather meant `lutyuv=u=128:v=128` (hinted by `man ffmpeg-filters`), which cancels the chroma components (while keeping these null components in the output). I just tested it, it is exactly the same (bit-equal) as the filter chain `format=gray, format=yuv420p` which I was using in the question.
Maëlan
CC BY-SA 4.0
2022-06-06T00:28:26.283Z
Right you are! I've learned a bit more about color in the year since I replied. Sometimes I wonder if ffmpeg's automatic format conversion filter insertion does too much.   It makes things much easier to get working most of the time, but in this case it automatically inserts a format conversion filter to rgb24 before `lutrgb=g=0:b=0`. If I was forced to be explicit about fmt conversions I probably would have re-thought what I was doing. Just some musings. Anyway, thanks for correcting me!
Chris
<ffmpeg><compression><colorspace><h265>
Why has grayscale a higher bitrate than YUV with H.265/HEVC?
Maëlan
# Why has grayscale a higher bitrate than YUV with H.265/HEVC?

(Asked by: username_0 on 2020-05-27)

For compression purposes, I am re‐encoding a grayscale video to the H.265/HEVC codec. Although the input video is more or less perfectly grayscale in aspect, it is provided in the yuv420p pixel format. So I thought that mapping the video to the gray pixel format would reduce file size further. I was expecting this, not only because gray uses 8 bits per pixel while yuv420p uses 12 (according to ffmpeg -pix_fmts), but also because stripping noisy data (irrelevant color information) would help compression.
To my surprise, the opposite happened: the output video in gray is about 14 % larger than the output video in yuv420p!

As an example, I measured the byte size with a 60‐second footage, which I encoded as follows :
ffmpeg -i in.h264 \
    -filter:V 'crop=960:720:160:0, format=gray, format=yuv420p' \
    -c:V libx265 -crf 26 -preset medium \
  out-gray-yuv.h265

I tried several filter chains (I was also cropping the video):

nothing (output file out.h265),
turning the video to gray (output file out-gray.h265)
turning the video to gray, then back to yuv420p (output file out-gray-yuv.h265) — as hinted at by that answer.

(I also tried the hue filter, like this: hue=s=0, but it is apparently subsumed by converting the video to gray. Also, using the -pix_fmt option appears to be equivalent to appending a format filter)
BYTES      NAME                FFPROBE
14972779   in.h264             h264 (Main), yuv420p(tv, progressive), 1280x720 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 1200k tbn, 50 tbc
 3043717   out-gray.h265       hevc (Rext), gray(tv),                 960x720 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 1200k tbn, 25 tbc
 2670564   out.h265            hevc (Main), yuv420p(tv),              960x720 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 1200k tbn, 25 tbc
 2662991   out-gray-yuv.h265   hevc (Main), yuv420p(tv),              960x720 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 1200k tbn, 25 tbc

It appears that out-gray-yuv is very slightly smaller than out, which is not surprising (it could come from the input video not being perfectly grayscale yet). However, it is also about 14 % smaller than out-gray, which I cannot explain.

Why do I observe these results? What should I do to benefit from grayscale compression with H.265?

**Tags:** ffmpeg, compression, colorspace, h265

> **Comments:**
> **username_1**: Imna hazard a guess and say out-gray.h265 doesn’t use chroma sub sampling, and isn’t just the y’ component, maybe? Maybe it’s 411? I don’t understand why out-gray-Yuv would be 420, either; it shouldn’t have a chrominance component — it should just be black and white.  
> **username_2**: encoding videos can be quirky. A different combination of preset and crf values might give you totally different results!  Also I imagine that the libx265 encoder was primarily optimized for yuv420/yuv420p10/color  formats. You might just be running into some slightly substandard behavior.  One thing you can try is keep the yuv420p format, but explicitly remove the chroma components with `lutrgb="g=0:b=0"` and see what happens.  
> **username_0**: I consistently observe this. @JasonConrad the `gray` pixel format doesn’t even have a chroma to sub-sample. It’s really just the Y component (or Y', I don’t know exactly) at 8 bits per pixel. Whereas the `yuv420p` is 12 bits per pixel (Y at 8b/px, U at 8b/4px, V at 8b/4px). This is documented by `ffmpeg -pix_fmts`. As far as I understand, the encoding of `out-gray-yuv` is just the same as that of `out-gray` with four additional null bits per pixel. So I guess it’s just that H.265 compression algorithms/settings have not been optimized for 8bit-pixels. ¯\\_(ツ)_/¯  
> **username_0**: @username_2 The video filter `lutrgb=g=0:b=0` imposes RGB instead of YUV, and removes the green and blue components, leaving the picture in redscale. I guess you rather meant `lutyuv=u=128:v=128` (hinted by `man ffmpeg-filters`), which cancels the chroma components (while keeping these null components in the output). I just tested it, it is exactly the same (bit-equal) as the filter chain `format=gray, format=yuv420p` which I was using in the question.  
> **username_2**: Right you are! I've learned a bit more about color in the year since I replied. Sometimes I wonder if ffmpeg's automatic format conversion filter insertion does too much.   It makes things much easier to get working most of the time, but in this case it automatically inserts a format conversion filter to rgb24 before `lutrgb=g=0:b=0`. If I was forced to be explicit about fmt conversions I probably would have re-thought what I was doing. Just some musings. Anyway, thanks for correcting me!  

---

## 0 answers

