summaryrefslogtreecommitdiff
path: root/libavformat/asfdec.c
diff options
context:
space:
mode:
authorAlexandra Hájková <alexandra.khirnova@gmail.com>2015-08-04 12:46:27 +0200
committerLuca Barbato <lu_zero@gentoo.org>2015-08-04 21:33:55 +0200
commit944f60866f507e3c0850ae9c2f30dac1da54587c (patch)
tree037246a4cff5ca3f611a16c0e1cc86986dc37d77 /libavformat/asfdec.c
parentb197f78329615893201c0e241d00b71b7c749dbb (diff)
asfdec: read values properly
The length of BOOL values is 16 bits in the Metadata Object but 32 bits in the Extended Content Description Object. Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
Diffstat (limited to 'libavformat/asfdec.c')
-rw-r--r--libavformat/asfdec.c52
1 files changed, 36 insertions, 16 deletions
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index be0ebd5b34..70f54e04f6 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -304,30 +304,41 @@ failed:
av_freep(&value);
return ret;
}
-
-static int asf_read_generic_value(AVFormatContext *s, const uint8_t *name,
- uint16_t name_len, int type, AVDictionary **met)
+static int asf_read_generic_value(AVIOContext *pb, int type, uint64_t *value)
{
- AVIOContext *pb = s->pb;
- uint64_t value;
- char buf[32];
switch (type) {
case ASF_BOOL:
- value = avio_rl32(pb);
+ *value = avio_rl16(pb);
break;
case ASF_DWORD:
- value = avio_rl32(pb);
+ *value = avio_rl32(pb);
break;
case ASF_QWORD:
- value = avio_rl64(pb);
+ *value = avio_rl64(pb);
break;
case ASF_WORD:
- value = avio_rl16(pb);
+ *value = avio_rl16(pb);
break;
default:
return AVERROR_INVALIDDATA;
}
+
+ return 0;
+}
+
+static int asf_set_metadata(AVFormatContext *s, const uint8_t *name,
+ uint16_t name_len, int type, AVDictionary **met)
+{
+ AVIOContext *pb = s->pb;
+ uint64_t value;
+ char buf[32];
+ int ret;
+
+ ret = asf_read_generic_value(pb, type, &value);
+ if (ret < 0)
+ return ret;
+
snprintf(buf, sizeof(buf), "%"PRIu64, value);
if (av_dict_set(met, name, buf, 0) < 0)
av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");
@@ -470,7 +481,7 @@ static int process_metadata(AVFormatContext *s, const uint8_t *name, uint16_t na
ff_get_guid(s->pb, &guid);
break;
default:
- if ((ret = asf_read_generic_value(s, name, name_len, type, met)) < 0)
+ if ((ret = asf_set_metadata(s, name, name_len, type, met)) < 0)
return ret;
break;
}
@@ -500,6 +511,10 @@ static int asf_read_ext_content(AVFormatContext *s, const GUIDParseTable *g)
avio_get_str16le(pb, name_len, name,
name_len);
type = avio_rl16(pb);
+ // BOOL values are 16 bits long in the Metadata Object
+ // but 32 bits long in the Extended Content Description Object
+ if (type == ASF_BOOL)
+ type = ASF_DWORD;
val_len = avio_rl16(pb);
ret = process_metadata(s, name, name_len, val_len, type, &s->metadata);
@@ -528,13 +543,16 @@ static AVStream *find_stream(AVFormatContext *s, uint16_t st_num)
return st;
}
-static void asf_store_aspect_ratio(AVFormatContext *s, uint8_t st_num, uint8_t *name)
+static int asf_store_aspect_ratio(AVFormatContext *s, uint8_t st_num, uint8_t *name, int type)
{
ASFContext *asf = s->priv_data;
AVIOContext *pb = s->pb;
- uint16_t value = 0;
+ uint64_t value = 0;
+ int ret;
- value = avio_rl16(pb);
+ ret = asf_read_generic_value(pb, type, &value);
+ if (ret < 0)
+ return ret;
if (st_num < ASF_MAX_STREAMS) {
if (!strcmp(name, "AspectRatioX"))
@@ -542,6 +560,7 @@ static void asf_store_aspect_ratio(AVFormatContext *s, uint8_t st_num, uint8_t *
else
asf->asf_sd[st_num].aspect_ratio.den = value;
}
+ return 0;
}
static int asf_read_metadata_obj(AVFormatContext *s, const GUIDParseTable *g)
@@ -569,9 +588,10 @@ static int asf_read_metadata_obj(AVFormatContext *s, const GUIDParseTable *g)
return AVERROR(ENOMEM);
avio_get_str16le(pb, name_len, name,
buflen);
-
if (!strcmp(name, "AspectRatioX") || !strcmp(name, "AspectRatioY")) {
- asf_store_aspect_ratio(s, st_num, name);
+ ret = asf_store_aspect_ratio(s, st_num, name, type);
+ if (ret < 0)
+ return ret;
} else {
if (st_num < ASF_MAX_STREAMS) {
if ((ret = process_metadata(s, name, name_len, val_len, type,