mpegts: reanalyze packet size on mismatches
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 18 Aug 2013 14:35:38 +0000 (16:35 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 18 Aug 2013 14:40:18 +0000 (16:40 +0200)
Fixes Ticket1812
Fixes Ticket2838

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

index 996348a..e1f9865 100644 (file)
@@ -99,6 +99,10 @@ struct MpegTSContext {
     /** raw packet size, including FEC if present            */
     int raw_packet_size;
 
+    int size_stat[3];
+    int size_stat_count;
+#define SIZE_STAT_THRESHOLD 10
+
     int64_t pos47_full;
 
     /** if true, all pids are analyzed to find streams       */
@@ -1901,6 +1905,39 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
     return 0;
 }
 
+static void reanalyze(MpegTSContext *ts) {
+    AVIOContext *pb = ts->stream->pb;
+    int64_t pos = avio_tell(pb);
+    if(pos < 0)
+        return;
+    pos += ts->raw_packet_size - ts->pos47_full;
+    if (pos == TS_PACKET_SIZE) {
+        ts->size_stat[0] ++;
+    } else if (pos == TS_DVHS_PACKET_SIZE) {
+        ts->size_stat[1] ++;
+    } else if (pos == TS_FEC_PACKET_SIZE) {
+        ts->size_stat[2] ++;
+    }
+
+    ts->size_stat_count ++;
+    if(ts->size_stat_count > SIZE_STAT_THRESHOLD) {
+        int newsize = 0;
+        if (ts->size_stat[0] > SIZE_STAT_THRESHOLD) {
+            newsize = TS_PACKET_SIZE;
+        } else if (ts->size_stat[1] > SIZE_STAT_THRESHOLD) {
+            newsize = TS_DVHS_PACKET_SIZE;
+        } else if (ts->size_stat[2] > SIZE_STAT_THRESHOLD) {
+            newsize = TS_FEC_PACKET_SIZE;
+        }
+        if (newsize) {
+            av_log(ts->stream, AV_LOG_WARNING, "changing packet size to %d\n", newsize);
+            ts->raw_packet_size = newsize;
+        }
+        ts->size_stat_count = 0;
+        memset(ts->size_stat, 0, sizeof(ts->size_stat));
+    }
+}
+
 /* XXX: try to find a better synchro over several packets (use
    get_packet_size() ?) */
 static int mpegts_resync(AVFormatContext *s)
@@ -1914,6 +1951,7 @@ static int mpegts_resync(AVFormatContext *s)
             return -1;
         if (c == 0x47) {
             avio_seek(pb, -1, SEEK_CUR);
+            reanalyze(s->priv_data);
             return 0;
         }
     }