Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > VapourSynth

Reply
 
Thread Tools Search this Thread Display Modes
Old 26th January 2022, 16:50   #341  |  Link
asarian
Registered User
 
Join Date: May 2005
Posts: 1,462
I was wondering whether there's way to convert regular Bluray HD to UHD HDR10, using fmtconv? I saw several attempts here, but in all those examples something went wrong. A clean example would be nice.
__________________
Gorgeous, delicious, deculture!
asarian is offline   Reply With Quote
Old 18th February 2022, 03:49   #342  |  Link
Blue_MiSfit
Derek Prestegard IRL
 
Blue_MiSfit's Avatar
 
Join Date: Nov 2003
Location: Los Angeles
Posts: 5,960
I'm struggling a bit with some HDR conversions:

Source:
16 bit full range RGB
PQ, BT. 2020

Target:
12 bit limited range YCbCr 4:4:4
PQ, BT. 2020

(for ProRes XQ encoding)

With this script:

Quote:
import vapoursynth as vs
core = vs.core

source = core.ffms2.Source("flattened_video.mov")

c = source

c = core.fmtc.matrix(source, mat="2100", bits=16)
c = core.fmtc.bitdepth(c, bits=12)

c.set_output()
I get something that's mostly right, but doesn't fully match the source in Resolve. Suggestions?
__________________
These are all my personal statements, not those of my employer :)
Blue_MiSfit is online now   Reply With Quote
Old 13th March 2022, 23:47   #343  |  Link
cretindesalpes
͡҉҉ ̵̡̢̛̗̘̙̜̝̞̟̠͇̊̋̌̍̎̏̿̿
 
cretindesalpes's Avatar
 
Join Date: Feb 2009
Location: No support in PM
Posts: 712
What kind of difference do you have? How could I reproduce your issue in Resolve?
__________________
dither 1.28.1 for AviSynth | avstp 1.0.4 for AviSynth development | fmtconv r30 for Vapoursynth & Avs+ | trimx264opt segmented encoding
cretindesalpes is offline   Reply With Quote
Old 11th April 2022, 17:30   #344  |  Link
cretindesalpes
͡҉҉ ̵̡̢̛̗̘̙̜̝̞̟̠͇̊̋̌̍̎̏̿̿
 
cretindesalpes's Avatar
 
Join Date: Feb 2009
Location: No support in PM
Posts: 712
fmtconv r29:
  • Vapoursynth: switched to API v4. Fmtconv now requires Vapoursynth r55 or later, API v3 is not supported anymore.
  • resample: Fixed degnerated cases with invks causing a crash. Thanks to Dogway for the report.
  • resample/Avisynth+: fixed frame property writing when only cplaced is defined, thanks to Dogway for the report.
  • transfer: Added sigmoid curve as a transfer function.
  • transfer: Fixed the float to integer path.
__________________
dither 1.28.1 for AviSynth | avstp 1.0.4 for AviSynth development | fmtconv r30 for Vapoursynth & Avs+ | trimx264opt segmented encoding
cretindesalpes is offline   Reply With Quote
Old 27th April 2022, 02:36   #345  |  Link
Blue_MiSfit
Derek Prestegard IRL
 
Blue_MiSfit's Avatar
 
Join Date: Nov 2003
Location: Los Angeles
Posts: 5,960
Ok, here's a sample frame:

https://drive.google.com/file/d/1vJg...ew?usp=sharing

Again, this is 16 bit full range RGB in HDR with BT. 2020 primaries and ST. 2084 / PQ transfer. Things have evolved a bit since my last post, and now I want to produce two different types of output:

1) Limited range 4:2:0 10 bit (for HDR10 encoding with HEVC)

2) Limited range 4:4:4 12 bit (for ProRes XQ encoding)

Both seem totally fine if I keep full resolution. However, if I downscale (e.g. to 1080p) I'd like to do the scaling in linear light since this is best practice. When I do, a lot of the higher code values are clipped.

Examples: https://imgur.com/a/1K8iKG3

Good (... I think):
Code:
import vapoursynth as vs
core = vs.core

a = core.ffms2.Source("HDR_Ramp.tif")

#a = a.fmtc.transfer(transs="pq", transd="linear", fulls=True, fulld=True)
a = a.fmtc.resample(w=1920, h=1080)
#a = a.fmtc.transfer(transs="linear", transd="pq", fulls=True, fulld=True)
a = a.fmtc.matrix(mat="2020", fulls=True, fulld=False)
a = a.fmtc.resample(css="420")
a = a.fmtc.bitdepth(bits=10)

