Skip to content

Commit

Permalink
Expose bits_per_coded_sample on VideoCodecContext
Browse files Browse the repository at this point in the history
---------

Co-authored-by: JoeUgly <[email protected]>
Co-authored-by: WyattBlue <[email protected]>
  • Loading branch information
3 people committed Mar 12, 2024
1 parent ba35f55 commit 7a5c2d1
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
20 changes: 20 additions & 0 deletions av/video/codeccontext.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,26 @@ cdef class VideoCodecContext(CodecContext):
self.ptr.height = value
self._build_format()

@property
def bits_per_coded_sample(self):
"""
The number of bits per sample in the codedwords, basically the bitrate per sample.
It is mandatory for this to be set for some formats to decode them.
Wraps :ffmpeg:`AVCodecContext::bits_per_coded_sample`
:type: int
"""
return self.ptr.bits_per_coded_sample

@bits_per_coded_sample.setter
def bits_per_coded_sample(self, int value):
if self.is_encoder:
raise ValueError("Not supported for encoders")

self.ptr.bits_per_coded_sample = value
self._build_format()

@property
def pix_fmt(self):
"""
Expand Down
2 changes: 2 additions & 0 deletions include/libavcodec/avcodec.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ cdef extern from "libavcodec/avcodec.h" nogil:
int bit_rate_tolerance
int mb_decision

int bits_per_coded_sample

int global_quality
int compression_level

Expand Down
25 changes: 25 additions & 0 deletions tests/test_codec_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,31 @@ def test_encoder_pix_fmt(self):
self.assertEqual(str(cm.exception), "not a pixel format: '__unknown_pix_fmt'")
self.assertEqual(ctx.pix_fmt, "yuv420p")

def test_bits_per_coded_sample(self):
with av.open(fate_suite("qtrle/aletrek-rle.mov")) as container:
stream = container.streams.video[0]
stream.bits_per_coded_sample = 32

for packet in container.demux(stream):
for frame in packet.decode():
pass
self.assertEqual(packet.stream.bits_per_coded_sample, 32)

with av.open(fate_suite("qtrle/aletrek-rle.mov")) as container:
stream = container.streams.video[0]
stream.bits_per_coded_sample = 31

with self.assertRaises(av.error.InvalidDataError):
for packet in container.demux(stream):
for frame in packet.decode():
pass

with av.open(self.sandboxed("output.mov"), "w") as output:
stream = output.add_stream("qtrle")

with self.assertRaises(ValueError):
stream.codec_context.bits_per_coded_sample = 32

def test_parse(self):
# This one parses into a single packet.
self._assert_parse("mpeg4", fate_suite("h264/interlaced_crop.mp4"))
Expand Down

0 comments on commit 7a5c2d1

Please sign in to comment.