On 3/24/19 6:00 PM, Karthick J wrote: > --- > doc/muxers.texi | 3 ++ > libavformat/dashenc.c | 119 ++++++++++++++++++++++++++++-------------- > 2 files changed, 84 insertions(+), 38 deletions(-) > > diff --git a/doc/muxers.texi b/doc/muxers.texi > index aac7d94edf..83ae017d6c 100644 > --- a/doc/muxers.texi > +++ b/doc/muxers.texi > @@ -293,6 +293,9 @@ Set container format (mp4/webm) options using a @code{:} > separated list of > key=value parameters. Values containing @code{:} special characters must be > escaped. > > +@item -global_sidx @var{global_sidx} > +Write global SIDX atom. Applicable only for single file, mp4 output, > non-streaming mode. > + > @item -dash_segment_type @var{dash_segment_type} > Possible values: > @item auto > diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c > index 1b74bce060..f8d71166d4 100644 > --- a/libavformat/dashenc.c > +++ b/libavformat/dashenc.c > @@ -140,6 +140,7 @@ typedef struct DASHContext { > int64_t timeout; > int index_correction; > char *format_options_str; > + int global_sidx; > SegmentType segment_type_option; /* segment type as specified in > options */ > int ignore_io_errors; > int lhls; > @@ -368,7 +369,7 @@ static void set_codec_str(AVFormatContext *s, > AVCodecParameters *par, > } > } > > -static int flush_dynbuf(OutputStream *os, int *range_length) > +static int flush_dynbuf(DASHContext *c, OutputStream *os, int *range_length) > { > uint8_t *buffer; > > @@ -380,16 +381,21 @@ static int flush_dynbuf(OutputStream *os, int > *range_length) > 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); > - os->ctx->pb = NULL; > - if (os->out) > - avio_write(os->out, buffer + os->written_len, *range_length - > os->written_len); > - os->written_len = 0; > - av_free(buffer); > - > - // re-open buffer > - return avio_open_dyn_buf(&os->ctx->pb); > + if (!c->single_file) { > + // write out to file > + *range_length = avio_close_dyn_buf(os->ctx->pb, &buffer); > + os->ctx->pb = NULL; > + if (os->out) > + avio_write(os->out, buffer + os->written_len, *range_length - > os->written_len); > + os->written_len = 0; > + av_free(buffer); > + > + // re-open buffer > + return avio_open_dyn_buf(&os->ctx->pb); > + } else { > + *range_length = avio_tell(os->ctx->pb) - os->pos; > + return 0; > + } > } > > static void set_http_options(AVDictionary **options, DASHContext *c) > @@ -508,7 +514,7 @@ static int flush_init_segment(AVFormatContext *s, > OutputStream *os) > DASHContext *c = s->priv_data; > int ret, range_length; > > - ret = flush_dynbuf(os, &range_length); > + ret = flush_dynbuf(c, os, &range_length); > if (ret < 0) > return ret; > > @@ -537,8 +543,12 @@ static void dash_free(AVFormatContext *s) > return; > for (i = 0; i < s->nb_streams; i++) { > OutputStream *os = &c->streams[i]; > - if (os->ctx && os->ctx->pb) > - ffio_free_dyn_buf(&os->ctx->pb); > + if (os->ctx && os->ctx->pb) { > + if (!c->single_file) > + ffio_free_dyn_buf(&os->ctx->pb); > + else > + avio_close(os->ctx->pb); > + } > ff_format_io_close(s, &os->out); > if (os->ctx) > avformat_free_context(os->ctx); > @@ -1106,6 +1116,16 @@ static int dash_init(AVFormatContext *s) > c->lhls = 0; > } > > + if (c->global_sidx && !c->single_file) { > + av_log(s, AV_LOG_WARNING, "Global SIDX option will be ignored as > single_file is not enabled\n"); > + c->global_sidx = 0; > + } > + > + if (c->global_sidx && c->streaming) { > + av_log(s, AV_LOG_WARNING, "Global SIDX option will be ignored as > streaming is enabled\n"); > + c->global_sidx = 0; > + } > + > av_strlcpy(c->dirname, s->url, sizeof(c->dirname)); > ptr = strrchr(c->dirname, '/'); > if (ptr) { > @@ -1201,9 +1221,6 @@ static int dash_init(AVFormatContext *s) > ctx->avoid_negative_ts = s->avoid_negative_ts; > ctx->flags = s->flags; > > - if ((ret = avio_open_dyn_buf(&ctx->pb)) < 0) > - return ret; > - > if (c->single_file) { > if (os->single_file_name) > ff_dash_fill_tmpl_params(os->initfile, sizeof(os->initfile), > os->single_file_name, i, 0, os->bit_rate, 0); > @@ -1214,7 +1231,14 @@ static int dash_init(AVFormatContext *s) > } > snprintf(filename, sizeof(filename), "%s%s", c->dirname, > os->initfile); > set_http_options(&opts, c); > - ret = s->io_open(s, &os->out, filename, AVIO_FLAG_WRITE, &opts); > + if (!c->single_file) { > + if ((ret = avio_open_dyn_buf(&ctx->pb)) < 0) > + return ret; > + ret = s->io_open(s, &os->out, filename, AVIO_FLAG_WRITE, &opts); > + } else { > + ctx->url = av_strdup(filename); > + ret = avio_open2(&ctx->pb, filename, AVIO_FLAG_WRITE, NULL, > &opts); > + } > av_dict_free(&opts); > if (ret < 0) > return ret; > @@ -1232,8 +1256,12 @@ static int dash_init(AVFormatContext *s) > // skip_sidx : Reduce bitrate overhead > // skip_trailer : Avoids growing memory usage with time > av_dict_set(&opts, "movflags", > "frag_every_frame+dash+delay_moov+skip_sidx+skip_trailer", 0); > - else > - av_dict_set(&opts, "movflags", > "frag_custom+dash+delay_moov", 0); > + else { > + if (c->global_sidx) > + av_dict_set(&opts, "movflags", > "frag_custom+dash+delay_moov+global_sidx+skip_trailer", 0); > + else > + av_dict_set(&opts, "movflags", > "frag_custom+dash+delay_moov+skip_trailer", 0); > + } > } else { > av_dict_set_int(&opts, "cluster_time_limit", c->seg_duration / > 1000, 0); > av_dict_set_int(&opts, "cluster_size_limit", 5 * 1024 * 1024, > 0); // set a large cluster size limit > @@ -1518,7 +1546,7 @@ static int dash_flush(AVFormatContext *s, int final, > int stream) > snprintf(os->full_path, sizeof(os->full_path), "%s%s", > c->dirname, os->initfile); > } > > - ret = flush_dynbuf(os, &range_length); > + ret = flush_dynbuf(c, os, &range_length); > if (ret < 0) > break; > os->packets_written = 0; > @@ -1565,6 +1593,29 @@ static int dash_flush(AVFormatContext *s, int final, > int stream) > } > } > > + if (final) { > + for (i = 0; i < s->nb_streams; i++) { > + OutputStream *os = &c->streams[i]; > + if (os->ctx && os->ctx_inited) { > + int file_size = avio_tell(os->ctx->pb); > + av_write_trailer(os->ctx); > + if (c->global_sidx) { > + int j, start_index, start_number; > + int sidx_size = avio_tell(os->ctx->pb) - file_size; > + get_start_index_number(os, c, &start_index, > &start_number); > + if (start_index >= os->nb_segments || > + os->segment_type != SEGMENT_TYPE_MP4) > + continue; > + os->init_range_length += sidx_size; > + for (j = start_index; j < os->nb_segments; j++) { > + Segment *seg = os->segments[j]; > + seg->start_pos += sidx_size; > + } > + } > + > + } > + } > + } > if (ret >= 0) > ret = write_manifest(s, final); > return ret; > @@ -1735,30 +1786,21 @@ static int dash_write_trailer(AVFormatContext *s) > } > dash_flush(s, 1, -1); > > - for (i = 0; i < s->nb_streams; ++i) { > - OutputStream *os = &c->streams[i]; > - if (os->ctx && os->ctx_inited) { > - av_write_trailer(os->ctx); > - } > - > - if (c->remove_at_exit) { > + if (c->remove_at_exit) { > + for (i = 0; i < s->nb_streams; ++i) { > + OutputStream *os = &c->streams[i]; > dashenc_delete_media_segments(s, os, os->nb_segments); > dashenc_delete_segment_file(s, os->initfile); > + if (c->hls_playlist && os->segment_type == SEGMENT_TYPE_MP4) { > + char filename[1024]; > + get_hls_playlist_name(filename, sizeof(filename), > c->dirname, i); > + dashenc_delete_file(s, filename); > + } > } > - } > - > - if (c->remove_at_exit) { > dashenc_delete_file(s, s->url); > > if (c->hls_playlist && c->master_playlist_created) { > char filename[1024]; > - for (i = 0; i < s->nb_streams; ++i) { > - OutputStream *os = &c->streams[i]; > - if (os->segment_type == SEGMENT_TYPE_MP4) { > - get_hls_playlist_name(filename, sizeof(filename), > c->dirname, i); > - dashenc_delete_file(s, filename); > - } > - } > snprintf(filename, sizeof(filename), "%smaster.m3u8", > c->dirname); > dashenc_delete_file(s, filename); > } > @@ -1816,6 +1858,7 @@ static const AVOption options[] = { > { "timeout", "set timeout for socket I/O operations", OFFSET(timeout), > AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT_MAX, .flags = E }, > { "index_correction", "Enable/Disable segment index correction logic", > OFFSET(index_correction), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, > { "format_options","set list of options for the container format > (mp4/webm) used for dash", OFFSET(format_options_str), AV_OPT_TYPE_STRING, > {.str = NULL}, 0, 0, E}, > + { "global_sidx", "Write global SIDX atom. Applicable only for single > file, mp4 output, non-streaming mode", OFFSET(global_sidx), AV_OPT_TYPE_BOOL, > { .i64 = 0 }, 0, 1, E }, > { "dash_segment_type", "set dash segment files type", > OFFSET(segment_type_option), AV_OPT_TYPE_INT, {.i64 = SEGMENT_TYPE_AUTO }, 0, > SEGMENT_TYPE_NB - 1, E, "segment_type"}, > { "auto", "select segment file format based on codec", 0, > AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_AUTO }, 0, UINT_MAX, E, > "segment_type"}, > { "mp4", "make segment file in ISOBMFF format", 0, AV_OPT_TYPE_CONST, > {.i64 = SEGMENT_TYPE_MP4 }, 0, UINT_MAX, E, "segment_type"},
Patchset Pushed. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".