Browse Source

- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
needed to detect some files produced by pvr-250/350 capture cards.
- Adds AC3 audio support to the mpegts demuxer, and makes it a little more
tolerant of bad files.
patch by (Isaac Richards <ijr at po dot cwru dot edu>)

Originally committed as revision 2028 to svn://svn.ffmpeg.org/ffmpeg/trunk

Isaac Richards 21 years ago
parent
commit
ec23a47286
3 changed files with 50 additions and 19 deletions
  1. 19 15
      libavformat/mpeg.c
  2. 29 4
      libavformat/mpegts.c
  3. 2 0
      libavformat/mpegts.h

+ 19 - 15
libavformat/mpeg.c

@@ -405,9 +405,10 @@ static int mpeg_mux_end(AVFormatContext *ctx)
 
 
 static int mpegps_probe(AVProbeData *p)
 static int mpegps_probe(AVProbeData *p)
 {
 {
-    int code;
+    int code, c, i;
     const uint8_t *d;
     const uint8_t *d;
 
 
+    code = 0xff;
     /* we search the first start code. If it is a packet start code,
     /* we search the first start code. If it is a packet start code,
        then we decide it is mpeg ps. We do not send highest value to
        then we decide it is mpeg ps. We do not send highest value to
        give a chance to mpegts */
        give a chance to mpegts */
@@ -416,20 +417,23 @@ static int mpegps_probe(AVProbeData *p)
 
 
     if (p->buf_size < 6)
     if (p->buf_size < 6)
         return 0;
         return 0;
-    d = p->buf;
-    code = (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | (d[3]);
-    if ((code & 0xffffff00) == 0x100) {
-        if (code == PACK_START_CODE ||
-            code == SYSTEM_HEADER_START_CODE ||
-            (code >= 0x1e0 && code <= 0x1ef) ||
-            (code >= 0x1c0 && code <= 0x1df) ||
-            code == PRIVATE_STREAM_2 ||
-            code == PROGRAM_STREAM_MAP ||
-            code == PRIVATE_STREAM_1 ||
-            code == PADDING_STREAM)
-            return AVPROBE_SCORE_MAX - 1;
-        else
-            return 0;
+
+    for (i = 0; i < 20; i++) {
+        c = p->buf[i];
+        code = (code << 8) | c;
+        if ((code & 0xffffff00) == 0x100) {
+            if (code == PACK_START_CODE ||
+                code == SYSTEM_HEADER_START_CODE ||
+                (code >= 0x1e0 && code <= 0x1ef) ||
+                (code >= 0x1c0 && code <= 0x1df) ||
+                code == PRIVATE_STREAM_2 ||
+                code == PROGRAM_STREAM_MAP ||
+                code == PRIVATE_STREAM_1 ||
+                code == PADDING_STREAM)
+                return AVPROBE_SCORE_MAX - 1;
+            else
+                return 0;
+        }
     }
     }
     return 0;
     return 0;
 }
 }

+ 29 - 4
libavformat/mpegts.c

@@ -387,6 +387,7 @@ static void pmt_cb(void *opaque, const uint8_t *section, int section_len)
         case STREAM_TYPE_AUDIO_MPEG2:
         case STREAM_TYPE_AUDIO_MPEG2:
         case STREAM_TYPE_VIDEO_MPEG1:
         case STREAM_TYPE_VIDEO_MPEG1:
         case STREAM_TYPE_VIDEO_MPEG2:
         case STREAM_TYPE_VIDEO_MPEG2:
+        case STREAM_TYPE_AUDIO_AC3:
             add_pes_stream(ts->stream, pid);
             add_pes_stream(ts->stream, pid);
             break;
             break;
         default:
         default:
@@ -613,16 +614,19 @@ static void mpegts_push_data(void *opaque,
                 if (pes->header[0] == 0x00 && pes->header[1] == 0x00 &&
                 if (pes->header[0] == 0x00 && pes->header[1] == 0x00 &&
                     pes->header[2] == 0x01) {
                     pes->header[2] == 0x01) {
                     /* it must be an mpeg2 PES stream */
                     /* it must be an mpeg2 PES stream */
-                    /* XXX: add AC3 support */
                     code = pes->header[3] | 0x100;
                     code = pes->header[3] | 0x100;
                     if (!((code >= 0x1c0 && code <= 0x1df) ||
                     if (!((code >= 0x1c0 && code <= 0x1df) ||
-                          (code >= 0x1e0 && code <= 0x1ef)))
+                          (code >= 0x1e0 && code <= 0x1ef) ||
+                          (code == 0x1bd)))
                         goto skip;
                         goto skip;
                     if (!pes->st) {
                     if (!pes->st) {
                         /* allocate stream */
                         /* allocate stream */
                         if (code >= 0x1c0 && code <= 0x1df) {
                         if (code >= 0x1c0 && code <= 0x1df) {
                             codec_type = CODEC_TYPE_AUDIO;
                             codec_type = CODEC_TYPE_AUDIO;
                             codec_id = CODEC_ID_MP2;
                             codec_id = CODEC_ID_MP2;
+                        } else if (code == 0x1bd) {
+                            codec_type = CODEC_TYPE_AUDIO;
+                            codec_id = CODEC_ID_AC3;
                         } else {
                         } else {
                             codec_type = CODEC_TYPE_VIDEO;
                             codec_type = CODEC_TYPE_VIDEO;
                             codec_id = CODEC_ID_MPEG1VIDEO;
                             codec_id = CODEC_ID_MPEG1VIDEO;
@@ -805,6 +809,8 @@ static int handle_packets(AVFormatContext *s, int nb_packets)
     ByteIOContext *pb = &s->pb;
     ByteIOContext *pb = &s->pb;
     uint8_t packet[TS_FEC_PACKET_SIZE];
     uint8_t packet[TS_FEC_PACKET_SIZE];
     int packet_num, len;
     int packet_num, len;
+    int i, found = 0;
+    int64_t pos;
 
 
     ts->stop_parse = 0;
     ts->stop_parse = 0;
     packet_num = 0;
     packet_num = 0;
@@ -814,13 +820,32 @@ static int handle_packets(AVFormatContext *s, int nb_packets)
         packet_num++;
         packet_num++;
         if (nb_packets != 0 && packet_num >= nb_packets)
         if (nb_packets != 0 && packet_num >= nb_packets)
             break;
             break;
+        pos = url_ftell(pb);
         len = get_buffer(pb, packet, ts->raw_packet_size);
         len = get_buffer(pb, packet, ts->raw_packet_size);
         if (len != ts->raw_packet_size)
         if (len != ts->raw_packet_size)
             return AVERROR_IO;
             return AVERROR_IO;
         /* check paquet sync byte */
         /* check paquet sync byte */
-        /* XXX: accept to resync ? */
         if (packet[0] != 0x47)
         if (packet[0] != 0x47)
-            return AVERROR_INVALIDDATA;
+        {
+           //printf("bad packet: 0x%x\n", packet[0]);
+           found = 0;
+           for (i = 0; i < ts->raw_packet_size; i++)
+           {
+               if (packet[i] == 0x47)
+               {
+                   found = 1;
+                   //printf("packet start at: %d\n", i);
+                   break;
+               }
+           }
+           
+           if (found)
+           {
+               url_fseek(pb, pos + i, SEEK_SET);
+               continue;
+           }
+           return AVERROR_INVALIDDATA;
+        }
         handle_packet(s, packet);
         handle_packet(s, packet);
     }
     }
     return 0;
     return 0;

+ 2 - 0
libavformat/mpegts.h

@@ -38,5 +38,7 @@
 #define STREAM_TYPE_PRIVATE_SECTION 0x05
 #define STREAM_TYPE_PRIVATE_SECTION 0x05
 #define STREAM_TYPE_PRIVATE_DATA    0x06
 #define STREAM_TYPE_PRIVATE_DATA    0x06
 
 
+#define STREAM_TYPE_AUDIO_AC3       0x81
+
 unsigned int mpegts_crc32(const uint8_t *data, int len);
 unsigned int mpegts_crc32(const uint8_t *data, int len);
 extern AVOutputFormat mpegts_mux;
 extern AVOutputFormat mpegts_mux;