Body: <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>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-05-30T10:27:35.263Z
Comments.Text: 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.
Comments.UserDisplayName: Jason Conrad
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2021-02-09T22:41:04.150Z
Comments.Text: 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.
Comments.UserDisplayName: Chris
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-06-05T01:05:20.837Z
Comments.Text: 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. ¯\\_(ツ)_/¯
Comments.UserDisplayName: Maëlan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-06-05T01:08:13.260Z
Comments.Text: @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.
Comments.UserDisplayName: Maëlan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-06-06T00:28:26.283Z
Comments.Text: 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!
Comments.UserDisplayName: Chris
Tags: <ffmpeg><compression><colorspace><h265>
Title: Why has grayscale a higher bitrate than YUV with H.265/HEVC?
UserDisplayName: Maëlan
ThreadText: # 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](https://video.stackexchange.com/a/21642).
  
  (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. @username_1 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
  
  