[FFmpeg-cvslog] avformat/oggparsevorbis: Factor parsing a single VorbisComment out
Andreas Rheinhardt
git at videolan.org
Sat Aug 28 17:52:35 EEST 2021
ffmpeg | branch: master | Andreas Rheinhardt <andreas.rheinhardt at outlook.com> | Mon Aug 23 10:03:47 2021 +0200| [f1d89d6dd0aa825d48e9be13837d77e8c1964fe8] | committer: Andreas Rheinhardt
avformat/oggparsevorbis: Factor parsing a single VorbisComment out
This is in preparation for further commits.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f1d89d6dd0aa825d48e9be13837d77e8c1964fe8
---
libavformat/oggparsevorbis.c | 142 +++++++++++++++++++++++--------------------
1 file 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)
More information about the ffmpeg-cvslog
mailing list