Skip to content

Commit 98bb44d

Browse files
committed
Add Colorspace.BT2020 for BT.2020 YUV matrix conversion
1 parent fb43dfc commit 98bb44d

5 files changed

Lines changed: 27 additions & 0 deletions

File tree

‎CHANGELOG.rst‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Features:
4141
- Support ``yuv420p10le`` in ``VideoFrame.to_ndarray`` and ``VideoFrame.from_ndarray`` by :gh-user:`WyattBlue` (:issue:`1981`).
4242
- Add ``at`` parameter to ``Graph.push`` and ``Graph.vpush`` to push a frame to a single buffer source by index, for multi-input filters like ``overlay`` by :gh-user:`WyattBlue`.
4343
- ``find_best_pix_fmt_of_list`` now returns the loss as a ``PixFmtLoss`` ``enum.IntFlag`` instead of a plain ``int`` by :gh-user:`WyattBlue` (:issue:`2300`).
44+
- Add ``Colorspace.BT2020`` by :gh-user:`mark-oshea`.
4445

4546
Fixes:
4647

‎av/video/reformatter.pxd‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ cdef extern from "libswscale/swscale.h" nogil:
3333
cdef int SWS_CS_SMPTE170M
3434
cdef int SWS_CS_SMPTE240M
3535
cdef int SWS_CS_DEFAULT
36+
cdef int SWS_CS_BT2020
3637

3738
cdef SwsContext *sws_alloc_context()
3839
cdef void sws_free_context(SwsContext **ctx)

‎av/video/reformatter.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class Colorspace(IntEnum):
3636
SMPTE170M = SWS_CS_SMPTE170M
3737
SMPTE240M = SWS_CS_SMPTE240M
3838
DEFAULT = SWS_CS_DEFAULT
39+
BT2020 = SWS_CS_BT2020
3940
# Lowercase for b/c.
4041
itu709 = SWS_CS_ITU709
4142
fcc = SWS_CS_FCC
@@ -44,6 +45,7 @@ class Colorspace(IntEnum):
4445
smpte170m = SWS_CS_SMPTE170M
4546
smpte240m = SWS_CS_SMPTE240M
4647
default = SWS_CS_DEFAULT
48+
bt2020 = SWS_CS_BT2020
4749

4850

4951
class ColorRange(IntEnum):
@@ -146,6 +148,8 @@ def _set_frame_colorspace(
146148
frame.colorspace = lib.AVCOL_SPC_SMPTE170M
147149
elif colorspace == SWS_CS_SMPTE240M:
148150
frame.colorspace = lib.AVCOL_SPC_SMPTE240M
151+
elif colorspace == SWS_CS_BT2020:
152+
frame.colorspace = lib.AVCOL_SPC_BT2020_NCL
149153

150154

151155
@cython.final

‎av/video/reformatter.pyi‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@ class Colorspace(IntEnum):
3131
SMPTE170M = cast(int, ...)
3232
SMPTE240M = cast(int, ...)
3333
DEFAULT = cast(int, ...)
34+
BT2020 = cast(int, ...)
3435
itu709 = cast(int, ...)
3536
fcc = cast(int, ...)
3637
itu601 = cast(int, ...)
3738
itu624 = cast(int, ...)
3839
smpte170m = cast(int, ...)
3940
smpte240m = cast(int, ...)
4041
default = cast(int, ...)
42+
bt2020 = cast(int, ...)
4143

4244
class ColorRange(IntEnum):
4345
UNSPECIFIED = 0

‎tests/test_colorspace.py‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import av
2+
import pytest
23
from av.video.reformatter import (
34
ColorPrimaries,
45
ColorRange,
@@ -101,3 +102,21 @@ def test_reformat_preserves_color_primaries() -> None:
101102
frame.color_primaries = ColorPrimaries.BT709
102103
rgb = frame.reformat(format="rgb24")
103104
assert rgb.color_primaries == ColorPrimaries.BT709
105+
106+
107+
@pytest.mark.parametrize(
108+
("colorspace", "expected"),
109+
[
110+
(Colorspace.ITU709, Colorspace.ITU709),
111+
(Colorspace.FCC, Colorspace.FCC),
112+
(Colorspace.ITU601, 6), # AVCOL_SPC_SMPTE170M
113+
(Colorspace.SMPTE240M, Colorspace.SMPTE240M),
114+
(Colorspace.BT2020, Colorspace.BT2020),
115+
],
116+
)
117+
def test_reformat_dst_colorspace_metadata(
118+
colorspace: Colorspace, expected: Colorspace | int
119+
) -> None:
120+
frame = av.VideoFrame(width=64, height=64, format="yuv420p")
121+
rgb = frame.reformat(format="rgb24", dst_colorspace=colorspace)
122+
assert rgb.colorspace == expected

0 commit comments

Comments
 (0)