avformat/mpegts: skip updating programs/streams when determining duration
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 11 Jul 2014 14:42:52 +0000 (16:42 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 11 Jul 2014 14:43:27 +0000 (16:43 +0200)
Fixes Ticket2441

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavformat/mpegts.c
libavformat/utils.c

index d03fe2f..e814ab4 100644 (file)
@@ -137,6 +137,8 @@ struct MpegTSContext {
     /** to detect seek */
     int64_t last_pos;
 
+    int skip_changes;
+
     /******************************************/
     /* private mpegts data */
     /* scan context */
@@ -173,6 +175,8 @@ static const AVOption mpegts_options[] = {
      {.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
     {"ts_packetsize", "Output option carrying the raw packet size.", offsetof(MpegTSContext, raw_packet_size), AV_OPT_TYPE_INT,
      {.i64 = 0}, 0, 0, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY },
+    {"skip_changes", "Skip changing / adding streams / programs.", offsetof(MpegTSContext, skip_changes), AV_OPT_TYPE_INT,
+     {.i64 = 0}, 0, 1, 0 },
     { NULL },
 };
 
@@ -237,6 +241,7 @@ static void clear_avprogram(MpegTSContext *ts, unsigned int programid)
 {
     AVProgram *prg = NULL;
     int i;
+
     for (i = 0; i < ts->stream->nb_programs; i++)
         if (ts->stream->programs[i]->id == programid) {
             prg = ts->stream->programs[i];
@@ -952,6 +957,9 @@ static int mpegts_push_data(MpegTSFilter *filter,
 
                     /* stream not present in PMT */
                     if (!pes->st) {
+                        if (ts->skip_changes)
+                            goto skip;
+
                         pes->st = avformat_new_stream(ts->stream, NULL);
                         if (!pes->st)
                             return AVERROR(ENOMEM);
@@ -1721,6 +1729,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
 
     if (h->tid != PMT_TID)
         return;
+    if (ts->skip_changes)
+        return;
 
     clear_program(ts, h->id);
     pcr_pid = get16(&p, p_end);
@@ -1874,6 +1884,8 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
         return;
     if (h->tid != PAT_TID)
         return;
+    if (ts->skip_changes)
+        return;
 
     ts->stream->ts_id = h->id;
 
@@ -1942,6 +1954,8 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
         return;
     if (h->tid != SDT_TID)
         return;
+    if (ts->skip_changes)
+        return;
     onid = get16(&p, p_end);
     if (onid < 0)
         return;
index b25576e..3afe488 100644 (file)
@@ -2500,6 +2500,7 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
         }
     }
 
+    av_opt_set(ic, "skip_changes", "1", AV_OPT_SEARCH_CHILDREN);
     /* estimate the end time (duration) */
     /* XXX: may need to support wrapping */
     filesize = ic->pb ? avio_size(ic->pb) : 0;
@@ -2567,6 +2568,8 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
              offset &&
              ++retry <= DURATION_MAX_RETRY);
 
+    av_opt_set(ic, "skip_changes", "0", AV_OPT_SEARCH_CHILDREN);
+
     /* warn about audio/video streams which duration could not be estimated */
     for (i = 0; i < ic->nb_streams; i++) {
         st = ic->streams[i];