Based on patches by Rodger Combs.
---
 libavformat/dashenc.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 5afc40b..a76acf2 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -93,6 +93,7 @@ typedef struct DASHContext {
     const char *single_file_name;
     const char *init_seg_name;
     const char *media_seg_name;
+    int start_segment;
 } DASHContext;
 
 static int dash_write(void *opaque, uint8_t *buf, int buf_size)
@@ -195,10 +196,10 @@ static void dash_free(AVFormatContext *s)
 
 static void output_segment_list(OutputStream *os, AVIOContext *out, 
DASHContext *c)
 {
-    int i, start_index = 0, start_number = 1;
+    int i, start_index = 0, start_number = c->start_segment;
     if (c->window_size) {
         start_index  = FFMAX(os->nb_segments   - c->window_size, 0);
-        start_number = FFMAX(os->segment_index - c->window_size, 1);
+        start_number = FFMAX(os->segment_index - c->window_size, 
c->start_segment);
     }
 
     if (c->use_template) {
@@ -206,7 +207,7 @@ static void output_segment_list(OutputStream *os, 
AVIOContext *out, DASHContext
         avio_printf(out, "\t\t\t\t<SegmentTemplate timescale=\"%d\" ", 
timescale);
         if (!c->use_timeline)
             avio_printf(out, "duration=\"%"PRId64"\" ", c->last_duration);
-        avio_printf(out, "initialization=\"%s\" media=\"%s\" 
startNumber=\"%d\">\n", c->init_seg_name, c->media_seg_name, c->use_timeline ? 
start_number : 1);
+        avio_printf(out, "initialization=\"%s\" media=\"%s\" 
startNumber=\"%d\">\n", c->init_seg_name, c->media_seg_name, c->use_timeline ? 
start_number : c->start_segment);
         if (c->use_timeline) {
             int64_t cur_time = 0;
             avio_printf(out, "\t\t\t\t\t<SegmentTimeline>\n");
@@ -541,6 +542,13 @@ static int dash_write_header(AVFormatContext *s)
     if (c->single_file)
         c->use_template = 0;
 
+    /* If starting at a later segment than the first, don't shift
+     * timestamps back to zero, just make them nonnegative. The fragment
+     * timestamp offset written in the tfdt atoms assume that the stream
+     * starts (in the fragments that haven't been written) at dts=0. */
+    if (c->start_segment > 1 && s->avoid_negative_ts == 
AVFMT_AVOID_NEG_TS_AUTO)
+        s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE;
+
     av_strlcpy(c->dirname, s->filename, sizeof(c->dirname));
     ptr = strrchr(c->dirname, '/');
     if (ptr) {
@@ -626,7 +634,11 @@ static int dash_write_header(AVFormatContext *s)
             goto fail;
         os->init_start_pos = 0;
 
-        av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0);
+        if (c->start_segment > 1) {
+            av_dict_set(&opts, "movflags", 
"frag_custom+dash+delay_moov+frag_discont", 0);
+        } else {
+            av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0);
+        }
         if ((ret = avformat_write_header(ctx, &opts)) < 0) {
              goto fail;
         }
@@ -649,7 +661,7 @@ static int dash_write_header(AVFormatContext *s)
         set_codec_str(s, os->ctx->streams[0]->codec, os->codec_str, 
sizeof(os->codec_str));
         os->first_dts = AV_NOPTS_VALUE;
         os->end_dts = AV_NOPTS_VALUE;
-        os->segment_index = 1;
+        os->segment_index = c->start_segment;
     }
 
     if (!c->has_video && c->min_seg_duration <= 0) {
@@ -765,6 +777,7 @@ static int dash_flush(AVFormatContext *s, int final, int 
stream)
                 ffurl_close(os->out);
                 os->out = NULL;
             }
+            av_opt_set_int(os->ctx, "fragment_index", os->segment_index, 
AV_OPT_SEARCH_CHILDREN);
         }
 
         start_pos = avio_tell(os->ctx->pb);
@@ -929,6 +942,7 @@ static const AVOption options[] = {
     { "single_file_name", "DASH-templated name to be used for baseURL. Implies 
storing all segments in one file, accessed using byte ranges", 
OFFSET(single_file_name), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
     { "init_seg_name", "DASH-templated name to used for the initialization 
segment", OFFSET(init_seg_name), AV_OPT_TYPE_STRING, {.str = 
"init-stream$RepresentationID$.m4s"}, 0, 0, E },
     { "media_seg_name", "DASH-templated name to used for the media segments", 
OFFSET(media_seg_name), AV_OPT_TYPE_STRING, {.str = 
"chunk-stream$RepresentationID$-$Number%05d$.m4s"}, 0, 0, E },
+    { "start_segment", "Segment number of the first segment", 
OFFSET(start_segment), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, E },
     { NULL },
 };
 
-- 
1.9.3 (Apple Git-50)

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

Reply via email to