View Full Version : Preserving HDR metadata when transcoding
agentusa
26th January 2018, 17:02
With a UHD HDR 4K blu-ray source that's been converted into an mkv, is it possible to transcode with ffmpeg and x265 and retain the HDR metadata? I'm using a compiled version of ffmpeg with the 10 bit version of libx265. With the following command, the output looks very flat.
ffmpeg -i input.mkv -c:v libx265 -preset medium -x265-params crf=21 output.mkv
I've also tried adding various x265 parameters but it either has no effect on the output or it seems to transcode it to SDR. Thanks.
microchip8
26th January 2018, 17:20
use something like
-x265-params crf=21:master-display="...":max-cll=val1,val2
fill in the "..." and val1,val2
FastLaneJB
26th January 2018, 18:08
I've been having problems with this as well. It seems like most of the metadata is carried over to the container yet when trying to play the encoded file on my LG HDR TV it doesn't switch to HDR, the source sample file does and plays fine.
I've need trying all sorts of different combinations but not having much luck. Any ideas what I might be doing wrong?
ffmpeg version
ffmpeg version 3.4.1-1~16.04.york0 Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.5) 20160609
configuration: --prefix=/usr --extra-version='1~16.04.york0' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
ffmpeg command
ffmpeg -i "Sample_HDR.mp4" -pix_fmt yuv420p10le -vf scale=out_color_matrix=bt2020:out_h_chr_pos=0:out_v_chr_pos=0,format=yuv420p10 -c:v libx265 -preset medium -x265-params :colorprim=bt2020:transfer=smpte-st-2048:colormatrix=bt2020nc:master-display="G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(12000000,200)":max-cll=0,0:repeat-headers -c:a copy -max_muxing_queue_size 4096 "Sample_HDR-encode.mkv"
Source - MediaInfo
Video
ID : 1
Format : HEVC
Format/Info : High Efficiency Video Coding
Format profile : Main 10@L5.1@High
Codec ID : hev1
Codec ID/Info : High Efficiency Video Coding
Duration : 54 s 375 ms
Bit rate : 44.8 Mb/s
Width : 3 840 pixels
Height : 2 160 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 24.000 FPS
Original frame rate : 23.976 (24000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:0 (Type 2)
Bit depth : 10 bits
Bits/(Pixel*Frame) : 0.225
Stream size : 290 MiB (99%)
Writing library : ATEME Titan KFE 3.7.0 (4.7.0.2002)
Encoded date : UTC 1904-01-01 00:00:00
Tagged date : UTC 1904-01-01 00:00:00
Color range : Limited
Color primaries : BT.2020
Transfer characteristics : SMPTE ST 2084
Matrix coefficients : BT.2020 non-constant
Mastering display color primaries : R: x=0.680000 y=0.320000, G: x=0.265000 y=0.690000, B: x=0.150000 y=0.060000, White point: x=0.312700 y=0.329000
Mastering display luminance : min: 0.0200 cd/m2, max: 1200.0000 cd/m2
Destination - ffmpeg encode
Video
ID : 1
Format : HEVC
Format/Info : High Efficiency Video Coding
Format profile : Main 10@L5@Main
Codec ID : V_MPEGH/ISO/HEVC
Duration : 54 s 375 ms
Bit rate : 64.1 Mb/s
Width : 3 840 pixels
Height : 2 160 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 24.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 10 bits
Bits/(Pixel*Frame) : 0.322
Stream size : 416 MiB (98%)
Writing library : x265 2.6:[Linux][GCC 5.4.0][64 bit] 10bit
Encoding settings : cpuid=1173503 / frame-threads=4 / wpp / no-pmode / no-pme / no-psnr / no-ssim / log-level=2 / input-csp=1 / input-res=3840x2160 / interlace=0 / total-frames=0 / level-idc=0 / high-tier=1 / uhd-bd=0 / ref=3 / no-allow-non-conformance / repeat-headers / annexb / no-aud / no-hrd / info / hash=0 / no-temporal-layers / open-gop / min-keyint=24 / keyint=250 / bframes=4 / b-adapt=2 / b-pyramid / bframe-bias=0 / rc-lookahead=20 / lookahead-slices=8 / scenecut=40 / no-intra-refresh / ctu=64 / min-cu-size=8 / no-rect / no-amp / max-tu-size=32 / tu-inter-depth=1 / tu-intra-depth=1 / limit-tu=0 / rdoq-level=0 / dynamic-rd=0.00 / no-ssim-rd / signhide / no-tskip / nr-intra=0 / nr-inter=0 / no-constrained-intra / strong-intra-smoothing / max-merge=2 / limit-refs=3 / no-limit-modes / me=1 / subme=2 / merange=57 / temporal-mvp / weightp / no-weightb / no-analyze-src-pics / deblock=0:0 / sao / no-sao-non-deblock / rd=3 / no-early-skip / rskip / no-fast-intra / no-tskip-fast / no-cu-lossless / no-b-intra / no-splitrd-skip / rdpenalty=0 / psy-rd=2.00 / psy-rdoq=0.00 / no-rd-refine / analysis-reuse-mode=0 / no-lossless / cbqpoffs=0 / crqpoffs=0 / rc=crf / crf=12.0 / qcomp=0.60 / qpstep=4 / stats-write=0 / stats-read=0 / ipratio=1.40 / pbratio=1.30 / aq-mode=1 / aq-strength=1.00 / cutree / zone-count=0 / no-strict-cbr / qg-size=32 / no-rc-grain / qpmax=69 / qpmin=0 / no-const-vbv / sar=1 / overscan=0 / videoformat=5 / range=0 / colorprim=9 / transfer=0 / colormatrix=9 / chromaloc=0 / display-window=0 / master-display=G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1) / max-cll=1000,400 / min-luma=0 / max-luma=1023 / log2-max-poc-lsb=8 / vui-timing-info / vui-hrd-info / slices=1 / no-opt-qp-pps / no-opt-ref-list-length-pps / no-multi-pass-opt-rps / scenecut-bias=0.05 / no-opt-cu-delta-qp / no-aq-motion / hdr / no-hdr-opt / no-dhdr10-opt / analysis-reuse-level=5 / scale-factor=0 / refine-intra=0 / refine-inter=0 / refine-mv=0 / no-limit-sao / ctu-info=0 / no-lowpass-dct / refine-mv-type=0 / copy-pic=1
Default : Yes
Forced : No
Color range : Limited
Color primaries : BT.2020
Matrix coefficients : BT.2020 non-constant
DURATION : 00:00:54.375000000
HANDLER_NAME : VideoHandler
Mastering display color primaries : R: x=0.680000 y=0.320000, G: x=0.265000 y=0.690000, B: x=0.150000 y=0.060000, White point: x=0.312700 y=0.329000
Mastering display luminance : min: 0.0001 cd/m2, max: 1000.0000 cd/m2
Maximum Content Light Level : 1000 cd/m2
Maximum Frame-Average Light Level : 400 cd/m2
Thanks :)
sneaker_ger
26th January 2018, 21:26
Is the log showing any errors? I don't see the transfer in the resulting file. I know the naming changed some revisions back. If you want to be safe you can try the integers:
colorprim=9:transfer=16:colormatrix=9
The mkv container also has such flags which you may want to add (using mkvmerge, mkvpropedit or MkvToolNix GUI's Header Editor). (I don't remember if/how ffmpeg does it.)
kabelbrand
27th January 2018, 09:29
I've been having problems with this as well. It seems like most of the metadata is carried over to the container yet when trying to play the encoded file on my LG HDR TV it doesn't switch to HDR, the source sample file does and plays fine.
Theres is a slight mistake in the transfer option. It should be 2084 instead of 2048. Or use the numbers as sneaker_ger suggested.
FastLaneJB
28th January 2018, 00:30
Theres is a slight mistake in the transfer option. It should be 2084 instead of 2048. Or use the numbers as sneaker_ger suggested.
Thanks, well spotted and I'd missed that. I tried changing it but it still didn't work however using the numbers worked a treat.
So thanks you both for your help on this.
agentusa
28th January 2018, 05:29
Adding colorprim=9:transfer=16:colormatrix=9 into the mkv container header with the MKVToolNix GUI Header Editor worked for me. Thank you!
Edit - Here's the mkvpropedit command:
mkvpropedit --edit track:1 -s colour-primaries=9 -s colour-transfer-characteristics=16 -s colour-matrix-coefficients=9 output.mkv
kabelbrand
30th January 2018, 14:44
Writing library : x265 2.6:[Linux][GCC 5.4.0][64 bit] 10bit
Btw. in version 2.6 the values of the transfer parameter have been adjusted to match the ones in ffmpeg: "smpte-st-2084" is now "smpte2084"
Krautmaster
2nd July 2018, 16:22
how can i preserve the metadata for the display mastering?
Video
ID : 1
Format : HEVC
Format/Info : High Efficiency Video Coding
Format_Commercial_IfAny : HDR10
Format-Profil : Main 10@L5.1@High
Codec-ID : V_MPEGH/ISO/HEVC
Dauer : 1 h 52 min
Bitrate : 48,3 Mb/s
Breite : 3 840 Pixel
Höhe : 2 160 Pixel
Bildseitenverhältnis : 16:9
Modus der Bildwiederholungsrate : konstant
Bildwiederholungsrate : 23,976 (24000/1001) FPS
ColorSpace : YUV
ChromaSubsampling/String : 4:2:0 (Type 2)
BitDepth/String : 10 bits
Bits/(Pixel*Frame) : 0.243
Stream-Größe : 38,0 GiB (82%)
Default : Ja
Forced : Nein
colour_range : Limited
colour_primaries : BT.2020
transfer_characteristics : PQ
matrix_coefficients : BT.2020 non-constant
MasteringDisplay_ColorPrimaries : Display P3
MasteringDisplay_Luminance : min: 0.0050 cd/m2, max: 4000 cd/m2
MaxCLL : 4491 cd/m2
MaxFALL : 315 cd/m2
Im recompiling from eg 70GB/file down to somewhere around 20GB and want to keep all HDR information like in original. My current commandline is:
ffmpeg -y -i "in.mkv" -analyzeduration 100M -probesize 100M -max_muxing_queue_size 9999 -map 0:v -map 0:a -map 0:s? -c:s copy -c:a copy -pix_fmt yuv420p10le -vf scale=out_color_matrix=bt2020:out_h_chr_pos=0:out_v_chr_pos=0,format=yuv420p10 -c:v libx265 -preset medium -x265-params "high-tier=1:level-idc=5.1:open-gop=1:crf=22:crf-min=5:crf-max=40:aq-mode=1:colorprim=bt2020:colormatrix=bt2020nc:transfer=smpte2084:colormatrix=bt2020nc:hdr=1:hdr=1:info=1:repeat-headers=1:max-cll=0,0:master-display=G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(12000000,200)" "out.mkv"
which sets the maxCll and MaxFALL to
MasteringDisplay_ColorPrimaries : Display P3
MasteringDisplay_Luminance : min: 0.0200 cd/m2, max: 1200 cd/m2
but as said, I want to have a universal line keeping the input metadata.
Edit: FFMPEG Version:
ffmpeg.exe -version
ffmpeg version N-91399-g9f0077cc03-ffmpeg-windows-build-helpers Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 7.1.0 (GCC)
configuration: --arch=x86_64 --target-os=mingw32 --cross-prefix=/home/buildserver/build/ffmpeg-windows-build-helpers/sandbox/cross_compilers/mingw-w64-x86_64/bin/x86_64-w64-mingw32- --pkg-config=pkg-config --pkg-config-flags=--static --extra-version=ffmpeg-windows-build-helpers --enable-gray --enable-version3 --disable-debug --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-w32threads --enable-libtesseract --enable-fontconfig --enable-gmp --enable-gnutls --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libflite --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libzimg --enable-libzvbi --enable-nvenc --enable-nvdec --enable-libaom --extra-cflags=-DLIBTWOLAME_STATIC --extra-cflags=-DMODPLUG_STATIC --extra-cflags=-DCACA_STATIC --enable-gpl --enable-avisynth --enable-frei0r --enable-filter=frei0r --enable-librubberband --enable-libvidstab --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libmfx --enable-avresample --extra-cflags='-mtune=generic' --extra-cflags=-O3 --enable-static --disable-shared --prefix=/home/buildserver/build/ffmpeg-windows-build-helpers/sandbox/cross_compilers/mingw-w64-x86_64/x86_64-w64-mingw32 --enable-nonfree --enable-decklink --enable-libfdk-aac
libavutil 56. 18.102 / 56. 18.102
libavcodec 58. 20.104 / 58. 20.104
libavformat 58. 17.101 / 58. 17.101
libavdevice 58. 4.101 / 58. 4.101
libavfilter 7. 25.100 / 7. 25.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 2.100 / 5. 2.100
libswresample 3. 2.100 / 3. 2.100
libpostproc 55. 2.100 / 55. 2.100
x265 [info]: HEVC encoder version 2.8+11-df5bd3be9b11
x265 [info]: build info [Windows][GCC 7.1.0][64 bit] 10bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast LZCNT SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
x265 [warning]: Specifying a decoder level with constant rate factor rate-control requires
x265 [warning]: enabling VBV with vbv-bufsize=160000kb vbv-maxrate=160000kbps. VBV outputs are non-deterministic!
x265 [info]: Main 10 profile, Level-5.1 (High tier)
x265 [info]: Thread pool created using 36 threads
x265 [info]: Slices : 1
x265 [info]: frame threads / pool features : 6 / wpp(34 rows)
x265 [info]: Coding QT: max CU size, min CU size : 64 / 8
x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra
x265 [info]: ME / range / subpel / merge : hex / 57 / 2 / 2
x265 [info]: Keyframe min / max / scenecut / bias: 23 / 250 / 40 / 5.00
x265 [info]: Lookahead / bframes / badapt : 20 / 4 / 2
x265 [info]: b-pyramid / weightp / weightb : 1 / 1 / 0
x265 [info]: References / ref-limit cu / depth : 3 / on / on
x265 [info]: AQ: mode / str / qg-size / cu-tree : 1 / 1.0 / 32 / 1
x265 [info]: Rate Control / qCompress : CRF-22.0 / 0.60
x265 [info]: VBV/HRD buffer / max-rate / init : 160000 / 160000 / 0.900
x265 [info]: tools: rd=3 psy-rd=2.00 rskip signhide tmvp strong-intra-smoothing
x265 [info]: tools: lslices=8 deblock sao
Output #0, matroska, to 'out.mkv':
sneaker_ger
2nd July 2018, 16:40
MasteringDisplay_ColorPrimaries : Display P3
MasteringDisplay_Luminance : min: 0.0050 cd/m2, max: 4000 cd/m2
master-display G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(40000000,50)
http://x265.readthedocs.io/en/default/cli.html#cmdoption-master-display
MaxCLL : 4491 cd/m2
MaxFALL : 315 cd/m2
max-cll 4491,315
http://x265.readthedocs.io/en/default/cli.html#cmdoption-max-cll
You can read about the factors needed in the documentation I linked. Not exactly rocket science.
Krautmaster
2nd July 2018, 16:52
thx a lot ...
but can I grab / copy this data from the input video without adding them to my command line? I already found out that i can set maxCLL / FALL that way but it seems like that eg the option -repeat-header in x265 seems not to copy the mastering display data to the output file.
Edit. I might need to parse though ffprobe to get these values and to dynamically add them to my commandline if i cant copy it by a command.
Any ideas how to optimize my commandline or is it fine anyway?
sneaker_ger
2nd July 2018, 17:34
but can I grab / copy this data from the input video without adding them to my command line?
I don't think ffmpeg has a way to do that automatically (yet). So you'd need to write your own program/parser/script..
it seems like that eg the option -repeat-header in x265 seems not to copy the mastering display data to the output file.
Correct. --repeat-headers has nothing to do with the input file.
Krautmaster
3rd July 2018, 15:53
okay thanks for your support. Sry to bother u again, any ideas on my command line so far? - is it near to brilliant? ;)
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.