Just insert the path to the file, the function use the metadata but if missing they should be added manually :-)
The required plugin is vapoursynth-tonemap
Code:
import easytm
import vapoursynth as vs
core = vs.get_core()
c = core.ffms2.Source(source = 'C:/Users/.../video.mp4')
c=easytm.mobius(c,target_nits=100,masterdisplay=None,transfer=None,matrix=None,primaries=None,resize_1080p=True)
c.set_output()
The operators are mobius, reinhard, hable and bt2390test
The bt.2390 display mapping operator works for now in rgb and it assume black point=0
This is the code used, honestly i'm not sure it's right and i have modified the way KS is calculated
Code:
import vapoursynth as vs
core = vs.get_core()
c = core.ffms2.Source(source = 'C:/Users/.../videos.mp4')
def bt2390test(clip="",masterdisplay=None,target_nits="",transfer=None,matrix=None,primaries=None ) :
core = vs.get_core()
c=clip
if masterdisplay is None:
masterdisplay=c.get_frame(0).props.MasteringDisplayMaxLuminance
if transfer is None:
transfer=c.get_frame(0).props._Transfer
if matrix is None:
matrix=c.get_frame(0).props._Matrix
if transfer == 16 :
transfer = "st2084"
if transfer == 18 :
transfer = "std-b67"
if matrix == 9 :
matrix = "2020ncl"
if primaries is None:
primaries=c.get_frame(0).props._Primaries
if primaries == 9 :
primaries = "2020"
if primaries == 1 :
primaries = "709"
source_peak=masterdisplay
matrix_in_s=matrix
transfer_in_s=transfer
source_peak=source_peak
c=core.resize.Bicubic(clip=c, format=vs.RGBS, filter_param_a=0, filter_param_b=0.75, matrix_in_s=matrix_in_s,chromaloc_in_s="center",chromaloc_s="center", range_in_s="limited", range_s="full",dither_type="none")
lw = source_peak/10000
#eotf^-1 y=((x^0.1593017578125) * 18.8515625 + 0.8359375 / (x^0.1593017578125) * 18.6875 + 1)^78.84375
lw = ((((lw ** 0.1593017578125) * 18.8515625) + 0.8359375) / (((lw ** 0.1593017578125) * 18.6875) + 1))**78.84375
lmax=target_nits/10000
#eotf^-1 y=((x^0.1593017578125) * 18.8515625 + 0.8359375 / (x^0.1593017578125) * 18.6875 + 1)^78.84375
lmax = ((((lmax ** 0.1593017578125) * 18.8515625) + 0.8359375) / (((lmax ** 0.1593017578125) * 18.6875) + 1))**78.84375
#normalize the PQ values
#e1=(x-0)/(lw-0) ==> e1= x / lw
e1=core.std.Expr(clips=[c], expr="x {lw} /".format(lw=lw))
e1=core.std.Limiter(e1, 0,1)
#maxlum=(lmax-0)/(lw-0) ==> maxlum=lmax/lw
maxlum=lmax/lw
#ks1=(1.5*lmax)- 0.5
ks1=(1.5*lmax)- 0.5
#ks2=(1.5*maxlum)- 0.5
ks2=(1.5*maxlum)- 0.5
#ks=(ks1+ks2)/2
ks=(ks1+ks2)/2
#t=(x-ks)/(1-ks)
t = core.std.Expr(clips=[e1], expr="x {ks} - 1 {ks} - / ".format(ks=ks))
#p=(2t^3 - 3t^2 +1)*ks +( t^3-2t^2+t)*(1-ks)+(-2t^3+3t^2)* maxlum
p = core.std.Expr(clips=[t], expr=" 2 x 3 pow * 3 x 2 pow * - 1 + {ks} * 1 {ks} - x 3 pow 2 x 2 pow * - x + * + -2 x 3 pow * 3 x 2 pow * + {maxlum} * +".format(ks=ks,maxlum=maxlum))
e2=core.std.Expr(clips=[e1,p], expr="x {ks} < x y ? ".format(ks=ks))
#e3=e2+0*(1-e2)^4 ==> e3=e2
e3=e2
#invert the normalization of the PQ values
#e4=[e3*(lw-0)]+0 ==> e4=e3*lw
e4=core.std.Expr(clips=[e3], expr="x {lw} * ".format(lw=lw))
c=e4
c=core.resize.Bicubic(clip=c, format=vs.RGBS, transfer_in_s=transfer_in_s, transfer_s="linear",dither_type="none", nominal_luminance=target_nits)
c=core.resize.Bicubic(clip=c, format=vs.RGBS, primaries_in_s=primaries, primaries_s="709",dither_type="none")
c=core.resize.Bicubic(clip=c, format=vs.RGBS, transfer_in_s="linear", transfer_s="709",dither_type="none")
c=core.std.Limiter(c, 0,1)
c=core.resize.Bicubic(clip=c, format=vs.YUV422P16,matrix_s="709", filter_param_a=0, filter_param_b=0.75, range_in_s="full",range_s="limited", chromaloc_in_s="center", chromaloc_s="center",dither_type="none")
return c
c=bt2390test(c,target_nits=100,masterdisplay=None,transfer=None,matrix=None,primaries=None)
c.set_output()