Skip to content

Commit

Permalink
Add color_primaries, color_trc, colorspace
Browse files Browse the repository at this point in the history
  • Loading branch information
WyattBlue authored Mar 3, 2024
1 parent c47d01b commit 18bc34b
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 4 deletions.
4 changes: 4 additions & 0 deletions av/video/codeccontext.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class VideoCodecContext(CodecContext):
coded_width: int
coded_height: int
color_range: int
color_primaries: int
color_trc: int
colorspace: int

type: Literal["video"]
def encode(self, frame: VideoFrame | None = None) -> list[Packet]: ...
def encode_lazy(self, frame: VideoFrame | None = None) -> Iterator[Packet]: ...
Expand Down
58 changes: 57 additions & 1 deletion av/video/codeccontext.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -177,29 +177,85 @@ cdef class VideoCodecContext(CodecContext):

@property
def has_b_frames(self):
"""
:type: bool
"""
return bool(self.ptr.has_b_frames)

@property
def coded_width(self):
"""
:type: int
"""
return self.ptr.coded_width

@property
def coded_height(self):
"""
:type: int
"""
return self.ptr.coded_height

@property
def color_range(self):
"""
Color range of context.
Describes the signal range of the colorspace.
Wraps :ffmpeg:`AVFrame.color_range`.
:type: int
"""
return self.ptr.color_range

@color_range.setter
def color_range(self, value):
self.ptr.color_range = value

@property
def color_primaries(self):
"""
Describes the RGB/XYZ matrix of the colorspace.
Wraps :ffmpeg:`AVFrame.color_primaries`.
:type: int
"""
return self.ptr.color_primaries

@color_primaries.setter
def color_primaries(self, value):
self.ptr.color_primaries = value

@property
def color_trc(self):
"""
Describes the linearization function (a.k.a. transformation characteristics) of the colorspace.
Wraps :ffmpeg:`AVFrame.color_trc`.
:type: int
"""
return self.ptr.color_trc

@color_trc.setter
def color_trc(self, value):
self.ptr.color_trc = value

@property
def colorspace(self):
"""
Describes the YUV/RGB transformation matrix of the colorspace.
Wraps :ffmpeg:`AVFrame.colorspace`.
:type: int
"""
return self.ptr.colorspace

@colorspace.setter
def colorspace(self, value):
self.ptr.colorspace = value

@property
def max_b_frames(self):
"""
Expand Down
9 changes: 7 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,13 @@ def _doxylink_handler(name, rawtext, text, lineno, inliner, options={}, content=

url = get_url(name)
if not url:
print("ERROR: Could not find", name)
exit(1)
if name == "AVFrame.color_primaries":
url = "structAVFrame.html#a59a3f830494f2ed1133103a1bc9481e7"
elif name == "AVFrame.color_trc":
url = "structAVFrame.html#ab09abb126e3922bc1d010cf044087939"
else:
print("ERROR: Could not find", name)
exit(1)

node = addnodes.literal_strong(title, title)
if url:
Expand Down
5 changes: 5 additions & 0 deletions include/libavcodec/avcodec.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ cdef extern from "libavcodec/avcodec.h" nogil:
int max_b_frames
int has_b_frames
AVColorRange color_range
AVColorPrimaries color_primaries
AVColorTransferCharacteristic color_trc
AVColorSpace colorspace

# Audio.
AVSampleFormat sample_fmt
Expand Down Expand Up @@ -359,6 +362,8 @@ cdef extern from "libavcodec/avcodec.h" nogil:
int flags
int decode_error_flags
AVColorRange color_range
AVColorPrimaries color_primaries
AVColorTransferCharacteristic color_trc
AVColorSpace colorspace

cdef AVFrame* avcodec_alloc_frame()
Expand Down
43 changes: 43 additions & 0 deletions include/libavutil/avutil.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,49 @@ cdef extern from "libavutil/avutil.h" nogil:
AVCOL_RANGE_JPEG
AVCOL_RANGE_NB

cdef enum AVColorPrimaries:
AVCOL_PRI_RESERVED0
AVCOL_PRI_BT709
AVCOL_PRI_UNSPECIFIED
AVCOL_PRI_RESERVED
AVCOL_PRI_BT470M
AVCOL_PRI_BT470BG
AVCOL_PRI_SMPTE170M
AVCOL_PRI_SMPTE240M
AVCOL_PRI_FILM
AVCOL_PRI_BT2020
AVCOL_PRI_SMPTE428
AVCOL_PRI_SMPTEST428_1
AVCOL_PRI_SMPTE431
AVCOL_PRI_SMPTE432
AVCOL_PRI_EBU3213
AVCOL_PRI_JEDEC_P22
AVCOL_PRI_NB

cdef enum AVColorTransferCharacteristic:
AVCOL_TRC_RESERVED0
AVCOL_TRC_BT709
AVCOL_TRC_UNSPECIFIED
AVCOL_TRC_RESERVED
AVCOL_TRC_GAMMA22
AVCOL_TRC_GAMMA28
AVCOL_TRC_SMPTE170M
AVCOL_TRC_SMPTE240M
AVCOL_TRC_LINEAR
AVCOL_TRC_LOG
AVCOL_TRC_LOG_SQRT
AVCOL_TRC_IEC61966_2_4
AVCOL_TRC_BT1361_ECG
AVCOL_TRC_IEC61966_2_1
AVCOL_TRC_BT2020_10
AVCOL_TRC_BT2020_12
AVCOL_TRC_SMPTE2084
AVCOL_TRC_SMPTEST2084
AVCOL_TRC_SMPTE428
AVCOL_TRC_SMPTEST428_1
AVCOL_TRC_ARIB_STD_B67
AVCOL_TRC_NB

cdef double M_PI

cdef void* av_malloc(size_t size)
Expand Down
21 changes: 20 additions & 1 deletion tests/test_colorspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,35 @@


class TestColorSpace(TestCase):
def test_color_range(self):
def test_penguin_joke(self):
container = av.open(
fate_suite("amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv")
)
stream = container.streams.video[0]

self.assertEqual(stream.codec_context.color_range, 2)
self.assertEqual(stream.codec_context.color_range, ColorRange.JPEG)

self.assertEqual(stream.codec_context.color_primaries, 2)
self.assertEqual(stream.codec_context.color_trc, 2)

self.assertEqual(stream.codec_context.colorspace, 5)
self.assertEqual(stream.codec_context.colorspace, Colorspace.ITU601)

for packet in container.demux(stream):
for frame in packet.decode():
self.assertEqual(frame.color_range, ColorRange.JPEG) # a.k.a "pc"
self.assertEqual(frame.colorspace, Colorspace.ITU601)
return

def test_sky_timelapse(self):
container = av.open(
av.datasets.curated("pexels/time-lapse-video-of-night-sky-857195.mp4")
)
stream = container.streams.video[0]

self.assertEqual(stream.codec_context.color_range, 1)
self.assertEqual(stream.codec_context.color_range, ColorRange.MPEG)
self.assertEqual(stream.codec_context.color_primaries, 1)
self.assertEqual(stream.codec_context.color_trc, 1)
self.assertEqual(stream.codec_context.colorspace, 1)

0 comments on commit 18bc34b

Please sign in to comment.