Browse code

Generalize ID3v2 functions to support ID3v2-like ID headers with a different magic in the header (mainly targeted to Sony's .oma/.aa3 format).

Patch by Michael Karcher, ffmpeg A mkarcher dialup fu-berlin de

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

Michael Karcher authored on 2010/06/11 22:44:57
Showing 7 changed files
... ...
@@ -43,7 +43,7 @@ static int flac_read_header(AVFormatContext *s,
43 43
 
44 44
     /* skip ID3v2 header if found */
45 45
     ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE);
46
-    if (ret == ID3v2_HEADER_SIZE && ff_id3v2_match(buf)) {
46
+    if (ret == ID3v2_HEADER_SIZE && ff_id3v2_match(buf, ID3v2_DEFAULT_MAGIC)) {
47 47
         int len = ff_id3v2_tag_len(buf);
48 48
         url_fseek(s->pb, len - ID3v2_HEADER_SIZE, SEEK_CUR);
49 49
     } else {
... ...
@@ -130,7 +130,7 @@ static int flac_probe(AVProbeData *p)
130 130
     uint8_t *bufptr = p->buf;
131 131
     uint8_t *end    = p->buf + p->buf_size;
132 132
 
133
-    if(ff_id3v2_match(bufptr))
133
+    if(ff_id3v2_match(bufptr, ID3v2_DEFAULT_MAGIC))
134 134
         bufptr += ff_id3v2_tag_len(bufptr);
135 135
 
136 136
     if(bufptr > end-4 || memcmp(bufptr, "fLaC", 4)) return 0;
... ...
@@ -22,12 +22,13 @@
22 22
 #include "id3v2.h"
23 23
 #include "id3v1.h"
24 24
 #include "libavutil/avstring.h"
25
+#include "libavutil/intreadwrite.h"
25 26
 
26
-int ff_id3v2_match(const uint8_t *buf)
27
+int ff_id3v2_match(const uint8_t *buf, const char * magic)
27 28
 {
28
-    return  buf[0]         ==  'I' &&
29
-            buf[1]         ==  'D' &&
30
-            buf[2]         ==  '3' &&
29
+    return  buf[0]         == magic[0] &&
30
+            buf[1]         == magic[1] &&
31
+            buf[2]         == magic[2] &&
31 32
             buf[3]         != 0xff &&
32 33
             buf[4]         != 0xff &&
33 34
            (buf[6] & 0x80) ==    0 &&
... ...
@@ -48,7 +49,7 @@ int ff_id3v2_tag_len(const uint8_t * buf)
48 48
     return len;
49 49
 }
50 50
 
51
-void ff_id3v2_read(AVFormatContext *s)
51
+void ff_id3v2_read(AVFormatContext *s, const char *magic)
52 52
 {
53 53
     int len, ret;
54 54
     uint8_t buf[ID3v2_HEADER_SIZE];
... ...
@@ -56,7 +57,7 @@ void ff_id3v2_read(AVFormatContext *s)
56 56
     ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE);
57 57
     if (ret != ID3v2_HEADER_SIZE)
58 58
         return;
59
-    if (ff_id3v2_match(buf)) {
59
+    if (ff_id3v2_match(buf, magic)) {
60 60
         /* parse ID3v2 header */
61 61
         len = ((buf[6] & 0x7f) << 21) |
62 62
             ((buf[7] & 0x7f) << 14) |
... ...
@@ -29,10 +29,17 @@
29 29
 #define ID3v2_HEADER_SIZE 10
30 30
 
31 31
 /**
32
+ * Default magic bytes for ID3v2 header: "ID3"
33
+ */
34
+#define ID3v2_DEFAULT_MAGIC "ID3"
35
+
36
+/**
32 37
  * Detects ID3v2 Header.
33
- * @buf must be ID3v2_HEADER_SIZE byte long
38
+ * @buf   must be ID3v2_HEADER_SIZE byte long
39
+ * @magic magic bytes to identify the header, machine byte order.
40
+ * If in doubt, use ID3v2_DEFAULT_MAGIC.
34 41
  */
35
-int ff_id3v2_match(const uint8_t *buf);
42
+int ff_id3v2_match(const uint8_t *buf, const char *magic);
36 43
 
37 44
 /**
38 45
  * Gets the length of an ID3v2 tag.
... ...
@@ -50,7 +57,7 @@ void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags)
50 50
 /**
51 51
  * Read an ID3v2 tag
52 52
  */
53
-void ff_id3v2_read(AVFormatContext *s);
53
+void ff_id3v2_read(AVFormatContext *s, const char *magic);
54 54
 
55 55
 extern const AVMetadataConv ff_id3v2_metadata_conv[];
56 56
 
... ...
@@ -42,7 +42,7 @@ static int mp3_read_probe(AVProbeData *p)
42 42
     AVCodecContext avctx;
43 43
 
44 44
     buf0 = p->buf;
45
-    if(ff_id3v2_match(buf0)) {
45
+    if(ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC)) {
46 46
         buf0 += ff_id3v2_tag_len(buf0);
47 47
     }
48 48
     end = p->buf + p->buf_size - sizeof(uint32_t);
... ...
@@ -148,7 +148,7 @@ static int mp3_read_header(AVFormatContext *s,
148 148
     // lcm of all mp3 sample rates
149 149
     av_set_pts_info(st, 64, 1, 14112000);
150 150
 
151
-    ff_id3v2_read(s);
151
+    ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC);
152 152
     off = url_ftell(s->pb);
153 153
 
154 154
     if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
... ...
@@ -45,7 +45,7 @@ typedef struct {
45 45
 static int mpc_probe(AVProbeData *p)
46 46
 {
47 47
     const uint8_t *d = p->buf;
48
-    if (ff_id3v2_match(d)) {
48
+    if (ff_id3v2_match(d, ID3v2_DEFAULT_MAGIC)) {
49 49
         d += ff_id3v2_tag_len(d);
50 50
     }
51 51
     if (d+3 < p->buf+p->buf_size)
... ...
@@ -67,7 +67,7 @@ static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap)
67 67
         if (url_fseek(s->pb, pos, SEEK_SET) < 0)
68 68
             return -1;
69 69
         ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE);
70
-        if (ret != ID3v2_HEADER_SIZE || !ff_id3v2_match(buf)) {
70
+        if (ret != ID3v2_HEADER_SIZE || !ff_id3v2_match(buf, ID3v2_DEFAULT_MAGIC)) {
71 71
             av_log(s, AV_LOG_ERROR, "Not a Musepack file\n");
72 72
             return -1;
73 73
         }
... ...
@@ -82,7 +82,7 @@ static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap)
82 82
         /* read ID3 tags */
83 83
         if (url_fseek(s->pb, pos, SEEK_SET) < 0)
84 84
             return -1;
85
-        ff_id3v2_read(s);
85
+        ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC);
86 86
         get_le24(s->pb);
87 87
     }
88 88
     c->ver = get_byte(s->pb);
... ...
@@ -664,7 +664,7 @@ static int adts_aac_probe(AVProbeData *p)
664 664
     uint8_t *buf;
665 665
     uint8_t *end = buf0 + p->buf_size - 7;
666 666
 
667
-    if (ff_id3v2_match(buf0)) {
667
+    if (ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC)) {
668 668
         buf0 += ff_id3v2_tag_len(buf0);
669 669
     }
670 670
     buf = buf0;
... ...
@@ -706,7 +706,7 @@ static int adts_aac_read_header(AVFormatContext *s,
706 706
     st->need_parsing = AVSTREAM_PARSE_FULL;
707 707
 
708 708
     ff_id3v1_read(s);
709
-    ff_id3v2_read(s);
709
+    ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC);
710 710
 
711 711
     return 0;
712 712
 }
... ...
@@ -32,7 +32,7 @@ static int tta_probe(AVProbeData *p)
32 32
 {
33 33
     const uint8_t *d = p->buf;
34 34
 
35
-    if (ff_id3v2_match(d))
35
+    if (ff_id3v2_match(d, ID3v2_DEFAULT_MAGIC))
36 36
         d += ff_id3v2_tag_len(d);
37 37
 
38 38
     if (d - p->buf >= p->buf_size)
... ...
@@ -50,7 +50,7 @@ static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap)
50 50
     int i, channels, bps, samplerate, datalen, framelen;
51 51
     uint64_t framepos, start_offset;
52 52
 
53
-    ff_id3v2_read(s);
53
+    ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC);
54 54
     if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
55 55
         ff_id3v1_read(s);
56 56