[FFmpeg-user] VP9 to HEVC hdr demo conversion?

Andy Furniss adf.lists at gmail.com
Tue Dec 13 17:14:21 EET 2016


Andy Furniss wrote:
> traycold wrote:
>> hi,
>> I tried the same (convert a vp9.2 hdr video to hevc to watch it on a
>> samsung
>> smart tv).
>> So far, I tried this command (input.mkv contains both VP9.2 video
>> stream and
>> audio stream):
>>
>> ffmpeg -i input.mkv -vf
>> scale=out_color_matrix=bt2020:out_h_chr_pos=0:out_v_chr_pos=0,format=yuv420p10
>>
>> -pix_fmt yuv420p10le -c:v libx265 -x265-params
>> "colorprim=bt2020:transfer=smpte-st-2084:colormatrix=bt2020nc" -crf 22
>> -c:a
>> copy output.mkv
>>
>> It works in the sense that the video is visible on smart TV. Looking with
>> mediainfo it seems ok to me, but the video is notably darker and color
>> different than original (for instance: orange becomes almost a dark red).
>>
>> So probably there is something wrong. Honestly I just put that command
>> together looking at various forums, threads, tutorials I found on the
>> web,
>> as I'm a totally noob with encoding and ffmpeg.
>>
>> Hope this may help, anyway. And someone can provide a better way to
>> convert.
>
> I am not sure if it's currently possible or not - I don't have a TV to
> test.
>
> Looking with ffprobe at HDR hevc from the web you will see extradata in
> the stream.
>
> I don't know how to write that with ffmpeg.

Some progress now git head ffmpeg outputs mastering info from youtube webm.

I don't know how to get it into an output mkv - but in the case of hevc
it may not matter as long as it's in the hevc headers.

Turns out max-cll and max-fall are separate from st2086 metadata and
they don't seem to be in the youtube mkv (in fact I couldn't see that
they would be read - so tried adding code, but they came out 0 anyway).

The hevc online help shows how to make a mastering string and their
example is close to the data in the yt mkv so an easy paste just
changing min luma x10.

Below seems to make a stream that has mastering side data in the hevc
that mpv will read OK - so maybe try something like below, just a test
of course and you would need to tweak the mastering to match input as
shown by ffmpeg for each file (so finding a way to get ffmpeg to do it
for you will be far better).

Don't know if the cll/fall should be explicitly set to 0 or just omitted.

libx265 documentation on mastering and cll pasted below test console output.

Though ffmpeg -i output.mkv doesn't show mastering, ffprobe -show_frames 
does.

andy [377]$ ffm -i The\ World\ in\ HDR-tO01J-M3g0U.webm -c:v libx265 
-x265-params 
"colorprim=bt2020:transfer=smpte-st-2084:colormatrix=bt2020nc:master-display=G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,10):max-cll=0,0" 
-vframes 100 output.mkv
ffmpeg version N-82844-g265d451 Copyright (c) 2000-2016 the FFmpeg 
developers
   built with gcc 5.3.0 (GCC)
   configuration: --prefix=/usr --disable-doc --enable-gpl --enable-omx 
--enable-opencl --enable-libvpx --enable-libx265 --enable-libmp3lame 
--enable-libx264 --enable-gnutls
   libavutil      55. 43.100 / 55. 43.100
   libavcodec     57. 67.100 / 57. 67.100
   libavformat    57. 59.100 / 57. 59.100
   libavdevice    57.  2.100 / 57.  2.100
   libavfilter     6. 68.100 /  6. 68.100
   libswscale      4.  3.101 /  4.  3.101
   libswresample   2.  4.100 /  2.  4.100
   libpostproc    54.  2.100 / 54.  2.100
ADF max_cll = 0
ADF max_fall = 0
Input #0, matroska,webm, from 'The World in HDR-tO01J-M3g0U.webm':
   Metadata:
     encoder         : google
   Duration: 00:02:34.54, start: 0.000000, bitrate: 18208 kb/s
     Stream #0:0(eng): Video: vp9 (Profile 2), yuv420p10le(tv, 
bt2020nc/bt2020/smpte2084), 3840x2160, SAR 1:1 DAR 16:9, 59.94 fps, 
59.94 tbr, 1k tbn, 1k tbc (default)
     Side data:
       Mastering Display Metadata, has_primaries:1 has_luminance:1 
r(0.6800,0.3200) g(0.2649,0.6900) b(0.1500 0.0600) wp(0.3127, 0.3290) 
min_luminance=0.001000, max_luminance=1000.000000
File 'output.mkv' already exists. Overwrite ? [y/N] y
x265 [info]: HEVC encoder version 2.1
x265 [info]: build info [Linux][GCC 5.3.0][64 bit] 10bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast LZCNT
x265 [info]: Main 10 profile, Level-5.1 (Main tier)
x265 [info]: Thread pool created using 4 threads
x265 [info]: Slices                              : 1
x265 [info]: frame threads / pool features       : 2 / 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       : 25 / 250 / 40
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-28.0 / 0.60
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 'output.mkv':
   Metadata:
     encoder         : Lavf57.59.100
     Stream #0:0(eng): Video: hevc (libx265), yuv420p10le, 3840x2160 
