summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2018-02-21 22:25:25 -0500
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2018-02-22 16:14:57 -0500
commit91798e16cc09420163684d13779f13f374164ea2 (patch)
treedef2525a5634f94b87ebf6baa076d6386136abb0
parenta84b886a7d588e5eb54b4ca5a9c5538b9555556f (diff)
baseparse: Fix integer overflow in bitrate calculation
https://bugzilla.gnome.org/show_bug.cgi?id=793284
-rw-r--r--libs/gst/base/gstbaseparse.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/libs/gst/base/gstbaseparse.c b/libs/gst/base/gstbaseparse.c
index 7ad12127b..99283b8e8 100644
--- a/libs/gst/base/gstbaseparse.c
+++ b/libs/gst/base/gstbaseparse.c
@@ -1796,7 +1796,9 @@ static void
gst_base_parse_update_bitrates (GstBaseParse * parse, GstBaseParseFrame * frame)
{
guint64 data_len, frame_dur;
- gint overhead, frame_bitrate;
+ gint overhead;
+ guint frame_bitrate;
+ guint64 frame_bitrate64;
GstBuffer *buffer = frame->buffer;
overhead = frame->overhead;
@@ -1809,11 +1811,17 @@ gst_base_parse_update_bitrates (GstBaseParse * parse, GstBaseParseFrame * frame)
/* duration should be valid by now,
* either set by subclass or maybe based on fps settings */
if (GST_BUFFER_DURATION_IS_VALID (buffer) && parse->priv->acc_duration != 0) {
+ guint64 avg_bitrate;
+
/* Calculate duration of a frame from buffer properties */
frame_dur = GST_BUFFER_DURATION (buffer);
- parse->priv->avg_bitrate = (8 * parse->priv->data_bytecount * GST_SECOND) /
- parse->priv->acc_duration;
+ avg_bitrate = gst_util_uint64_scale (GST_SECOND,
+ 8 * parse->priv->data_bytecount, parse->priv->acc_duration);
+
+ if (avg_bitrate > G_MAXUINT)
+ return;
+ parse->priv->avg_bitrate = avg_bitrate;
} else {
/* No way to figure out frame duration (is this even possible?) */
return;
@@ -1828,11 +1836,16 @@ gst_base_parse_update_bitrates (GstBaseParse * parse, GstBaseParseFrame * frame)
parse->priv->tags_changed = TRUE;
}
- if (frame_dur)
- frame_bitrate = (8 * data_len * GST_SECOND) / frame_dur;
- else
+ if (!frame_dur)
return;
+ frame_bitrate64 = gst_util_uint64_scale (GST_SECOND, 8 * data_len, frame_dur);
+
+ if (frame_bitrate64 > G_MAXUINT)
+ return;
+
+ frame_bitrate = (guint) frame_bitrate64;
+
GST_LOG_OBJECT (parse, "frame bitrate %u, avg bitrate %u", frame_bitrate,
parse->priv->avg_bitrate);