From 9d72390d3995203795892e3382469e48c85230f0 Mon Sep 17 00:00:00 2001 From: WyattBlue Date: Mon, 15 Jun 2026 07:32:15 -0400 Subject: [PATCH] Add more interpolation flags closes #2307 --- av/video/reformatter.pxd | 7 +++++++ av/video/reformatter.py | 15 ++++++++++++--- av/video/reformatter.pyi | 15 +++++++++++---- tests/test_videoframe.py | 7 +++++++ 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/av/video/reformatter.pxd b/av/video/reformatter.pxd index e68a70105..fe4b68db5 100644 --- a/av/video/reformatter.pxd +++ b/av/video/reformatter.pxd @@ -19,6 +19,13 @@ cdef extern from "libswscale/swscale.h" nogil: cdef int SWS_SINC cdef int SWS_LANCZOS cdef int SWS_SPLINE + cdef int SWS_PRINT_INFO + cdef int SWS_FULL_CHR_H_INT + cdef int SWS_FULL_CHR_H_INP + cdef int SWS_DIRECT_BGR + cdef int SWS_ACCURATE_RND + cdef int SWS_BITEXACT + cdef int SWS_ERROR_DIFFUSION cdef int SWS_CS_ITU709 cdef int SWS_CS_FCC cdef int SWS_CS_ITU601 diff --git a/av/video/reformatter.py b/av/video/reformatter.py index 5778711d8..fbbef01b9 100644 --- a/av/video/reformatter.py +++ b/av/video/reformatter.py @@ -1,4 +1,4 @@ -from enum import IntEnum +from enum import IntEnum, IntFlag import cython import cython.cimports.libav as lib @@ -7,7 +7,7 @@ from cython.cimports.av.video.frame import alloc_video_frame -class Interpolation(IntEnum): +class Interpolation(IntFlag): FAST_BILINEAR: "Fast bilinear" = SWS_FAST_BILINEAR BILINEAR: "Bilinear" = SWS_BILINEAR BICUBIC: "2-tap cubic B-spline" = SWS_BICUBIC @@ -19,6 +19,13 @@ class Interpolation(IntEnum): SINC: "Unwindowed Sinc" = SWS_SINC LANCZOS: "3-tap sinc/sinc" = SWS_LANCZOS SPLINE: "Unwindowed natural cubic spline" = SWS_SPLINE + PRINT_INFO: "Emit verbose scaler info to the log" = SWS_PRINT_INFO + FULL_CHR_H_INT: "Full chroma interpolation" = SWS_FULL_CHR_H_INT + FULL_CHR_H_INP: "Full chroma input" = SWS_FULL_CHR_H_INP + DIRECT_BGR: "Direct BGR" = SWS_DIRECT_BGR + ACCURATE_RND: "Accurate rounding" = SWS_ACCURATE_RND + BITEXACT: "Bit-exact output" = SWS_BITEXACT + ERROR_DIFFUSION: "Error diffusion dither" = SWS_ERROR_DIFFUSION class Colorspace(IntEnum): @@ -182,7 +189,9 @@ def reformat( :type src_colorspace: :class:`Colorspace` or ``str`` :param dst_colorspace: Desired colorspace, or ``None`` for the frame colorspace. :type dst_colorspace: :class:`Colorspace` or ``str`` - :param interpolation: The interpolation method to use, or ``None`` for ``BILINEAR``. + :param interpolation: The scaling algorithm to use, or ``None`` for ``BILINEAR``. + Option flags such as ``ACCURATE_RND`` or ``BITEXACT`` may be combined with + the algorithm using ``|``, e.g. ``Interpolation.BILINEAR | Interpolation.ACCURATE_RND``. :type interpolation: :class:`Interpolation` or ``str`` :param src_color_range: Current color range, or ``None`` for the ``UNSPECIFIED``. :type src_color_range: :class:`ColorRange` or ``str`` diff --git a/av/video/reformatter.pyi b/av/video/reformatter.pyi index c9071df49..30508a32b 100644 --- a/av/video/reformatter.pyi +++ b/av/video/reformatter.pyi @@ -1,10 +1,10 @@ -from enum import IntEnum +from enum import IntEnum, IntFlag from typing import cast from .frame import VideoFrame -class Interpolation(IntEnum): - FAST_BILINEAER = cast(int, ...) +class Interpolation(IntFlag): + FAST_BILINEAR = cast(int, ...) BILINEAR = cast(int, ...) BICUBIC = cast(int, ...) X = cast(int, ...) @@ -15,6 +15,13 @@ class Interpolation(IntEnum): SINC = cast(int, ...) LANCZOS = cast(int, ...) SPLINE = cast(int, ...) + PRINT_INFO = cast(int, ...) + FULL_CHR_H_INT = cast(int, ...) + FULL_CHR_H_INP = cast(int, ...) + DIRECT_BGR = cast(int, ...) + ACCURATE_RND = cast(int, ...) + BITEXACT = cast(int, ...) + ERROR_DIFFUSION = cast(int, ...) class Colorspace(IntEnum): ITU709 = cast(int, ...) @@ -80,7 +87,7 @@ class VideoReformatter: format: str | None = None, src_colorspace: int | None = None, dst_colorspace: int | None = None, - interpolation: int | str | None = None, + interpolation: Interpolation | int | str | None = None, src_color_range: int | str | None = None, dst_color_range: int | str | None = None, dst_color_trc: int | ColorTrc | None = None, diff --git a/tests/test_videoframe.py b/tests/test_videoframe.py index 826a13c5d..acd3f53ab 100644 --- a/tests/test_videoframe.py +++ b/tests/test_videoframe.py @@ -155,6 +155,13 @@ def test_interpolation() -> None: ) assert img.width == 200 and img.height == 100 + # Option flags can be combined with the scaling algorithm. + combined = Interpolation.BILINEAR | Interpolation.ACCURATE_RND + assert isinstance(combined, Interpolation) + assert combined & Interpolation.ACCURATE_RND + img = frame.reformat(width=200, height=100, interpolation=combined) + assert img.width == 200 and img.height == 100 + def test_basic_to_ndarray() -> None: array = VideoFrame(640, 480, "rgb24").to_ndarray()