I have a source video that is a UHD HDR MKV file using the HEVC codec. Specifically, the input video stream as reported by ffprobe is:
hevc (Main 10), yuv420p10le(tv, bt2020nc/bt2020/smpte2084), 3840x2160 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 23.98 tbc (default)
I'm trying to take snapshots of it - extract single frames at specific times. Naively, I start with this: (the -ss time is just an example)
ffmpeg -ss 00:01:02 -i input.mkv -vframes 1 output.png
This "works", but results in washed out colors, because the original is HDR and my iMac monitor isn't.
OK, so I enable the tone mapping filter like so:
ffmpeg -ss 00:01:02 -i input.mkv -vf "zscale=transfer=linear,tonemap=hable,zscale=transfer=bt709" -vframes 1 output.png
This also appears to work, giving an extremely accurate looking result:
However, if I then convert the image using imagemagick from PNG to JPEG, the colors completely change.
convert output.png output.jpg
The image is still brighter than the un-tone-mapped original, but the color improvements have been lost. The image is washed out again.
Why?
Weirdly, and frustratingly, if I use ffmpeg to convert to BMP in the first place, instead of PNG, I get yet a third different result, with partially improved colors, but not as good as the PNG result, although the BMP file does convert to JPEG without the colors being further altered.
ffmpeg -ss 00:01:02 -i input.mkv -vf "zscale=transfer=linear,tonemap=hable,zscale=transfer=bt709" -vframes 1 output.bmp
What's going on?
I did note that the PNG uses 16-bit color channels, and not 8-bit:
identify output.png
output.png PNG 3840x2160 3840x2160+0+0 16-bit RGB 24.2MB 0.000u 0:00.000
I did try appending "format=rgb24" onto the end of the filter string to create an 8-bit channel PNG, which did work, but the results remain visually identical as above.
ffmpeg -i output.png -i output.bmp
?-i
options. I guess that the actual question is: What do you really want do do? Do you need JPEGs in the end?