avformat/oggparsevorbis: Factor parsing a single VorbisComment out
This is in preparation for further commits. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
@@ -84,52 +84,23 @@ int ff_vorbis_stream_comment(AVFormatContext *as, AVStream *st,
|
|||||||
return updates;
|
return updates;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m,
|
static int vorbis_parse_single_comment(AVFormatContext *as, AVDictionary **m,
|
||||||
const uint8_t *buf, int size,
|
const uint8_t *buf, uint32_t size,
|
||||||
int parse_picture)
|
int *updates, int parse_picture)
|
||||||
{
|
{
|
||||||
const uint8_t *p = buf;
|
const char *t = buf, *v = memchr(t, '=', size);
|
||||||
const uint8_t *end = buf + size;
|
char *tt, *ct;
|
||||||
int updates = 0;
|
|
||||||
unsigned n;
|
|
||||||
int s;
|
|
||||||
|
|
||||||
/* must have vendor_length and user_comment_list_length */
|
|
||||||
if (size < 8)
|
|
||||||
return AVERROR_INVALIDDATA;
|
|
||||||
|
|
||||||
s = bytestream_get_le32(&p);
|
|
||||||
|
|
||||||
if (end - p - 4 < s || s < 0)
|
|
||||||
return AVERROR_INVALIDDATA;
|
|
||||||
|
|
||||||
p += s;
|
|
||||||
|
|
||||||
n = bytestream_get_le32(&p);
|
|
||||||
|
|
||||||
while (end - p >= 4 && n > 0) {
|
|
||||||
const char *t, *v;
|
|
||||||
int tl, vl;
|
int tl, vl;
|
||||||
|
|
||||||
s = bytestream_get_le32(&p);
|
|
||||||
|
|
||||||
if (end - p < s || s < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
t = p;
|
|
||||||
p += s;
|
|
||||||
n--;
|
|
||||||
|
|
||||||
v = memchr(t, '=', s);
|
|
||||||
if (!v)
|
if (!v)
|
||||||
continue;
|
return 0;
|
||||||
|
|
||||||
tl = v - t;
|
tl = v - t;
|
||||||
vl = s - tl - 1;
|
vl = size - tl - 1;
|
||||||
v++;
|
v++;
|
||||||
|
|
||||||
if (tl && vl) {
|
if (!tl || !vl)
|
||||||
char *tt, *ct;
|
return 0;
|
||||||
|
|
||||||
tt = av_malloc(tl + 1);
|
tt = av_malloc(tl + 1);
|
||||||
ct = av_malloc(vl + 1);
|
ct = av_malloc(vl + 1);
|
||||||
@@ -153,13 +124,13 @@ int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m,
|
|||||||
*/
|
*/
|
||||||
if (!av_strcasecmp(tt, "METADATA_BLOCK_PICTURE") && parse_picture) {
|
if (!av_strcasecmp(tt, "METADATA_BLOCK_PICTURE") && parse_picture) {
|
||||||
int ret, len = AV_BASE64_DECODE_SIZE(vl);
|
int ret, len = AV_BASE64_DECODE_SIZE(vl);
|
||||||
char *pict = av_malloc(len);
|
uint8_t *pict = av_malloc(len);
|
||||||
|
|
||||||
if (!pict) {
|
if (!pict) {
|
||||||
av_log(as, AV_LOG_WARNING, "out-of-memory error. Skipping cover art block.\n");
|
av_log(as, AV_LOG_WARNING, "out-of-memory error. Skipping cover art block.\n");
|
||||||
av_freep(&tt);
|
av_freep(&tt);
|
||||||
av_freep(&ct);
|
av_freep(&ct);
|
||||||
continue;
|
return 0;
|
||||||
}
|
}
|
||||||
ret = av_base64_decode(pict, ct, len);
|
ret = av_base64_decode(pict, ct, len);
|
||||||
av_freep(&tt);
|
av_freep(&tt);
|
||||||
@@ -169,10 +140,10 @@ int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m,
|
|||||||
av_freep(&pict);
|
av_freep(&pict);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n");
|
av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n");
|
||||||
continue;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (!ogm_chapter(as, tt, ct)) {
|
} else if (!ogm_chapter(as, tt, ct)) {
|
||||||
updates++;
|
(*updates)++;
|
||||||
if (av_dict_get(*m, tt, NULL, 0)) {
|
if (av_dict_get(*m, tt, NULL, 0)) {
|
||||||
av_dict_set(m, tt, ";", AV_DICT_APPEND);
|
av_dict_set(m, tt, ";", AV_DICT_APPEND);
|
||||||
}
|
}
|
||||||
@@ -180,7 +151,44 @@ int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m,
|
|||||||
AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL |
|
AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL |
|
||||||
AV_DICT_APPEND);
|
AV_DICT_APPEND);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m,
|
||||||
|
const uint8_t *buf, int size,
|
||||||
|
int parse_picture)
|
||||||
|
{
|
||||||
|
const uint8_t *p = buf;
|
||||||
|
const uint8_t *end = buf + size;
|
||||||
|
int updates = 0;
|
||||||
|
unsigned n;
|
||||||
|
int s, ret;
|
||||||
|
|
||||||
|
/* must have vendor_length and user_comment_list_length */
|
||||||
|
if (size < 8)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
|
s = bytestream_get_le32(&p);
|
||||||
|
|
||||||
|
if (end - p - 4 < s || s < 0)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
|
p += s;
|
||||||
|
|
||||||
|
n = bytestream_get_le32(&p);
|
||||||
|
|
||||||
|
while (end - p >= 4 && n > 0) {
|
||||||
|
s = bytestream_get_le32(&p);
|
||||||
|
|
||||||
|
if (end - p < s || s < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret = vorbis_parse_single_comment(as, m, p, s, &updates, parse_picture);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
p += s;
|
||||||
|
n--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p != end)
|
if (p != end)
|
||||||
|
Reference in New Issue
Block a user