a.set_output()
Bad (clipped):
Code:
import vapoursynth as vs
core = vs.core

a = core.ffms2.Source("HDR_Ramp.tif")

a = a.fmtc.transfer(transs="pq", transd="linear", fulls=True, fulld=True)
a = a.fmtc.resample(w=1920, h=1080)
a = a.fmtc.transfer(transs="linear", transd="pq", fulls=True, fulld=True)
a = a.fmtc.matrix(mat="2020", fulls=True, fulld=False)
a = a.fmtc.resample(css="420")
a = a.fmtc.bitdepth(bits=10)

a.set_output()
Am I doing something wrong? The same pattern holds true if I omit the final resample (keeping 4:4:4) and change bitdepth to 12 to make 4:4:4 12 bit for ProRes XQ.
__________________
These are all my personal statements, not those of my employer :)

Last edited by Blue_MiSfit; 27th April 2022 at 02:38.
Blue_MiSfit is online now   Reply With Quote
Old 27th April 2022, 04:48   #346  |  Link
poisondeathray
Registered User
 
Join Date: Sep 2007
Posts: 5,166
Quote:
Originally Posted by Blue_MiSfit View Post

Bad (clipped):
Code:
import vapoursynth as vs
core = vs.core

a = core.ffms2.Source("HDR_Ramp.tif")

a = a.fmtc.transfer(transs="pq", transd="linear", fulls=True, fulld=True)
a = a.fmtc.resample(w=1920, h=1080)
a = a.fmtc.transfer(transs="linear", transd="pq", fulls=True, fulld=True)
a = a.fmtc.matrix(mat="2020", fulls=True, fulld=False)
a = a.fmtc.resample(css="420")
a = a.fmtc.bitdepth(bits=10)

a.set_output()
Am I doing something wrong? The same pattern holds true if I omit the final resample (keeping 4:4:4) and change bitdepth to 12 to make 4:4:4 12 bit for ProRes XQ.
Do calcs in 32bit float
a = core.ffms2.Source...
a = a.fmtc.bitdepth(bits=32)
.
.
.
poisondeathray is offline   Reply With Quote
Old 27th April 2022, 06:36   #347  |  Link
Blue_MiSfit
Derek Prestegard IRL
 
Blue_MiSfit's Avatar
 
Join Date: Nov 2003
Location: Los Angeles
Posts: 5,960
Wow, yeah that totally fixed it.

Why is this necessary? I understand how 32 bit float is certainly more precise than 16 bit integer, but I'd have imagined the differences being a whole lot more subtle than this!

On the off-chance, is it possible to reproduce this filter chain in ffmpeg?
__________________
These are all my personal statements, not those of my employer :)

Last edited by Blue_MiSfit; 27th April 2022 at 17:01.
Blue_MiSfit is online now   Reply With Quote
Old 27th April 2022, 18:57   #348  |  Link
poisondeathray
Registered User
 
Join Date: Sep 2007
Posts: 5,166
Quote:
Originally Posted by Blue_MiSfit View Post
Wow, yeah that totally fixed it.

Why is this necessary? I understand how 32 bit float is certainly more precise than 16 bit integer, but I'd have imagined the differences being a whole lot more subtle than this!

Yes 16bit has higher precision, but 16bit int will still clip to [black,white] or [min,max] , or 0 to 65535 for 16bit code values. "Higher precision" because there are more "steps" described between black to white, but "higher precision" still clips

But the ST2084 PQ to linear transfer function will have values >1 in float ( > 65635 in 16bit) , or "whiter than white"


Quote:
On the off-chance, is it possible to reproduce this filter chain in ffmpeg?

Yes, using zscale and format=gbrpf32le for float
https://ffmpeg.org/ffmpeg-filters.html#zscale-1

Code:
-vf zscale=w=1920:h=1080:transferin=smpte2084:transfer=linear,format=gbrpf32le,zscale=matrix=2020_ncl:transferin=linear:transfer=smpte2084,format=yuv420p10le

Last edited by poisondeathray; 27th April 2022 at 19:00.
poisondeathray is offline   Reply With Quote
Old 27th April 2022, 20:01   #349  |  Link
Blue_MiSfit
Derek Prestegard IRL
 
Blue_MiSfit's Avatar
 
Join Date: Nov 2003
Location: Los Angeles
Posts: 5,960
Thanks very much for the ffmpeg filter chain! I'll do some testing with that.

Thanks also for the explanation. After I thought about it a bit more this did indeed occur to me
__________________
These are all my personal statements, not those of my employer :)
Blue_MiSfit is online now   Reply With Quote
Old 27th April 2022, 23:12   #350  |  Link
Blue_MiSfit
Derek Prestegard IRL
 
Blue_MiSfit's Avatar
 
Join Date: Nov 2003
Location: Los Angeles
Posts: 5,960
Hmm ok so I had to add a couple of parameters to

a) Identify the input primaries as bt2020

and

b) Specify limited range output


This worked great for a TIF input. The output matches the source in Resolve perfectly:

Code:
ffmpeg -i HDR_Ramp.tif -vf zscale=w=1920:h=1080:pin=bt2020:p=bt2020:tin=smpte2084:t=linear,format=gbrpf32le,zscale=m=2020_ncl:tin=linear:t=smpte2084:r=limited,format=yuv420p10le -c:v libx265 -crf 10 reference2.mp4
However, as soon as I swapped over to using the IMF MXF J2K wrapped version of this (same image, just a lossless compressed version of the full range 16 bit RGB TIF), I get the same clipped whites:

Code:
ffmpeg -f imf -i .\CPL_FOX-TPS-1MIN-HDR10-ML7_20181105_OV.xml -map 0:v -vf zscale=w=1920:h=1080:pin=bt2020:p=bt2020:tin=smpte2084:t=linear,format=gbrpf32le,zscale=m=2020_ncl:tin=linear:t=smpte2084:r=limited,format=yuv420p10le -c:v libx265 -crf 10 -preset superfast -x265-params keyint=24 -t 1 scale_linear_08.mp4
That clipped white is visible both in MPC-HC and in Resolve.

Both formats seem to insert the same auto scaler from rgb48le to gbrp16le:

Code:
[auto_scale_0 @ 00000157ac51b040] picking gbrp16le out of 48 ref:rgb48le alpha:0
...
[auto_scale_0 @ 00000157ac51b040] w:3840 h:2160 fmt:rgb48le sar:0/1 -> w:3840 h:2160 fmt:gbrp16le sar:0/1 flags:0x0
I tried disabling auto conversion and explicitly adding format=gbrp16le to the head of the filter graph and that errors out:

Code:
[format @ 000001f0f4c5ea00] Setting 'pix_fmts' to value 'yuv420p|yuvj420p|yuv422p|yuvj422p|yuv444p|yuvj444p|gbrp|yuv420p10le|yuv422p10le|yuv444p10le|gbrp10le|yuv420p12le|yuv422p12le|yuv444p12le|gbrp12le|gray|gray10le|gray12le'
The filters 'graph 0 input from stream 0:0' and 'Parsed_format_0' do not have a common format and automatic conversion is disabled.
Error reinitializing filters!
__________________
These are all my personal statements, not those of my employer :)

Last edited by Blue_MiSfit; 28th April 2022 at 00:11.
Blue_MiSfit is online now   Reply With Quote
Old 28th April 2022, 00:04   #351  |  Link
poisondeathray
Registered User
 
Join Date: Sep 2007
Posts: 5,166
Quote:
Originally Posted by Blue_MiSfit View Post
Hmm ok so I had to add a couple of parameters to

a) Identify the input primaries as bt2020

and

b) Specify limited range output


This worked great for a TIF input. The output matches the source in Resolve perfectly:

Code:
ffmpeg -i HDR_Ramp.tif -vf zscale=w=1920:h=1080:pin=bt2020:p=bt2020:tin=smpte2084:t=linear,format=gbrpf32le,zscale=m=2020_ncl:tin=linear:t=smpte2084:r=limited,format=yuv420p10le -c:v libx265 -crf 10 reference2.mp4
Interesting, I would have thought that in tif without any flags or metadata, pin=bt2020=bt2020 should be a no-op and do nothing, and that RGB to YUV limited range would be default setting... But you're right, they are required or the proper flags need to be set

But for current ffmpeg behaviour - it appears is the metadata for primaries in the output file isn't written , unless you set it in the zscale arguments, or the encoder settings. The actual video data is unaffected and still a no-op
Color primaries : BT.2020

