View Full Version : Emulating MadVR's HDR to SDR tonemapping using FFMPEG
Atak_Snajpera
19th December 2017, 16:16
sample
http://www.4ktv.de/sony-camp-2016-hdr-version-download/
MadVR - frame 3596
http://i.cubeupload.com/uwgYPy.png
FFMPEG
ffmpeg.exe -ss 00:01:00.12 -i Sony_4K_HDR_Camp.mp4 -frames 1 -vf zscale=transfer=linear,tonemap=clip,zscale=transfer=bt709,format=yuv420p c:\users\dave\desktop\ffmpeg.png
http://i.cubeupload.com/SLFmvU.png
Does anybody know how to tweak default values (param). I really do not know where those values should be put in command line.
https://ffmpeg.org/ffmpeg-filters.html#tonemap
richardpl
19th December 2017, 17:25
It is rocket science:
ffmpeg.exe -ss 00:01:00.12 -i Sony_4K_HDR_Camp.mp4 -frames 1 -vf zscale=transfer=linear,tonemap=tonemap=clip:param=1.0:desat=2:peak=0,zscale=transfer=bt709,format=yuv420p c:\users\dave\desktop\ffmpeg.png
Atak_Snajpera
19th December 2017, 18:42
Thank you! :)
Atak_Snajpera
20th December 2017, 16:06
I have another question. Why I'm getting this error when I try to work from .avs script.
SCRIPT
LoadPlugin("C:\Users\Dave\Documents\Delphi_Projects\RipBot264\_Compiled\Tools\AviSynth plugins\ffms\ffms_latest\x64\ffms2.dll")
video=FFVideoSource("E:\_Video_Samples\mp4\Sony_4K_HDR_Camp.mp4",cachefile = "C:\Temp\RipBot264temp\job1\Sony_4K_HDR_Camp.mp4.ffindex")
return video
"ffmpeg.exe" -i "C:\Temp\RipBot264temp\job1\job1.avs" -vf zscale=transfer=linear,tonemap=tonemap=hable:param=1.0:desat=0:peak=10,zscale=transfer=bt709,format=yuv420p C:\Temp\test.y4m
http://i.cubeupload.com/VKXwga.png
When I use file directly instead of script it works fine
"ffmpeg.exe" -i "E:\_Video_Samples\mp4\Sony_4K_HDR_Camp.mp4" -vf zscale=transfer=linear,tonemap=tonemap=hable:param=1.0:desat=0:peak=10,zscale=transfer=bt709,format=yuv420p C:\Temp\test.y4m
http://i.cubeupload.com/u4ecVb.png
dipje
20th December 2017, 16:53
out of curiousity? did you try the other tonemapping algorithms? From the description 'mobius' seems promising.
About your avs filter not seeing any path.. I'm _a bit_ stumped.. yuv420p10le in both cases.
What I'm guessing here (really guessing):
The tonemap filter only accepts float values, so it's trying to go from yuv420p10le to some yuv444-floating point.
I'm guessing (since yuv444p32f or something is not in my pix_fmts list) that the only filter capable of producing float-video is the zscale filter.
And the zscale filter refuses to work if you don't say what kind of color-matrices and such it needs for yuv / colorspace conversion.
In your original .mp4, that information is available from the stream (you see it listed after the yuv444p10le) but the .avs reader in ffmpeg is not reporting any colorspace/color-primaries information zo scale refuses to work.
Atak_Snajpera
20th December 2017, 21:15
I tried this ...
ffmpeg.exe -i C:\Temp\RipBot264temp\job1\job1.avs -color_range 1 -color_primaries bt2020 -color_trc smpte2084 -colorspace bt2020nc -vf zscale=transfer=linear,tonemap=tonemap=hable:param=1.0:desat=0:peak=10,zscale=transfer=bt709,format=yuv420p -strict -1 C:\Temp\test.y4m
... and still I'm getting the same error.
http://i.cubeupload.com/YaB3cb.png
nevcairiel
21st December 2017, 10:01
The error is from z.img, not FFmpeg, so its likely some missing information somewhere.
You can probably override the input information by providing the -color* options before the -i option. Anything after -i refers to the output.
dipje
21st December 2017, 10:06
nah that won't work. -color_range parameters etc are for container work or something in ffmpeg, the filters never see them. You have to tell it the zscale filter itself (remember, I'm still guessing). zscale has rangein/primariesin/matrixin/transferin parameters
BTW, recompiled my ffmpeg to get tonemap, and did a few tests with mobius/hable and so far they're not yet the answer I was hoping for :(.
nevcairiel
21st December 2017, 10:27
I would generally recommend to avoid AviSynth because of all these issues however. Even more so with HDR, all the extra HDR metadata is also lost from AviSynth, and I don't think there even is any way to specify it manually (although I don't know if zscale uses that, but if not, it may in the future)
If FFmpeg is allowed to see the input file directly, then it'll all fall in place magically.
dipje
21st December 2017, 11:03
-vf zscale=tin=smpte2084:min=bt2020nc:pin=bt2020:rin=tv:t=smpte2084:m=bt2020nc:p=bt2020:r=tv,zscale=t=linear,tonemap=tonemap=clip,zscale=t=bt709,format=yuv420p
this works! (man that took some time to figure out :S).
With the first 'zscale' I'm basically doing a sort of no-op, but I'm telling zscale what kind of input data it is, and I'm telling it to convert it to 'the same'. But now, the information of what it is is known in the ffmpeg filter chain, so the next zscale=t=linear will now work (and convert it to gbrpf32le apparently).
if I do it in a single zscale filter instance, I'm hitting issues that the zscale implementation inside of ffmpeg has no way to convert to RGB.. and the linear information can only be RGB (a 'matrix=rgb' is missing but needed for this apparently).
I've tested this on a .y4m file that (just like the Avisynth reader) has no information on what kind of format the yuv stream is in besides the planar configuration.
edit: Actually, mobius and hable tonemapping options (even reinhard) don't look that bad now. With all 3 of them you clearly see a bit more detail / local contrast in the water in the opening at that 1 minute opening mark for example. Still have the feeling it's a bit too desaturated
dipje
21st December 2017, 11:28
Think I got the desaturation a bit figured out. You / we never change the color primaries and/or the colormatrix. That means the primaries are still in bt2020. We tonemap the brightness but not much else.
There might be a simpler method, but what I do:
zscale=t=linear,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable,zscale=t=bt709:m=bt709:r=tv
(after the whole 'setting the correct input format' thing).
The first zscale=t=linear turns the YUV format into linear-space-RGB. (Linear space is only a thing in RGB). But the colorprimaries are still in bt2020. (Note, not the colormatrix. The colormatrix is a YUV only thing. But the colorprimarie is basically your colorspace).
Then comes the format=gbrpf32le to turn it all into floating-point RGB. _Then_ do we tell zscale to change the primaries to bt709. According to the zimg documentation changing primaries need to be done in linear space anyway, and this way we make sure the data is linear first. Because we're changing from bt2020 to bt709, we actually start to clip the data at very saturated colors. This is why we first convert to floating point, so this data isn't lost, it's just out-of-gamut.
Then we do the tonemapping, and because it now has data that falls outside of the 0.0 - 1.0 range, it can do it's thing and start desaturating the colors where it thinks it's needed.
After the tonemapping, we use zscale to go back to 'the usual' SDR config of bt709 gamma transfer, and switch to YUV with bt709 colormatrix (the primaries were already in bt709) and we make sure the go to limited range YUV. You may also set the dither options for zscale because we're now requesting it to go down to 8bit. Zscale gets the data from the filter-chain that 'yuv420p' is requested after it and it does the conversion (I believe this is how it works, thus not using the ffmpeg scaler / swscale for this thing). IF you put a 'showinfo' filter between the last zscale and the final 'format=yuv420p' you'll see that the data is already yuv420p after zscale (so I'm guessing zscale is doing the conversion).
edit:
in the 'zscale=t=linear' filter, you might want to add the npl parameter. So it becomes something like 'zscale=t=linear:npl=100'.
I have the feeling it maps the smpte2084 curve and peak data to something that is more alike for a 100 nits screen. This will cause a lot of values to go out of scope (float < 0.0 or float > 1.0, specially the last thing). But that is where the tonemapping filter comes in: How to deal and what to do with values that are outside the display range.
The 'peak=' parameter to the tonemapping filter doesn't seem to have much effect on my side (at least when using hable algorithm), while with 'npl' I can control the final output brightness. The higher the npl= value, the darker the final output video (Because it's meant for displays that have / can do a higher brightness ).
If I use 'hable' and NOT set any peak information and read directly from the Sony .mp4 file, it goes bonkers. I need to set npl=100000 in the first zscale step to get a normal looking video there.
If I use a .y4m as input and don't set the npl, it looks OK, so there are quite some differences in how things are handled.. the bt2020nc is for 'non constant luminace' right? Is there extra metadata in the stream that constantly tells the maximum luminance for a scene??
Atak_Snajpera
21st December 2017, 13:29
dipje you are my hero! Thank you very much for your help! I would never figure that on my own.
I'm posting example command line for those who what to convert HDR to SDR and pipe result to encoder.
ffmpeg.exe -loglevel panic -i script.avs -vf zscale=tin=smpte2084:min=bt2020nc:pin=bt2020:rin=tv:t=smpte2084:m=bt2020nc:p=bt2020:r=tv,zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p -strict -1 -f yuv4mpegpipe - | x264_x64.exe --stdin y4m --output "C:\video.264" -
dipje
21st December 2017, 13:40
all HDR movies are not made the same, so you'll still have to check movie by movie, or even scene by scene how it turns out. There are scenes in the sony demo for instance which I think are too dark.. or I'm tempted to up the 'shadows' slider in Lightroom so to speak :).
But other scenes are clearly very bright and the algorithm is working to map it, so don't really know what to do about that.
Atak_Snajpera
21st December 2017, 17:08
It looks like desat=0 works the best. No idea why by default desat is enabled.
The default of 2.0 is somewhat conservative and will mostly just apply to skies or directly sunlit surfaces. A setting of 0.0 disables this option.
desat = 2 (default)
http://i.cubeupload.com/qyqDEU.png
desat = 0 (disabled)
http://i.cubeupload.com/uyHgif.png
Another reason why desat should be disabled!
desat = 2 (default)
http://i.cubeupload.com/4m2lD4.png
desat = 0 (disabled)
http://i.cubeupload.com/y1g1FR.png
kolak
21st December 2017, 19:16
So you say that this crazy oversaturated/unreal footage of guy next to fire is better?
Atak_Snajpera
21st December 2017, 19:35
Yes, sir!
dipje
24th December 2017, 16:57
like the docs say, desat=2 is taking it easy. I would turn it up higher to desaturate places where SDR can't cope with the color gamut.... I would _not_ turn it off... but to each his/her own I guess.
The purpose of desat is too _lower_ saturation in places where otherwise the saturation would be so high that you won't see any details. I would rather see 'less red' in the coat, but actually see the details and movement in the coat. Not just a 'saturated blob of red' which is undefined... just very red.
If you like desat=0, go ahead and use it... but please use it in your own personal encodes... do not bake it into a GUI or tool as default or something :S.
Atak_Snajpera
24th December 2017, 17:33
desat destroys image. Desat must be disabled. Period!
http://i.cubeupload.com/34c2yw.png
shekh
24th December 2017, 17:37
desat destroys image. Desat must be disabled. Period!
This is obviously not the intended effect. Maybe a bug in zscale or something else?
dipje
24th December 2017, 21:53
was the effect I saw with hable and mobius.. I would try tweaking other parameters to fix glitches like that but keep desat at >= 2. But, once again, your choice.
Selur
31st December 2017, 09:45
@Atak_Snajpera: Thanks for the example!
----
@all: Is there a way to do this in Vapoursynth? Only thing I saw was the HDR10 to SDR with Hable tone-mapping (https://forum.doom9.org/showthread.php?t=174415)'-thread.
I also read somewhere that tone-mapping basically is wrapping zimg, so this should be possible with Vapoursynth (for someone who knows their way around Python&Vapoursynth), but is there a script out there which basically brings the tone-mapping functionality to Vapoursynth?
Cu Selur
dipje
2nd January 2018, 00:35
zimg is the scaling library built into vapoursynth. So the vs.resize.xxxx functions are Z.Img routines. (And I used a lot of Vapoursynth's Resize docs in figuring out stuff for ffmpeg zscale filter :P).
So after using zimg / vs.resize to convert to linear RGB in floating point, you can tonemap with basic math in Python if you know the algorithm. The thread about it you're already active in: https://forum.doom9.org/showthread.php?t=174415
Kef71
4th January 2018, 08:14
ITU has released recommendation for HDR -> SDR conversion. You can find it here: https://www.itu.int/pub/R-REP-BT.2390-3-2017
Look at page 19:
5.4.1 Mapping to display with limited brightness range
dipje
4th January 2018, 10:35
Do note that they're talking about taking the full reference signal (between basically 0 and 10.000 nits) and display it on a normal HDR screen (which for instance can take a maximum of 1.000 nits).
That being said, in figure 20 they show multiple lines for target displays with different brightness capabilities, and they show a blue line for a screen with 100 nits max, which is a nice SDR target.
I'm no math expert, so not really looking at that, but just the text and the graphs basically describe what looks like a pretty normal 'knee' to map the values? Which I boil down in my mind to 'they are recommending to clip signals lower than a certain threshold, clip signals higher than a certain threshold, and use a s-curve for the left-over signal so it looks nice with rolled-off shadows and rolled-off highlights on the target display'. Am I wrong?
This will not really show any detail that might be present in the signal of 1000 nits or brighter, it just rolls it off and compresses it in the upper region. Algorithms like Hable are ment to recover some of those details, right?
Kef71
4th January 2018, 11:08
Do note that they're talking about taking the full reference signal (between basically 0 and 10.000 nits) and display it on a normal HDR screen (which for instance can take a maximum of 1.000 nits).
Agreed, HDR10 supports up to 4,000 nits peak brightness, with a current 1,000 nit peak brightness target, 10-bit color depth and capable of displaying everything in the Rec.2020 color space.
That being said, in figure 20 they show multiple lines for target displays with different brightness capabilities, and they show a blue line for a screen with 100 nits max, which is a nice SDR target.
Yep, agreed. ;)
I'm no math expert, so not really looking at that, but just the text and the graphs basically describe what looks like a pretty normal 'knee' to map the values? Which I boil down in my mind to 'they are recommending to clip signals lower than a certain threshold, clip signals higher than a certain threshold, and use a s-curve for the left-over signal so it looks nice with rolled-off shadows and rolled-off highlights on the target display'. Am I wrong?
AFAIK, you are correct in your assumption.
This will not really show any detail that might be present in the signal of 1000 nits or brighter, it just rolls it off and compresses it in the upper region. Algorithms like Hable are ment to recover some of those details, right?
It is an official recommendation not tied to any specific hardware so yes, there are compromises to be made. Remember that the scale is logarithmic so most of the information maps 1:1 from UHD to SDR. Just need to compress a little bit in the upper and lower regions to get a picture as close as possible to UHD. Hable, Reinhard, Mobius are just slightly different shapes of this s-curve as far as I know.
edit: UHD to SDR blu-ray most likely follow this recommendation.
Atak_Snajpera
6th February 2018, 13:14
Single threaded tonemapping is creating huge bottleneck on my 8C/16T CPU. Is there any way to speed up zscale by using multi-threading?
http://i.cubeupload.com/RLMy7N.png
http://i.cubeupload.com/JR9KMb.png
dipje
6th February 2018, 13:45
From my Vapoursynth experience it's not zscale that is the speed limiting factor, but I'm only guessing.
ffmpeg isn't very good at multi-threading at all, and I think the tonemap filter is just made as a proof of concept as a single-threaded demo. Guess you will have to ask on the ffmpeg-user list.
tyee
9th February 2018, 20:26
dipje you are my hero! Thank you very much for your help! I would never figure that on my own.
I'm posting example command line for those who what to convert HDR to SDR and pipe result to encoder.
ffmpeg.exe -loglevel panic -i script.avs -vf zscale=tin=smpte2084:min=bt2020nc:pin=bt2020:rin=tv:t=smpte2084:m=bt2020nc:p=bt2020:r=tv,zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p -strict -1 -f yuv4mpegpipe - | x264_x64.exe --stdin y4m --output "C:\video.264" -
@Atak_Snajpera - I tried your command line and get this error - x264 [error]: could not open input file `-' - Do you know why? I'm using 32 bit ffmpeg and x264 because I have 32 bit avisynth installed.
Selur
9th February 2018, 20:28
Remove the '-loglevel panic' to see wether ffmpeg complains about having problems with you avs file,..
Atak_Snajpera
9th February 2018, 20:32
See how it is done in ripbot264. Add some HDR footage and see C:\Temp\RipBot264temp\Job1\job1_EncodeVideoPass1.cmd.
Probably you made a typo somewhere...
tyee
9th February 2018, 20:35
It's getting further now but still errors -
Input #0, avisynth, from 'Standard.avs':
Duration: 00:01:56.83, start: 0.000000, bitrate: 0 kb/s
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 1280x532, 23.98 fps, 23.98 tbr, 23.98
tbn, 23.98 tbc
[zscale @ 19ce05c0] [Eval @ 0028e6cc] Undefined constant or missing '(' in 'smpte2084'
[zscale @ 19ce05c0] Unable to parse option value "smpte2084"
[zscale @ 19ce05c0] [Eval @ 0028e6cc] Undefined constant or missing '(' in 'bt2020nc'
[zscale @ 19ce05c0] Unable to parse option value "bt2020nc"
[zscale @ 19ce05c0] [Eval @ 0028e6cc] Undefined constant or missing '(' in 'bt2020'
[zscale @ 19ce05c0] Unable to parse option value "bt2020"
[zscale @ 19ce05c0] [Eval @ 0028e6cc] Undefined constant or missing '(' in 'tv'
[zscale @ 19ce05c0] Unable to parse option value "tv"
[zscale @ 19ce05c0] [Eval @ 0028e6cc] Undefined constant or missing '(' in 'smpte2084'
[zscale @ 19ce05c0] Unable to parse option value "smpte2084"
[zscale @ 19ce05c0] [Eval @ 0028e6cc] Undefined constant or missing '(' in 'bt2020nc'
[zscale @ 19ce05c0] Unable to parse option value "bt2020nc"
[zscale @ 19ce05c0] [Eval @ 0028e6cc] Undefined constant or missing '(' in 'bt2020'
[zscale @ 19ce05c0] Unable to parse option value "bt2020"
[zscale @ 19ce05c0] [Eval @ 0028e6cc] Undefined constant or missing '(' in 'tv'
[zscale @ 19ce05c0] Unable to parse option value "tv"
[zscale @ 19ce05c0] [Eval @ 0028e71c] Undefined constant or missing '(' in 'smpte2084'
[zscale @ 19ce05c0] Unable to parse option value "smpte2084"
[zscale @ 19ce05c0] Error setting option tin to value smpte2084.
[Parsed_zscale_0 @ 19ce0b80] Error applying options to the filter.
[AVFilterGraph @ 031b18e0] Error initializing filter 'zscale' with args 'tin=smpte2084:min=bt2020nc:
pin=bt2020:rin=tv:t=smpte2084:m=bt2020nc:p=bt2020:r=tv'
Error opening filters!
x264 [error]: could not open input file `-'
Atak_Snajpera
9th February 2018, 20:36
Update your ffmpeg https://ffmpeg.zeranoe.com/builds/
tyee
9th February 2018, 20:43
That did it, thanks! This will give me 8 bit output, yes? I thought I read somewhere that ffmpeg did not support 10 bit yet?
Update - confirmed it is 8 bit.
sneaker_ger
9th February 2018, 22:50
ffmpeg does support 10 bit input/output. But "format=yuv420p" sets 8 bit. 10 bit equivalent is called "yuv420p10le". (I haven't looked at the complete filter list, this is just the last filter.) And if you pipe to x264cli/x265cli you have to use a 10 bit build and possibly explicity set 10 bit output if it's a multi-depth build.
SpasV
10th October 2018, 09:31
dipje you are my hero! Thank you very much for your help! I would never figure that on my own.
I'm posting example command line for those who what to convert HDR to SDR and pipe result to encoder.
ffmpeg.exe -loglevel panic -i script.avs -vf zscale=tin=smpte2084:min=bt2020nc:pin=bt2020:rin=tv:t=smpte2084:m=bt2020nc:p=bt2020:r=tv,zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p -strict -1 -f yuv4mpegpipe - | x264_x64.exe --stdin y4m --output "C:\video.264" -
Thank you for the post.
The pipe -f yuv4mpegpipe - | doesn't work, but -f rawvideo - | x265 - does.
The CL generates 3840x2160 rawvideo. If 1920x1080 is needed instead, add one more resizing filter:
format=yuv420p,zscale=s=1920x1080
Thank you for the help with this topic. :)
There is no need for using script.avs to introduce a Source filter. ffmpeg has one.
sneaker_ger
10th October 2018, 10:06
The pipe -f yuv4mpegpipe - | doesn't work
It's
-strict -1 -f yuv4mpegpipe - | x265 - --y4m
or
-strict -1 -f yuv4mpegpipe - | x264 - --demuxer y4m
respectively.
(Atak_Snajpera had the -strict -1 part in his example.)
SpasV
13th October 2018, 21:03
No, it seems format yuv4mpegpipe is not supported anymore.
Besides, the filter zscale=tin=smpte2084:min=bt2020nc:pin=bt2020:rin=tv:t=smpte2084:m=bt2020nc:p=bt2020:r=tv, added by dipje is not needed with the current FFmpeg version.
It is not only a sort of no-op but it adds additional processing time with any frame. These FFmpeg filters (without this no-op) work at least three times slower than DGTonemap filters.
sneaker_ger
13th October 2018, 21:20
No, it seems format yuv4mpegpipe is not supported anymore.
I highly doubt that. Why don't you post any logs?
Besides, the filter zscale=tin=smpte2084:min=bt2020nc:pin=bt2020:rin=tv:t=smpte2084:m=bt2020nc:p=bt2020:r=tv, added by dipje is not needed with the current FFmpeg version.
It is not only a sort of no-op but it adds additional processing time with any frame. These FFmpeg filters (without this no-op) work at least three times slower than DGTonemap filters.
No one said you should use both at the same time. They are alternatives.
Selur
13th October 2018, 23:44
No, it seems format yuv4mpegpipe is not supported anymore.
yuv4mpegpipe works fine here with latest builds of ffmpeg&co, as an example:
ffmpeg -y -loglevel fatal -threads 8 -i "F:\TestClips&Co\files\HDR\4K sun HDR test.mp4" -map 0:0 -an -sn -vf zscale=tin=smpte2084:min=bt2020nc:pin=bt2020:rin=tv:t=smpte2084:m=bt2020nc:p=bt2020:r=tv,zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=2.000:peak=0.000,zscale=t=bt709:m=bt709:r=tv -pix_fmt yuv420p10le -strict -1 -vsync 0 -f yuv4mpegpipe - | x265 --input - --output-depth 10 --y4m --profile main10 --qg-size 8 --limit-modes --no-open-gop --opt-ref-list-length-pps --radl 2 --lookahead-slices 0 --crf 18.00 --opt-qp-pps --cbqpoffs -2 --crqpoffs -2 --limit-refs 0 --ssim-rd --psy-rd 2.50 --rdoq-level 2 --psy-rdoq 10.00 --aq-mode 0 --deblock=-1:-1 --limit-sao --range limited --colormatrix bt709 --output "E:\Temp\00_35_54_2910_01.265"
works fine here,..
-strict -1
is only needed for 10bit color spaces, not with 8bit 4:2:0
,format=yuv420p -strict -1 -f yuv4mpegpipe
-> I agree remove '-loglevel panic' and post the log if you can't make heads and tail of the error messages of ffmpeg.
Cu Selur
jhughy2010
8th December 2018, 05:34
I'm trying to convert an HDR/UHD movie to SDR/FHD. I've stumbled upon this article (https://stevens.li/guides/video/converting-hdr-to-sdr-with-ffmpeg/) and am trying ffmpeg for the first time. I'm a regular user of Handbrake but unfortunately this is my first run with ffmpeg.
I've installed ffmpeg and ran the following command:
ffmpeg.exe -i D:\Videos\Media\Temp\video.mkv -vf zscale=t=linear:npl=100,format=gbrpf32le,
zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,
format=yuv420p -c:v libx265 -crf 18 -preset slower D:\Videos\Media\Temp\output.mkv
I've renamed the movie file (for simplicity sake) to video. Right now I'm getting the following error: "at least one output file must be specified".
Any help would be greatly appreciated. If someone could give me the exact command to try that would be most helpful. The "video.mkv" file is located in D:\Videos\Media\Temp.
Thanks!
richardpl
8th December 2018, 10:35
From my Vapoursynth experience it's not zscale that is the speed limiting factor, but I'm only guessing.
ffmpeg isn't very good at multi-threading at all, and I think the tonemap filter is just made as a proof of concept as a single-threaded demo. Guess you will have to ask on the ffmpeg-user list.
Have proof for such harsh claims?
tebasuna51
8th December 2018, 10:38
... I'm getting the following error: "at least one output file must be specified"...
Work for me using a unique line like this:
ffmpeg.exe -i D:\Videos\Media\Temp\video.mkv -vf zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p -c:v libx265 -crf 18 -preset slower D:\Videos\Media\Temp\output.mkv
Copy/Paste or make a .bat file with a unique line.
jhughy2010
10th December 2018, 05:13
Work for me using a unique line like this:
Copy/Paste or make a .bat file with a unique line.
Thank you. I appreciate your help... it appears it's working; however, I'm getting approximately 0.5 fps for the encode. At this rate I figured it would take 96 hours to complete the encode. A few questions: what do I have to do in order to speed up the encode? I'm using an i7-4790k overclocked to 4.6GHz. It is a bit old... I'm willing to upgrade to speed the process up.
Perhaps there is a command that'll speed it up as well? This is my first experience with ffmpeg and/or CLI encoding. Thanks!
tebasuna51
10th December 2018, 10:25
I'm getting approximately 0.5 fps for the encode. At this rate I figured it would take 96 hours to complete the encode...
Is a normal speed for encode 4K HEVC with your CPU.
Is more or less the same if you use x265 to encode instead ffmpeg.
You can use other -preset between: ultrafast superfast veryfast faster fast medium slow slower veryslow placebo
to improve the speed obtaining less quality or more size.
Only if you can use some GPU to encode HEVC you can obtain much more speed.
EmKayVe
14th December 2018, 02:17
Work for me using a unique line like this:
Copy/Paste or make a .bat file with a unique line.
Is a normal speed for encode 4K HEVC with your CPU.
Is more or less the same if you use x265 to encode instead ffmpeg.
You can use other -preset between: ultrafast superfast veryfast faster fast medium slow slower veryslow placebo
to improve the speed obtaining less quality or more size.
Only if you can use some GPU to encode HEVC you can obtain much more speed.
This worked wonders for me. I changed the preset to "medium" and crf to 20. I was getting around 3 to 4 fps for the encode.
One thing I would like to know with ffmpeg is now to set the audio to encode to AAC 320kbps 5.1 channels. Also, how do you set the target resolution to 1920x1080. I found that in order to make those two adjusments, I am having to utilize handbrake after ffmpeg since I don't know the CLI.
tebasuna51
14th December 2018, 11:43
One thing I would like to know with ffmpeg is now to set the audio to encode to AAC 320kbps 5.1 channels. Also, how do you set the target resolution to 1920x1080. I found that in order to make those two adjusments, I am having to utilize handbrake after ffmpeg since I don't know the CLI.
A full recode with ffmpeg is out of scope of this thread (HDR to SDR) and need a answer from a ffmpeg expert (I'm not).
BTW if you want a 1920x1080 SDR output better use a BluRay source.
EmKayVe
17th December 2018, 08:11
BTW if you want a 1920x1080 SDR output better use a BluRay source.
Can you be more specific? What do you mean... use a BD rip?
tebasuna51
17th December 2018, 10:40
Of course.
A 4K HDR BT-2020 is better than a BD by resolution and colour space, if you reduce resolution to 1920x1080 and colour space to BT-709 you obtain the same quality (or less) than the BD.
BTW to reduce resolution you have the answer in previous post by SpasV:
add at end of video filter: ...,format=yuv420p,zscale=s=1920x1080
EmKayVe
20th December 2018, 01:12
Of course.
A 4K HDR BT-2020 is better than a BD by resolution and colour space, if you reduce resolution to 1920x1080 and colour space to BT-709 you obtain the same quality (or less) than the BD.
BTW to reduce resolution you have the answer in previous post by SpasV:
add at end of video filter: ...,format=yuv420p,zscale=s=1920x1080
Ok thank you for your help!
I tried the following and I am getting an error:
ffmpeg.exe -i D:\Videos\Media\Temp\video.mkv -vf zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p, zscale=s=1920x1080 -c:v libx265 -crf 20 -preset medium D:\Videos\Media\Temp\output.mkv
The error is "unable to find a suitable output format for zscale=s=1920x1080: Invalid argument.
Any suggestions?
Monarc
20th December 2018, 10:44
-vf zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p, zscale=s=1920x1080
remove the space before zscale=s=1920x1080
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.