[FFmpeg-devel] [PATCH] id3v2: read all textual chapter subframes
Paul B Mahol
onemda at gmail.com
Fri May 17 20:04:39 CEST 2013
Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
libavformat/id3v2.c | 54 +++++++++++++++++++++++++++++++----------------------
1 file changed, 32 insertions(+), 22 deletions(-)
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index e585f0e..74d6375 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -271,7 +271,7 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
* Parse a text tag.
*/
static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen,
- const char *key)
+ AVDictionary **metadata, const char *key)
{
uint8_t *dst;
int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_VAL;
@@ -306,7 +306,7 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen,
av_freep(&dst);
if (dst)
- av_dict_set(&s->metadata, key, dst, dict_flags);
+ av_dict_set(metadata, key, dst, dict_flags);
}
/**
@@ -518,39 +518,49 @@ fail:
avio_seek(pb, end, SEEK_SET);
}
-static void read_chapter(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta)
+static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, char *ttag, ID3v2ExtraMeta **extra_meta)
{
AVRational time_base = {1, 1000};
uint32_t start, end;
+ AVChapter *chapter;
uint8_t *dst = NULL;
- int encoding;
+ int taglen;
+ char tag[5];
- decode_str(s, pb, 0, &dst, &taglen);
- if (taglen < 16)
+ decode_str(s, pb, 0, &dst, &len);
+ if (len < 16)
return;
start = avio_rb32(pb);
end = avio_rb32(pb);
- taglen -= 27;
- if (taglen > 0) {
- char tag[4];
+ avio_skip(pb, 8);
+
+ chapter = avpriv_new_chapter(s, s->nb_chapters + 1, time_base, start, end, dst);
+ if (!chapter) {
+ av_free(dst);
+ return;
+ }
- avio_skip(pb, 8);
+ len -= 16;
+ while (len > 10) {
avio_read(pb, tag, 4);
- if (!memcmp(tag, "TIT2", 4)) {
- taglen = FFMIN(taglen, avio_rb32(pb));
- if (taglen < 0) {
- av_free(dst);
- return;
- }
- avio_skip(pb, 2);
- encoding = avio_r8(pb);
- av_freep(&dst);
- decode_str(s, pb, encoding, &dst, &taglen);
+ tag[4] = 0;
+ taglen = avio_rb32(pb);
+ avio_skip(pb, 2);
+ len -= 10;
+ if (taglen < 0 || taglen > len) {
+ av_free(dst);
+ return;
}
+ if (tag[0] == 'T')
+ read_ttag(s, pb, taglen, &chapter->metadata, tag);
+ else
+ avio_skip(pb, taglen);
+ len -= taglen;
}
- avpriv_new_chapter(s, s->nb_chapters + 1, time_base, start, end, dst);
+ ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_34_metadata_conv);
+ ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_4_metadata_conv);
av_free(dst);
}
@@ -774,7 +784,7 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,
#endif
if (tag[0] == 'T')
/* parse text tag */
- read_ttag(s, pbx, tlen, tag);
+ read_ttag(s, pbx, tlen, &s->metadata, tag);
else
/* parse special meta tag */
extra_func->read(s, pbx, tlen, tag, extra_meta);
--
1.7.11.2
More information about the ffmpeg-devel
mailing list