I need to validate if a video file (HEVC encoded) is or is not an HDR video. I know that there are many HDR standards, but I did not find a way to identify it using mediainfo or ffprobe.

The need is because I have an API that receives several video profiles (different bitrates, dimensions and codecs) for a single video, which are used to deliver to users the best match based on their devices and connection speed. So now I want to allow them to select HDR profile but to achieve this I need first to validate the ingest files.

Do you know how to handle this?

5 Answers 5


Assuming your file is ${F}, the below is an efficient means I have been able to create:

COLORS=$(ffprobe -show_streams -v error "${F}" |egrep "^color_transfer|^color_space=|^color_primaries=" |head -3)
for C in $COLORS; do
        if [[ "$C" = "color_space="* ]]; then
        elif [[ "$C" = "color_transfer="* ]]; then
        elif [[ "$C" = "color_primaries="* ]]; then
if [ "${COLORSPACE}" = "bt2020nc" ] && [ "${COLORTRANSFER}" = "smpte2084" ] && [ "${COLORPRIMARIES}" = "bt2020" ]; then 
        echo ${F}

I use this inside a looping function to know when to use https://github.com/Fmstrat/ffmkv to create an SDR version of a video on one of the presets.

  • Note, this defaults to the top video stream. I use -select_stream when I need to be specific. And you'll want to reset the variables in a loop.
    – Fmstrat
    Oct 21, 2019 at 13:48
  • So you assume that these parameters must be satisfied: ColorSpace = bt2020nc; ColorTransfer = smpte2084; ColorPrimaries = bt2020; Looks good. Thanks. Aug 18, 2020 at 21:31

I've found how to get this information from color primaries attribute. Considering color primaries BT.2020 as a HDR video.

mediainfo video.mp4 --Inform="Video;%colour_primaries%"

In this example above, if the return of the command is BT.2020 so I consider the video as HDR. Otherwise SDR.

  • 1
    Technically, that will only determine if a video is WCG. To test for HDR-ness, you also need to check that the transfer function is one of the HDR flavors. Jan 6, 2018 at 20:53
  • Nice to know @JasonConrad . So could I consider PQ and HLG as valid transfer functions for and HDR video? Apr 21, 2018 at 2:17
  • 1
    Yes. I think that the color space, transfer function, and bit depth (HDR also needs to be 10 bits per channel) are enough to minimally qualify video as HDR, but there are different flavors and specifications. Apr 22, 2018 at 7:10

Checking color_primaries is the right approach. I use ffprobe to get the JSON output. Then you can parse the JSON output instead of searching for a string in the normal output.

$ ffprobe -v error -show_streams -select_streams v:0 -of json -i test.mp4
    "streams": [
            "index": 0,
            "codec_name": "hevc",
            "codec_long_name": "H.265 / HEVC (High Efficiency Video Coding)",
            "color_transfer": "arib-std-b67",
            "color_primaries": "bt2020",
            "refs": 1,
            // …

This answer relies on but simplifies the answer by Валерий Заподовников who seems to know his stuff.

ffprobe -v quiet -show_streams -select_streams v:0 video.mp4 | grep ^color_transfer=

IF color_transfer EQUALS arib-std-b67 OR smpte2084 THEN the video is HDR

  • Thanks, this answer helped me most. Is there a way to do a grep where it just shows a result when we have arib-std-b67 OR smpte2084, and not output anything when that is NOT the case? I want to use this in a batch file for a lot of movies at once. Apr 29 at 14:19

Well, and yeah, all answers are wrong here. HDR is only the new transfer function, PQ or HLG. So that means you need to look into that, PQ is SMPTE 2084 and HLG is ARIB STD-B67.

Yes, 8 bit file tagged as PQ will be played as HDR.

Yes, 10 bit files tagged as BT.2020 transfer are SDR, because BT.2020 transfer is the same as BT.709 and BT.601. Moreover Rec. BT.2020 is SDR only spec., HDR was defined in BT.2100.

Yes, you need to color manage BT.2020 primaires to your primaries.

Yes, it is 0.0001 to 10000 nits, not 0.001 to 4000 in PQ.

Yes, BT.2390 EETF dynamical tone mapper is mandatory unless the master display is the same.

Yes, almost all movies are inside DCI-D65 inside BT.2020, only Planet Earth 2 is not and some others.

Yes, film and cameras supported HDR back in 1970s and Photo CD supported HDR and WCG.

  • thanks for this helpful answer - but what does this mean in practical terms? how should we check for HDR with ffmpeg?
    – danday74
    Jan 4 at 14:25
  • ffprobe file, look for smpte2086 or arib transfer. Jan 4 at 14:28
  • color_space=bt2020nc ... color_transfer=arib-std-b67 ... color_primaries=bt2020 ... this is what I have ... IF color_primaries === 'bt2020' && (color_transfer.startsWith('arib') || color_transfer.startsWith('smpte')) ... does this check sound correct? the other guys refer to smpte2084 not smpte2086 which is why I used startsWith
    – danday74
    Jan 4 at 14:33
  • 1
    smpte 2084, yes, a typo. No, primaries are not required. Jan 4 at 14:48
  • many thanks much appreciated
    – danday74
    Jan 4 at 14:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.