diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 274fa159b..56676162d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -37,6 +37,7 @@ Major: - Remove the undocumented ``CodecContext.hwaccel`` attribute. It held the ``HWAccel`` settings object passed in, not the live device context; use ``CodecContext.is_hwaccel`` to check whether hardware acceleration is in use. - Rational attributes (``time_base``, ``average_rate``, ``base_rate``, ``guessed_rate``, ``framerate``, ``rate``, ``sample_aspect_ratio``, and ``display_aspect_ratio``) now return :class:`av.AVRational` rather than ``fractions.Fraction``, and are never ``None``: an unset value is the falsy ``AVRational(0, 1)``. Test them with ``if not stream.time_base:`` instead of ``is None``. Setters still accept a ``fractions.Fraction``. - Remove ``Capabilities.hwaccel``, ``Capabilities.hwaccel_vdpau``, and ``Capabilities.neg_linesizes``, none of which FFmpeg defines any more. +- Remove the ``stream_options`` argument to :func:`av.open` and the matching attribute. They only ever reached ``avformat_find_stream_info()``, and only for formats that expose their streams before it runs, so they raised for MPEG and friends; output containers rejected them outright. Pass ``options`` for every stream, set ``stream.codec_context.options`` for one, and ``Container.add_stream(..., options={})`` when writing. Features: diff --git a/av/container/core.pxd b/av/container/core.pxd index cdf4d5dc7..c6f0a910d 100644 --- a/av/container/core.pxd +++ b/av/container/core.pxd @@ -16,34 +16,27 @@ ctypedef struct timeout_info: cdef class Container: cdef lib.AVFormatContext *ptr - cdef readonly object name + cdef readonly str name cdef readonly str metadata_encoding cdef readonly str metadata_errors - cdef readonly PyIOFile file cdef int buffer_size cdef readonly object io_open cdef readonly object open_files - cdef readonly ContainerFormat format - cdef readonly dict options cdef readonly dict container_options - cdef readonly list stream_options + cdef dict _metadata + cdef readonly StreamContainer streams + cdef readonly object open_timeout + cdef readonly object read_timeout cdef HWAccel hwaccel - cdef readonly StreamContainer streams - cdef dict _metadata - - # Private API. + cdef timeout_info interrupt_callback_info cdef uint8_t _myflag # enum: writeable, input_was_opened, started, done, extradata_planned - cdef void _assert_open(self) - cdef int err_check(self, int value) except -1 - # Timeouts - cdef readonly object open_timeout - cdef readonly object read_timeout - cdef timeout_info interrupt_callback_info + cdef void _assert_open(self) cdef void set_timeout(self, object) cdef void start_timeout(self) + cdef int err_check(self, int value) except -1 diff --git a/av/container/core.py b/av/container/core.py index d07b7167b..6b630802d 100755 --- a/av/container/core.py +++ b/av/container/core.py @@ -234,7 +234,6 @@ def __cinit__( format_name, options, container_options, - stream_options, hwaccel, metadata_encoding, metadata_errors, @@ -257,16 +256,11 @@ def __cinit__( self.options = dict(options or ()) self.container_options = dict(container_options or ()) - self.stream_options = [dict(x) for x in stream_options or ()] - self.hwaccel = hwaccel - self.metadata_encoding = metadata_encoding self.metadata_errors = metadata_errors - self.open_timeout = open_timeout self.read_timeout = read_timeout - self.buffer_size = buffer_size self.io_open = io_open @@ -497,7 +491,6 @@ def open( format=None, options=None, container_options=None, - stream_options=None, metadata_encoding="utf-8", metadata_errors="strict", buffer_size=32768, @@ -514,7 +507,6 @@ def open( :param str format: Specific format to use. Defaults to autodect. :param dict options: Options to pass to the container and all streams. :param dict container_options: Options to pass to the container. - :param list stream_options: Options to pass to each stream. :param str metadata_encoding: Encoding to use when reading or writing file metadata. Defaults to ``"utf-8"``. :param str metadata_errors: Specifies how to handle encoding errors; behaves like @@ -581,7 +573,6 @@ def open( format, options, container_options, - stream_options, hwaccel, metadata_encoding, metadata_errors, @@ -591,17 +582,12 @@ def open( io_open, ) - if stream_options: - raise ValueError( - "Provide stream options via Container.add_stream(..., options={})." - ) return OutputContainer( _cinit_sentinel, file, format, options, container_options, - stream_options, None, metadata_encoding, metadata_errors, diff --git a/av/container/core.pyi b/av/container/core.pyi index 9350aa4b4..a99ff7b4a 100644 --- a/av/container/core.pyi +++ b/av/container/core.pyi @@ -87,7 +87,6 @@ class Container: format: ContainerFormat options: dict[str, str] container_options: dict[str, str] - stream_options: list[dict[str, str]] streams: StreamContainer metadata: dict[str, str] open_timeout: Real | None @@ -114,7 +113,6 @@ def open( format: str | None = None, options: dict[str, str] | None = None, container_options: dict[str, str] | None = None, - stream_options: list[str] | None = None, metadata_encoding: str = "utf-8", metadata_errors: str = "strict", buffer_size: int = 32768, @@ -129,7 +127,6 @@ def open( format: str | None = None, options: dict[str, str] | None = None, container_options: dict[str, str] | None = None, - stream_options: list[str] | None = None, metadata_encoding: str = "utf-8", metadata_errors: str = "strict", buffer_size: int = 32768, @@ -144,7 +141,6 @@ def open( format: str | None = None, options: dict[str, str] | None = None, container_options: dict[str, str] | None = None, - stream_options: list[str] | None = None, metadata_encoding: str = "utf-8", metadata_errors: str = "strict", buffer_size: int = 32768, @@ -159,7 +155,6 @@ def open( format: str | None = None, options: dict[str, str] | None = None, container_options: dict[str, str] | None = None, - stream_options: list[str] | None = None, metadata_encoding: str = "utf-8", metadata_errors: str = "strict", buffer_size: int = 32768, diff --git a/av/container/input.py b/av/container/input.py index d18a3aaaf..09a18e074 100644 --- a/av/container/input.py +++ b/av/container/input.py @@ -30,20 +30,13 @@ def __cinit__(self, *args, **kwargs): codec: cython.pointer[cython.const[lib.AVCodec]] codec_context: cython.pointer[lib.AVCodecContext] - # If we have either the global `options`, or a `stream_options`, prepare - # a mashup of those options for each stream. + # Hand `options` to every stream that is already known. Only allocate + # c_options when they are: some formats (e.g. MPEG) do not expose their + # streams until avformat_find_stream_info has run. c_options: cython.pointer[cython.pointer[lib.AVDictionary]] = cython.NULL base_dict: Dictionary - stream_dict: Dictionary nb_streams_before: cython.uint = self.ptr.nb_streams - if self.stream_options and nb_streams_before == 0: - raise ValueError( - "stream_options were provided, but this format does not expose " - "its streams before avformat_find_stream_info (e.g. MPEG). " - "Per-stream options cannot be applied." - ) - # Only allocate c_options when streams are already known. - if (self.options or self.stream_options) and nb_streams_before > 0: + if self.options and nb_streams_before > 0: base_dict = Dictionary(self.options) c_options = cython.cast( cython.pointer[cython.pointer[lib.AVDictionary]], @@ -51,12 +44,7 @@ def __cinit__(self, *args, **kwargs): ) for i in range(nb_streams_before): c_options[i] = cython.NULL - if i < len(self.stream_options) and self.stream_options: - stream_dict = base_dict.copy() - stream_dict.update(self.stream_options[i]) - lib.av_dict_copy(cython.address(c_options[i]), stream_dict.ptr, 0) - else: - lib.av_dict_copy(cython.address(c_options[i]), base_dict.ptr, 0) + lib.av_dict_copy(cython.address(c_options[i]), base_dict.ptr, 0) self.set_timeout(self.open_timeout) self.start_timeout() diff --git a/av/container/output.pxd b/av/container/output.pxd index ea164abf5..fc98c8828 100644 --- a/av/container/output.pxd +++ b/av/container/output.pxd @@ -9,7 +9,7 @@ cdef class OutputContainer(Container): cdef lib.AVPacket *packet_ptr cdef dict _extradata_bsfs cdef list[Packet] _buffered_packets - cdef void _mux_one(self, Packet packet) cdef _buffer_for_extradata(self, Packet packet) + cdef void _mux_one(self, Packet packet) cdef void _try_extract_extradata(self, Packet packet) cpdef start_encoding(self) diff --git a/docs/api/container.rst b/docs/api/container.rst index 71739fe3f..4c82ecdd0 100644 --- a/docs/api/container.rst +++ b/docs/api/container.rst @@ -14,7 +14,6 @@ Generic .. attribute:: options .. attribute:: container_options - .. attribute:: stream_options .. attribute:: metadata_encoding .. attribute:: metadata_errors .. attribute:: open_timeout