Fix probing of files with ID3v2 tags. Discussed at
authorAlex Converse <alex.converse@gmail.com>
Mon, 19 Jan 2009 21:54:06 +0000 (21:54 +0000)
committerAlex Converse <alex.converse@gmail.com>
Mon, 19 Jan 2009 21:54:06 +0000 (21:54 +0000)
http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/2009-January/059302.html

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

libavformat/Makefile
libavformat/id3v2.c
libavformat/id3v2.h
libavformat/mp3.c
libavformat/mpc.c
libavformat/raw.c

index 231afbb..6879d6a 100644 (file)
@@ -8,7 +8,7 @@ HEADERS = avformat.h avio.h rtsp.h rtspcodes.h
 OBJS = allformats.o cutils.o metadata.o metadata_compat.o options.o os_support.o sdp.o utils.o
 
 # muxers/demuxers
-OBJS-$(CONFIG_AAC_DEMUXER)               += raw.o
+OBJS-$(CONFIG_AAC_DEMUXER)               += raw.o id3v2.o
 OBJS-$(CONFIG_AC3_DEMUXER)               += raw.o
 OBJS-$(CONFIG_AC3_MUXER)                 += raw.o
 OBJS-$(CONFIG_ADTS_MUXER)                += adtsenc.o
@@ -97,7 +97,7 @@ OBJS-$(CONFIG_MP2_MUXER)                 += mp3.o
 OBJS-$(CONFIG_MP3_DEMUXER)               += mp3.o id3v2.o
 OBJS-$(CONFIG_MP3_MUXER)                 += mp3.o
 OBJS-$(CONFIG_MP4_MUXER)                 += movenc.o riff.o isom.o avc.o
-OBJS-$(CONFIG_MPC_DEMUXER)               += mpc.o
+OBJS-$(CONFIG_MPC_DEMUXER)               += mpc.o id3v2.o
 OBJS-$(CONFIG_MPC8_DEMUXER)              += mpc8.o
 OBJS-$(CONFIG_MPEG1SYSTEM_MUXER)         += mpegenc.o
 OBJS-$(CONFIG_MPEG1VCD_MUXER)            += mpegenc.o
index c27443b..018fd51 100644 (file)
@@ -33,3 +33,15 @@ int ff_id3v2_match(const uint8_t *buf)
             (buf[8] & 0x80) == 0 &&
             (buf[9] & 0x80) == 0;
 }
+
+int ff_id3v2_tag_len(const uint8_t * buf)
+{
+    int len = ((buf[6] & 0x7f) << 21) +
+        ((buf[7] & 0x7f) << 14) +
+        ((buf[8] & 0x7f) << 7) +
+        (buf[9] & 0x7f) +
+        ID3v2_HEADER_SIZE;
+    if (buf[5] & 0x10)
+        len += ID3v2_HEADER_SIZE;
+    return len;
+}
index f54e290..6d62f11 100644 (file)
  */
 int ff_id3v2_match(const uint8_t *buf);
 
+/**
+ * Gets the length of an ID3v2 tag.
+ * @buf must be ID3v2_HEADER_SIZE bytes long and point to the start of an
+ * already detected ID3v2 tag
+ */
+int ff_id3v2_tag_len(const uint8_t *buf);
+
 #endif /* AVFORMAT_ID3V2_H */
index 1a3c5e2..ec8c0bb 100644 (file)
@@ -354,14 +354,16 @@ static int mp3_read_probe(AVProbeData *p)
     int max_frames, first_frames = 0;
     int fsize, frames, sample_rate;
     uint32_t header;
-    uint8_t *buf, *buf2, *end;
+    uint8_t *buf, *buf0, *buf2, *end;
     AVCodecContext avctx;
 
-    if(ff_id3v2_match(p->buf))
-        return AVPROBE_SCORE_MAX/2+1; // this must be less than mpeg-ps because some retards put id3v2 tags before mpeg-ps files
+    buf0 = p->buf;
+    if(ff_id3v2_match(buf0)) {
+        buf0 += ff_id3v2_tag_len(buf0);
+    }
 
     max_frames = 0;
-    buf = p->buf;
+    buf = buf0;
     end = buf + p->buf_size - sizeof(uint32_t);
 
     for(; buf < end; buf= buf2+1) {
@@ -375,7 +377,7 @@ static int mp3_read_probe(AVProbeData *p)
             buf2 += fsize;
         }
         max_frames = FFMAX(max_frames, frames);
-        if(buf == p->buf)
+        if(buf == buf0)
             first_frames= frames;
     }
     if   (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;
index 1a22c11..9dbd239 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "libavcodec/bitstream.h"
 #include "avformat.h"
+#include "id3v2.h"
 
 #define MPC_FRAMESIZE  1152
 #define DELAY_FRAMES   32
@@ -43,10 +44,12 @@ typedef struct {
 static int mpc_probe(AVProbeData *p)
 {
     const uint8_t *d = p->buf;
+    if (ff_id3v2_match(d)) {
+        d += ff_id3v2_tag_len(d);
+    }
+    if (d+3 < p->buf+p->buf_size)
     if (d[0] == 'M' && d[1] == 'P' && d[2] == '+' && (d[3] == 0x17 || d[3] == 0x7))
         return AVPROBE_SCORE_MAX;
-    if (d[0] == 'I' && d[1] == 'D' && d[2] == '3')
-        return AVPROBE_SCORE_MAX / 2;
     return 0;
 }
 
index 2ca011e..fe6f6e4 100644 (file)
@@ -26,6 +26,7 @@
 #include "libavcodec/bytestream.h"
 #include "avformat.h"
 #include "raw.h"
+#include "id3v2.h"
 
 /* simple formats */
 #if CONFIG_FLAC_MUXER
@@ -582,9 +583,15 @@ static int adts_aac_probe(AVProbeData *p)
 {
     int max_frames = 0, first_frames = 0;
     int fsize, frames;
+    uint8_t *buf0 = p->buf;
     uint8_t *buf2;
-    uint8_t *buf = p->buf;
-    uint8_t *end = buf + p->buf_size - 7;
+    uint8_t *buf;
+    uint8_t *end = buf0 + p->buf_size - 7;
+
+    if (ff_id3v2_match(buf0)) {
+        buf0 += ff_id3v2_tag_len(buf0);
+    }
+    buf = buf0;
 
     for(; buf < end; buf= buf2+1) {
         buf2 = buf;
@@ -599,7 +606,7 @@ static int adts_aac_probe(AVProbeData *p)
             buf2 += fsize;
         }
         max_frames = FFMAX(max_frames, frames);
-        if(buf == p->buf)
+        if(buf == buf0)
             first_frames= frames;
     }
     if   (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;