Skip to content

Commit

Permalink
Add a bob deinterlacer that uses core lib resizing.
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinTArthur committed Feb 24, 2022
1 parent 2c41ecd commit 98dc349
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
41 changes: 41 additions & 0 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,50 @@ Just VapourSynth.
Functions
---------
.. autofunction:: vsfieldkit.assume_bff(clip: VideoNode) -> VideoNode

.. autofunction:: vsfieldkit.assume_progressive(clip: VideoNode) -> VideoNode

.. autofunction:: vsfieldkit.assume_tff(clip: VideoNode) -> VideoNode

.. function:: vsfieldkit.bob( \
clip: VideoNode, \
tff: Optional[bool] = None, \
keep_field_property: bool = True, \
kernel: Callable = core.resize.Spline36, \
dither_type: str = 'random' \
) -> VideoNode

A simple bob deinterlacer. Returns a clip of progressive frames, each
consisting of a field from the original interlaced clip in order of its
original capture. As interlaced fields have half the resolution of a given
moment, the new frames are stretched up to the original clip's height.

This is similar to :py:func:`havsfunc.Bob` except it uses VapourSynth's
standard resizing/dithering features instead of those from the 3rd party
fmtconv plugin.

:param VideoNode clip: Video with interlaced frames to bob into
the resulting clip.

:param bool tff:
Specifies the field order to assume when scanning progressive footage
or clips without field order marking. ``True`` assumes top-field-first.
``False`` for bottom-field-first.

:param typing.Callable kernel:
Resizing/resampling function from vapoursynth.core.resize to use to
stretch the fields to the target frame height. Defaults to
:py:func:`resize.Spline36`.

:param str dither_type:
If video is processed at a higher bit depth internally before being
returned to an original depth of less than 16 bits per plane, this
dithering method will be used to avoid banding and other unnatural
artifacts caused by rounding at low bit rate.


.. autofunction:: vsfieldkit.double(clip: VideoNode) -> VideoNode

.. function:: vsfieldkit.group_by_combed( \
clip: VideoNode \
) -> Iterator[Tuple[Union[bool, None], VideoNode]]
Expand Down
1 change: 1 addition & 0 deletions vsfieldkit/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from vsfieldkit.deinterlacing import bob
from vsfieldkit.scanning import scan_interlaced
from vsfieldkit.types import (ChromaSubsampleScanning,
InterlacedScanPostProcessor)
Expand Down
31 changes: 31 additions & 0 deletions vsfieldkit/deinterlacing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from typing import Callable, Optional

from vapoursynth import VideoNode, core

from vsfieldkit.util import convert_format_if_needed


def bob(
clip: VideoNode,
tff: Optional[bool] = None,
keep_field_property: bool = True,
kernel: Callable = core.resize.Spline36,
dither_type: str = 'random'
) -> VideoNode:
"""Returns a clip of progressive frames, each consisting of a field from
the original interlaced clip in order of its original capture.
As interlaced fields have half the resolution of a given moment, the new
frames are stretched up to the original clip's height.
"""
as_fields = clip.std.SeparateFields(tff=tff)
stretched = convert_format_if_needed(
as_fields,
height=clip.height,
kernel=kernel,
dither_type=dither_type
)
if keep_field_property:
return stretched

return stretched.std.RemoveFrameProps(('_Field',))

0 comments on commit 98dc349

Please sign in to comment.