MP3 muxer: Write all metadata.
Patch by Anton Khirnov <wyskas at gmail dot com> Originally committed as revision 20170 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		
							parent
							
								
									79c0790789
								
							
						
					
					
						commit
						078d89a2b0
					
				@ -261,3 +261,12 @@ const AVMetadataConv ff_id3v2_metadata_conv[] = {
 | 
			
		||||
    { "TSOT", "titlesort"},
 | 
			
		||||
    { 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",
 | 
			
		||||
   { 0 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -54,4 +54,10 @@ void ff_id3v2_read(AVFormatContext *s);
 | 
			
		||||
 | 
			
		||||
extern const AVMetadataConv ff_id3v2_metadata_conv[];
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A list of ID3v2.4 text information frames.
 | 
			
		||||
 * http://www.id3.org/id3v2.4.0-frames
 | 
			
		||||
 */
 | 
			
		||||
extern const char const ff_id3v2_tags[][4];
 | 
			
		||||
 | 
			
		||||
#endif /* AVFORMAT_ID3V2_H */
 | 
			
		||||
 | 
			
		||||
@ -238,14 +238,14 @@ static void id3v2_put_size(AVFormatContext *s, int size)
 | 
			
		||||
    put_byte(s->pb, size       & 0x7f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void id3v2_put_ttag(AVFormatContext *s, const char *string, uint32_t tag)
 | 
			
		||||
static void id3v2_put_ttag(AVFormatContext *s, const char *buf, int len,
 | 
			
		||||
                           uint32_t tag)
 | 
			
		||||
{
 | 
			
		||||
    int len = strlen(string);
 | 
			
		||||
    put_be32(s->pb, tag);
 | 
			
		||||
    id3v2_put_size(s, len + 1);
 | 
			
		||||
    put_be16(s->pb, 0);
 | 
			
		||||
    put_byte(s->pb, 3); /* UTF-8 */
 | 
			
		||||
    put_buffer(s->pb, string, len);
 | 
			
		||||
    put_buffer(s->pb, buf, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -255,45 +255,57 @@ static void id3v2_put_ttag(AVFormatContext *s, const char *string, uint32_t tag)
 | 
			
		||||
 | 
			
		||||
static int mp3_write_header(struct AVFormatContext *s)
 | 
			
		||||
{
 | 
			
		||||
    AVMetadataTag *title, *author, *album, *genre, *copyright, *track, *year;
 | 
			
		||||
    AVMetadataTag *t = NULL;
 | 
			
		||||
    int totlen = 0;
 | 
			
		||||
 | 
			
		||||
    title     = av_metadata_get(s->metadata, "title",     NULL, 0);
 | 
			
		||||
    author    = av_metadata_get(s->metadata, "author",    NULL, 0);
 | 
			
		||||
    album     = av_metadata_get(s->metadata, "album",     NULL, 0);
 | 
			
		||||
    genre     = av_metadata_get(s->metadata, "genre",     NULL, 0);
 | 
			
		||||
    copyright = av_metadata_get(s->metadata, "copyright", NULL, 0);
 | 
			
		||||
    track     = av_metadata_get(s->metadata, "track",     NULL, 0);
 | 
			
		||||
    year      = av_metadata_get(s->metadata, "year",      NULL, 0);
 | 
			
		||||
 | 
			
		||||
    if(title)     totlen += 11 + strlen(title->value);
 | 
			
		||||
    if(author)    totlen += 11 + strlen(author->value);
 | 
			
		||||
    if(album)     totlen += 11 + strlen(album->value);
 | 
			
		||||
    if(genre)     totlen += 11 + strlen(genre->value);
 | 
			
		||||
    if(copyright) totlen += 11 + strlen(copyright->value);
 | 
			
		||||
    if(track)     totlen += 11 + strlen(track->value);
 | 
			
		||||
    if(year)      totlen += 11 + strlen(year->value);
 | 
			
		||||
    if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
 | 
			
		||||
        totlen += strlen(LIBAVFORMAT_IDENT) + 11;
 | 
			
		||||
 | 
			
		||||
    if(totlen == 0)
 | 
			
		||||
        return 0;
 | 
			
		||||
    int64_t size_pos, cur_pos;
 | 
			
		||||
 | 
			
		||||
    put_be32(s->pb, MKBETAG('I', 'D', '3', 0x04)); /* ID3v2.4 */
 | 
			
		||||
    put_byte(s->pb, 0);
 | 
			
		||||
    put_byte(s->pb, 0); /* flags */
 | 
			
		||||
 | 
			
		||||
    id3v2_put_size(s, totlen);
 | 
			
		||||
    /* reserve space for size */
 | 
			
		||||
    size_pos = url_ftell(s->pb);
 | 
			
		||||
    put_be32(s->pb, 0);
 | 
			
		||||
 | 
			
		||||
    while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) {
 | 
			
		||||
        uint32_t tag = 0;
 | 
			
		||||
 | 
			
		||||
        if (t->key[0] == 'T' && strcmp(t->key, "TSSE")) {
 | 
			
		||||
            int i;
 | 
			
		||||
            for (i = 0; *ff_id3v2_tags[i]; i++)
 | 
			
		||||
                if (AV_RB32(t->key) == AV_RB32(ff_id3v2_tags[i])) {
 | 
			
		||||
                    int len = strlen(t->value);
 | 
			
		||||
                    tag = AV_RB32(t->key);
 | 
			
		||||
                    totlen += len + ID3v2_HEADER_SIZE + 2;
 | 
			
		||||
                    id3v2_put_ttag(s, t->value, len + 1, tag);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!tag) { /* unknown tag, write as TXXX frame */
 | 
			
		||||
            int   len = strlen(t->key), len1 = strlen(t->value);
 | 
			
		||||
            char *buf = av_malloc(len + len1 + 2);
 | 
			
		||||
            if (!buf)
 | 
			
		||||
                return AVERROR(ENOMEM);
 | 
			
		||||
            tag = MKBETAG('T', 'X', 'X', 'X');
 | 
			
		||||
            strcpy(buf,           t->key);
 | 
			
		||||
            strcpy(buf + len + 1, t->value);
 | 
			
		||||
            id3v2_put_ttag(s, buf, len + len1 + 2, tag);
 | 
			
		||||
            totlen += len + len1 + ID3v2_HEADER_SIZE + 3;
 | 
			
		||||
            av_free(buf);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
 | 
			
		||||
        totlen += strlen(LIBAVFORMAT_IDENT) + ID3v2_HEADER_SIZE + 2;
 | 
			
		||||
        id3v2_put_ttag(s, LIBAVFORMAT_IDENT, strlen(LIBAVFORMAT_IDENT) + 1,
 | 
			
		||||
                       MKBETAG('T', 'S', 'S', 'E'));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cur_pos = url_ftell(s->pb);
 | 
			
		||||
    url_fseek(s->pb, size_pos, SEEK_SET);
 | 
			
		||||
    id3v2_put_size(s, totlen);
 | 
			
		||||
    url_fseek(s->pb, cur_pos, SEEK_SET);
 | 
			
		||||
 | 
			
		||||
    if(title)     id3v2_put_ttag(s, title->value,     MKBETAG('T', 'I', 'T', '2'));
 | 
			
		||||
    if(author)    id3v2_put_ttag(s, author->value,    MKBETAG('T', 'P', 'E', '1'));
 | 
			
		||||
    if(album)     id3v2_put_ttag(s, album->value,     MKBETAG('T', 'A', 'L', 'B'));
 | 
			
		||||
    if(genre)     id3v2_put_ttag(s, genre->value,     MKBETAG('T', 'C', 'O', 'N'));
 | 
			
		||||
    if(copyright) id3v2_put_ttag(s, copyright->value, MKBETAG('T', 'C', 'O', 'P'));
 | 
			
		||||
    if(track)     id3v2_put_ttag(s, track->value,     MKBETAG('T', 'R', 'C', 'K'));
 | 
			
		||||
    if(year)      id3v2_put_ttag(s, year->value,      MKBETAG('T', 'Y', 'E', 'R'));
 | 
			
		||||
    if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
 | 
			
		||||
        id3v2_put_ttag(s, LIBAVFORMAT_IDENT,            MKBETAG('T', 'E', 'N', 'C'));
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user