Commit cb6bc576 authored by Anton Khirnov's avatar Anton Khirnov Committed by Janne Grunau

id3v2: split tables for various ID3v2 versions

This is needed for upcoming ID3v2.3 muxing support.
Signed-off-by: 's avatarJanne Grunau <janne-ffmpeg@jannau.net>
parent 8c3caf7f
...@@ -273,46 +273,67 @@ void ff_id3v2_read(AVFormatContext *s, const char *magic) ...@@ -273,46 +273,67 @@ void ff_id3v2_read(AVFormatContext *s, const char *magic)
url_fseek(s->pb, off, SEEK_SET); url_fseek(s->pb, off, SEEK_SET);
} }
} while (found_header); } while (found_header);
ff_metadata_conv(&s->metadata, NULL, ff_id3v2_metadata_conv); ff_metadata_conv(&s->metadata, NULL, ff_id3v2_34_metadata_conv);
ff_metadata_conv(&s->metadata, NULL, ff_id3v2_2_metadata_conv);
ff_metadata_conv(&s->metadata, NULL, ff_id3v2_4_metadata_conv);
} }
const AVMetadataConv ff_id3v2_metadata_conv[] = { const AVMetadataConv ff_id3v2_34_metadata_conv[] = {
{ "TALB", "album"}, { "TALB", "album"},
{ "TAL", "album"},
{ "TCOM", "composer"}, { "TCOM", "composer"},
{ "TCON", "genre"}, { "TCON", "genre"},
{ "TCO", "genre"},
{ "TCOP", "copyright"}, { "TCOP", "copyright"},
{ "TDRL", "date"},
{ "TDRC", "date"},
{ "TDEN", "creation_time"},
{ "TENC", "encoded_by"}, { "TENC", "encoded_by"},
{ "TEN", "encoded_by"},
{ "TIT2", "title"}, { "TIT2", "title"},
{ "TT2", "title"},
{ "TLAN", "language"}, { "TLAN", "language"},
{ "TPE1", "artist"}, { "TPE1", "artist"},
{ "TP1", "artist"},
{ "TPE2", "album_artist"}, { "TPE2", "album_artist"},
{ "TP2", "album_artist"},
{ "TPE3", "performer"}, { "TPE3", "performer"},
{ "TP3", "performer"},
{ "TPOS", "disc"}, { "TPOS", "disc"},
{ "TPUB", "publisher"}, { "TPUB", "publisher"},
{ "TRCK", "track"}, { "TRCK", "track"},
{ "TRK", "track"}, { "TSSE", "encoder"},
{ 0 }
};
const AVMetadataConv ff_id3v2_4_metadata_conv[] = {
{ "TDRL", "date"},
{ "TDRC", "date"},
{ "TDEN", "creation_time"},
{ "TSOA", "album-sort"}, { "TSOA", "album-sort"},
{ "TSOP", "artist-sort"}, { "TSOP", "artist-sort"},
{ "TSOT", "title-sort"}, { "TSOT", "title-sort"},
{ "TSSE", "encoder"},
{ 0 } { 0 }
}; };
const AVMetadataConv ff_id3v2_2_metadata_conv[] = {
{ "TAL", "album"},
{ "TCO", "genre"},
{ "TT2", "title"},
{ "TEN", "encoded_by"},
{ "TP1", "artist"},
{ "TP2", "album_artist"},
{ "TP3", "performer"},
{ "TRK", "track"},
{ 0 }
};
const char ff_id3v2_tags[][4] = { const char ff_id3v2_tags[][4] = {
"TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDEN", "TDLY", "TDOR", "TDRC", "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
"TDRL", "TDTG", "TENC", "TEXT", "TFLT", "TIPL", "TIT1", "TIT2", "TIT3", "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
"TKEY", "TLAN", "TLEN", "TMCL", "TMED", "TMOO", "TOAL", "TOFN", "TOLY", "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
"TOPE", "TOWN", "TPE1", "TPE2", "TPE3", "TPE4", "TPOS", "TPRO", "TPUB", "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
"TRCK", "TRSN", "TRSO", "TSOA", "TSOP", "TSOT", "TSRC", "TSSE", "TSST", { 0 },
};
const char ff_id3v2_4_tags[][4] = {
"TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
"TPRO", "TSOA", "TSOP", "TSOT", "TSST",
{ 0 },
};
const char ff_id3v2_3_tags[][4] = {
"TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
{ 0 }, { 0 },
}; };
...@@ -65,12 +65,25 @@ int ff_id3v2_tag_len(const uint8_t *buf); ...@@ -65,12 +65,25 @@ int ff_id3v2_tag_len(const uint8_t *buf);
*/ */
void ff_id3v2_read(AVFormatContext *s, const char *magic); void ff_id3v2_read(AVFormatContext *s, const char *magic);
extern const AVMetadataConv ff_id3v2_metadata_conv[]; extern const AVMetadataConv ff_id3v2_34_metadata_conv[];
extern const AVMetadataConv ff_id3v2_4_metadata_conv[];
extern const AVMetadataConv ff_id3v2_2_metadata_conv[];
/** /**
* A list of ID3v2.4 text information frames. * A list of text information frames allowed in both ID3 v2.3 and v2.4
* http://www.id3.org/id3v2.4.0-frames * http://www.id3.org/id3v2.4.0-frames
* http://www.id3.org/id3v2.4.0-changes
*/ */
extern const char ff_id3v2_tags[][4]; extern const char ff_id3v2_tags[][4];
/**
* ID3v2.4-only text information frames.
*/
extern const char ff_id3v2_4_tags[][4];
/**
* ID3v2.3-only text information frames.
*/
extern const char ff_id3v2_3_tags[][4];
#endif /* AVFORMAT_ID3V2_H */ #endif /* AVFORMAT_ID3V2_H */
...@@ -148,6 +148,20 @@ AVOutputFormat mp2_muxer = { ...@@ -148,6 +148,20 @@ AVOutputFormat mp2_muxer = {
#endif #endif
#if CONFIG_MP3_MUXER #if CONFIG_MP3_MUXER
static int id3v2_check_write_tag(AVFormatContext *s, AVMetadataTag *t, const char table[][4])
{
uint32_t tag;
int i;
if (t->key[0] != 'T' || strlen(t->key) != 4)
return -1;
tag = AV_RB32(t->key);
for (i = 0; *table[i]; i++)
if (tag == AV_RB32(table[i]))
return id3v2_put_ttag(s, t->value, NULL, tag, ID3v2_ENCODING_UTF8);
return -1;
}
/** /**
* Write an ID3v2.4 header at beginning of stream * Write an ID3v2.4 header at beginning of stream
*/ */
...@@ -166,30 +180,26 @@ static int mp3_write_header(struct AVFormatContext *s) ...@@ -166,30 +180,26 @@ static int mp3_write_header(struct AVFormatContext *s)
size_pos = url_ftell(s->pb); size_pos = url_ftell(s->pb);
put_be32(s->pb, 0); put_be32(s->pb, 0);
ff_metadata_conv(&s->metadata, ff_id3v2_metadata_conv, NULL); ff_metadata_conv(&s->metadata, ff_id3v2_34_metadata_conv, NULL);
ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL);
while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) { while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) {
uint32_t tag = 0;
int ret; int ret;
if (t->key[0] == 'T' && strlen(t->key) == 4) { if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_tags)) > 0) {
int i;
for (i = 0; *ff_id3v2_tags[i]; i++)
if (AV_RB32(t->key) == AV_RB32(ff_id3v2_tags[i])) {
tag = AV_RB32(t->key);
if ((ret = id3v2_put_ttag(s, t->value, NULL, tag, ID3v2_ENCODING_UTF8)) < 0)
return ret;
totlen += ret; totlen += ret;
break; continue;
} }
if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_4_tags)) > 0) {
totlen += ret;
continue;
} }
if (!tag) { /* unknown tag, write as TXXX frame */ /* unknown tag, write as TXXX frame */
tag = MKBETAG('T', 'X', 'X', 'X'); if ((ret = id3v2_put_ttag(s, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'),
if ((ret = id3v2_put_ttag(s, t->key, t->value, tag, ID3v2_ENCODING_UTF8)) < 0) ID3v2_ENCODING_UTF8)) < 0)
return ret; return ret;
totlen += ret; totlen += ret;
} }
}
cur_pos = url_ftell(s->pb); cur_pos = url_ftell(s->pb);
url_fseek(s->pb, size_pos, SEEK_SET); url_fseek(s->pb, size_pos, SEEK_SET);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment