Skip to content

Mikewando/IVTC-DN-plugin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IVTC DN VapourSynth Plugin

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.

Usage

Plugin Documentation

.. 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.

Example

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()

Project File Discussion

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',
}

Building

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.

Bundled Dependencies

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