Search code examples
videoffmpegvideo-processingflowplayerhls.js

Why is ffmpeg output video contrast / brightness too bright?


I have a .mov file which I run through ffmpeg to create HLS segments / chunks. However, when I playback the HLS video it is too bright.

For a sanity check, I ran the same .mov video file through the FlowPlayer processing pipeline and the results were the same, the output video is too bright!

I have a number of videos. Most do not have this problem but some (and only some) of the .mov files exhibit this issue.

A broken video stream reports (see below for full output):

Stream #0:0[0x1](und): Video: hevc (Main 10) (hvc1 / 0x31637668), yuv420p10le(tv, bt2020nc/bt2020/arib-std-b67), 1920x1080, 8507 kb/s, 29.98 fps, 29.97 tbr, 600 tbn (default)

A working video stream reports (see below for full output):

Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 3840x2160, 45457 kb/s, 29.99 fps, 29.97 tbr, 600 tbn (default)

Is this something to do with hevc v h264 (whatever they mean)?

Incidentally, I am using the native HTML5 video player in conjunction with hls.js to playback the videos.

How do I fix this?

Here is my ffmpeg command:

ffmpeg -i "rgb.mov" \
  -v warning -preset ultrafast -g 59.96 -sc_threshold 0 \
  -map 0:0 -map 0:0 \
  -s:v:0 1920x1080 -c:v:0 libx264 -b:v:0 4521k \
  -s:v:1 1920x1080 -c:v:1 libx264 -b:v:1 7347k \
  -var_stream_map "v:0 v:1" \
  -master_pl_name master.m3u8 -f hls \
  -hls_time 6 -hls_list_size 0 -hls_playlist_type vod \
  -hls_segment_filename "hls/v%v/chunk%d.ts" "hls/v%v/index.m3u8"

And here are some screenshots showing the original video in comparison to the output video.

ORIGINAL:

enter image description here

OUTPUT:

enter image description here

For the problem video ffmpeg -i "rgb.mov" -hide_banner gives:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'rgb.mov':
  Metadata:
    major_brand     : qt
    minor_version   : 0
    compatible_brands: qt
    creation_time   : 2021-08-03T11:23:40.000000Z
    com.apple.quicktime.location.accuracy.horizontal: 3.594173
    com.apple.quicktime.location.ISO6709: +51.5483+000.1628+000.459/
    com.apple.quicktime.make: Apple
    com.apple.quicktime.model: iPhone 12 Pro
    com.apple.quicktime.software: 14.7.1
    com.apple.quicktime.creationdate: 2021-08-03T12:23:40+0100
  Duration: 00:00:54.54, start: 0.000000, bitrate: 8730 kb/s
  Stream #0:0[0x1](und): Video: hevc (Main 10) (hvc1 / 0x31637668), yuv420p10le(tv, bt2020nc/bt2020/arib-std-b67), 1920x1080, 8507 kb/s, 29.98 fps, 29.97 tbr, 600 tbn (default)
    Metadata:
      creation_time   : 2021-08-03T11:23:40.000000Z
      handler_name    : Core Media Video
      vendor_id       : [0][0][0][0]
      encoder         : HEVC
    Side data:
      DOVI configuration record: version: 1.0, profile: 8, level: 4, rpu flag: 1, el flag: 0, bl flag: 1, compatibility id: 4
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 172 kb/s (default)
    Metadata:
      creation_time   : 2021-08-03T11:23:40.000000Z
      handler_name    : Core Media Audio
      vendor_id       : [0][0][0][0]
  Stream #0:2[0x3](und): Data: none (mebx / 0x7862656D), 0 kb/s (default)
    Metadata:
      creation_time   : 2021-08-03T11:23:40.000000Z
      handler_name    : Core Media Metadata
  Stream #0:3[0x4](und): Data: none (mebx / 0x7862656D), 0 kb/s (default)
    Metadata:
      creation_time   : 2021-08-03T11:23:40.000000Z
      handler_name    : Core Media Metadata
  Stream #0:4[0x5](und): Data: none (mebx / 0x7862656D), 34 kb/s (default)
    Metadata:
      creation_time   : 2021-08-03T11:23:40.000000Z
      handler_name    : Core Media Metadata
At least one output file must be specified

For a working video ffmpeg -i "rgb.mov" -hide_banner gives:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'rgb.mov':
  Metadata:
    major_brand     : qt
    minor_version   : 0
    compatible_brands: qt
    creation_time   : 2021-12-01T10:53:47.000000Z
    com.apple.quicktime.location.accuracy.horizontal: 4.785777
    com.apple.quicktime.location.ISO6709: +51.5485+000.1627+012.533/
    com.apple.quicktime.make: Apple
    com.apple.quicktime.model: iPhone 12 Pro
    com.apple.quicktime.software: 14.8.1
    com.apple.quicktime.creationdate: 2021-12-01T10:53:47+0000
  Duration: 00:00:36.35, start: 0.000000, bitrate: 45692 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 3840x2160, 45457 kb/s, 29.99 fps, 29.97 tbr, 600 tbn (default)
    Metadata:
      creation_time   : 2021-12-01T10:53:47.000000Z
      handler_name    : Core Media Video
      vendor_id       : [0][0][0][0]
      encoder         : H.264
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 188 kb/s (default)
    Metadata:
      creation_time   : 2021-12-01T10:53:47.000000Z
      handler_name    : Core Media Audio
      vendor_id       : [0][0][0][0]
  Stream #0:2[0x3](und): Data: none (mebx / 0x7862656D), 0 kb/s (default)
    Metadata:
      creation_time   : 2021-12-01T10:53:47.000000Z
      handler_name    : Core Media Metadata
  Stream #0:3[0x4](und): Data: none (mebx / 0x7862656D), 0 kb/s (default)
    Metadata:
      creation_time   : 2021-12-01T10:53:47.000000Z
      handler_name    : Core Media Metadata
  Stream #0:4[0x5](und): Data: none (mebx / 0x7862656D), 34 kb/s (default)
    Metadata:
      creation_time   : 2021-12-01T10:53:47.000000Z
      handler_name    : Core Media Metadata
At least one output file must be specified

Solution

  • caniuse.com explains that:

    The High Efficiency Video Coding (HEVC) compression standard is a video compression format intended to succeed H.264

    and further reveals that browser support for HEVC is currently very poor.

    @Gyan comments that:

    Your source video is HDR. You'll have to tonemap it to SDR.

    Now I assume @Gyan knows it HDR based on the fact that its using HEVC. This article explains HDR (High Dynamic Range) and talks in detail how it impacts brightness, color and contrast.

    Finally, this article explains that HDR looks bad - e.g. brightness, contrast and color issues - on devices that do not support HDR. Thankfully it also gives an ffmpeg fix by using this filter:

    -vf zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p
    

    Adding this flag to my existing ffmpeg command did the HDR to SDR (Standard Dynamic Range) conversion / tonemap, making it work on Chrome and fixing my problem.

    NOTE: Detecting HDR is an issue in its own right so I won't cover that here but please refer to this link