diff options
author | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2021-08-23 10:03:47 +0200 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2021-08-28 15:25:18 +0200 |
commit | f1d89d6dd0aa825d48e9be13837d77e8c1964fe8 (patch) | |
tree | bf79d79669140d2422088082cefca77f825ab380 /libavformat/oggparsevorbis.c | |
parent | 033105a73901cf9ecfa6d410e96d7f347dc69c71 (diff) | |
download | ffmpeg-f1d89d6dd0aa825d48e9be13837d77e8c1964fe8.tar.gz |
avformat/oggparsevorbis: Factor parsing a single VorbisComment out
This is in preparation for further commits.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavformat/oggparsevorbis.c')
-rw-r--r-- | libavformat/oggparsevorbis.c | 142 |
1 files changed, 75 insertions, 67 deletions
diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c index c48658ceda..103a8784ab 100644 --- a/libavformat/oggparsevorbis.c +++ b/libavformat/oggparsevorbis.c @@ -84,6 +84,77 @@ int ff_vorbis_stream_comment(AVFormatContext *as, AVStream *st, return updates; } +static int vorbis_parse_single_comment(AVFormatContext *as, AVDictionary **m, + const uint8_t *buf, uint32_t size, + int *updates, int parse_picture) +{ + const char *t = buf, *v = memchr(t, '=', size); + char *tt, *ct; + int tl, vl; + + if (!v) + return 0; + + tl = v - t; + vl = size - tl - 1; + v++; + + if (!tl || !vl) + return 0; + + tt = av_malloc(tl + 1); + ct = av_malloc(vl + 1); + if (!tt || !ct) { + av_freep(&tt); + av_freep(&ct); + return AVERROR(ENOMEM); + } + + memcpy(tt, t, tl); + tt[tl] = 0; + + memcpy(ct, v, vl); + ct[vl] = 0; + + /* The format in which the pictures are stored is the FLAC format. + * Xiph says: "The binary FLAC picture structure is base64 encoded + * and placed within a VorbisComment with the tag name + * 'METADATA_BLOCK_PICTURE'. This is the preferred and + * recommended way of embedding cover art within VorbisComments." + */ + if (!av_strcasecmp(tt, "METADATA_BLOCK_PICTURE") && parse_picture) { + int ret, len = AV_BASE64_DECODE_SIZE(vl); + uint8_t *pict = av_malloc(len); + + if (!pict) { + av_log(as, AV_LOG_WARNING, "out-of-memory error. Skipping cover art block.\n"); + av_freep(&tt); + av_freep(&ct); + return 0; + } + ret = av_base64_decode(pict, ct, len); + av_freep(&tt); + av_freep(&ct); + if (ret > 0) + ret = ff_flac_parse_picture(as, pict, ret, 0); + av_freep(&pict); + if (ret < 0) { + av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n"); + return 0; + } + } else if (!ogm_chapter(as, tt, ct)) { + (*updates)++; + if (av_dict_get(*m, tt, NULL, 0)) { + av_dict_set(m, tt, ";", AV_DICT_APPEND); + } + av_dict_set(m, tt, ct, + AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL | + AV_DICT_APPEND); + } + + return 0; +} + int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, const uint8_t *buf, int size, int parse_picture) @@ -92,7 +163,7 @@ int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, const uint8_t *end = buf + size; int updates = 0; unsigned n; - int s; + int s, ret; /* must have vendor_length and user_comment_list_length */ if (size < 8) @@ -108,79 +179,16 @@ int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, n = bytestream_get_le32(&p); while (end - p >= 4 && n > 0) { - const char *t, *v; - int tl, vl; - s = bytestream_get_le32(&p); if (end - p < s || s < 0) break; - t = p; + ret = vorbis_parse_single_comment(as, m, p, s, &updates, parse_picture); + if (ret < 0) + return ret; p += s; n--; - - v = memchr(t, '=', s); - if (!v) - continue; - - tl = v - t; - vl = s - tl - 1; - v++; - - if (tl && vl) { - char *tt, *ct; - - tt = av_malloc(tl + 1); - ct = av_malloc(vl + 1); - if (!tt || !ct) { - av_freep(&tt); - av_freep(&ct); - return AVERROR(ENOMEM); - } - - memcpy(tt, t, tl); - tt[tl] = 0; - - memcpy(ct, v, vl); - ct[vl] = 0; - - /* The format in which the pictures are stored is the FLAC format. - * Xiph says: "The binary FLAC picture structure is base64 encoded - * and placed within a VorbisComment with the tag name - * 'METADATA_BLOCK_PICTURE'. This is the preferred and - * recommended way of embedding cover art within VorbisComments." - */ - if (!av_strcasecmp(tt, "METADATA_BLOCK_PICTURE") && parse_picture) { - int ret, len = AV_BASE64_DECODE_SIZE(vl); - char *pict = av_malloc(len); - - if (!pict) { - av_log(as, AV_LOG_WARNING, "out-of-memory error. Skipping cover art block.\n"); - av_freep(&tt); - av_freep(&ct); - continue; - } - ret = av_base64_decode(pict, ct, len); - av_freep(&tt); - av_freep(&ct); - if (ret > 0) - ret = ff_flac_parse_picture(as, pict, ret, 0); - av_freep(&pict); - if (ret < 0) { - av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n"); - continue; - } - } else if (!ogm_chapter(as, tt, ct)) { - updates++; - if (av_dict_get(*m, tt, NULL, 0)) { - av_dict_set(m, tt, ";", AV_DICT_APPEND); - } - av_dict_set(m, tt, ct, - AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL | - AV_DICT_APPEND); - } - } } if (p != end) |