Mercurial > libavformat.hg
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 |