[SAR 1:1 DAR 16:9], q=2-31, 59.94 fps, 1k tbn, 59.94 tbc (default)
     Metadata:
       encoder         : Lavc57.67.100 libx265
Stream mapping:
   Stream #0:0 -> #0:0 (vp9 (native) -> hevc (libx265))
Press [q] to stop, [?] for help
frame=  100 fps=1.0 q=-0.0 Lsize=     388kB time=00:00:01.61 
bitrate=1965.3kbits/s speed=0.0156x
video:386kB audio:0kB subtitle:0kB other streams:0kB global headers:1kB 
muxing overhead: 0.649109%
x265 [info]: frame I:      1, Avg QP:26.06  kb/s: 83339.70
x265 [info]: frame P:     24, Avg QP:30.42  kb/s: 3231.43
x265 [info]: frame B:     75, Avg QP:38.68  kb/s: 378.67
x265 [info]: Weighted P-Frames: Y:0.0% UV:0.0%
x265 [info]: consecutive B-frames: 4.0% 0.0% 0.0% 84.0% 12.0%

encoded 100 frames in 104.10s (0.96 fps), 1892.94 kb/s, Avg QP:36.57
andy [377]$
andy [377]$
andy [377]$ ffm -i output.mkv
ffmpeg version N-82844-g265d451 Copyright (c) 2000-2016 the FFmpeg 
developers
   built with gcc 5.3.0 (GCC)
   configuration: --prefix=/usr --disable-doc --enable-gpl --enable-omx 
--enable-opencl --enable-libvpx --enable-libx265 --enable-libmp3lame 
--enable-libx264 --enable-gnutls
   libavutil      55. 43.100 / 55. 43.100
   libavcodec     57. 67.100 / 57. 67.100
   libavformat    57. 59.100 / 57. 59.100
   libavdevice    57.  2.100 / 57.  2.100
   libavfilter     6. 68.100 /  6. 68.100
   libswscale      4.  3.101 /  4.  3.101
   libswresample   2.  4.100 /  2.  4.100
   libpostproc    54.  2.100 / 54.  2.100
Input #0, matroska,webm, from 'output.mkv':
   Metadata:
     ENCODER         : Lavf57.59.100
   Duration: 00:00:01.67, start: 0.000000, bitrate: 1906 kb/s
     Stream #0:0(eng): Video: hevc (Main 10), yuv420p10le(tv, 
bt2020nc/bt2020/smpte2084, progressive), 3840x2160 [SAR 1:1 DAR 16:9], 
59.94 fps, 59.94 tbr, 1k tbn, 59.94 tbc (default)
     Metadata:
       ENCODER         : Lavc57.67.100 libx265
       DURATION        : 00:00:01.669000000
At least one output file must be specified




--master-display <string>

     SMPTE ST 2086 mastering display color volume SEI info, specified as 
a string which is parsed when the stream header SEI are emitted. The 
string format is “G(%hu,%hu)B(%hu,%hu)R(%hu,%hu)WP(%hu,%hu)L(%u,%u)” 
where %hu are unsigned 16bit integers and %u are unsigned 32bit 
integers. The SEI includes X,Y display primaries for RGB channels and 
white point (WP) in units of 0.00002 and max,min luminance (L) values in 
units of 0.0001 candela per meter square. (HDR)

     Example for a P3D65 1000-nits monitor, where G(x=0.265, y=0.690), 
B(x=0.150, y=0.060), R(x=0.680, y=0.320), WP(x=0.3127, y=0.3290), 
L(max=1000, min=0.0001):

 
G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)

     Note that this string value will need to be escaped or quoted to 
protect against shell expansion on many platforms. No default.

--max-cll <string>

     Maximum content light level (MaxCLL) and maximum frame average 
light level (MaxFALL) as required by the Consumer Electronics 
Association 861.3 specification.

     Specified as a string which is parsed when the stream header SEI 
are emitted. The string format is “%hu,%hu” where %hu are unsigned 16bit 
integers. The first value is the max content light level (or 0 if no 
maximum is indicated), the second value is the maximum picture average 
light level (or 0). (HDR)

     Example for MaxCLL=1000 candela per square meter, MaxFALL=400 
candela per square meter:

         –max-cll ?1000,400?

     Note that this string value will need to be escaped or quoted to 
protect against shell expansion on many platforms. No default.





More information about the ffmpeg-user mailing list