Posts: 4
Threads: 1
Joined: Dec 2025
04.12.2025, 19:15
When tagging the encoder with manually set VUI values (such as color_primaries=smpte170m:color_trc=bt709:colorspace=smpte170m) in the ProRes codec tab, the log states that ffmpeg is respecting those values for the bitstream filter with the parameter: (-bsf:v prores_metadata=color_primaries=smpte170m:color_trc=bt709:colorspace=smpte170m) .
However, ffmpeg is also incorporating native tagging flags such as -color_primaries bt470m -color_trc bt709 -colorspace bt470bg presumably from Vapoursynth (just a guess on looking at the log.)
Therefore, the output file is shown from mediainfo and ffprobe as
Color primaries : BT.470 System M
colour_primaries_Original : BT.601 NTSC
Transfer characteristics : BT.709
Matrix coefficients : BT.470 System B/G
matrix_coefficients_Original : BT.601
(bt470bg/bt470m/bt709, progressive)
The input file used in the log is read from ffprobe and mediainfo as: smpte170m/smpte170m/bt709 but seems to be mis-adjusted around line 2629 as bt470bg.
The desired output from ffprobe would be: (smpte170m/smpte170m/bt709, progressive)
The desired output is achieved when using the x264 codec VUI options, but not for ProRes (including 'standard' and 'kostya').
This has been tested on the latest dev versions for a while now (as in several months of dev builds); I just haven't taken the time to post and mention it.
Thanks for your hard work on this incredible gui!
HybridDebugOutput.zip (Size: 112,73 KB / Downloads: 2)
Posts: 12.185
Threads: 66
Joined: May 2017
04.12.2025, 20:39
(This post was last modified: 04.12.2025, 20:57 by Selur.)
For the input ffmpeg reports:
smpte170m/smpte170m/bt709,
mkvmerge reports:
"color_matrix_coefficients": 6, <> SMTPE170M
"color_primaries": 6, <> SMTPE170M
"color_transfer_characteristics": 1, <> ITU-R BT.709
mediainfo reports:
colour_range_Source : Container
Color primaries : BT.601 NTSC
colour_primaries_Source : Container
Transfer characteristics : BT.709
transfer_characteristics_Source : Container
Matrix coefficients : BT.601
matrix_coefficients_Source : Container
coder_type : Range Coder
Hybrid assumed:
ColorMatrix: bt601 <> smtpe170M <> bt470m <= here is the problem, somewhere it's assumed that these are identical
"C:\Users\redacted\Documents\Programs\Hybrid\64bit\ffmpeg.exe" -y -noautorotate -nostdin -threads 8 -color_primaries bt470m -color_trc bt709 -colorspace bt470bg -color_range tv -f yuv4mpegpipe -i - -an -sn -color_primaries bt470m -color_trc bt709 -colorspace bt470bg -color_range tv -pix_fmt yuv422p10le -strict -1 -fps_mode auto -r 30000/1001 -vcodec prores_ks -profile:v 3 -vtag apch -bsf:v prores_metadata=color_primaries=smpte170m:color_trc=bt709:colorspace=smpte170m -metadata encoding_tool="Hybrid 2025.11.22.1" -aspect 20:15 -f mov "C:\Users\redacted\AppData\Local\Temp\2011177-1-1-pass3_1_2025-12-03@13_14_16_6310_03.mov"
"-bsf:v ..." sets the tags in the stream.
"-color_primaries bt470m -color_trc bt709 -colorspace bt470bg" sets the tags on the container.
Following what you posted, MediaInfo reports fpr the result:
colour_primaries_Original : BT.601 NTSC
matrix_coefficients_Original : BT.601
for the stream
Color primaries : BT.470 System M
Matrix coefficients : BT.470 System B/G
for the container
and
Transfer characteristics : BT.709
for both the stream and the container. ('original' is only mentioned if stream and container differ)
I'll try to some testing over the weekend. Not sure how I will handle it.
Cu Selur
ps.: if you can share a small sample of the source that would help to reproduce and trying to fix the problem.
----
Dev versions are in the 'experimental'-folder of my GoogleDrive, which is linked on the download page.
Posts: 12.185
Threads: 66
Joined: May 2017
SMTPE170M and BT.601 (NTSC/PAL) all use: Y = 0.299 R + 0.587 G + 0.114 B so the whole thing is more a cosmetic issue.
But I agree the output signaling should be consistent for container and stream.
=> uploaded a new dev version, try whether that one fixes the problem for you.
Cu Selur
----
Dev versions are in the 'experimental'-folder of my GoogleDrive, which is linked on the download page.
Posts: 4
Threads: 1
Joined: Dec 2025
The color signaling looks to be fixed according to the screenshot, thanks for such a quick turnaround!
but now I'm running into an error message about fps when loading the same file:
HybridDebugOutput.zip (Size: 60,04 KB / Downloads: 2)
Posts: 12.185
Threads: 66
Joined: May 2017
5 hours ago
(This post was last modified: 5 hours ago by Selur.)
Looking at the script:
# Imports
import vapoursynth as vs
# getting Vapoursynth core
import ctypes
import sys
import os
core = vs.core
# Import scripts folder
scriptPath = 'C:/Users/redacted/Documents/Programs/Hybrid/64bit/vsscripts'
sys.path.insert(0, os.path.abspath(scriptPath))
# Loading Support Files
Dllref = ctypes.windll.LoadLibrary("C:/Users/redacted/Documents/Programs/Hybrid/64bit/vsfilters/Support/libfftw3f-3.dll")
# loading plugins
core.std.LoadPlugin(path="C:/Users/redacted/Documents/Programs/Hybrid/64bit/vsfilters/GrainFilter/AddGrain/AddGrain.dll")
core.std.LoadPlugin(path="C:/Users/redacted/Documents/Programs/Hybrid/64bit/vsfilters/DenoiseFilter/NEO_FFT3DFilter/neo-fft3d.dll")
core.std.LoadPlugin(path="C:/Users/redacted/Documents/Programs/Hybrid/64bit/vsfilters/DenoiseFilter/DFTTest/DFTTest.dll")
core.std.LoadPlugin(path="C:/Users/redacted/Documents/Programs/Hybrid/64bit/vsfilters/Support/EEDI3m.dll") # vsQTGMC
core.std.LoadPlugin(path="C:/Users/redacted/Documents/Programs/Hybrid/64bit/vsfilters/ResizeFilter/nnedi3/vsznedi3.dll")
core.std.LoadPlugin(path="C:/Users/redacted/Documents/Programs/Hybrid/64bit/vsfilters/Support/libmvtools.dll")
core.std.LoadPlugin(path="C:/Users/redacted/Documents/Programs/Hybrid/64bit/vsfilters/Support/fmtconv.dll")
core.std.LoadPlugin(path="C:/Users/redacted/Documents/Programs/Hybrid/64bit/vsfilters/DeinterlaceFilter/Bwdif/Bwdif.dll")
core.std.LoadPlugin(path="C:/Users/redacted/Documents/Programs/Hybrid/64bit/vsfilters/Support/libllvmexpr.dll")
core.std.LoadPlugin(path="C:/Users/redacted/Documents/Programs/Hybrid/64bit/vsfilters/DenoiseFilter/ZSmooth/zsmooth.dll")
core.std.LoadPlugin(path="C:/Users/redacted/Documents/Programs/Hybrid/64bit/vsfilters/SourceFilter/LSmashSource/LSMASHSource.dll")
# Import scripts
import qtgmc
import validate
# Source: 'C:\Users\redacted\Videos\Example\2011177-1-1-pass3.mkv'
# Current color space: YUV422P10, bit depth: 10, resolution: 720x486, frame rate: 29.97fps, scanorder: bottom field first, yuv luminance scale: limited, matrix: 470bg, transfer: bt.709, primaries: bt.601 ntsc, format: FFV1
# Loading 'C:\Users\redacted\Videos\Example\2011177-1-1-pass3.mkvÄ using LWLibavSource
clip = core.lsmas.LWLibavSource(source="C:/Users/redacted/Videos/Example/2011177-1-1-pass3.mkv", format="YUV422P10", stream_index=0, cache=0, fpsnum=30000, fpsden=1001, prefer_hw=0)
frame = clip.get_frame(0)
# setting color matrix to 470bg.
clip = core.std.SetFrameProps(clip, _Matrix=vs.MATRIX_BT470_BG)
# setting color transfer (vs.TRANSFER_BT709), if it is not set.
if validate.transferIsInvalid(clip):
clip = core.std.SetFrameProps(clip=clip, _Transfer=vs.TRANSFER_BT709)
# setting color primaries info (to vs.PRIMARIES_BT470_BG), if it is not set.
if validate.primariesIsInvalid(clip):
clip = core.std.SetFrameProps(clip=clip, _Primaries=vs.PRIMARIES_BT470_BG)
# setting color range to TV (limited) range.
clip = core.std.SetFrameProps(clip=clip, _ColorRange=vs.RANGE_LIMITED)
# making sure frame rate is set to 29.97fps
clip = core.std.AssumeFPS(clip=clip, fpsnum=30000, fpsden=1001)
# making sure the detected scan type is set (detected: bottom field first)
clip = core.std.SetFrameProps(clip=clip, _FieldBased=vs.FIELD_BOTTOM) # scan type: bottom field first
clip = core.std.AddBorders(clip=clip, left=0, right=0, top=0, bottom=2) # add borders to archive mod 4 (vsQTGMC) - 720x488
# Deinterlacing using QTGMC
clip = qtgmc.QTGMC(Input=clip, Preset="Slower", InputType=0, TFF=False, TR2=0, Sharpness=0.1, SourceMatch=2, Lossless=2) # new fps: 29.97
clip = core.std.Crop(clip=clip, left=0, right=0, top=0, bottom=2) # removing added borders from mod requirement (vsQTGMC) - 720x486
# Making sure content is preceived as frame based
clip = core.std.SetFrameProps(clip=clip, _FieldBased=vs.FIELD_PROGRESSIVE) # scan type: progressive
clip = clip[::2] # selecting previously even frames, new fps: 14.985
# Resizing using 9 - lanczos
clip = core.fmtc.resample(clip, kernel="lanczos", w=720, h=480, interlaced=False, interlacedd=False) # resolution 720x480 before YUV422P10 after YUV422P16
# adjusting output color from YUV422P16 to YUV422P10 for ProResModel
clip = core.resize.Bicubic(clip=clip, format=vs.YUV422P10, dither_type="error_diffusion")
# set output frame rate to 14.985fps (progressive)
clip = core.std.AssumeFPS(clip=clip, fpsnum=15000, fpsden=1001)
# output
clip.set_output()
# script was created by Hybrid 2025.12.05.1
Hmm,.. I can't reproduce this.
I get:
# Imports
import vapoursynth as vs
# getting Vapoursynth core
import ctypes
import sys
import os
core = vs.core
# Limit frame cache to 48449MB
core.max_cache_size = 48449
# Import scripts folder
scriptPath = 'F:/Hybrid/64bit/vsscripts'
sys.path.insert(0, os.path.abspath(scriptPath))
# Loading Support Files
Dllref = ctypes.windll.LoadLibrary("F:/Hybrid/64bit/vsfilters/Support/libfftw3f-3.dll")
# loading plugins
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/GrainFilter/AddGrain/AddGrain.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DenoiseFilter/NEO_FFT3DFilter/neo-fft3d.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DenoiseFilter/DFTTest/DFTTest.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/EEDI3m_opencl.dll") # vsQTGMC
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/ResizeFilter/nnedi3/libsneedif.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/libmvtools.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/fmtconv.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DeinterlaceFilter/Bwdif/Bwdif.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/akarin.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DenoiseFilter/ZSmooth/zsmooth.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/SourceFilter/BestSource/BestSource.dll")
# Import scripts
import qtgmc
import validate
# Source: 'G:\Output\test_new.mkv'
# Current color space: YUV420P10, bit depth: 10, resolution: 720x486, frame rate: 29.97fps, scanorder: top field first, yuv luminance scale: limited, matrix: 470bg, format: AV1
# Loading 'G:\Output\test_new.mkv' using BestSource
clip = core.bs.VideoSource(source="G:/Output/test_new.mkv", cachepath="J:/tmp/test_new_bestSource", track=0, hwdevice="opencl")
frame = clip.get_frame(0)
# setting color matrix to 470bg.
clip = core.std.SetFrameProps(clip, _Matrix=vs.MATRIX_BT470_BG)
# setting color transfer (vs.TRANSFER_BT601), if it is not set.
if validate.transferIsInvalid(clip):
clip = core.std.SetFrameProps(clip=clip, _Transfer=vs.TRANSFER_BT601)
# setting color primaries info (to vs.PRIMARIES_BT470_BG), if it is not set.
if validate.primariesIsInvalid(clip):
clip = core.std.SetFrameProps(clip=clip, _Primaries=vs.PRIMARIES_BT470_BG)
# setting color range to TV (limited) range.
clip = core.std.SetFrameProps(clip=clip, _ColorRange=vs.RANGE_LIMITED)
# making sure frame rate is set to 29.97fps
clip = core.std.AssumeFPS(clip=clip, fpsnum=30000, fpsden=1001)
# making sure the detected scan type is set (detected: top field first)
clip = core.std.SetFrameProps(clip=clip, _FieldBased=vs.FIELD_TOP) # scan type: top field first
clip = core.std.AddBorders(clip=clip, left=0, right=0, top=0, bottom=2) # add borders to archive mod 4 (vsQTGMC) - 720x488
# Deinterlacing using QTGMC
clip = qtgmc.QTGMC(clip, Preset="Fast", TFF=True, opencl=True) # new fps: 59.94
clip = core.std.Crop(clip=clip, left=0, right=0, top=0, bottom=2) # removing added borders from mod requirement (vsQTGMC) - 720x486
# Making sure content is preceived as frame based
clip = core.std.SetFrameProps(clip=clip, _FieldBased=vs.FIELD_PROGRESSIVE) # scan type: progressive
clip = clip[::2] # selecting previously even frames, new fps: 29.97
# Resizing using 10 - bicubic spline
clip = core.fmtc.resample(clip, kernel="spline16", w=720, h=480, interlaced=False, interlacedd=False) # resolution 720x480 before YUV420P10 after YUV420P16
# adjusting output color from YUV420P16 to YUV420P10 for NVEncModel
clip = core.resize.Bicubic(clip=clip, format=vs.YUV420P10, dither_type="error_diffusion")
# set output frame rate to 29.97fps (progressive)
clip = core.std.AssumeFPS(clip=clip, fpsnum=30000, fpsden=1001)
# output
clip.set_output()
# script was created by Hybrid 2025.12.05.1
For me, the output resolution is properly calculated and I'm using the same version of Hybrid.  (same with a bff source with that resolution)
=> I can't reproduce this
What are the steps you are using to get this?
Cu Selur
----
Dev versions are in the 'experimental'-folder of my GoogleDrive, which is linked on the download page.
Posts: 4
Threads: 1
Joined: Dec 2025
1. Changing codec to ProRes HQ accompanied with specified VUI
2. Deinterlace with QTGMC via Vapoursynth via these settings (no bob):
3. Resizing the height from 720x486 to 720x480 via Lanczos, while specifying the input par/sar as 9x10 and outputting to 8x9
4. Render
Nothing too fancy I don't think.
Posts: 12.185
Threads: 66
Joined: May 2017
4 hours ago
(This post was last modified: 4 hours ago by Selur.)
Ahhh,... I know where the problem is and when I introduced this a few days ago. (I did refactor some code and overlooked the fps adjustment inside the custom part,...)
=> fixing the code now
Cu Selur
----
Dev versions are in the 'experimental'-folder of my GoogleDrive, which is linked on the download page.
Posts: 12.185
Threads: 66
Joined: May 2017
Uploaded a new dev, which should fix this.
Cu Selur
----
Dev versions are in the 'experimental'-folder of my GoogleDrive, which is linked on the download page.
Posts: 4
Threads: 1
Joined: Dec 2025
Wonderful, both fixes are working as intended! Thanks so much Selur, you're incredible with the quick turnarounds!
Side note for discussion. I haven't looked around/researched into it, but have there been anything major changes to the rendering pipeline from VapourSynth itself within the past 6 months or so? I believe I've been experiencing what the user Wolf mentioned in this thread: https://forum.selur.net/thread-4180-post...l#pid27441 . I remember the Hybrid versions around May, like the one he mentioned (2025.05.18.2) were some of the last ones that were able to more quickly load and process the VsViewer (and subsequently get to the video encoding stage in the render process quicker). Since then, the viewer and render process still load, it just takes a much longer time now to prep the file for viewing and rendering. So, I'm assuming there was a change with something on Vapoursynth's end (not you) that has to do with the rendering. I've tried fresh installs of Hybrid (with previous versions completely removed). I've also installed it on fresh Windows builds of other hardware (AVX-512 supported i9-10940X, a Ryzen 5900X and a Threadripper 3960x). My current build has a 14900K, so I thought it may have been the P-core E-core situation. I tried keeping Hybrid 'in focus' as well as Process Lasso, but still got the same results just like when I tried the other machines. All of these machines were faster on that specific May build and the versions before, but only for the Vapoursynth stages (viewer and render step). The actual ffmpeg encoding/rendering speed is the same though, which is to be expected. It also doesn't seem to be single thread bound either. Task manager, and HWInfo don't show a single core pegged at 100% like it used to when trying to load the viewer. So that also makes me think it's Vapoursynth framework change. I also thought that having the input file on a 10Gbe connection to a NAS was causing the issue, but got the same result having it on a Gen4 NVME. This is well out of my knowledge base as you can tell, but I wanted to mention this to showcase that another person is also experiencing a similar issue. I presume Wolf thought that there was no 'Preview Window' since he or she didn't wait on the long loading process for it to eventually pop up.
It's not that big of a deal to me though since the rendering occurs overnight, and I'm never in that big of a hurry, but just wanted to thought provoke with you.
As an example, the input file I've used to troubleshoot with you was encoded as a 720x486 4:2:2 FFV1 (12 Slices and Level 3) and is about 27 minutes long. Once the file is added to the queue and has started processing, the audio .wav file was generated at 1:37pm in the local %temp% directory. The file didn't actually start encoding with ffmpeg until 1:49pm. So about 12 minutes in hang time for Vapoursynth to prep the file. This normally would've taken way less than that.
Ahh, nevermind. It potentially looks to be a change in LWLibavSource. When changing the source viewer to 'Prefer Best Source' ,it speeds it up dramatically, but still not quite to the same level as way before
Posts: 12.185
Threads: 66
Joined: May 2017
Didn't really change anything I'm aware of, which should really cause a slow-down.
Depending on the source and the source filter preferences, different source filters will behave differently.
Some allow to create the index file separately, others create it inside the RAM or on the file system during the start of the job.
Also note that indexing on files that are on a network share indexing can take more time depending on the source filter.
(during indexing, the whole file gets read)
After the indexing the actual decoding and processing of the script starts and if machine learning filters are used, engine files might need to get created.
One thing that change which might cause problems in regard of starting Hybrid itself or similar is that the Qt version was updated a few times in the last 6 month,...
Cu Selur
Ps.: In the dev versions, I sometimes change the defaults when testing stuff, so sometimes it might help jut to reset your settings.
PPs.: some times it might also be better to now enable gpu support in every filter, since that can lead to bottlenecks.
----
Dev versions are in the 'experimental'-folder of my GoogleDrive, which is linked on the download page.
|