aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-08-18 16:35:38 +0200
committerMichael Niedermayer <michaelni@gmx.at>2013-08-18 16:40:18 +0200
commitc666c59ac1a9d78cc706fa9708c400d8bf454cda (patch)
treeed2fc126f5046d6cdcc057db699de61bd9b79f5e
parent7d776062f97d14d5d9db96764f4785c91fb3e1f2 (diff)
downloadffmpeg-c666c59ac1a9d78cc706fa9708c400d8bf454cda.tar.gz
mpegts: reanalyze packet size on mismatches
Fixes Ticket1812 Fixes Ticket2838 Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavformat/mpegts.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 996348af92..e1f9865e47 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -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;
}
}