View Full Version : fmtconv: resize, bitdepth and colorspace conversions
Pages :
1
2
3
4
5
6
7
[
8]
poisondeathray
28th April 2022, 00:04
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:
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:p=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)
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:
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
Blue_MiSfit
28th April 2022, 03:07
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 :)
mastrboy
11th July 2022, 23:44
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:
# old method
Dither_convert_8_to_16()
Dither_convert_yuv_to_rgb(matrix="601", output="rgb48y", lsb_in=true)
r = SelectEvery (3, 0)
g = SelectEvery (3, 1)
b = SelectEvery (3, 2)
Dither_convert_rgb_to_yuv (r, g, b, matrix="709", lsb=false, mode=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:
# old method
Dither_convert_8_to_16()
Dither_convert_yuv_to_rgb(matrix="709", output="rgb48y", lsb_in=true)
r = SelectEvery (3, 0)
g = SelectEvery (3, 1)
b = SelectEvery (3, 2)
Dither_convert_rgb_to_yuv (r, g, b, matrix="601", lsb=false, mode=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...)
cretindesalpes
31st August 2022, 08:06
fmtconv r30 (https://forum.doom9.org/showthread.php?t=166504):
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.
cretindesalpes
12th April 2026, 14:26
fmtconv r31 (https://forum.doom9.org/showthread.php?t=166504):
bitdepth/Vapoursynth: Can work on clips of variable frame size. The function was already designed to handle this feature, but the parameter check was more strict than necessary. Thanks to Vardë for the report.
matrix: Added the SMPTE ST 2128 IPT-PQ-C2 transform to and from L’M’S’.
resample: Fixed 14 to 16 bit AVX2 conversion path, thanks to NSQY for the report.
resample: Fixed chroma placement: U and V vertical positions for interlaced PAL-DV were swapped and vertical subsampling > 2 was not handled at all. Thanks to Chortos-2 for the report.
transfer: Added L* transfer function.
transfer: Added Arri LogC4 transfer function.
transfer: Rescaled the S-Log3 curve to be used with limited-range code values, like the other S-Log curves.
primaries: Added Arri Wide Gamut 4 colorspace.
primaries: Fixed white XYZ coordinates for the NTSC-J colorspace (exact D93 location), thanks to Chortos-2 for the report.
Program path without x86 SIMD: fixed wrong conversions affecting a lot of functions (noticed on ARM/Apple). Thanks to SaltyChiang for the fix.
On Windows/x64, the Vapoursynth plug-in can be installed with the command line pip install vapoursynth-fmtconv. Requires Vapoursynth r74 or above.
Adub
14th April 2026, 20:39
Are there any plans to support Linux installs via PyPi ("pip install") and/or sdist (source distribution) packaging so that at the very least users can compile things on their own machine if you don't want to bother with making Linux binaries yourself?
Many plugin authors have been using Meson as their build system since it simplifies much of this work, in case you are looking for a tool.
Z2697
10th May 2026, 08:15
Inline assembly code use 32bit register to store memory address and causes crash on 64bit Windows.
Possible fix: https://gist.github.com/Mr-Z-2697/a761228cd0189b50e8022088d780e4c5
(Or, _InterlockedCompareExchange64 is available in MinGW, just use that instead? By appending || defined (__MINGW32__) to #if defined (_MSC_VER))
(Inline assembly seems to be slightly faster...)
src/conc/Interlocked.hpp
int64_t Interlocked::cas (int64_t volatile &dest, int64_t excg, int64_t comp) noexcept
{
...
#if defined (_MSC_VER)
...
#elif defined (_WIN32) || defined (WIN32) || defined (__WIN32__) || defined (__CYGWIN__) || defined (__CYGWIN32__)
...
asm volatile (
" lea %[comp], %%esi \n"
" mov (%%esi), %%eax \n"
...
Story:
I wanted to build fmtc with MSYS2 for a long time, because MSVC is so, err, massive. (but I still have MSVC anyway...)
But the plugin just keeps crashing. So I had to use MSVC.
Today I finally decided to sit down and find out what's wrong.
ChaosKing
14th May 2026, 10:38
Are there any plans to support Linux installs via PyPi ("pip install") and/or sdist (source distribution) packaging so that at the very least users can compile things on their own machine if you don't want to bother with making Linux binaries yourself?
Many plugin authors have been using Meson as their build system since it simplifies much of this work, in case you are looking for a tool.
I hope we get official linux/mac releases. For now there is https://github.com/Jaded-Encoding-Thaumaturgy/vs-wheels#fmtconv--fmtc
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.