From b16e9db79ba8c4437276165c402e75a085a8a20e Mon Sep 17 00:00:00 2001 From: WyattBlue Date: Thu, 23 Apr 2026 13:35:50 -0400 Subject: [PATCH] Set vcodec on container, closes #2243 --- av/container/core.py | 10 ++++++++++ av/container/core.pyi | 1 + include/avformat.pxd | 7 ++++--- tests/test_containerformat.py | 19 +++++++++++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/av/container/core.py b/av/container/core.py index 4195be248..8aeaa7a3e 100755 --- a/av/container/core.py +++ b/av/container/core.py @@ -390,6 +390,16 @@ def _assert_open(self): if self.ptr == cython.NULL: raise AssertionError("Container is not open") + @property + def video_codec_id(self): + self._assert_open() + return self.ptr.video_codec_id + + @video_codec_id.setter + def video_codec_id(self, value: lib.AVCodecID): + self._assert_open() + self.ptr.video_codec_id = value + @property def flags(self): self._assert_open() diff --git a/av/container/core.pyi b/av/container/core.pyi index f62b6c813..81e4936e4 100644 --- a/av/container/core.pyi +++ b/av/container/core.pyi @@ -91,6 +91,7 @@ class Container: open_timeout: Real | None read_timeout: Real | None flags: int + video_codec_id: int def __enter__(self) -> Container: ... def __exit__( self, diff --git a/include/avformat.pxd b/include/avformat.pxd index 94bf27b2e..5aca5e287 100644 --- a/include/avformat.pxd +++ b/include/avformat.pxd @@ -71,7 +71,7 @@ cdef extern from "libavformat/avformat.h" nogil: int64_t(*seek)(void *opaque, int64_t offset, int whence) ) - # http://ffmpeg.org/doxygen/trunk/structAVInputFormat.html + # https://ffmpeg.org/doxygen/trunk/structAVInputFormat.html cdef struct AVInputFormat: const char *name const char *long_name @@ -79,13 +79,13 @@ cdef extern from "libavformat/avformat.h" nogil: int flags const AVClass *priv_class - # http://ffmpeg.org/doxygen/trunk/structAVOutputFormat.html + # https://ffmpeg.org/doxygen/trunk/structAVOutputFormat.html cdef struct AVOutputFormat: const char *name const char *long_name const char *extensions - AVCodecID video_codec AVCodecID audio_codec + AVCodecID video_codec AVCodecID subtitle_codec int flags const AVClass *priv_class @@ -156,6 +156,7 @@ cdef extern from "libavformat/avformat.h" nogil: int bit_rate int flags AVCodecID audio_codec_id + AVCodecID video_codec_id void *opaque int (*io_open)( AVFormatContext *s, diff --git a/tests/test_containerformat.py b/tests/test_containerformat.py index 43f1eca9f..ca0b72fd7 100644 --- a/tests/test_containerformat.py +++ b/tests/test_containerformat.py @@ -1,5 +1,7 @@ from av import ContainerFormat, formats_available, open +from .common import fate_suite + def test_matroska() -> None: with open("test.mkv", "w") as container: @@ -56,5 +58,22 @@ def test_stream_segment() -> None: assert fmt.no_file +def test_video_codec_id() -> None: + # Regression test for https://github.com/PyAV-Org/PyAV/issues/2243 + # video_codec_id allows overriding the codec used when opening a container. + AV_CODEC_ID_NONE = 0 + AV_CODEC_ID_H264 = 27 + + with open(fate_suite("h264/interlaced_crop.mp4")) as container: + assert container.video_codec_id == AV_CODEC_ID_NONE + container.video_codec_id = AV_CODEC_ID_H264 + assert container.video_codec_id == AV_CODEC_ID_H264 + + with open("test.mkv", "w") as container: + assert container.video_codec_id == AV_CODEC_ID_NONE + container.video_codec_id = AV_CODEC_ID_H264 + assert container.video_codec_id == AV_CODEC_ID_H264 + + def test_formats_available() -> None: assert formats_available