Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated...
authorMichael Niedermayer <michaelni@gmx.at>
Tue, 6 Feb 2007 19:14:16 +0000 (19:14 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Tue, 6 Feb 2007 19:14:16 +0000 (19:14 +0000)
Originally committed as revision 7853 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/avcodec.h
libavformat/mpeg.c

index 416d8ea..497439b 100644 (file)
@@ -238,6 +238,7 @@ enum CodecID {
     CODEC_ID_DSICINAUDIO,
     CODEC_ID_IMC,
     CODEC_ID_MUSEPACK7,
+    CODEC_ID_MLP,
 
     /* subtitle codecs */
     CODEC_ID_DVD_SUBTITLE= 0x17000,
index a8ba882..06f27a9 100644 (file)
@@ -1445,6 +1445,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 +1479,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;
@@ -1531,6 +1532,29 @@ static int mpegps_read_pes_header(AVFormatContext *s,
                 header_len -= 5;
             }
         }
+        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);
@@ -1541,12 +1565,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)
@@ -1629,15 +1658,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 */
@@ -1655,7 +1696,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