Mercurial > libavformat.hg
comparison mp3.c @ 5016:eb6dd7717805 libavformat
Move id3v2 parsing code from mp3.c to id3v2.h and id3v2.c.
patch by Patrick Dehne, patrick mysonicweb com
author | diego |
---|---|
date | Thu, 11 Jun 2009 15:26:57 +0000 |
parents | d24b4e25db8d |
children | 9ed3c88ed9ba |
comparison
equal
deleted
inserted
replaced
5015:7b260f4d453d | 5016:eb6dd7717805 |
---|---|
23 #include "libavutil/avstring.h" | 23 #include "libavutil/avstring.h" |
24 #include "libavcodec/mpegaudio.h" | 24 #include "libavcodec/mpegaudio.h" |
25 #include "libavcodec/mpegaudiodecheader.h" | 25 #include "libavcodec/mpegaudiodecheader.h" |
26 #include "avformat.h" | 26 #include "avformat.h" |
27 #include "id3v2.h" | 27 #include "id3v2.h" |
28 | 28 #include "id3v1.h" |
29 #define ID3v1_TAG_SIZE 128 | |
30 | |
31 #define ID3v1_GENRE_MAX 125 | |
32 | |
33 static const char * const id3v1_genre_str[ID3v1_GENRE_MAX + 1] = { | |
34 [0] = "Blues", | |
35 [1] = "Classic Rock", | |
36 [2] = "Country", | |
37 [3] = "Dance", | |
38 [4] = "Disco", | |
39 [5] = "Funk", | |
40 [6] = "Grunge", | |
41 [7] = "Hip-Hop", | |
42 [8] = "Jazz", | |
43 [9] = "Metal", | |
44 [10] = "New Age", | |
45 [11] = "Oldies", | |
46 [12] = "Other", | |
47 [13] = "Pop", | |
48 [14] = "R&B", | |
49 [15] = "Rap", | |
50 [16] = "Reggae", | |
51 [17] = "Rock", | |
52 [18] = "Techno", | |
53 [19] = "Industrial", | |
54 [20] = "Alternative", | |
55 [21] = "Ska", | |
56 [22] = "Death Metal", | |
57 [23] = "Pranks", | |
58 [24] = "Soundtrack", | |
59 [25] = "Euro-Techno", | |
60 [26] = "Ambient", | |
61 [27] = "Trip-Hop", | |
62 [28] = "Vocal", | |
63 [29] = "Jazz+Funk", | |
64 [30] = "Fusion", | |
65 [31] = "Trance", | |
66 [32] = "Classical", | |
67 [33] = "Instrumental", | |
68 [34] = "Acid", | |
69 [35] = "House", | |
70 [36] = "Game", | |
71 [37] = "Sound Clip", | |
72 [38] = "Gospel", | |
73 [39] = "Noise", | |
74 [40] = "AlternRock", | |
75 [41] = "Bass", | |
76 [42] = "Soul", | |
77 [43] = "Punk", | |
78 [44] = "Space", | |
79 [45] = "Meditative", | |
80 [46] = "Instrumental Pop", | |
81 [47] = "Instrumental Rock", | |
82 [48] = "Ethnic", | |
83 [49] = "Gothic", | |
84 [50] = "Darkwave", | |
85 [51] = "Techno-Industrial", | |
86 [52] = "Electronic", | |
87 [53] = "Pop-Folk", | |
88 [54] = "Eurodance", | |
89 [55] = "Dream", | |
90 [56] = "Southern Rock", | |
91 [57] = "Comedy", | |
92 [58] = "Cult", | |
93 [59] = "Gangsta", | |
94 [60] = "Top 40", | |
95 [61] = "Christian Rap", | |
96 [62] = "Pop/Funk", | |
97 [63] = "Jungle", | |
98 [64] = "Native American", | |
99 [65] = "Cabaret", | |
100 [66] = "New Wave", | |
101 [67] = "Psychadelic", | |
102 [68] = "Rave", | |
103 [69] = "Showtunes", | |
104 [70] = "Trailer", | |
105 [71] = "Lo-Fi", | |
106 [72] = "Tribal", | |
107 [73] = "Acid Punk", | |
108 [74] = "Acid Jazz", | |
109 [75] = "Polka", | |
110 [76] = "Retro", | |
111 [77] = "Musical", | |
112 [78] = "Rock & Roll", | |
113 [79] = "Hard Rock", | |
114 [80] = "Folk", | |
115 [81] = "Folk-Rock", | |
116 [82] = "National Folk", | |
117 [83] = "Swing", | |
118 [84] = "Fast Fusion", | |
119 [85] = "Bebob", | |
120 [86] = "Latin", | |
121 [87] = "Revival", | |
122 [88] = "Celtic", | |
123 [89] = "Bluegrass", | |
124 [90] = "Avantgarde", | |
125 [91] = "Gothic Rock", | |
126 [92] = "Progressive Rock", | |
127 [93] = "Psychedelic Rock", | |
128 [94] = "Symphonic Rock", | |
129 [95] = "Slow Rock", | |
130 [96] = "Big Band", | |
131 [97] = "Chorus", | |
132 [98] = "Easy Listening", | |
133 [99] = "Acoustic", | |
134 [100] = "Humour", | |
135 [101] = "Speech", | |
136 [102] = "Chanson", | |
137 [103] = "Opera", | |
138 [104] = "Chamber Music", | |
139 [105] = "Sonata", | |
140 [106] = "Symphony", | |
141 [107] = "Booty Bass", | |
142 [108] = "Primus", | |
143 [109] = "Porn Groove", | |
144 [110] = "Satire", | |
145 [111] = "Slow Jam", | |
146 [112] = "Club", | |
147 [113] = "Tango", | |
148 [114] = "Samba", | |
149 [115] = "Folklore", | |
150 [116] = "Ballad", | |
151 [117] = "Power Ballad", | |
152 [118] = "Rhythmic Soul", | |
153 [119] = "Freestyle", | |
154 [120] = "Duet", | |
155 [121] = "Punk Rock", | |
156 [122] = "Drum Solo", | |
157 [123] = "A capella", | |
158 [124] = "Euro-House", | |
159 [125] = "Dance Hall", | |
160 }; | |
161 | |
162 static unsigned int id3v2_get_size(ByteIOContext *s, int len) | |
163 { | |
164 int v=0; | |
165 while(len--) | |
166 v= (v<<7) + (get_byte(s)&0x7F); | |
167 return v; | |
168 } | |
169 | |
170 static void id3v2_read_ttag(AVFormatContext *s, int taglen, const char *key) | |
171 { | |
172 char *q, dst[512]; | |
173 int len, dstlen = sizeof(dst) - 1; | |
174 unsigned genre; | |
175 | |
176 dst[0]= 0; | |
177 if(taglen < 1) | |
178 return; | |
179 | |
180 taglen--; /* account for encoding type byte */ | |
181 | |
182 switch(get_byte(s->pb)) { /* encoding type */ | |
183 | |
184 case 0: /* ISO-8859-1 (0 - 255 maps directly into unicode) */ | |
185 q = dst; | |
186 while(taglen--) { | |
187 uint8_t tmp; | |
188 PUT_UTF8(get_byte(s->pb), tmp, if (q - dst < dstlen - 1) *q++ = tmp;) | |
189 } | |
190 *q = '\0'; | |
191 break; | |
192 | |
193 case 3: /* UTF-8 */ | |
194 len = FFMIN(taglen, dstlen-1); | |
195 get_buffer(s->pb, dst, len); | |
196 dst[len] = 0; | |
197 break; | |
198 } | |
199 | |
200 if (!strcmp(key, "genre") | |
201 && (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) | |
202 && genre <= ID3v1_GENRE_MAX) | |
203 av_strlcpy(dst, id3v1_genre_str[genre], sizeof(dst)); | |
204 | |
205 if (*dst) | |
206 av_metadata_set(&s->metadata, key, dst); | |
207 } | |
208 | |
209 /** | |
210 * ID3v2 parser | |
211 * | |
212 * Handles ID3v2.2, 2.3 and 2.4. | |
213 * | |
214 */ | |
215 | |
216 static void id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags) | |
217 { | |
218 int isv34, tlen; | |
219 uint32_t tag; | |
220 int64_t next; | |
221 int taghdrlen; | |
222 const char *reason; | |
223 | |
224 switch(version) { | |
225 case 2: | |
226 if(flags & 0x40) { | |
227 reason = "compression"; | |
228 goto error; | |
229 } | |
230 isv34 = 0; | |
231 taghdrlen = 6; | |
232 break; | |
233 | |
234 case 3: | |
235 case 4: | |
236 isv34 = 1; | |
237 taghdrlen = 10; | |
238 break; | |
239 | |
240 default: | |
241 reason = "version"; | |
242 goto error; | |
243 } | |
244 | |
245 if(flags & 0x80) { | |
246 reason = "unsynchronization"; | |
247 goto error; | |
248 } | |
249 | |
250 if(isv34 && flags & 0x40) /* Extended header present, just skip over it */ | |
251 url_fskip(s->pb, id3v2_get_size(s->pb, 4)); | |
252 | |
253 while(len >= taghdrlen) { | |
254 if(isv34) { | |
255 tag = get_be32(s->pb); | |
256 tlen = id3v2_get_size(s->pb, 4); | |
257 get_be16(s->pb); /* flags */ | |
258 } else { | |
259 tag = get_be24(s->pb); | |
260 tlen = id3v2_get_size(s->pb, 3); | |
261 } | |
262 len -= taghdrlen + tlen; | |
263 | |
264 if(len < 0) | |
265 break; | |
266 | |
267 next = url_ftell(s->pb) + tlen; | |
268 | |
269 switch(tag) { | |
270 case MKBETAG('T', 'I', 'T', '2'): | |
271 case MKBETAG(0, 'T', 'T', '2'): | |
272 id3v2_read_ttag(s, tlen, "title"); | |
273 break; | |
274 case MKBETAG('T', 'P', 'E', '1'): | |
275 case MKBETAG(0, 'T', 'P', '1'): | |
276 id3v2_read_ttag(s, tlen, "author"); | |
277 break; | |
278 case MKBETAG('T', 'A', 'L', 'B'): | |
279 case MKBETAG(0, 'T', 'A', 'L'): | |
280 id3v2_read_ttag(s, tlen, "album"); | |
281 break; | |
282 case MKBETAG('T', 'C', 'O', 'N'): | |
283 case MKBETAG(0, 'T', 'C', 'O'): | |
284 id3v2_read_ttag(s, tlen, "genre"); | |
285 break; | |
286 case MKBETAG('T', 'C', 'O', 'P'): | |
287 case MKBETAG(0, 'T', 'C', 'R'): | |
288 id3v2_read_ttag(s, tlen, "copyright"); | |
289 break; | |
290 case MKBETAG('T', 'R', 'C', 'K'): | |
291 case MKBETAG(0, 'T', 'R', 'K'): | |
292 id3v2_read_ttag(s, tlen, "track"); | |
293 break; | |
294 case 0: | |
295 /* padding, skip to end */ | |
296 url_fskip(s->pb, len); | |
297 len = 0; | |
298 continue; | |
299 } | |
300 /* Skip to end of tag */ | |
301 url_fseek(s->pb, next, SEEK_SET); | |
302 } | |
303 | |
304 if(version == 4 && flags & 0x10) /* Footer preset, always 10 bytes, skip over it */ | |
305 url_fskip(s->pb, 10); | |
306 return; | |
307 | |
308 error: | |
309 av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n", version, reason); | |
310 url_fskip(s->pb, len); | |
311 } | |
312 | 29 |
313 static void id3v1_get_string(AVFormatContext *s, const char *key, | 30 static void id3v1_get_string(AVFormatContext *s, const char *key, |
314 const uint8_t *buf, int buf_size) | 31 const uint8_t *buf, int buf_size) |
315 { | 32 { |
316 int i, c; | 33 int i, c; |
350 snprintf(str, sizeof(str), "%d", buf[126]); | 67 snprintf(str, sizeof(str), "%d", buf[126]); |
351 av_metadata_set(&s->metadata, "track", str); | 68 av_metadata_set(&s->metadata, "track", str); |
352 } | 69 } |
353 genre = buf[127]; | 70 genre = buf[127]; |
354 if (genre <= ID3v1_GENRE_MAX) | 71 if (genre <= ID3v1_GENRE_MAX) |
355 av_metadata_set(&s->metadata, "genre", id3v1_genre_str[genre]); | 72 av_metadata_set(&s->metadata, "genre", ff_id3v1_genre_str[genre]); |
356 return 0; | 73 return 0; |
357 } | 74 } |
358 | 75 |
359 /* mp3 read */ | 76 /* mp3 read */ |
360 | 77 |
490 /* parse ID3v2 header */ | 207 /* parse ID3v2 header */ |
491 len = ((buf[6] & 0x7f) << 21) | | 208 len = ((buf[6] & 0x7f) << 21) | |
492 ((buf[7] & 0x7f) << 14) | | 209 ((buf[7] & 0x7f) << 14) | |
493 ((buf[8] & 0x7f) << 7) | | 210 ((buf[8] & 0x7f) << 7) | |
494 (buf[9] & 0x7f); | 211 (buf[9] & 0x7f); |
495 id3v2_parse(s, len, buf[3], buf[5]); | 212 ff_id3v2_parse(s, len, buf[3], buf[5]); |
496 } else { | 213 } else { |
497 url_fseek(s->pb, 0, SEEK_SET); | 214 url_fseek(s->pb, 0, SEEK_SET); |
498 } | 215 } |
499 | 216 |
500 off = url_ftell(s->pb); | 217 off = url_ftell(s->pb); |
555 buf[126] = atoi(tag->value); | 272 buf[126] = atoi(tag->value); |
556 count++; | 273 count++; |
557 } | 274 } |
558 if ((tag = av_metadata_get(s->metadata, "genre", NULL, 0))) { | 275 if ((tag = av_metadata_get(s->metadata, "genre", NULL, 0))) { |
559 for(i = 0; i <= ID3v1_GENRE_MAX; i++) { | 276 for(i = 0; i <= ID3v1_GENRE_MAX; i++) { |
560 if (!strcasecmp(tag->value, id3v1_genre_str[i])) { | 277 if (!strcasecmp(tag->value, ff_id3v1_genre_str[i])) { |
561 buf[127] = i; | 278 buf[127] = i; |
562 count++; | 279 count++; |
563 break; | 280 break; |
564 } | 281 } |
565 } | 282 } |