changeset 4254:d05b13327b07 libavformat

Fix probing of files with ID3v2 tags. Discussed at http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/2009-January/059302.html
author alexc
date Mon, 19 Jan 2009 21:54:06 +0000
parents b43c5c858f25
children 3d4314e9213f
files Makefile id3v2.c id3v2.h mp3.c mpc.c raw.c
diffstat 6 files changed, 43 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Mon Jan 19 17:01:22 2009 +0000
+++ b/Makefile	Mon Jan 19 21:54:06 2009 +0000
@@ -8,7 +8,7 @@
 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_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
--- a/id3v2.c	Mon Jan 19 17:01:22 2009 +0000
+++ b/id3v2.c	Mon Jan 19 21:54:06 2009 +0000
@@ -33,3 +33,15 @@
             (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;
+}
--- a/id3v2.h	Mon Jan 19 17:01:22 2009 +0000
+++ b/id3v2.h	Mon Jan 19 21:54:06 2009 +0000
@@ -32,4 +32,11 @@
  */
 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 */
--- a/mp3.c	Mon Jan 19 17:01:22 2009 +0000
+++ b/mp3.c	Mon Jan 19 21:54:06 2009 +0000
@@ -354,14 +354,16 @@
     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 @@
             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;
--- a/mpc.c	Mon Jan 19 17:01:22 2009 +0000
+++ b/mpc.c	Mon Jan 19 21:54:06 2009 +0000
@@ -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 @@
 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;
 }
 
--- a/raw.c	Mon Jan 19 17:01:22 2009 +0000
+++ b/raw.c	Mon Jan 19 21:54:06 2009 +0000
@@ -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 @@
 {
     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 @@
             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;