id3v2: split tables for various ID3v2 versions

This is needed for upcoming ID3v2.3 muxing support.

Signed-off-by: Janne Grunau <janne-ffmpeg@jannau.net>
This commit is contained in:
Anton Khirnov 2011-01-21 19:54:34 +00:00 committed by Janne Grunau
parent 8c3caf7fb1
commit cb6bc57681
3 changed files with 85 additions and 41 deletions

View File

@ -273,46 +273,67 @@ void ff_id3v2_read(AVFormatContext *s, const char *magic)
url_fseek(s->pb, off, SEEK_SET);
}
} 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"},
{ "TAL", "album"},
{ "TCOM", "composer"},
{ "TCON", "genre"},
{ "TCO", "genre"},
{ "TCOP", "copyright"},
{ "TDRL", "date"},
{ "TDRC", "date"},
{ "TDEN", "creation_time"},
{ "TENC", "encoded_by"},
{ "TEN", "encoded_by"},
{ "TIT2", "title"},
{ "TT2", "title"},
{ "TLAN", "language"},
{ "TPE1", "artist"},
{ "TP1", "artist"},
{ "TPE2", "album_artist"},
{ "TP2", "album_artist"},
{ "TPE3", "performer"},
{ "TP3", "performer"},
{ "TPOS", "disc"},
{ "TPUB", "publisher"},
{ "TRCK", "track"},
{ "TRK", "track"},
{ "TSOA", "album-sort"},
{ "TSOP", "artist-sort"},
{ "TSOT", "title-sort"},
{ "TSSE", "encoder"},
{ 0 }
};
const AVMetadataConv ff_id3v2_4_metadata_conv[] = {
{ "TDRL", "date"},
{ "TDRC", "date"},
{ "TDEN", "creation_time"},
{ "TSOA", "album-sort"},
{ "TSOP", "artist-sort"},
{ "TSOT", "title-sort"},
{ 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] = {
"TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDEN", "TDLY", "TDOR", "TDRC",
"TDRL", "TDTG", "TENC", "TEXT", "TFLT", "TIPL", "TIT1", "TIT2", "TIT3",
"TKEY", "TLAN", "TLEN", "TMCL", "TMED", "TMOO", "TOAL", "TOFN", "TOLY",
"TOPE", "TOWN", "TPE1", "TPE2", "TPE3", "TPE4", "TPOS", "TPRO", "TPUB",
"TRCK", "TRSN", "TRSO", "TSOA", "TSOP", "TSOT", "TSRC", "TSSE", "TSST",
"TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
"TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
"TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
"TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
{ 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 },
};

View File

@ -65,12 +65,25 @@ int ff_id3v2_tag_len(const uint8_t *buf);
*/
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-changes
*/
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 */

View File

@ -148,6 +148,20 @@ AVOutputFormat mp2_muxer = {
#endif
#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
*/
@ -166,29 +180,25 @@ static int mp3_write_header(struct AVFormatContext *s)
size_pos = url_ftell(s->pb);
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))) {
uint32_t tag = 0;
int ret;
if (t->key[0] == 'T' && strlen(t->key) == 4) {
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;
break;
}
if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_tags)) > 0) {
totlen += ret;
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 */
tag = MKBETAG('T', 'X', 'X', 'X');
if ((ret = id3v2_put_ttag(s, t->key, t->value, tag, ID3v2_ENCODING_UTF8)) < 0)
return ret;
totlen += ret;
}
/* unknown tag, write as TXXX frame */
if ((ret = id3v2_put_ttag(s, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'),
ID3v2_ENCODING_UTF8)) < 0)
return ret;
totlen += ret;
}
cur_pos = url_ftell(s->pb);