rigaya / VCEEnc

VCEによる高速エンコードの性能実験
https://rigaya34589.blog.fc2.com/blog-category-12.html
Other
219 stars 22 forks source link

HDR10 mastering data doesn't appear in output files #60

Closed ghost closed 1 year ago

ghost commented 1 year ago

When setting HDR10 mastering metadata on HEVC, it shows up in the encode options list but is all blank in the output file. In this case I encode to a raw HEVC file, mux into a temporary m2ts to feed into madmeasurehdr, then add Dolby Vision metadata generated by dovi_tool. Since the dolby vision metadata is there, the TV ignores the fact that the video file itself isn't recognized as HDR10 and just uses the Dolby information which is correct, but if I wanted to generate plain HDR10 without dynamic data I'm not sure what exactly would happen on playback. MaxCLL and MaxFALL can be set to 0 if they're unknown but the mastering display information should be important for correct colors AFAIK.

10bpc data with matching primaries, etc is piped from ffmpeg since there doesn't seem to be a way to do SDR->HDR colorspace conversions directly in vceenc and specify a peak level, but the results were the same when doing all colorspace conversion in VCEenc and outputting to a muxed container. vceencc64 --y4m -i - -c hevc --profile main10 --tier high --preset slow --cqp 18:22 --output-depth 10 --pa --ref 4 --gop-len 48 --enforce-hrd --chromaloc 2 --max-bitrate 35000 --vbv-bufsize 40000 --transfer smpte2084 --colorprim bt2020 --colormatrix bt2020nc --colorrange limited --max-cll "900,400" --master-display "G(8500,39850)B(6550,2300)R(35400,14600)WP(15635,16450)L(10000000,1)" -o ...

VUI: matrix:bt2020nc,colorprim:bt2020,transfer:smpte2084,range:limited,chromaloc:topleft MasteringDisp: G(0.170000 0.797000) B(0.131000 0.046000) R(0.708000 0.292000) WP(0.312700 0.329000) L(1000.000000 0.000100) MaxCLL/MaxFALL:900/400

Then when madmeasurehdr runs: Measuring video file ... Metadata: Mastering display luminance: 0/0, gamut: 0 0, 0 0, 0 0, 0 0 MaxCLL: 0, MaxFALL: 0 nits Measurements: Frames: 12144, MaxCLL 100%: 936, 99.9%: 852, MaxFALL: 235, AvgFALL: 134, AvgFMLL: 650 nits

Same results from mediainfo or ffprobe -show_frames...

I know most people are converting HDR to SDR and not the other way around so this might have gone unnoticed. I attempted adding --atc-sei smpte2084 which isn't really appropriate (it's not the alternative transfer characteristic, it's the only one) but that didn't change anything, as expected. x265 has an auto-inserted --repeat-headers when mastering characteristics or maxcll are specified that injects this information.

Like I said I'm only doing this as a way of shoehorning dynamic HDR into regular old 1080p SDR material so it doesn't affect me much, but it would be a bigger issue if I were attempting to use a LUT to convert S-Log3 to SMPTE2084 without the metadata.

rigaya commented 1 year ago

Thank you for reporting the issue.

I've tried fixing this issue in VCEEnc 7.01, should have the HDR mastering data coming out in the output file.

ghost commented 1 year ago

Thank you, I'll check the next time I up-convert something. I'll test it with in-program colorspace conversion and output to .mp4 as well, since that had the same issue, but I'm guessing if you fixed an HEVC header it covers the containers as well.

OT but is SDR->HDR tonemapping / inverse tonemapping possible with --vpp-colorspace? It looked like it was from the code but I couldn't figure out what combination of parameters needed to be set to use it. If I can stop using FFMPEG for that I gain around 300fps encode speed on 1080p using only your tool. :D

ghost commented 1 year ago

This fixed mastering data and MaxCLL / MaxFALL for raw .hevc and .m2ts, .mkv, and .mp4 containers, and probably everything else that can validly contain an HEVC file.

As a possible linked issue, with the above parameters, I get this info from ffprobe for the .hevc: Stream #0:0: Video: hevc (Main 10), yuv420p10le(tv, bt2020nc/bt2020/smpte2084), 1920x1080 [SAR 1:1 DAR 16:9], 30 fps, 30 tbr, 1200k tbn

But for the .mp4 output directly from vceenc: Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Win.mp4': Metadata: major_brand : mp42 minor_version : 512 compatible_brands: mp42iso2mp41 encoder : VCEEnc (x64) 7.02 Duration: 00:01:29.73, start: 0.000000, bitrate: 8003 kb/s Stream #0:00x1: Video: hevc (Main 10) (hev1 / 0x31766568), yuv420p10le(tv, unknown/bt2020/smpte2084, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 8002 kb/s, 30 fps, 30 tbr, 15360 tbn (default)

I'm not sure why bt2020nc doesn't show up there, as ffprobe -show_frames lists it on the frame-level headers: "color_space": "bt2020nc", "color_primaries": "bt2020", "color_transfer": "smpte2084", So it's likely an issue with some file level header. I get the same issue outputting directly to .mkv but it's fine if I output to .m2ts if that's of any use. AFAIK HDR10 devices are supposed to get that info from frame headers anyway since it's all allowed to change mid-stream, although I've never actually seen that being abused... it might affect something that only does a cursory glance at the file header for the purposes of determining input type like ffmpeg when doing colorspace conversions without specifying input characteristics.

ghost commented 1 year ago

I'm going to close this because the original bug is fixed. The file level headers are a different issue (but don't really seem to affect anything, I suppose they'd be an issue for automatic colorspace detection on the input with zscale or other filters.