View Full Version : vs-jetpack QTempGaussMC: The definitive version of QTGMC
orchid
9th August 2026, 12:26
QTempGaussMC
Links & Documentation
GitHub Repository: Jaded-Encoding-Thaumaturgy/vs-jetpack (https://github.com/Jaded-Encoding-Thaumaturgy/vs-jetpack)
Documentation: vs-jetpack API Docs (https://jaded-encoding-thaumaturgy.github.io/vs-jetpack/api/vsdeinterlace/qtgmc/)
Usage Guide (WIP): JET Encoding Guide (https://jaded-encoding-thaumaturgy.github.io/JET-guide/master/filtering/situational/qtgmc/)
Settings mapping: AVS/havsfunc -> vs-jetpack (https://gist.github.com/emotion3459/5229aac20eabb63e7f50e55d5e96fb02)
Migration Guide coming soon.
Overview
vs-jetpack QTempGaussMC is NOT just another fork.
While there are numerous forks based on the original AviSynth QTGMC (realfinder, Dogway, DTL, etc.), and 1:1 ports to VapourSynth (havsfunc, Selur)—this version was rebuilt entirely from scratch in modern, idiomatic Python.
No code is shared with prior implementations; the only resemblance is the underlying core algorithm.
Why remake QTGMC?
For years, QTGMC has remained an "unmaintainable black box," whose legacy implementations suffered from several fundamental issues:
Confusing, monolithic, and messy codebases
Numerous unfixed bugs across various forks
Pervasive "magic numbers" and undocumented constants
Severe lack of configurability due to many hardcoded internal parameters
Unnecessary performance overhead (far slower than it needs to be)
Every single aspect of the original algorithm was researched, understood, and reimplemented to solve these issues.
Key Changes & Improvements
Improvements to Performance and Accuracy
Heavily optimized code, resulting in massive speedups (typically yielding 2x to 3x+ performance gains compared to equivalent settings in all legacy versions).
Extensive quality improvements and fixes across the entire processing chain.
Correct handling of higher bit-depth inputs after fixing numerous bit-depth scaling errors present in all legacy versions.
High Modularity and Configurability
Underlying deinterlacers and denoisers are now fully configurable, allowing users to supply custom filters instead of being locked into standard defaults.
All arbitrary parameter limits have been removed. In particular, TR (temporal radius) settings, erosion distance, and more are now uncapped.
Parameters passed to MVTools functions are fully exposed alongside an advanced preset system, improving ease of use without sacrificing motion estimation fine-tuning.
Every previously hardcoded setting is now fully user-configurable.
Carefully Thought-out API Design with Greatly Improved Usability
Replaced obscure numeric arguments with descriptive Enums and intuitively categorized settings.
Grouped parameters by processing stage and exposed them using modern idiomatic Python APIs.
Each processing mode (Progressive, Repair, Interlace) now has dedicated callable methods instead of relying on obscure parameters.
Default parameters have been carefully fine-tuned, making the legacy preset system unnecessary and requiring minimal code to set up a fast and high-quality deinterlacing script.
All redundant, low-quality, or non-functional settings have been pruned, and undocumented "magic numbers" have been completely eliminated.
A single object can be initialized and reused across multiple clips, eliminating the need to copy-paste massive function calls in complex scripts.
Selur
9th August 2026, 13:41
Congratulation figuring this out.
Every single aspect of the original algorithm was researched, understood, and reimplemented to solve these issues.
Nice, is there some human understandable documentation about that?
The API documentation (https://jaded-encoding-thaumaturgy.github.io/vs-jetpack/api/vsdeinterlace/qtgmc/)doesn't really help to understand what is happening and why.
Refer to the AviSynth QTGMC documentation and the havsfunc implementation for detailed explanations of the underlying algorithm.
... okay ...
To be frank from a software engineering standpoint it looks nice, everything split, configurable, but from a user perspective this seems even more confusing than before.
And instead of a mapping (https://gist.github.com/Ichunjo/76c96f1130c9e9f972de956f40571e54) adding a wrapper to accept the old syntax would have been preferable.
Improvements to Performance and Accuracy
is that documented somewhere in more details?
Default parameters have been carefully fine-tuned, making the legacy preset system unnecessary and requiring minimal code to set up a fast and high-quality deinterlacing script.
What are these defaults?
=> looking forward for someone to figure out how to actually use this. (especially when not using an llm,...)
Cu Selur
orchid
9th August 2026, 15:47
Nice, is there some human understandable documentation about that?
The API documentationdoesn't really help to understand what is happening and why.
Edit: The api documentation now fully covers this.
... okay ...
Edit: The api documentation now fully replaces havsfunc comments / avs wiki docs.
but from a user perspective this seems even more confusing than before.
Edit: The usage guide now covers how to use it, and showcases it's ease-of-use & quality of life features.
And instead of a mapping adding a wrapper to accept the old syntax would have been preferable.
Not possible. The design is too different. A wrapper with the old syntax also just re-introduces one of the major problems this rewrite is meant to solve.
The entire point of the new syntax is to make it obvious what part of QTGMC's processing a setting belongs to. The old syntax obscured this and as such, was nearly impossible to fine-tune to an acceptable degree.
This flaw was part of why the "preset" system made sense back then, but now with the properly categorized settings and fine-tuned defaults, theres really no longer any need for settings presets.
is that documented somewhere in more details?
Only in code (soon to be documented).
What are these defaults?
Edit: The api documentation covers the new defaults, you can compare them yourself for now (the differences will be documented in more detail soon)
looking forward for someone to figure out how to actually use this. (especially when not using an llm,...)
The API documentation has usage examples, and there is a more detailed usage guide linked.
Myrsloik
9th August 2026, 16:38
Reference documentation is not the same as a good getting started guide. Preferably complete with a porting from other QTGMC guide. Even AI slop would be preferable to nothing.
"I beg to differ. Making QTGMC easy to use was a primary goal."
I have no clue how to use it. So I double beg to double differ. You better pull out a triple nope card if you want to try to stop me.
Columbo
9th August 2026, 18:30
Anything announced with "The definitive..." is already suspect.
orchid
9th August 2026, 18:44
Anything announced with "The definitive..." is already suspect.
What else would you consider it if not definitive, seeing as every aspect of the script has been improved through fixes/quality enhancements/performance improvements?
Frankly, this is a rude response and dismissive of how many hours it took to achieve this.
I will look into creating more examples/usage guide info later. I'm a developer, not a guide writer, so its not my strong suite.
Selur
9th August 2026, 18:48
@orchid: how to use i.e.
vs_deepdeinterlace.DDD(clip, tff=True, tta=False, device="cuda", fp16=True)
for the bobbing?
Could I use:
basic_bobber=vs_deepdeinterlace.DDD(tff=True, tta=False, device="cuda", fp16=True),
?
What color formats are supported? I suspect 8-16bit integer YUV with at least 4:2:0, 4:2:2 and 4:4:4 color sampling.
Cu Selur
orchid
9th August 2026, 19:12
(totally untested)
@orchid: how to use i.e.
vs_deepdeinterlace.DDD(clip, tff=True, tta=False, device="cuda", fp16=True)
for the bobbing?
Could I use:
basic_bobber=vs_deepdeinterlace.DDD(tff=True, tta=False, device="cuda", fp16=True),
?
Not quite. The bobbers expect a *Bobber* class (see: https://jaded-encoding-thaumaturgy.github.io/vs-jetpack/api/vskernels/abstract/base/#vskernels.abstract.base.Bobber)
So if you want to pass your own deinterlacer to this you can refer to: https://github.com/Jaded-Encoding-Thaumaturgy/vs-jetpack/blob/main/vsaa/deinterlacers.py for pre-made options.
If you want to make your own you will have to wrap "DDD" in a Bobber class and provide a .bob() method for it.
What color formats are supported? I suspect 8-16bit integer YUV with at least 4:2:0, 4:2:2 and 4:4:4 color sampling.
GRAY and YUV at 8-16 bit integer or 32 bit float. No subsampling restrictions.
LightArrowsEXE
9th August 2026, 19:18
RE: matching old presets, the whole idea behind dropping support for those and not adding our own based on them was because on top of being rather difficult to properly follow, they also made a lot of questionable quality decisions. A quick example of that would be the old Placebo profile setting SLSad to 3 (https://github.com/emotion3459/havsfunc/blob/qtgmc_old/havsfunc/havsfunc.py#L489). This severely increases the sharpening allowed by QTGMC, which very quickly leads to excessive oversharpening (which is a problem even at `SLSad=1`). The Placebo preset similarly reduces the "quality" of a lot of other settings, and this is carried through the entire hierarchy. The default parameters for the vsjetpack version is already set to a high quality preset without negatively impacting the output quality the way the "highest quality" preset of yore does.
If you *really* want to match the old parameters, there's a gist of mappings between havsfunc's and JET's version here (https://gist.github.com/Ichunjo/76c96f1130c9e9f972de956f40571e54), but it's better to not blindly copy parameters over.
Reference documentation is not the same as a good getting started guide. Preferably complete with a porting from other QTGMC guide. Even AI slop would be preferable to nothing.
This is more in the realm of something for the JET guide to implement imo, not the function's own documentation. If you want in-depth instructions for tuning something like QTGMC, then the current docstrings are already going above and beyond what you would typically expect to see in public APIs, and further elaboration should be delegated to an external document (see also: AVS wiki and forum threads).
"I beg to differ. Making QTGMC easy to use was a primary goal."
I have no clue how to use it. So I double beg to double differ. You better pull out a triple nope card if you want to try to stop me.
It's not at all dissimilar from typical Python builder classes. You initialise the class and call builder methods for whatever additional steps you need, and you call the final build method (in this case, `deinterlace`) to get your final clip. I think feigning a complete lack of understanding (or worse, not even attempting to understand before immediately writing it off) isn't productive.
ChaosKing
9th August 2026, 20:29
I think a couple examples which shows some of the qtgmc concepts and how to use it would really help. Give the user some 1-2 liners to start with.
_Al_
9th August 2026, 21:00
If you have coders expressing you, that is not easy to understand how things work, it is a red flag, I don't personally think, it is rude. Vapoursynth author deliberately makes everyhing simple as a calling a function with parameters. If not, It would be a hell to write a code to just deal with video. I think the whole vapoursynth is calling just one parameter as a class and that is resizer method within resize module. All Enums could be all called from vs module, if I'm not mistaken. Video guys are not coders. And going forward for sure not. And 99% vapoursynth users just copy/paste a function line from "other guy" and hunt for parameter values. They have ABSOLUTELY no idea what a class is, how to use it, what modules are, even has no idea how to use enums, not even remotely know mechanism how to use them, using proper import or how to chain modules: mainclass.module.other_module.enum. They have no idea if using "Bob" for example, that they have to call a different function, even perfectly preferable in Python.
People will use interfaces like Selur just layed out, and continue calling functions that someone else recommended for them. I doubt someone will start from scratch and using your proper python lines directly. It is very difficult, and folk cannot spend a weekend to figure out for them an "unknown "habit of coding.
So it will end up like that. Only a coder would really investigate and tweak parameters to come up with better code. Or AI could become that in-between party, just suggesting I want deinterlace with slight or harder denoise, do not sharp much, do it fast, etc. And it will spit up a code. Ok, slightly more sharp please,... etc.
So even if it is super as you say, that's totally awesome man, or if it is faster, again, vapoursynth rules! , you rule as well! but as of now, it needs that third, vip party, to deliver for a user. So if it is working overall better, it will still take off more slowly because voluntaries are needed, coders are needed in between. Lets do not expect a video guy starting to tweak a python qtgmc code to chase details. Dedicating explanation how to create scripts of all kinds would definitely clear things up. People would not start vapoursynth scripts on their own, because in vapoursynth documents, functions have no "core.std" preceding in them and for people it is a hard stop, script did not work, and go back to avisynth. :-) I was one of them! Postponed vapoursynth for a valuable of time because of exactly that. :-) . Even if an Error actually says that an attribute is missing could be totally useless for a non python user.
Thanks for a new deinterlacer!
Vapoursynth user does not equal to a python coder/user.
It is basically set up for AI, that is the positive, write everything in readable, effective python code but AI will find a proper code for an action. How far away are we from that? :-)
orchid
10th August 2026, 12:44
Alright, you've been heard loud and clear. I will write algorithm details, a usage guide, and a migration guide. I am a bit busy, so give me some time.
Adub
10th August 2026, 18:36
@orchid - thank you for all your hard work on reverse engineering the original algo + magic numbers etc. Also looking forward to the enhanced documentation, so thank you.
For those who are looking for basic examples of how someone may use this, here's a few examples of how I've used this in a few projects.
from vsdenoise import MVToolsPreset
from vsdeinterlace import QTempGaussMC
from vsaa import NNEDI3
clip = ...
# Basic deinterlace with defaults
deint = QTempGaussMC().deinterlace(clip)
# More advanced deinterlace with settings tuned for my clip
deint = (QTempGaussMC()
.analyze(preset=MVToolsPreset.HQ_SAD | dict(chroma=False), thscd=(300,51))
.basic(tr=1, bobber=NNEDI3(nsize=1, nns=1, gpu=True))
.source_match(mode=QTempGaussMC.SourceMatchMode.BASIC)
.deinterlace(clip))
orchid
11th August 2026, 08:07
A (WIP) usage guide has been added to the OP. Should be enough to get people started.
Now its even more definitive than before.
@Selur I would appreciate it if you removed the AI slop, its not anywhere close to correct. A proper migration guide will be made.
ChaosKing
11th August 2026, 11:04
The debugging feature for every filter step is very handy. Can't believe we only have this now in 2026.
And you already added mvutensils support, 2x speed gain: https://github.com/Jaded-Encoding-Thaumaturgy/vs-jetpack/pull/345
Great job!
With the new VS GPU 4.3 API this thing will deinterlace to the moon!
orchid
11th August 2026, 13:15
The debugging feature for every filter step is very handy. Can't believe we only have this now in 2026.
Well, I added this back in 2024 (if I recall correctly...), I just neglected to make a thread about my work till this year.
Selur
12th August 2026, 16:06
@Selur I would appreciate it if you removed the AI slop, its not anywhere close to correct. A proper migration guide will be made.
no, problem, I removed the text
Z2697
12th August 2026, 19:17
Not written by AI doesn't automatically make it non-slop
orchid
23rd August 2026, 04:10
A large code refactor has been done, improving readability, performance, and adding a few new features. The documentation has been completely rewritten, it is now even more detailed than the old avs wiki in many respects. The new documentation includes a high level overview of how every step of the algorithm works, usage examples, explanations for what purpose each individual setting serves and how tweaking it affects the output, clearly listed defaults, and more. Code comments for anything which isn't obvious were added as well.
Upcoming work will be making a more detailed settings mapping, with notes/migration details. A list of what features / improvements were added will eventually come as well (though that may take some time, it's a lengthy list...)
orchid
23rd August 2026, 04:20
My initial reply has been updated to reflect the status of the documentation, every critique brought up here has been resolved or is in the process of being resolved.
Selur
23rd August 2026, 06:23
I like the API doc with the high level documentation parts.
Looking at https://jaded-encoding-thaumaturgy.github.io/JET-guide/master/filtering/situational/qtgmc/.
I like:
the 'Basic Usage'-section.
the 'Reusing'-section.
the first 4 lines of the 'Configuring'-section.
Looking forward to the final version of the configuration documentation and the migration guide for users.
Cu Selur
orchid
23rd August 2026, 14:42
Looking forward to the final version of the configuration documentation and the migration guide for users.
What do you think is missing from the configuration documentation? So I know what to focus on.
Selur
23rd August 2026, 15:05
What do you think is missing from the configuration documentation?
For my personal taste:
Referring users to the api doc and docstrings is simply bad. (api doc without knowing what classes&co mean is just scaring folks away)
'Configuring' should expand bit by bit i.e. start with configure aspect xy not start with a huge block of code that folks will not understand
You write " There are two ways to pass settings to QTGMC. The first is to use the configuration methods for each of the individual stages:"
then you paste a block of code and basically say, "If you want to understand this, become a coder and read the api doc."
Then you go over to the second option. "The second way to pass settings is to pass all of them when constructing the QTempGaussMC method by prefixing each stage's parameter with the stage's name:"
You never named the stages, so this is confusion.
Maybe better start out with an overview and define some of the naming nomenclature you are planning to use.
In the intro you said there are several stages which can be grouped which are roughly these three ....
1. Create a naively bobbed and strongly temporally blurred clip to run motion analysis on.
2. Bob the input clip with a high-quality spatial deinterlacer like NNEDI3 or EEDI3.
3. Use the computed motion vectors to refine the spatially deinterlaced clip further.
now you assume the reader knows all the possible stages.
In general, it would be better to:
a. give more overview
b. explain stuff separately
A usage guide should give at least a rough overview and not explode.
Cu Selur
orchid
23rd August 2026, 15:25
Referring users to the api doc and docstrings is simply bad. (api doc without knowing what classes&co mean is just scaring folks away)
This is unavoidable to an extent, since the api docs explain a large amount of details in a human readable manner (i.e. not code details).
It would be somewhat pointless and troublesome to paste this into the usage guide, since duplicating documentation creates a large maintenance burden and opens the door for desynced documentation across the guide/api docs. So i'm not really sure what to do there.
Note taken on the other points, they will be resolved.
Selur
23rd August 2026, 18:42
Maybe the api isn't the right place for that documentation then? Maybe the API should reference the 'usage guide' and not the other way around.
PatchWorKs
24th August 2026, 14:42
Suggestion: involving teaching-droid (https://github.com/teaching-droid) - who "translated" QTGMC into vpp-RTGMC, aka High quality QTGMC deinterlacer with relaxed implementation for GPU, for all Rigaya's HW-encoders (https://github.com/rigaya) - would be interesting, IMHO.
ChaosKing
24th August 2026, 15:33
Almost obsolete with vapoursynth gpu api https://forum.doom9.org/showthread.php?t=187078
orchid
24th August 2026, 19:53
Suggestion: involving teaching-droid (https://github.com/teaching-droid) - who "translated" QTGMC into vpp-RTGMC, aka High quality QTGMC deinterlacer with relaxed implementation for GPU, for all Rigaya's HW-encoders (https://github.com/rigaya) - would be interesting, IMHO.
I don't understand what you're trying to suggest.
orchid
24th August 2026, 20:46
Maybe the api isn't the right place for that documentation then? Maybe the API should reference the 'usage guide' and not the other way around.
The human-readable details im talking about are notes about how the algorithm works, and what individual settings do. Thats more fit for an api reference than usage guide.
Anyway, I started working on a more comprehensive settings mapping. You can view it here (https://gist.github.com/emotion3459/5229aac20eabb63e7f50e55d5e96fb02).
I plan on creating a script to automatically convert a avs/havsfunc call into a vs-jetpack preset. No ETA on that though.
Q3CPMA
24th August 2026, 21:06
Thanks a lot for your efforts, I'm glad to see the Vapoursynth ecosystem picking up features and ease of use these last few years! Seems like once vs-jetpack stabilizes a bit (in a semver kind of way), it'll almost be a second stdlib for all vapoursynthers, from amateur to expert.
Selur
25th August 2026, 03:08
Anyway, I started working on a more comprehensive settings mapping.
That looks useful to me.
Selur
25th August 2026, 03:16
@PatchWorKs: imho a RTGMC for Vapoursynth only really makes sense if you write a separate filter (not just a script), which uses its own CUDA code, otherwise you would just add restrictions and simplifications to QTGMC.
So I doubt it would make sense to change the vs-jetpack implementation to make a similar mode for this.
orchid
25th August 2026, 15:41
--vpp-qtgmc: "Quartic Temporal Gaussian Motion Compensated"
Dogway: "Quasi Temporal Gauss Motion Compensation Plus"
lol, just fyi: I found the *original* QTGMC script posted by Vit in another forum (before it was ever released onto doom9). Back then, the name hadn't been abbreviated yet. The original post by Vit referred to the filter as "Quick TempGaussMC". The definitive meaning of the "Q" is "Quick".
I even put research effort into de-mystifying the name.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.