From b6a86e57a7db189b02c5ba4f8cbc8327ae2295f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jeremy=20Lain=C3=A9?= <jeremy.laine@m4x.org> Date: Mon, 28 Mar 2022 19:33:15 +0200 Subject: [PATCH] [codec context] deprecate CodecContext.time_base for decoders The FFmpeg API docs state that using AVCodecContext.time_base for decoders is deprecated and AVCodecContext.framerate should be used instead. --- av/codec/context.pyx | 17 +++++++++++++++-- docs/api/time.rst | 3 --- tests/test_codec_context.py | 19 ++++++++++++++++++- tests/test_decode.py | 5 +++-- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/av/codec/context.pyx b/av/codec/context.pyx index fd3b26f..c9f5177 100644 --- a/av/codec/context.pyx +++ b/av/codec/context.pyx @@ -1,3 +1,5 @@ +import warnings + from libc.errno cimport EAGAIN from libc.stdint cimport int64_t, uint8_t from libc.string cimport memcpy @@ -11,6 +13,7 @@ from av.error cimport err_check from av.packet cimport Packet from av.utils cimport avrational_to_fraction, to_avrational +from av.deprecation import AVDeprecationWarning from av.dictionary import Dictionary @@ -282,8 +285,8 @@ cdef class CodecContext(object): cdef _Dictionary options = Dictionary() options.update(self.options or {}) - # Assert we have a time_base. - if not self.ptr.time_base.num: + # Assert we have a time_base for encoders. + if not self.ptr.time_base.num and self.is_encoder: self._set_default_time_base() err_check(lib.avcodec_open2(self.ptr, self.codec.ptr, &options.ptr)) @@ -551,9 +554,19 @@ cdef class CodecContext(object): property time_base: def __get__(self): + if self.is_decoder: + warnings.warn( + "Using CodecContext.time_base for decoders is deprecated.", + AVDeprecationWarning + ) return avrational_to_fraction(&self.ptr.time_base) def __set__(self, value): + if self.is_decoder: + warnings.warn( + "Using CodecContext.time_base for decoders is deprecated.", + AVDeprecationWarning + ) to_avrational(value, &self.ptr.time_base) property codec_tag: diff --git a/docs/api/time.rst b/docs/api/time.rst index c0234e0..35e4cfc 100644 --- a/docs/api/time.rst +++ b/docs/api/time.rst @@ -29,9 +29,6 @@ Time is expressed as integer multiples of arbitrary units of time called a ``tim >>> video.time_base Fraction(1, 25) - >>> video.codec_context.time_base - Fraction(1, 50) - Attributes that represent time on those objects will be in that object's ``time_base``: .. doctest:: diff --git a/tests/test_codec_context.py b/tests/test_codec_context.py index ca94336..a62c05c 100644 --- a/tests/test_codec_context.py +++ b/tests/test_codec_context.py @@ -1,6 +1,7 @@ from fractions import Fraction from unittest import SkipTest import os +import warnings from av import AudioResampler, Codec, Packet from av.codec.codec import UnknownCodecError @@ -79,6 +80,23 @@ class TestCodecContext(TestCase): self.assertEqual(ctx.extradata, None) self.assertEqual(ctx.extradata_size, 0) + def test_decoder_timebase(self): + ctx = av.codec.Codec("h264", "r").create() + + with warnings.catch_warnings(record=True) as captured: + self.assertIsNone(ctx.time_base) + self.assertEqual( + captured[0].message.args[0], + "Using CodecContext.time_base for decoders is deprecated.", + ) + + with warnings.catch_warnings(record=True) as captured: + ctx.time_base = Fraction(1, 25) + self.assertEqual( + captured[0].message.args[0], + "Using CodecContext.time_base for decoders is deprecated.", + ) + def test_encoder_extradata(self): ctx = av.codec.Codec("h264", "w").create() self.assertEqual(ctx.extradata, None) @@ -357,7 +375,6 @@ class TestEncoding(TestCase): f.write(packet) ctx = Codec(codec_name, "r").create() - ctx.time_base = Fraction(1) / sample_rate ctx.sample_rate = sample_rate ctx.format = sample_fmt ctx.layout = channel_layout diff --git a/tests/test_decode.py b/tests/test_decode.py index b4e13c1..7090101 100644 --- a/tests/test_decode.py +++ b/tests/test_decode.py @@ -1,3 +1,5 @@ +from fractions import Fraction + import av from .common import TestCase, fate_suite @@ -59,9 +61,8 @@ class TestDecode(TestCase): container = av.open(fate_suite("h264/interlaced_crop.mp4")) stream = container.streams.video[0] - codec_context = stream.codec_context - self.assertNotEqual(stream.time_base, codec_context.time_base) + self.assertEqual(stream.time_base, Fraction(1, 25)) for packet in container.demux(stream): for frame in packet.decode(): -- GitLab