]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/mpeg.c
allocate 32 extra bytes at the end of the probe buffer and remove most probe buf_size...
[ffmpeg] / libavformat / mpeg.c
index cff9fe2b1e09de6b98ef6f5da0653ea2d8c36d31..40a7a259f24942dae0bd48fa889cfd31948c3cc1 100644 (file)
@@ -513,7 +513,7 @@ static int mpeg_mux_init(AVFormatContext *ctx)
     for(i=0;i<ctx->nb_streams;i++) {
         av_free(ctx->streams[i]->priv_data);
     }
-    return -ENOMEM;
+    return AVERROR(ENOMEM);
 }
 
 static inline void put_timestamp(ByteIOContext *pb, int id, int64_t timestamp)
@@ -1260,8 +1260,6 @@ static int mpeg_mux_end(AVFormatContext *ctx)
 static int cdxa_probe(AVProbeData *p)
 {
     /* check file header */
-    if (p->buf_size <= 32)
-        return 0;
     if (p->buf[0] == 'R' && p->buf[1] == 'I' &&
         p->buf[2] == 'F' && p->buf[3] == 'F' &&
         p->buf[8] == 'C' && p->buf[9] == 'D' &&
@@ -1445,6 +1443,7 @@ static int mpegps_read_pes_header(AVFormatContext *s,
 {
     MpegDemuxContext *m = s->priv_data;
     int len, size, startcode, c, flags, header_len;
+    int pes_ext, ext2_len, id_ext, skip;
     int64_t pts, dts;
     int64_t last_sync= url_ftell(&s->pb);
 
@@ -1478,7 +1477,7 @@ static int mpegps_read_pes_header(AVFormatContext *s,
     /* find matching stream */
     if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
           (startcode >= 0x1e0 && startcode <= 0x1ef) ||
-          (startcode == 0x1bd)))
+          (startcode == 0x1bd) || (startcode == 0x1fd)))
         goto redo;
     if (ppos) {
         *ppos = url_ftell(&s->pb) - 4;
@@ -1522,21 +1521,41 @@ static int mpegps_read_pes_header(AVFormatContext *s,
         len -= 2;
         if (header_len > len)
             goto error_redo;
+        len -= header_len;
         if (flags & 0x80) {
             dts = pts = get_pts(&s->pb, -1);
             header_len -= 5;
-            len -= 5;
             if (flags & 0x40) {
                 dts = get_pts(&s->pb, -1);
                 header_len -= 5;
-                len -= 5;
             }
         }
-        len -= header_len;
-        while (header_len > 0) {
-            get_byte(&s->pb);
+        if (flags & 0x01) { /* PES extension */
+            pes_ext = get_byte(&s->pb);
             header_len--;
+            if (pes_ext & 0x40) { /* pack header - should be zero in PS */
+                goto error_redo;
+            }
+            /* Skip PES private data, program packet sequence counter and P-STD buffer */
+            skip = (pes_ext >> 4) & 0xb;
+            skip += skip & 0x9;
+            url_fskip(&s->pb, skip);
+            header_len -= skip;
+
+            if (pes_ext & 0x01) { /* PES extension 2 */
+                ext2_len = get_byte(&s->pb);
+                header_len--;
+                if ((ext2_len & 0x7f) > 0) {
+                    id_ext = get_byte(&s->pb);
+                    if ((id_ext & 0x80) == 0)
+                        startcode = ((startcode & 0xff) << 8) | id_ext;
+                    header_len--;
+                }
+            }
         }
+        if(header_len < 0)
+            goto error_redo;
+        url_fskip(&s->pb, header_len);
     }
     else if( c!= 0xf )
         goto redo;
@@ -1544,12 +1563,17 @@ static int mpegps_read_pes_header(AVFormatContext *s,
     if (startcode == PRIVATE_STREAM_1 && !m->psm_es_type[startcode & 0xff]) {
         startcode = get_byte(&s->pb);
         len--;
-        if (startcode >= 0x80 && startcode <= 0xbf) {
+        if (startcode >= 0x80 && startcode <= 0xcf) {
             /* audio: skip header */
             get_byte(&s->pb);
             get_byte(&s->pb);
             get_byte(&s->pb);
             len -= 3;
+            if (startcode >= 0xb0 && startcode <= 0xbf) {
+                /* MLP/TrueHD audio has a 4-byte header */
+                get_byte(&s->pb);
+                len--;
+            }
         }
     }
     if(len<0)
@@ -1632,15 +1656,27 @@ static int mpegps_read_packet(AVFormatContext *s,
     } else if (startcode >= 0x80 && startcode <= 0x87) {
         type = CODEC_TYPE_AUDIO;
         codec_id = CODEC_ID_AC3;
-    } else if (startcode >= 0x88 && startcode <= 0x9f) {
+    } else if ((startcode >= 0x88 && startcode <= 0x8f)
+               ||( startcode >= 0x98 && startcode <= 0x9f)) {
+        /* 0x90 - 0x97 is reserved for SDDS in DVD specs */
         type = CODEC_TYPE_AUDIO;
         codec_id = CODEC_ID_DTS;
-    } else if (startcode >= 0xa0 && startcode <= 0xbf) {
+    } else if (startcode >= 0xa0 && startcode <= 0xaf) {
         type = CODEC_TYPE_AUDIO;
         codec_id = CODEC_ID_PCM_S16BE;
+    } else if (startcode >= 0xb0 && startcode <= 0xbf) {
+        type = CODEC_TYPE_AUDIO;
+        codec_id = CODEC_ID_MLP;
+    } else if (startcode >= 0xc0 && startcode <= 0xcf) {
+        /* Used for both AC-3 and E-AC-3 in EVOB files */
+        type = CODEC_TYPE_AUDIO;
+        codec_id = CODEC_ID_AC3;
     } else if (startcode >= 0x20 && startcode <= 0x3f) {
         type = CODEC_TYPE_SUBTITLE;
         codec_id = CODEC_ID_DVD_SUBTITLE;
+    } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) {
+        type = CODEC_TYPE_VIDEO;
+        codec_id = CODEC_ID_VC1;
     } else {
     skip:
         /* skip packet */
@@ -1658,7 +1694,7 @@ static int mpegps_read_packet(AVFormatContext *s,
  found:
     if(st->discard >= AVDISCARD_ALL)
         goto skip;
-    if (startcode >= 0xa0 && startcode <= 0xbf) {
+    if (startcode >= 0xa0 && startcode <= 0xaf) {
         int b1, freq;
 
         /* for LPCM, we just skip the header and consider it is raw