Commit 537f5a19 authored by Ulrik's avatar Ulrik
Browse files

OutputContainer: Open output with avio_open2 and pass "protocol_options"

Allows overriding protocol-specific options such as HTTP method and HTTP
retrial policy
1 merge request!704OutputContainer: Open output with avio_open2 and pass "protocol_options"
Pipeline #1487 failed with stages
Showing with 18 additions and 12 deletions
+18 -12
......@@ -31,6 +31,7 @@ cdef class Container(object):
cdef readonly ContainerFormat format
cdef readonly dict options
cdef readonly dict protocol_options
cdef readonly dict container_options
cdef readonly list stream_options
......
......@@ -171,7 +171,7 @@ Flags = define_enum('Flags', __name__, (
cdef class Container(object):
def __cinit__(self, sentinel, file_, format_name, options,
container_options, stream_options,
protocol_options, container_options, stream_options,
metadata_encoding, metadata_errors,
buffer_size, open_timeout, read_timeout,
io_open):
......@@ -189,6 +189,7 @@ cdef class Container(object):
self.name = str(getattr(file_, 'name', '<none>'))
self.options = dict(options or ())
self.protocol_options = dict(protocol_options or ())
self.container_options = dict(container_options or ())
self.stream_options = [dict(x) for x in stream_options or ()]
......@@ -257,7 +258,7 @@ cdef class Container(object):
ifmt = self.format.iptr if self.format else NULL
c_options = Dictionary(self.options, self.container_options)
c_options = Dictionary(self.options, self.protocol_options, self.container_options)
self.set_timeout(self.open_timeout)
self.start_timeout()
......@@ -335,8 +336,8 @@ cdef class Container(object):
auto_bsf = flags.flag_property('AUTO_BSF')
def open(file, mode=None, format=None, options=None,
container_options=None, stream_options=None,
def open(file, mode=None, format=None, options=None, *,
protocol_options=None, container_options=None, stream_options=None,
metadata_encoding='utf-8', metadata_errors='strict',
buffer_size=32768, timeout=None, io_open=None):
"""open(file, mode='r', **kwargs)
......@@ -347,6 +348,7 @@ def open(file, mode=None, format=None, options=None,
:param str mode: ``"r"`` for reading and ``"w"`` for writing.
:param str format: Specific format to use. Defaults to autodect.
:param dict options: Options to pass to the container and all streams.
:param dict protocol_options: Options to pass to the protocol implementation.
: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.
......@@ -400,7 +402,7 @@ def open(file, mode=None, format=None, options=None,
if mode.startswith('r'):
return InputContainer(
_cinit_sentinel, file, format, options,
container_options, stream_options,
protocol_options, container_options, stream_options,
metadata_encoding, metadata_errors,
buffer_size, open_timeout, read_timeout,
io_open
......@@ -410,7 +412,7 @@ def open(file, mode=None, format=None, options=None,
raise ValueError("Provide stream options via Container.add_stream(..., options={}).")
return OutputContainer(
_cinit_sentinel, file, format, options,
container_options, stream_options,
protocol_options, container_options, stream_options,
metadata_encoding, metadata_errors,
buffer_size, open_timeout, read_timeout,
io_open
......
......@@ -157,11 +157,14 @@ cdef class OutputContainer(Container):
stream._finalize_for_output()
cdef _Dictionary all_options = Dictionary(self.options, self.container_options, self.protocol_options)
cdef _Dictionary options = all_options.copy()
# Open the output file, if needed.
cdef bytes name_obj = os.fsencode(self.name if self.file is None else "")
cdef char *name = name_obj
if self.ptr.pb == NULL and not self.ptr.oformat.flags & lib.AVFMT_NOFILE:
err_check(lib.avio_open(&self.ptr.pb, name, lib.AVIO_FLAG_WRITE))
err_check(lib.avio_open2(&self.ptr.pb, name, lib.AVIO_FLAG_WRITE, NULL, &options.ptr))
# Copy the metadata dict.
dict_to_avdict(
......@@ -170,8 +173,6 @@ cdef class OutputContainer(Container):
errors=self.metadata_errors
)
cdef _Dictionary all_options = Dictionary(self.options, self.container_options)
cdef _Dictionary options = all_options.copy()
self.err_check(lib.avformat_write_header(
self.ptr,
&options.ptr
......
......@@ -13,6 +13,7 @@ Generic
.. autoclass:: Container
.. attribute:: options
.. attribute:: protocol_options
.. attribute:: container_options
.. attribute:: stream_options
.. attribute:: metadata_encoding
......@@ -76,4 +77,3 @@ Flags
.. enumtable:: av.format.Flags
:class: av.format.ContainerFormat
......@@ -240,10 +240,12 @@ cdef extern from "libavformat/avformat.h" nogil:
AVPacket *pkt
)
cdef int avio_open(
cdef int avio_open2(
AVIOContext **s,
char *url,
int flags
int flags,
AVIOInterruptCB *interrupt_callback,
AVDictionary **options,
)
cdef int64_t avio_size(
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment