On Sun, 29 Jan 2017, Peter Große wrote:

The dash_write function drops data, if no IOContext is initialized.

Since the mp4 muxer is used in "frag_custom" mode, data is only
written when calling av_write_frame(NULL) explicitly and thus
there will be no data loss.

To add support for webm as subordinate muxer, which doesn't have
such a mode, a dynamic buffer is required to provide an always
initialized IOContext.

Signed-off-by: Peter Große <[email protected]>
---
v2: * fix mp4 init segment handling * reword commit message
---
libavformat/dashenc.c | 60 ++++++++++++++++++++++++++++++---------------------
1 file changed, 35 insertions(+), 25 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 4116fc8..d5bf275 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -67,11 +67,10 @@ typedef struct AdaptationSet {
typedef struct OutputStream {
    AVFormatContext *ctx;
    int ctx_inited, as_idx;
-    uint8_t iobuf[32768];
    AVIOContext *out;
    int packets_written;
    char initfile[1024];
-    int64_t init_start_pos;
+    int64_t init_start_pos, pos;
    int init_range_length;
    int nb_segments, segments_size, segment_index;
    Segment **segments;
@@ -107,14 +106,6 @@ typedef struct DASHContext {
    const char *utc_timing_url;
} DASHContext;

-static int dash_write(void *opaque, uint8_t *buf, int buf_size)
-{
-    OutputStream *os = opaque;
-    if (os->out)
-        avio_write(os->out, buf, buf_size);
-    return buf_size;
-}
-
// RFC 6381
static void set_codec_str(AVFormatContext *s, AVCodecParameters *par,
                          char *str, int size)
@@ -181,6 +172,27 @@ static void set_codec_str(AVFormatContext *s, 
AVCodecParameters *par,
    }
}

+static int flush_dynbuf(OutputStream *os, int *range_length)
+{
+    uint8_t *buffer;
+
+    if (!os->ctx->pb) {
+        return AVERROR(EINVAL);
+    }
+
+    // flush
+    av_write_frame(os->ctx, NULL);
+    avio_flush(os->ctx->pb);
+
+    // write out to file
+    *range_length = avio_close_dyn_buf(os->ctx->pb, &buffer);
+    avio_write(os->out, buffer, *range_length);
+    av_free(buffer);
+
+    // re-open buffer
+    return avio_open_dyn_buf(&os->ctx->pb);
+}

Sorry for not noticing in the previous round, but... If avio_open_dyn_buf fails, it will not set the pointer to NULL, so in that case, we'd end up with a dangling pointer in os->ctx->pb and end up with a double free later.

The rest of the patch seems fine. No need to repost just for this, I can add the necessary os->ctx->pb = NULL before pushing.

// Martin
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to