3 * Copyright (c) 2003 Fabrice Bellard
5 * This file is part of Libav.
7 * Libav is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * Libav is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "libavutil/avstring.h"
25 #include "libavutil/intreadwrite.h"
26 #include "libavutil/dict.h"
27 #include "avio_internal.h"
30 const AVMetadataConv ff_id3v2_34_metadata_conv
[] = {
32 { "TCOM", "composer"},
34 { "TCOP", "copyright"},
35 { "TENC", "encoded_by"},
37 { "TLAN", "language"},
39 { "TPE2", "album_artist"},
40 { "TPE3", "performer"},
42 { "TPUB", "publisher"},
48 const AVMetadataConv ff_id3v2_4_metadata_conv
[] = {
51 { "TDEN", "creation_time"},
52 { "TSOA", "album-sort"},
53 { "TSOP", "artist-sort"},
54 { "TSOT", "title-sort"},
58 static const AVMetadataConv id3v2_2_metadata_conv
[] = {
62 { "TEN", "encoded_by"},
64 { "TP2", "album_artist"},
65 { "TP3", "performer"},
71 const char ff_id3v2_tags
[][4] = {
72 "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
73 "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
74 "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
75 "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
79 const char ff_id3v2_4_tags
[][4] = {
80 "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
81 "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
85 const char ff_id3v2_3_tags
[][4] = {
86 "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
90 const char *ff_id3v2_picture_types
[21] = {
92 "32x32 pixels 'file icon'",
97 "Media (e.g. label side of CD)",
98 "Lead artist/lead performer/soloist",
103 "Lyricist/text writer",
104 "Recording Location",
106 "During performance",
107 "Movie/video screen capture",
108 "A bright coloured fish",
110 "Band/artist logotype",
111 "Publisher/Studio logotype",
114 const CodecMime ff_id3v2_mime_tags
[] = {
115 {"image/gif" , AV_CODEC_ID_GIF
},
116 {"image/jpeg", AV_CODEC_ID_MJPEG
},
117 {"image/jpg", AV_CODEC_ID_MJPEG
},
118 {"image/png" , AV_CODEC_ID_PNG
},
119 {"image/tiff", AV_CODEC_ID_TIFF
},
120 {"image/bmp", AV_CODEC_ID_BMP
},
121 {"JPG", AV_CODEC_ID_MJPEG
}, /* ID3v2.2 */
122 {"PNG" , AV_CODEC_ID_PNG
}, /* ID3v2.2 */
123 {"", AV_CODEC_ID_NONE
},
126 int ff_id3v2_match(const uint8_t *buf
, const char * magic
)
128 return buf
[0] == magic
[0] &&
129 buf
[1] == magic
[1] &&
130 buf
[2] == magic
[2] &&
133 (buf
[6] & 0x80) == 0 &&
134 (buf
[7] & 0x80) == 0 &&
135 (buf
[8] & 0x80) == 0 &&
136 (buf
[9] & 0x80) == 0;
139 int ff_id3v2_tag_len(const uint8_t * buf
)
141 int len
= ((buf
[6] & 0x7f) << 21) +
142 ((buf
[7] & 0x7f) << 14) +
143 ((buf
[8] & 0x7f) << 7) +
147 len
+= ID3v2_HEADER_SIZE
;
151 static unsigned int get_size(AVIOContext
*s
, int len
)
155 v
= (v
<< 7) + (avio_r8(s
) & 0x7F);
160 * Free GEOB type extra metadata.
162 static void free_geobtag(void *obj
)
164 ID3v2ExtraMetaGEOB
*geob
= obj
;
165 av_free(geob
->mime_type
);
166 av_free(geob
->file_name
);
167 av_free(geob
->description
);
173 * Decode characters to UTF-8 according to encoding type. The decoded buffer is
174 * always null terminated. Stop reading when either *maxread bytes are read from
175 * pb or U+0000 character is found.
177 * @param dst Pointer where the address of the buffer with the decoded bytes is
178 * stored. Buffer must be freed by caller.
179 * @param maxread Pointer to maximum number of characters to read from the
180 * AVIOContext. After execution the value is decremented by the number of bytes
182 * @returns 0 if no error occurred, dst is uninitialized on error
184 static int decode_str(AVFormatContext
*s
, AVIOContext
*pb
, int encoding
,
185 uint8_t **dst
, int *maxread
)
191 unsigned int (*get
)(AVIOContext
*) = avio_rb16
;
194 if ((ret
= avio_open_dyn_buf(&dynbuf
)) < 0) {
195 av_log(s
, AV_LOG_ERROR
, "Error opening memory stream\n");
201 case ID3v2_ENCODING_ISO8859
:
204 PUT_UTF8(ch
, tmp
, avio_w8(dynbuf
, tmp
);)
209 case ID3v2_ENCODING_UTF16BOM
:
210 if ((left
-= 2) < 0) {
211 av_log(s
, AV_LOG_ERROR
, "Cannot read BOM value, input too short\n");
212 avio_close_dyn_buf(dynbuf
, dst
);
214 return AVERROR_INVALIDDATA
;
216 switch (avio_rb16(pb
)) {
222 av_log(s
, AV_LOG_ERROR
, "Incorrect BOM value\n");
223 avio_close_dyn_buf(dynbuf
, dst
);
226 return AVERROR_INVALIDDATA
;
230 case ID3v2_ENCODING_UTF16BE
:
231 while ((left
> 1) && ch
) {
232 GET_UTF16(ch
, ((left
-= 2) >= 0 ? get(pb
) : 0), break;)
233 PUT_UTF8(ch
, tmp
, avio_w8(dynbuf
, tmp
);)
236 left
+= 2; /* did not read last char from pb */
239 case ID3v2_ENCODING_UTF8
:
247 av_log(s
, AV_LOG_WARNING
, "Unknown encoding\n");
253 avio_close_dyn_buf(dynbuf
, dst
);
262 static void read_ttag(AVFormatContext
*s
, AVIOContext
*pb
, int taglen
, const char *key
)
265 int encoding
, dict_flags
= AV_DICT_DONT_OVERWRITE
| AV_DICT_DONT_STRDUP_VAL
;
271 encoding
= avio_r8(pb
);
272 taglen
--; /* account for encoding type byte */
274 if (decode_str(s
, pb
, encoding
, &dst
, &taglen
) < 0) {
275 av_log(s
, AV_LOG_ERROR
, "Error reading frame %s, skipped\n", key
);
279 if (!(strcmp(key
, "TCON") && strcmp(key
, "TCO"))
280 && (sscanf(dst
, "(%d)", &genre
) == 1 || sscanf(dst
, "%d", &genre
) == 1)
281 && genre
<= ID3v1_GENRE_MAX
) {
283 dst
= av_strdup(ff_id3v1_genre_str
[genre
]);
284 } else if (!(strcmp(key
, "TXXX") && strcmp(key
, "TXX"))) {
285 /* dst now contains the key, need to get value */
287 if (decode_str(s
, pb
, encoding
, &dst
, &taglen
) < 0) {
288 av_log(s
, AV_LOG_ERROR
, "Error reading frame %s, skipped\n", key
);
292 dict_flags
|= AV_DICT_DONT_STRDUP_KEY
;
297 av_dict_set(&s
->metadata
, key
, dst
, dict_flags
);
301 * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
303 static void read_geobtag(AVFormatContext
*s
, AVIOContext
*pb
, int taglen
, char *tag
, ID3v2ExtraMeta
**extra_meta
)
305 ID3v2ExtraMetaGEOB
*geob_data
= NULL
;
306 ID3v2ExtraMeta
*new_extra
= NULL
;
313 geob_data
= av_mallocz(sizeof(ID3v2ExtraMetaGEOB
));
315 av_log(s
, AV_LOG_ERROR
, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMetaGEOB
));
319 new_extra
= av_mallocz(sizeof(ID3v2ExtraMeta
));
321 av_log(s
, AV_LOG_ERROR
, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMeta
));
325 /* read encoding type byte */
326 encoding
= avio_r8(pb
);
329 /* read MIME type (always ISO-8859) */
330 if (decode_str(s
, pb
, ID3v2_ENCODING_ISO8859
, &geob_data
->mime_type
, &taglen
) < 0
335 if (decode_str(s
, pb
, encoding
, &geob_data
->file_name
, &taglen
) < 0
339 /* read content description */
340 if (decode_str(s
, pb
, encoding
, &geob_data
->description
, &taglen
) < 0
345 /* save encapsulated binary data */
346 geob_data
->data
= av_malloc(taglen
);
347 if (!geob_data
->data
) {
348 av_log(s
, AV_LOG_ERROR
, "Failed to alloc %d bytes\n", taglen
);
351 if ((len
= avio_read(pb
, geob_data
->data
, taglen
)) < taglen
)
352 av_log(s
, AV_LOG_WARNING
, "Error reading GEOB frame, data truncated.\n");
353 geob_data
->datasize
= len
;
355 geob_data
->data
= NULL
;
356 geob_data
->datasize
= 0;
359 /* add data to the list */
360 new_extra
->tag
= "GEOB";
361 new_extra
->data
= geob_data
;
362 new_extra
->next
= *extra_meta
;
363 *extra_meta
= new_extra
;
368 av_log(s
, AV_LOG_ERROR
, "Error reading frame %s, skipped\n", tag
);
369 free_geobtag(geob_data
);
374 static int is_number(const char *str
)
376 while (*str
>= '0' && *str
<= '9') str
++;
380 static AVDictionaryEntry
* get_date_tag(AVDictionary
*m
, const char *tag
)
382 AVDictionaryEntry
*t
;
383 if ((t
= av_dict_get(m
, tag
, NULL
, AV_DICT_MATCH_CASE
)) &&
384 strlen(t
->value
) == 4 && is_number(t
->value
))
389 static void merge_date(AVDictionary
**m
)
391 AVDictionaryEntry
*t
;
392 char date
[17] = {0}; // YYYY-MM-DD hh:mm
394 if (!(t
= get_date_tag(*m
, "TYER")) &&
395 !(t
= get_date_tag(*m
, "TYE")))
397 av_strlcpy(date
, t
->value
, 5);
398 av_dict_set(m
, "TYER", NULL
, 0);
399 av_dict_set(m
, "TYE", NULL
, 0);
401 if (!(t
= get_date_tag(*m
, "TDAT")) &&
402 !(t
= get_date_tag(*m
, "TDA")))
404 snprintf(date
+ 4, sizeof(date
) - 4, "-%.2s-%.2s", t
->value
+ 2, t
->value
);
405 av_dict_set(m
, "TDAT", NULL
, 0);
406 av_dict_set(m
, "TDA", NULL
, 0);
408 if (!(t
= get_date_tag(*m
, "TIME")) &&
409 !(t
= get_date_tag(*m
, "TIM")))
411 snprintf(date
+ 10, sizeof(date
) - 10, " %.2s:%.2s", t
->value
, t
->value
+ 2);
412 av_dict_set(m
, "TIME", NULL
, 0);
413 av_dict_set(m
, "TIM", NULL
, 0);
417 av_dict_set(m
, "date", date
, 0);
420 static void free_apic(void *obj
)
422 ID3v2ExtraMetaAPIC
*apic
= obj
;
423 av_buffer_unref(&apic
->buf
);
424 av_freep(&apic
->description
);
428 static void read_apic(AVFormatContext
*s
, AVIOContext
*pb
, int taglen
, char *tag
, ID3v2ExtraMeta
**extra_meta
)
432 const CodecMime
*mime
= ff_id3v2_mime_tags
;
433 enum AVCodecID id
= AV_CODEC_ID_NONE
;
434 ID3v2ExtraMetaAPIC
*apic
= NULL
;
435 ID3v2ExtraMeta
*new_extra
= NULL
;
436 int64_t end
= avio_tell(pb
) + taglen
;
441 new_extra
= av_mallocz(sizeof(*new_extra
));
442 apic
= av_mallocz(sizeof(*apic
));
443 if (!new_extra
|| !apic
)
450 taglen
-= avio_get_str(pb
, taglen
, mimetype
, sizeof(mimetype
));
451 while (mime
->id
!= AV_CODEC_ID_NONE
) {
452 if (!av_strncasecmp(mime
->str
, mimetype
, sizeof(mimetype
))) {
458 if (id
== AV_CODEC_ID_NONE
) {
459 av_log(s
, AV_LOG_WARNING
, "Unknown attached picture mimetype: %s, skipping.\n", mimetype
);
465 pic_type
= avio_r8(pb
);
467 if (pic_type
< 0 || pic_type
>= FF_ARRAY_ELEMS(ff_id3v2_picture_types
)) {
468 av_log(s
, AV_LOG_WARNING
, "Unknown attached picture type %d.\n", pic_type
);
471 apic
->type
= ff_id3v2_picture_types
[pic_type
];
473 /* description and picture data */
474 if (decode_str(s
, pb
, enc
, &apic
->description
, &taglen
) < 0) {
475 av_log(s
, AV_LOG_ERROR
, "Error decoding attached picture description.\n");
479 apic
->buf
= av_buffer_alloc(taglen
);
480 if (!apic
->buf
|| avio_read(pb
, apic
->buf
->data
, taglen
) != taglen
)
483 new_extra
->tag
= "APIC";
484 new_extra
->data
= apic
;
485 new_extra
->next
= *extra_meta
;
486 *extra_meta
= new_extra
;
493 av_freep(&new_extra
);
494 avio_seek(pb
, end
, SEEK_SET
);
497 typedef struct ID3v2EMFunc
{
500 void (*read
)(AVFormatContext
*, AVIOContext
*, int, char*, ID3v2ExtraMeta
**);
501 void (*free
)(void *obj
);
504 static const ID3v2EMFunc id3v2_extra_meta_funcs
[] = {
505 { "GEO", "GEOB", read_geobtag
, free_geobtag
},
506 { "PIC", "APIC", read_apic
, free_apic
},
511 * Get the corresponding ID3v2EMFunc struct for a tag.
512 * @param isv34 Determines if v2.2 or v2.3/4 strings are used
513 * @return A pointer to the ID3v2EMFunc struct if found, NULL otherwise.
515 static const ID3v2EMFunc
*get_extra_meta_func(const char *tag
, int isv34
)
518 while (id3v2_extra_meta_funcs
[i
].tag3
) {
520 (isv34
? id3v2_extra_meta_funcs
[i
].tag4
:
521 id3v2_extra_meta_funcs
[i
].tag3
),
523 return &id3v2_extra_meta_funcs
[i
];
529 static void ff_id3v2_parse(AVFormatContext
*s
, int len
, uint8_t version
, uint8_t flags
, ID3v2ExtraMeta
**extra_meta
)
531 int isv34
, tlen
, unsync
;
533 int64_t next
, end
= avio_tell(s
->pb
) + len
;
535 const char *reason
= NULL
;
538 unsigned char *buffer
= NULL
;
540 const ID3v2EMFunc
*extra_func
;
545 reason
= "compression";
563 unsync
= flags
& 0x80;
565 if (isv34
&& flags
& 0x40) { /* Extended header present, just skip over it */
566 int extlen
= get_size(s
->pb
, 4);
568 extlen
-= 4; // in v2.4 the length includes the length field we just read
571 reason
= "invalid extended header length";
574 avio_skip(s
->pb
, extlen
);
577 while (len
>= taghdrlen
) {
578 unsigned int tflags
= 0;
582 avio_read(s
->pb
, tag
, 4);
585 tlen
= avio_rb32(s
->pb
);
587 tlen
= get_size(s
->pb
, 4);
588 tflags
= avio_rb16(s
->pb
);
589 tunsync
= tflags
& ID3v2_FLAG_UNSYNCH
;
591 avio_read(s
->pb
, tag
, 3);
593 tlen
= avio_rb24(s
->pb
);
595 if (tlen
< 0 || tlen
> len
- taghdrlen
) {
596 av_log(s
, AV_LOG_WARNING
, "Invalid size in frame %s, skipping the rest of tag.\n", tag
);
599 len
-= taghdrlen
+ tlen
;
600 next
= avio_tell(s
->pb
) + tlen
;
604 av_log(s
, AV_LOG_DEBUG
, "Invalid empty frame %s, skipping.\n", tag
);
608 if (tflags
& ID3v2_FLAG_DATALEN
) {
613 if (tflags
& (ID3v2_FLAG_ENCRYPTION
| ID3v2_FLAG_COMPRESSION
)) {
614 av_log(s
, AV_LOG_WARNING
, "Skipping encrypted/compressed ID3v2 frame %s.\n", tag
);
615 avio_skip(s
->pb
, tlen
);
616 /* check for text tag or supported special meta tag */
617 } else if (tag
[0] == 'T' || (extra_meta
&& (extra_func
= get_extra_meta_func(tag
, isv34
)))) {
618 if (unsync
|| tunsync
) {
619 int64_t end
= avio_tell(s
->pb
) + tlen
;
621 av_fast_malloc(&buffer
, &buffer_size
, tlen
);
623 av_log(s
, AV_LOG_ERROR
, "Failed to alloc %d bytes\n", tlen
);
627 while (avio_tell(s
->pb
) < end
) {
628 *b
++ = avio_r8(s
->pb
);
629 if (*(b
- 1) == 0xff && avio_tell(s
->pb
) < end
- 1) {
630 uint8_t val
= avio_r8(s
->pb
);
631 *b
++ = val
? val
: avio_r8(s
->pb
);
634 ffio_init_context(&pb
, buffer
, b
- buffer
, 0, NULL
, NULL
, NULL
, NULL
);
636 pbx
= &pb
; // read from sync buffer
638 pbx
= s
->pb
; // read straight from input
642 read_ttag(s
, pbx
, tlen
, tag
);
644 /* parse special meta tag */
645 extra_func
->read(s
, pbx
, tlen
, tag
, extra_meta
);
649 av_log(s
, AV_LOG_WARNING
, "invalid frame id, assuming padding");
650 avio_skip(s
->pb
, tlen
);
653 /* Skip to end of tag */
655 avio_seek(s
->pb
, next
, SEEK_SET
);
658 if (version
== 4 && flags
& 0x10) /* Footer preset, always 10 bytes, skip over it */
663 av_log(s
, AV_LOG_INFO
, "ID3v2.%d tag skipped, cannot handle %s\n", version
, reason
);
664 avio_seek(s
->pb
, end
, SEEK_SET
);
669 void ff_id3v2_read(AVFormatContext
*s
, const char *magic
, ID3v2ExtraMeta
**extra_meta
)
672 uint8_t buf
[ID3v2_HEADER_SIZE
];
677 /* save the current offset in case there's nothing to read/skip */
678 off
= avio_tell(s
->pb
);
679 ret
= avio_read(s
->pb
, buf
, ID3v2_HEADER_SIZE
);
680 if (ret
!= ID3v2_HEADER_SIZE
)
682 found_header
= ff_id3v2_match(buf
, magic
);
684 /* parse ID3v2 header */
685 len
= ((buf
[6] & 0x7f) << 21) |
686 ((buf
[7] & 0x7f) << 14) |
687 ((buf
[8] & 0x7f) << 7) |
689 ff_id3v2_parse(s
, len
, buf
[3], buf
[5], extra_meta
);
691 avio_seek(s
->pb
, off
, SEEK_SET
);
693 } while (found_header
);
694 ff_metadata_conv(&s
->metadata
, NULL
, ff_id3v2_34_metadata_conv
);
695 ff_metadata_conv(&s
->metadata
, NULL
, id3v2_2_metadata_conv
);
696 ff_metadata_conv(&s
->metadata
, NULL
, ff_id3v2_4_metadata_conv
);
697 merge_date(&s
->metadata
);
700 void ff_id3v2_free_extra_meta(ID3v2ExtraMeta
**extra_meta
)
702 ID3v2ExtraMeta
*current
= *extra_meta
, *next
;
703 const ID3v2EMFunc
*extra_func
;
706 if ((extra_func
= get_extra_meta_func(current
->tag
, 1)))
707 extra_func
->free(current
->data
);
708 next
= current
->next
;
714 int ff_id3v2_parse_apic(AVFormatContext
*s
, ID3v2ExtraMeta
**extra_meta
)
718 for (cur
= *extra_meta
; cur
; cur
= cur
->next
) {
719 ID3v2ExtraMetaAPIC
*apic
;
722 if (strcmp(cur
->tag
, "APIC"))
726 if (!(st
= avformat_new_stream(s
, NULL
)))
727 return AVERROR(ENOMEM
);
729 st
->disposition
|= AV_DISPOSITION_ATTACHED_PIC
;
730 st
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
731 st
->codec
->codec_id
= apic
->id
;
732 av_dict_set(&st
->metadata
, "title", apic
->description
, 0);
733 av_dict_set(&st
->metadata
, "comment", apic
->type
, 0);
735 av_init_packet(&st
->attached_pic
);
736 st
->attached_pic
.buf
= apic
->buf
;
737 st
->attached_pic
.data
= apic
->buf
->data
;
738 st
->attached_pic
.size
= apic
->buf
->size
;
739 st
->attached_pic
.stream_index
= st
->index
;
740 st
->attached_pic
.flags
|= AV_PKT_FLAG_KEY
;