]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/mpegts.c
avcodec/jacosubdec: add some memory checks
[ffmpeg] / libavformat / mpegts.c
index a1186895dfc5dd2438a4bd12d87e2faa6745842e..2252b44949f99e06aa75a83848acead6e9ea26b9 100644 (file)
@@ -140,6 +140,8 @@ struct MpegTSContext {
     int skip_changes;
     int skip_clear;
 
+    int resync_size;
+
     /******************************************/
     /* private mpegts data */
     /* scan context */
@@ -153,25 +155,11 @@ struct MpegTSContext {
     int current_pid;
 };
 
-static const AVOption mpegtsraw_options[] = {
-    { "compute_pcr",   "Compute exact PCR for each transport stream packet.",
-          offsetof(MpegTSContext, mpeg2ts_compute_pcr), AV_OPT_TYPE_INT,
-          { .i64 = 0 }, 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 },
-    { NULL },
-};
-
-static const AVClass mpegtsraw_class = {
-    .class_name = "mpegtsraw demuxer",
-    .item_name  = av_default_item_name,
-    .option     = mpegtsraw_options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+#define MPEGTS_OPTIONS \
+    { "resync_size",   "Size limit for looking up a new synchronization.", offsetof(MpegTSContext, resync_size), AV_OPT_TYPE_INT,  { .i64 =  MAX_RESYNC_SIZE}, 0, INT_MAX,  AV_OPT_FLAG_DECODING_PARAM }
 
-static const AVOption mpegts_options[] = {
+static const AVOption options[] = {
+    MPEGTS_OPTIONS,
     {"fix_teletext_pts", "Try to fix pts values of dvb teletext streams.", offsetof(MpegTSContext, fix_teletext_pts), AV_OPT_TYPE_INT,
      {.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,
@@ -186,7 +174,26 @@ static const AVOption mpegts_options[] = {
 static const AVClass mpegts_class = {
     .class_name = "mpegts demuxer",
     .item_name  = av_default_item_name,
-    .option     = mpegts_options,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVOption raw_options[] = {
+    MPEGTS_OPTIONS,
+    { "compute_pcr",   "Compute exact PCR for each transport stream packet.",
+          offsetof(MpegTSContext, mpeg2ts_compute_pcr), AV_OPT_TYPE_INT,
+          { .i64 = 0 }, 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 },
+    { NULL },
+};
+
+static const AVClass mpegtsraw_class = {
+    .class_name = "mpegtsraw demuxer",
+    .item_name  = av_default_item_name,
+    .option     = raw_options,
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
@@ -504,9 +511,9 @@ static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter)
 static int analyze(const uint8_t *buf, int size, int packet_size, int *index)
 {
     int stat[TS_MAX_PACKET_SIZE];
+    int stat_all = 0;
     int i;
     int best_score = 0;
-    int best_score2 = 0;
 
     memset(stat, 0, packet_size * sizeof(*stat));
 
@@ -514,17 +521,16 @@ static int analyze(const uint8_t *buf, int size, int packet_size, int *index)
         if (buf[i] == 0x47 && !(buf[i + 1] & 0x80) && buf[i + 3] != 0x47) {
             int x = i % packet_size;
             stat[x]++;
+            stat_all++;
             if (stat[x] > best_score) {
                 best_score = stat[x];
                 if (index)
                     *index = x;
-            } else if (stat[x] > best_score2) {
-                best_score2 = stat[x];
             }
         }
     }
 
-    return best_score - best_score2;
+    return best_score - FFMAX(stat_all - 10*best_score, 0)/10;
 }
 
 /* autodetect fec presence. Must have at least 1024 bytes  */
@@ -1511,7 +1517,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
 
     av_dlog(fc, "tag: 0x%02x len=%d\n", desc_tag, desc_len);
 
-    if (st->codec->codec_id == AV_CODEC_ID_NONE &&
+    if ((st->codec->codec_id == AV_CODEC_ID_NONE || st->request_probe > 0) &&
         stream_type == STREAM_TYPE_PRIVATE_DATA)
         mpegts_find_stream_type(st, desc_tag, DESC_types);
 
@@ -2188,10 +2194,11 @@ static void reanalyze(MpegTSContext *ts) {
  * get_packet_size() ?) */
 static int mpegts_resync(AVFormatContext *s)
 {
+    MpegTSContext *ts = s->priv_data;
     AVIOContext *pb = s->pb;
     int c, i;
 
-    for (i = 0; i < MAX_RESYNC_SIZE; i++) {
+    for (i = 0; i < ts->resync_size; i++) {
         c = avio_r8(pb);
         if (avio_feof(pb))
             return AVERROR_EOF;