Skip to content

blending

Functions:

  • deblend

    Automatically deblends if normal field matching leaves 2 blends every 5 frames. Adopted from jvsfunc.

  • deblend_bob

    Stronger version of deblend that uses a bobbed clip to deblend. Adopted from jvsfunc.

  • deblend_fix_kf

    Should be used after deblend/_bob to fix scene changes. Adopted from jvsfunc.

  • deblending_helper

    Helper function to select a deblended clip pattern from a fieldmatched clip.

deblend

deblend(
    clip: VideoNode,
    fieldmatched: VideoNode | None = None,
    decomber: VSFunctionNoArgs[VideoNode, VideoNode] | None = vinverse,
    **kwargs: Any
) -> ConstantFormatVideoNode

Automatically deblends if normal field matching leaves 2 blends every 5 frames. Adopted from jvsfunc.

Parameters:

  • clip

    (VideoNode) –

    Input source to fieldmatching.

  • fieldmatched

    (VideoNode | None, default: None ) –

    Source after field matching, must have field=3 and possibly low cthresh.

  • decomber

    (VSFunctionNoArgs[VideoNode, VideoNode] | None, default: vinverse ) –

    Optional post processing decomber after deblending and before pattern matching.

Returns:

  • ConstantFormatVideoNode

    Deblended clip.

Source code
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
def deblend(
    clip: vs.VideoNode,
    fieldmatched: vs.VideoNode | None = None,
    decomber: VSFunctionNoArgs[vs.VideoNode, vs.VideoNode] | None = vinverse,
    **kwargs: Any,
) -> ConstantFormatVideoNode:
    """
    Automatically deblends if normal field matching leaves 2 blends every 5 frames. Adopted from jvsfunc.

    :param clip:             Input source to fieldmatching.
    :param fieldmatched:    Source after field matching, must have field=3 and possibly low cthresh.
    :param decomber:        Optional post processing decomber after deblending and before pattern matching.

    :return: Deblended clip.
    """

    deblended = norm_expr(shift_clip_multi(clip, (-1, 2)), 'z a 2 / - y x 2 / - +', func=deblend)

    if decomber:
        deblended = decomber(deblended, **kwargs)

    if fieldmatched:
        deblended = deblending_helper(fieldmatched, deblended)

    return join(fieldmatched or clip, deblended)

deblend_bob

deblend_bob(
    bobbed: VideoNode, fieldmatched: VideoNode | None = None
) -> ConstantFormatVideoNode

Stronger version of deblend that uses a bobbed clip to deblend. Adopted from jvsfunc.

Parameters:

  • bobbed

    (VideoNode) –

    Bobbed source.

  • fieldmatched

    (VideoNode | None, default: None ) –

    Source after field matching, must have field=3 and possibly low cthresh.

Returns:

  • ConstantFormatVideoNode

    Deblended clip.

Source code
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
def deblend_bob(bobbed: vs.VideoNode, fieldmatched: vs.VideoNode | None = None) -> ConstantFormatVideoNode:
    """
    Stronger version of `deblend` that uses a bobbed clip to deblend. Adopted from jvsfunc.

    :param bobbed:          Bobbed source.
    :param fieldmatched:    Source after field matching, must have field=3 and possibly low cthresh.

    :return: Deblended clip.
    """

    assert check_variable(bobbed, deblend_bob)

    ab0, bc0, c0 = shift_clip_multi(bobbed[::2], (0, 2))
    bc1, ab1, a1 = shift_clip_multi(bobbed[1::2])

    deblended = norm_expr([a1, ab1, ab0, bc1, bc0, c0], ('b', 'y x - z + b c - a + + 2 /'), func=deblend_bob)

    if fieldmatched:
        return deblending_helper(fieldmatched, deblended)

    return deblended

deblend_fix_kf

deblend_fix_kf(
    deblended: VideoNode, fieldmatched: VideoNode
) -> ConstantFormatVideoNode

