comparison mp3.c @ 5045:9ed3c88ed9ba libavformat

Move id3v1/id3v2 handling code from mp3.c to id3v[12].c. patch by Patrick Dehne, patrick mysonicweb com
author diego
date Fri, 19 Jun 2009 14:03:35 +0000
parents eb6dd7717805
children cbaefd9135ac
comparison
equal deleted inserted replaced
5044:2ef633b32f7a 5045:9ed3c88ed9ba
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 #include "id3v1.h" 28 #include "id3v1.h"
29 29
30 static void id3v1_get_string(AVFormatContext *s, const char *key,
31 const uint8_t *buf, int buf_size)
32 {
33 int i, c;
34 char *q, str[512];
35
36 q = str;
37 for(i = 0; i < buf_size; i++) {
38 c = buf[i];
39 if (c == '\0')
40 break;
41 if ((q - str) >= sizeof(str) - 1)
42 break;
43 *q++ = c;
44 }
45 *q = '\0';
46
47 if (*str)
48 av_metadata_set(&s->metadata, key, str);
49 }
50
51 /* 'buf' must be ID3v1_TAG_SIZE byte long */
52 static int id3v1_parse_tag(AVFormatContext *s, const uint8_t *buf)
53 {
54 char str[5];
55 int genre;
56
57 if (!(buf[0] == 'T' &&
58 buf[1] == 'A' &&
59 buf[2] == 'G'))
60 return -1;
61 id3v1_get_string(s, "title", buf + 3, 30);
62 id3v1_get_string(s, "author", buf + 33, 30);
63 id3v1_get_string(s, "album", buf + 63, 30);
64 id3v1_get_string(s, "year", buf + 93, 4);
65 id3v1_get_string(s, "comment", buf + 97, 30);
66 if (buf[125] == 0 && buf[126] != 0) {
67 snprintf(str, sizeof(str), "%d", buf[126]);
68 av_metadata_set(&s->metadata, "track", str);
69 }
70 genre = buf[127];
71 if (genre <= ID3v1_GENRE_MAX)
72 av_metadata_set(&s->metadata, "genre", ff_id3v1_genre_str[genre]);
73 return 0;
74 }
75
76 /* mp3 read */ 30 /* mp3 read */
77 31
78 static int mp3_read_probe(AVProbeData *p) 32 static int mp3_read_probe(AVProbeData *p)
79 { 33 {
80 int max_frames, first_frames = 0; 34 int max_frames, first_frames = 0;
170 124
171 static int mp3_read_header(AVFormatContext *s, 125 static int mp3_read_header(AVFormatContext *s,
172 AVFormatParameters *ap) 126 AVFormatParameters *ap)
173 { 127 {
174 AVStream *st; 128 AVStream *st;
175 uint8_t buf[ID3v1_TAG_SIZE];
176 int len, ret, filesize;
177 int64_t off; 129 int64_t off;
178 130
179 st = av_new_stream(s, 0); 131 st = av_new_stream(s, 0);
180 if (!st) 132 if (!st)
181 return AVERROR(ENOMEM); 133 return AVERROR(ENOMEM);
183 st->codec->codec_type = CODEC_TYPE_AUDIO; 135 st->codec->codec_type = CODEC_TYPE_AUDIO;
184 st->codec->codec_id = CODEC_ID_MP3; 136 st->codec->codec_id = CODEC_ID_MP3;
185 st->need_parsing = AVSTREAM_PARSE_FULL; 137 st->need_parsing = AVSTREAM_PARSE_FULL;
186 st->start_time = 0; 138 st->start_time = 0;
187 139
188 /* try to get the TAG */ 140 ff_id3v1_read(s);
189 if (!url_is_streamed(s->pb)) { 141 ff_id3v2_read(s);
190 /* XXX: change that */
191 filesize = url_fsize(s->pb);
192 if (filesize > 128) {
193 url_fseek(s->pb, filesize - 128, SEEK_SET);
194 ret = get_buffer(s->pb, buf, ID3v1_TAG_SIZE);
195 if (ret == ID3v1_TAG_SIZE) {
196 id3v1_parse_tag(s, buf);
197 }
198 url_fseek(s->pb, 0, SEEK_SET);
199 }
200 }
201
202 /* if ID3v2 header found, skip it */
203 ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE);
204 if (ret != ID3v2_HEADER_SIZE)
205 return -1;
206 if (ff_id3v2_match(buf)) {
207 /* parse ID3v2 header */
208 len = ((buf[6] & 0x7f) << 21) |
209 ((buf[7] & 0x7f) << 14) |
210 ((buf[8] & 0x7f) << 7) |
211 (buf[9] & 0x7f);
212 ff_id3v2_parse(s, len, buf[3], buf[5]);
213 } else {
214 url_fseek(s->pb, 0, SEEK_SET);
215 }
216 142
217 off = url_ftell(s->pb); 143 off = url_ftell(s->pb);
218 if (mp3_parse_vbr_tags(s, st, off) < 0) 144 if (mp3_parse_vbr_tags(s, st, off) < 0)
219 url_fseek(s->pb, off, SEEK_SET); 145 url_fseek(s->pb, off, SEEK_SET);
220 146