This is a small plugin to perform Inverse Telecine (IVTC) of a VapourSynth clip based on an IVTC DN project file.
It is intended only for situations where automatic field matching produces undesirable results. For example if a source has production issues that have degraded individual fields.
Only constant rate field-based material is supported. Furthermore only one cycle is supported; 10 input fields will always yield 4 output frames.
.. function:: IVTC(clip clip, string projectfile[, bint rawproject=False, clip linedoubled=None])
:module: ivtcdn
Will IVTC the given clip based on the actions described in the projectfile.
Parameters:
clip
Input clip. Fields should already be separated (e.g. with `std.SeparateFields()`).
projectfile
The path to the IVTC DN project file.
rawproject
The projectfile arugment contains decompressed json contents of a project file rather than a path to the project file. This is mostly intended for internal use by the IVTC DN GUI tool.
linedoubled
By default if a single field is selected for an output frame the selected field will be naively doubled to match the height of other output frames. If more sophisticated line doubling is desirable this option can be used to provide a clip which will be used to substitute such frames instead.
import vapousynth as vs
import havsfunc as haf
clip = vs.core.d2v.Source('example.d2v')
qtgmc = haf.QTGMC(clip, preset='Fast')
clip = clip.std.SeparateFields()
clip = clip.ivtcdn.IVTC('project.ivtc', linedoubled=qtgmc)
clip.set_output()
This plugin is designed to be paired with the IVTC DN GUI tool, but it is certainly possible to use it independently if a project file with matching structure is used. The structure is not overly complicated so while this may not be a complete specification, it is hopefully sufficient for most purposes.
Broadly the project file is just a zlib compressed json file. The structure of the json object is currently:
{
"ivtc_actions": [0, ...], // An array of integers with one entry for every input field (see later definition)
"no_match_handling": { // A map of output_frame => action for output frames which should use non-default action if no input fields are matched
1234: "Next"
},
"no_match_handling_default": "Previous", // What to do if no match or specific handling was specified (default is "[Use ]Previous[ Frame]")
"extra_attributes": { // A map of output_frame => user-generated string, intended to be used for whatever additional processing scripts may want to do by processing the project outside of the plugin
1234: "Foo"
},
"project_garbage": { // Ignored by the plugin, and used only by GUI
"version": 1,
"active_cycle": 0,
"script_file": "/home/users/example/example.vpy",
"auto_reload": true,
"notes": ["A", ...],
"scene_changes": [],
"combed_detection": false,
"combed_threshold": 45
}
}
An example script to illustrate inspecting a project file:
import json
import zlib
with open('example.ivtc', 'rb') as project_file:
compressed_contents = project_file.read()
decompressed_contents = zlib.decompress(compressed_contents)
project = json.loads(decompressed_contents)
print(json.dumps(project['project_garbage'], indent=2))
The valid values for ivtc_actions
are:
{
# Normal matching
# If there are duplicates in a cycle the first occurrence will be used
0: 'Top Frame 0',
1: 'Bottom Frame 0',
2: 'Top Frame 1',
3: 'Bottom Frame 1',
4: 'Top Frame 2',
5: 'Bottom Frame 2',
6: 'Top Frame 3',
7: 'Bottom Frame 3',
# Field will be dropped
8: 'Drop',
# Allows first field of N+1th cycle to complete Nth cycle
# Necessary for sources which are edited after telecining
9: 'Complete Previous Cycle',
}
I haven't spent much time testing builds on different systems, so this section is sparse. Broadly most dependencies other than the VapourSynth SDK should be bundled, so hopefully if you are familiar with C++ builds you can build it.
meson setup build
meson compile -C build
# build/ivtcdn.dll should be created
Windows builds should be auto-generated by github actions, see https://github.com/Mikewando/IVTC-DN-plugin/actions.
Some dependencies are directly copied into the src/
directory from their respective projects. It is the author's understanding that this usage is compatible with the applicable licenses.
From nlohmann/json fetched 2022-05-15
json.hpp
From miniz fetched 2022-05-16
miniz.h
zip.h
zip.c
From gzip-hpp fetched 2022-05-16 with modifications
gzip/decompress.hpp