diff mbox series

[FFmpeg-devel,6/6] avformat/webm_chunk: Open AVIOContext before initializing sub-muxer

Message ID 20200517231319.13067-6-andreas.rheinhardt@gmail.com
State Accepted
Commit aef670cff4d8856a99451995aff6d77a2f20403f
Headers show
Series [FFmpeg-devel,1/6] avformat/segment: Access AVStream more directly
Related show

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Andreas Rheinhardt May 17, 2020, 11:13 p.m. UTC
The description of AVOutputFormat.init contains the statement that "this
method must not write output". Due to this, the webm_chunk muxer defers
opening the AVIOContext for the child muxer until avformat_write_header(),
i.e. there is no AVIOContext when the sub-muxer's avformat_init_output()
is called. But this violates the documentation of said function which
requires the AVFormatContext to have an already opened AVIOContext.
This commit fixes this.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavformat/webm_chunk.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/libavformat/webm_chunk.c b/libavformat/webm_chunk.c
index 1749509975..f1bee5fa9f 100644
--- a/libavformat/webm_chunk.c
+++ b/libavformat/webm_chunk.c
@@ -44,6 +44,7 @@  typedef struct WebMChunkContext {
     uint64_t duration_written;
     int64_t prev_pts;
     AVFormatContext *avf;
+    int header_written;
 } WebMChunkContext;
 
 static int webm_chunk_init(AVFormatContext *s)
@@ -101,6 +102,15 @@  static int webm_chunk_init(AVFormatContext *s)
     avpriv_set_pts_info(st, ost->pts_wrap_bits, ost->time_base.num,
                                                 ost->time_base.den);
 
+    if (wc->http_method)
+        if ((ret = av_dict_set(&dict, "method", wc->http_method, 0)) < 0)
+            return ret;
+    ret = s->io_open(s, &oc->pb, oc->url, AVIO_FLAG_WRITE, &dict);
+    av_dict_free(&dict);
+    if (ret < 0)
+        return ret;
+    oc->pb->seekable = 0;
+
     if ((ret = av_dict_set_int(&dict, "dash", 1, 0))   < 0 ||
         (ret = av_dict_set_int(&dict, "cluster_time_limit",
                                wc->chunk_duration, 0)) < 0 ||
@@ -147,19 +157,10 @@  static int webm_chunk_write_header(AVFormatContext *s)
     WebMChunkContext *wc = s->priv_data;
     AVFormatContext *oc = wc->avf;
     int ret;
-    AVDictionary *options = NULL;
 
-    if (wc->http_method)
-        if ((ret = av_dict_set(&options, "method", wc->http_method, 0)) < 0)
-            return ret;
-    ret = s->io_open(s, &oc->pb, oc->url, AVIO_FLAG_WRITE, &options);
-    av_dict_free(&options);
-    if (ret < 0)
-        return ret;
-
-    oc->pb->seekable = 0;
     ret = avformat_write_header(oc, NULL);
     ff_format_io_close(s, &oc->pb);
+    wc->header_written = 1;
     if (ret < 0)
         return ret;
     return 0;
@@ -270,7 +271,10 @@  static void webm_chunk_deinit(AVFormatContext *s)
     if (!wc->avf)
         return;
 
-    ffio_free_dyn_buf(&wc->avf->pb);
+    if (wc->header_written)
+        ffio_free_dyn_buf(&wc->avf->pb);
+    else
+        ff_format_io_close(s, &wc->avf->pb);
     avformat_free_context(wc->avf);
     wc->avf = NULL;
 }