From ac772f1f0e8f893edaf7cbd70106ec21c7cd42cb Mon Sep 17 00:00:00 2001 From: WyattBlue Date: Fri, 27 Feb 2026 00:46:22 -0500 Subject: [PATCH] Use new config api --- av/codec/codec.py | 86 +++++++++++++++++++++++++----------------- av/container/output.py | 12 +++++- include/avcodec.pxd | 22 +++++++---- 3 files changed, 78 insertions(+), 42 deletions(-) diff --git a/av/codec/codec.py b/av/codec/codec.py index f70717905..930a9ecec 100644 --- a/av/codec/codec.py +++ b/av/codec/codec.py @@ -182,56 +182,74 @@ def id(self): @property def frame_rates(self): """A list of supported frame rates (:class:`fractions.Fraction`), or ``None``.""" - if not self.ptr.supported_framerates: + out: cython.p_void = cython.NULL + num: cython.int = 0 + lib.avcodec_get_supported_config( + cython.NULL, + self.ptr, + lib.AV_CODEC_CONFIG_FRAME_RATE, + 0, + cython.address(out), + cython.address(num), + ) + if not out: return - - ret: list = [] - i: cython.int = 0 - while self.ptr.supported_framerates[i].denum: - ret.append( - avrational_to_fraction(cython.address(self.ptr.supported_framerates[i])) - ) - i += 1 - return ret + rates = cython.cast(cython.pointer[lib.AVRational], out) + return [avrational_to_fraction(cython.address(rates[i])) for i in range(num)] @property def audio_rates(self): """A list of supported audio sample rates (``int``), or ``None``.""" - if not self.ptr.supported_samplerates: + out: cython.p_void = cython.NULL + num: cython.int = 0 + lib.avcodec_get_supported_config( + cython.NULL, + self.ptr, + lib.AV_CODEC_CONFIG_SAMPLE_RATE, + 0, + cython.address(out), + cython.address(num), + ) + if not out: return - - ret: list = [] - i: cython.int = 0 - while self.ptr.supported_samplerates[i]: - ret.append(self.ptr.supported_samplerates[i]) - i += 1 - return ret + rates = cython.cast(cython.pointer[cython.int], out) + return [rates[i] for i in range(num)] @property def video_formats(self): """A list of supported :class:`.VideoFormat`, or ``None``.""" - if not self.ptr.pix_fmts: + out: cython.p_void = cython.NULL + num: cython.int = 0 + lib.avcodec_get_supported_config( + cython.NULL, + self.ptr, + lib.AV_CODEC_CONFIG_PIX_FORMAT, + 0, + cython.address(out), + cython.address(num), + ) + if not out: return - - ret: list = [] - i: cython.int = 0 - while self.ptr.pix_fmts[i] != -1: - ret.append(get_video_format(self.ptr.pix_fmts[i], 0, 0)) - i += 1 - return ret + fmts = cython.cast(cython.pointer[lib.AVPixelFormat], out) + return [get_video_format(fmts[i], 0, 0) for i in range(num)] @property def audio_formats(self): """A list of supported :class:`.AudioFormat`, or ``None``.""" - if not self.ptr.sample_fmts: + out: cython.p_void = cython.NULL + num: cython.int = 0 + lib.avcodec_get_supported_config( + cython.NULL, + self.ptr, + lib.AV_CODEC_CONFIG_SAMPLE_FORMAT, + 0, + cython.address(out), + cython.address(num), + ) + if not out: return - - ret: list = [] - i: cython.int = 0 - while self.ptr.sample_fmts[i] != -1: - ret.append(get_audio_format(self.ptr.sample_fmts[i])) - i += 1 - return ret + fmts = cython.cast(cython.pointer[lib.AVSampleFormat], out) + return [get_audio_format(fmts[i]) for i in range(num)] @property def hardware_configs(self): diff --git a/av/container/output.py b/av/container/output.py index 1e02168cb..600d84720 100644 --- a/av/container/output.py +++ b/av/container/output.py @@ -87,7 +87,17 @@ def add_stream(self, codec_name, rate=None, options: dict | None = None, **kwarg # Some sane audio defaults elif codec.type == lib.AVMEDIA_TYPE_AUDIO: - ctx.sample_fmt = codec.sample_fmts[0] + out: cython.p_void = cython.NULL + lib.avcodec_get_supported_config( + cython.NULL, + codec, + lib.AV_CODEC_CONFIG_SAMPLE_FORMAT, + 0, + cython.address(out), + cython.NULL, + ) + if out: + ctx.sample_fmt = cython.cast(cython.pointer[lib.AVSampleFormat], out)[0] ctx.bit_rate = kwargs.pop("bit_rate", 0) ctx.bit_rate_tolerance = kwargs.pop("bit_rate_tolerance", 32000) try: diff --git a/include/avcodec.pxd b/include/avcodec.pxd index 09c7dabf0..98114fa12 100644 --- a/include/avcodec.pxd +++ b/include/avcodec.pxd @@ -179,19 +179,27 @@ cdef extern from "libavcodec/avcodec.h" nogil: char *long_name AVMediaType type AVCodecID id - int capabilities - - AVRational* supported_framerates - AVSampleFormat* sample_fmts - AVPixelFormat* pix_fmts - int* supported_samplerates - AVClass *priv_class cdef int av_codec_is_encoder(AVCodec*) cdef int av_codec_is_decoder(AVCodec*) + cdef enum AVCodecConfig: + AV_CODEC_CONFIG_PIX_FORMAT + AV_CODEC_CONFIG_FRAME_RATE + AV_CODEC_CONFIG_SAMPLE_RATE + AV_CODEC_CONFIG_SAMPLE_FORMAT + + cdef int avcodec_get_supported_config( + const AVCodecContext *avctx, + const AVCodec *codec, + AVCodecConfig config, + unsigned flags, + const void **out_configs, + int *out_num_configs, + ) + cdef struct AVProfile: int profile char *name