(I guess it's better to be explicit and check assumptions)


Quote:
Originally Posted by Blue_MiSfit View Post
However, as soon as I swapped over to using the IMF MXF J2K wrapped version of this (same image), I get the same clipped whites:

Code:
ffmpeg -f imf -i .\CPL_FOX-TPS-1MIN-HDR10-ML7_20181105_OV.xml -map 0:v -vf zscale=w=1920:h=1080:pin=bt2020:p=bt2020:tin=smpte2084:t=linear,format=gbrpf32le,zscale=m=2020_ncl:tin=linear:t=smpte2084:r=limited,format=yuv420p10le -c:v libx265 -crf 10 -preset superfast -x265-params keyint=24 -t 1 scale_linear_08.mp4
That clipped white is visible both in MPC-HC and in Resolve.


Not sure, there might be other metadata or flags in the imf that overrides some settings or assumptions. what pixel format for the imf ?

You can add -report to the command line and look ath the ffmpeg log for clues

Last edited by poisondeathray; 28th April 2022 at 00:24.
poisondeathray is offline   Reply With Quote
Old 28th April 2022, 03:07   #352  |  Link
Blue_MiSfit
Derek Prestegard IRL
 
Blue_MiSfit's Avatar
 
Join Date: Nov 2003
Location: Los Angeles
Posts: 5,960
Thanks. It's all still 16 bit full range RGB BT. 2020 / PQ in the IMF.

I'll start a new thread elsewhere about the ffmpeg stuff. Continuing on the VapourSynth track here I realized I'd missed some really nasty halos in the high contrast areas. Forcing kernel=bicubic helped this quite a lot.

Resting the eyes now, hopefully I'll get that sorted tomorrow
__________________
These are all my personal statements, not those of my employer :)
Blue_MiSfit is online now   Reply With Quote
Old 11th July 2022, 23:44   #353  |  Link
mastrboy
Registered User
 
Join Date: Sep 2008
Posts: 360
I have some unexpected behavior when doing 709->601 conversion having to run fmtc_matrix twice to get the expected result when compared to "old" dither based conversion.
I'm updating some of my ancient script and started to move to fmtc from Dither.

On the other hand 601->709 works as expected, the following two snippets create visually similear color output:
PHP Code:
# old method
Dither_convert_8_to_16()
Dither_convert_yuv_to_rgb(matrix="601"output="rgb48y"lsb_in=true)
SelectEvery (30)
SelectEvery (31)
SelectEvery (32)
Dither_convert_rgb_to_yuv (rgbmatrix="709"lsb=falsemode=6)

# new method:
fmtc_resample (css="444")
fmtc_matrix (mats="601"matd="709")
fmtc_resample (css="420")
fmtc_bitdepth (bits=8
But the following 709->601 snippets does not produce the similar results:
PHP Code:
# old method
Dither_convert_8_to_16()
Dither_convert_yuv_to_rgb(matrix="709"output="rgb48y"lsb_in=true)
SelectEvery (30)
SelectEvery (31)
SelectEvery (32)
Dither_convert_rgb_to_yuv (rgbmatrix="601"lsb=falsemode=6)

# new method:
fmtc_resample (css="444")
fmtc_matrix (mats="709"matd="601")
fmtc_resample (css="420")
fmtc_bitdepth (bits=8
But, if I call fmtc_matrix twice, like "fmtc_matrix (mats="709", matd="601").fmtc_matrix (mats="709", matd="601")" I get similar results to Dither.

What am I doing wrong here with fmtc? Or is it Dither that is wrong?

Edit: Seems the issue is with AVSPmod and not fmtc, after downgrading AVSPmod v2.6.2.8 I'm not able to reproduce this issue anymore. (Seems to be a bug introduced in AVSPmod somewhere between v2.6.2.9 - v2.7.1.3 where it looks like it fetches a cached frame somewhere in the filter pipeline...)
__________________
(i have a tendency to drunk post)

Last edited by mastrboy; 12th July 2022 at 16:48. Reason: Added "solution".
mastrboy is offline   Reply With Quote
Old 31st August 2022, 08:06   #354  |  Link
cretindesalpes
͡҉҉ ̵̡̢̛̗̘̙̜̝̞̟̠͇̊̋̌̍̎̏̿̿
 
cretindesalpes's Avatar
 
Join Date: Feb 2009
Location: No support in PM
Posts: 712
fmtconv r30:
  • matrix: The _ColorRange frame property is now set when a matrix preset is used.
  • transfer: Added ACEScct transfer function.
  • primaries: Added DCI P3+ and Cinema Gamut presets.
  • primaries: Added wconv parameter for full conversion.
  • Changed the configure options to compile with Clang.
  • Updated datatypes in the examples.
__________________
dither 1.28.1 for AviSynth | avstp 1.0.4 for AviSynth development | fmtconv r30 for Vapoursynth & Avs+ | trimx264opt segmented encoding
cretindesalpes is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 23:44.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2023, vBulletin Solutions Inc.