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: VSFunction | None = vinverse,
    **kwargs: Any
) -> VideoNode

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

    (VSFunction | None, default: vinverse ) –

    Optional post processing decomber after deblending and before pattern matching.

Returns:

  • VideoNode

    Deblended clip.

Source code
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def deblend(
    clip: vs.VideoNode, fieldmatched: vs.VideoNode | None = None, decomber: VSFunction | None = vinverse, **kwargs: Any
) -> vs.VideoNode:
    """
    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 | tuple[VideoNode, VideoNode],
    fieldmatched: VideoNode | None = None,
) -> VideoNode

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

Parameters:

  • bobbed

    (VideoNode | tuple[VideoNode, VideoNode]) –

    Bobbed source or a tuple of even/odd fields.

  • fieldmatched

    (VideoNode | None, default: None ) –

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

Returns:

  • VideoNode

    Deblended clip.

Source code
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
def deblend_bob(
    bobbed: vs.VideoNode | tuple[vs.VideoNode, vs.VideoNode], fieldmatched: vs.VideoNode | None = None
) -> vs.VideoNode:
    """
    Stronger version of `deblend` that uses a bobbed clip to deblend. Adopted from jvsfunc.

    :param bobbed:          Bobbed source or a tuple of even/odd fields.
    :param fieldmatched:    Source after field matching, must have field=3 and possibly low cthresh.

    :return: Deblended clip.
    """

    if isinstance(bobbed, tuple):
        bob0, bob1 = bobbed
    else:
        bob0, bob1 = bobbed.std.SelectEvery(2, 0), bobbed.std.SelectEvery(2, 1)

    ab0, bc0, c0 = shift_clip_multi(bob0, (0, 2))
    bc1, ab1, a1 = shift_clip_multi(bob1)

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

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:

  • VideoNode

    Deblended clip with fixed blended keyframes.

Source code
110
111
112
113
114
115
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
def deblend_fix_kf(deblended: vs.VideoNode, fieldmatched: vs.VideoNode) -> vs.VideoNode:
    """
    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.
    """

    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 deblended.std.FrameEval(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 deblended.std.FrameEval(_keyframe_fix, prop_srcs)

deblending_helper

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

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:

  • VideoNode

    Deblended clip.

Source code
20
21
22
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
def deblending_helper(deblended: vs.VideoNode, fieldmatched: vs.VideoNode, length: int = 5) -> vs.VideoNode:
    """
    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.
    """
    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 fieldmatched.std.FrameEval(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 fieldmatched.std.FrameEval(_deblend_eval, prop_srcs)