Should be used after deblend/_bob to fix scene changes. Adopted from jvsfunc.

Parameters:

  • deblended

    (VideoNode) –

    Deblended clip.

  • fieldmatched

    (VideoNode) –

    Fieldmatched clip used to debled, must have field=3 and possibly low cthresh.

Returns:

  • ConstantFormatVideoNode

    Deblended clip with fixed blended keyframes.

Source code
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
def deblend_fix_kf(deblended: vs.VideoNode, fieldmatched: vs.VideoNode) -> ConstantFormatVideoNode:
    """
    Should be used after deblend/_bob to fix scene changes. Adopted from jvsfunc.

    :param deblended:       Deblended clip.
    :param fieldmatched:    Fieldmatched clip used to debled, must have field=3 and possibly low cthresh.

    :return: Deblended clip with fixed blended keyframes.
    """

    assert check_variable(deblended, deblend_fix_kf)

    shifted_clips = shift_clip_multi(deblended)
    prop_srcs = shift_clip_multi(fieldmatched, (0, 1))

    if complexpr_available:
        index_src = expr_func(
            prop_srcs, 'x._Combed x.VFMSceneChange and y.VFMSceneChange 2 0 ? 1 ?', vs.GRAY8
        )

        return core.std.FrameEval(deblended, lambda n, f: shifted_clips[f[0][0, 0]], index_src)

    def _keyframe_fix(n: int, f: list[vs.VideoFrame]) -> vs.VideoNode:
        keyfm = cast(tuple[int, int], (f[0].props.VFMSceneChange, f[1].props.VFMSceneChange))

        idx = 1
        if f[0].props._Combed == 1:
            if keyfm == (1, 0):
                idx = 0
            elif keyfm == (1, 1):
                idx = 2

        return shifted_clips[idx]

    return core.std.FrameEval(deblended, _keyframe_fix, prop_srcs)

deblending_helper

deblending_helper(
    deblended: VideoNode, fieldmatched: VideoNode, length: int = 5
) -> ConstantFormatVideoNode

Helper function to select a deblended clip pattern from a fieldmatched clip.

Parameters:

  • deblended

    (VideoNode) –

    Deblended clip.

  • fieldmatched

    (VideoNode) –

    Source after field matching, must have field=3 and possibly low cthresh.

  • length

    (int, default: 5 ) –

    Length of the pattern.

Returns:

  • ConstantFormatVideoNode

    Deblended clip.

Source code
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
def deblending_helper(deblended: vs.VideoNode, fieldmatched: vs.VideoNode, length: int = 5) -> ConstantFormatVideoNode:
    """
    Helper function to select a deblended clip pattern from a fieldmatched clip.

    :param deblended:       Deblended clip.
    :param fieldmatched:    Source after field matching, must have field=3 and possibly low cthresh.
    :param length:          Length of the pattern.

    :return: Deblended clip.
    """

    assert check_variable(deblended, deblending_helper)
    assert check_variable(fieldmatched, deblending_helper)
    check_ref_clip(fieldmatched, deblended, deblending_helper)

    inters = telecine_patterns(fieldmatched, deblended, length)
    inters += [shift_clip(inter, 1) for inter in inters]

    inters.insert(0, fieldmatched)

    prop_srcs = shift_clip_multi(fieldmatched, (0, 1))

    if complexpr_available:
        index_src = expr_func(
            prop_srcs, f'x._Combed N {length} % 1 + y._Combed {length} 0 ? + 0 ?', vs.GRAY8
        )

        return core.std.FrameEval(fieldmatched, lambda n, f: inters[f[0][0, 0]], index_src)

    def _deblend_eval(n: int, f: list[vs.VideoFrame]) -> vs.VideoNode:
        idx = 0

        if f[0].props._Combed == 1:
            idx += (n % length) + 1

            if f[1].props._Combed == 1:
                idx += length

        return inters[idx]

    return core.std.FrameEval(fieldmatched, _deblend_eval, prop_srcs)