Revision 22272f61
libavformat/mp3enc.c | ||
---|---|---|
24 | 24 |
#include "id3v1.h" |
25 | 25 |
#include "id3v2.h" |
26 | 26 |
#include "libavutil/intreadwrite.h" |
27 |
#include "libavutil/opt.h" |
|
27 | 28 |
|
28 | 29 |
static int id3v1_set_string(AVFormatContext *s, const char *key, |
29 | 30 |
uint8_t *buf, int buf_size) |
... | ... | |
148 | 149 |
#endif |
149 | 150 |
|
150 | 151 |
#if CONFIG_MP3_MUXER |
151 |
static int id3v2_check_write_tag(AVFormatContext *s, AVMetadataTag *t, const char table[][4]) |
|
152 |
typedef struct MP3Context { |
|
153 |
const AVClass *class; |
|
154 |
int id3v2_version; |
|
155 |
} MP3Context; |
|
156 |
|
|
157 |
static const AVOption options[] = { |
|
158 |
{ "id3v2_version", "Select ID3v2 version to write. Currently 3 and 4 are supported.", |
|
159 |
offsetof(MP3Context, id3v2_version), FF_OPT_TYPE_INT, 4, 3, 4, AV_OPT_FLAG_ENCODING_PARAM}, |
|
160 |
{ NULL }, |
|
161 |
}; |
|
162 |
|
|
163 |
static const AVClass mp3_muxer_class = { |
|
164 |
"MP3 muxer", |
|
165 |
av_default_item_name, |
|
166 |
options, |
|
167 |
LIBAVUTIL_VERSION_INT, |
|
168 |
}; |
|
169 |
|
|
170 |
static int id3v2_check_write_tag(AVFormatContext *s, AVMetadataTag *t, const char table[][4], |
|
171 |
enum ID3v2Encoding enc) |
|
152 | 172 |
{ |
153 | 173 |
uint32_t tag; |
154 | 174 |
int i; |
... | ... | |
158 | 178 |
tag = AV_RB32(t->key); |
159 | 179 |
for (i = 0; *table[i]; i++) |
160 | 180 |
if (tag == AV_RB32(table[i])) |
161 |
return id3v2_put_ttag(s, t->value, NULL, tag, ID3v2_ENCODING_UTF8);
|
|
181 |
return id3v2_put_ttag(s, t->value, NULL, tag, enc);
|
|
162 | 182 |
return -1; |
163 | 183 |
} |
164 | 184 |
|
165 | 185 |
/** |
166 |
* Write an ID3v2.4 header at beginning of stream
|
|
186 |
* Write an ID3v2 header at beginning of stream |
|
167 | 187 |
*/ |
168 | 188 |
|
169 | 189 |
static int mp3_write_header(struct AVFormatContext *s) |
170 | 190 |
{ |
191 |
MP3Context *mp3 = s->priv_data; |
|
171 | 192 |
AVMetadataTag *t = NULL; |
172 |
int totlen = 0; |
|
193 |
int totlen = 0, enc = mp3->id3v2_version == 3 ? ID3v2_ENCODING_UTF16BOM : |
|
194 |
ID3v2_ENCODING_UTF8; |
|
173 | 195 |
int64_t size_pos, cur_pos; |
174 | 196 |
|
175 |
put_be32(s->pb, MKBETAG('I', 'D', '3', 0x04)); /* ID3v2.4 */
|
|
197 |
put_be32(s->pb, MKBETAG('I', 'D', '3', mp3->id3v2_version));
|
|
176 | 198 |
put_byte(s->pb, 0); |
177 | 199 |
put_byte(s->pb, 0); /* flags */ |
178 | 200 |
|
... | ... | |
181 | 203 |
put_be32(s->pb, 0); |
182 | 204 |
|
183 | 205 |
ff_metadata_conv(&s->metadata, ff_id3v2_34_metadata_conv, NULL); |
184 |
ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL); |
|
206 |
if (mp3->id3v2_version == 4) |
|
207 |
ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL); |
|
208 |
|
|
185 | 209 |
while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) { |
186 | 210 |
int ret; |
187 | 211 |
|
188 |
if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_tags)) > 0) { |
|
212 |
if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_tags, enc)) > 0) {
|
|
189 | 213 |
totlen += ret; |
190 | 214 |
continue; |
191 | 215 |
} |
192 |
if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_4_tags)) > 0) { |
|
216 |
if ((ret = id3v2_check_write_tag(s, t, mp3->id3v2_version == 3 ? |
|
217 |
ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) { |
|
193 | 218 |
totlen += ret; |
194 | 219 |
continue; |
195 | 220 |
} |
196 | 221 |
|
197 | 222 |
/* unknown tag, write as TXXX frame */ |
198 |
if ((ret = id3v2_put_ttag(s, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), |
|
199 |
ID3v2_ENCODING_UTF8)) < 0) |
|
223 |
if ((ret = id3v2_put_ttag(s, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0) |
|
200 | 224 |
return ret; |
201 | 225 |
totlen += ret; |
202 | 226 |
} |
... | ... | |
214 | 238 |
NULL_IF_CONFIG_SMALL("MPEG audio layer 3"), |
215 | 239 |
"audio/x-mpeg", |
216 | 240 |
"mp3", |
217 |
0,
|
|
241 |
sizeof(MP3Context),
|
|
218 | 242 |
CODEC_ID_MP3, |
219 | 243 |
CODEC_ID_NONE, |
220 | 244 |
mp3_write_header, |
221 | 245 |
mp3_write_packet, |
222 | 246 |
mp3_write_trailer, |
223 | 247 |
AVFMT_NOTIMESTAMPS, |
248 |
.priv_class = &mp3_muxer_class, |
|
224 | 249 |
}; |
225 | 250 |
#endif |
Also available in: Unified diff