diff options
author | Nicolas Dufresne <nicolas.dufresne@collabora.com> | 2018-02-21 22:25:25 -0500 |
---|---|---|
committer | Nicolas Dufresne <nicolas.dufresne@collabora.com> | 2018-02-22 16:14:57 -0500 |
commit | 91798e16cc09420163684d13779f13f374164ea2 (patch) | |
tree | def2525a5634f94b87ebf6baa076d6386136abb0 | |
parent | a84b886a7d588e5eb54b4ca5a9c5538b9555556f (diff) |
baseparse: Fix integer overflow in bitrate calculation
https://bugzilla.gnome.org/show_bug.cgi?id=793284
-rw-r--r-- | libs/gst/base/gstbaseparse.c | 25 |
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); |