level: Fix integer overflow when filling LevelMeta
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Fri, 29 Nov 2024 18:41:54 +0000 (13:41 -0500)
committerBackport Bot <gitlab-backport-bot@gstreamer-foundation.org>
Mon, 2 Dec 2024 22:51:12 +0000 (22:51 +0000)
The level in GstAudioLevelMeta is represented as a signed 8bit value from 0 to
127 (with 127 meaning silence). When converting from double, make sure to clip
the value, this also prevent integer overflow in the conversion. This fixes an
issue where a lower then -127db is reported and random level with near silent
streams (due to integer overflow).

Fixes #4068

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8029>

subprojects/gst-plugins-good/gst/level/gstlevel.c

index cc8e6203abdd58e28018b1cf19c8b4a34d71f239..b12a6221f9e05517b0eae28d4b50a894eedd80b3 100644 (file)
@@ -731,8 +731,18 @@ gst_level_transform_ip (GstBaseTransform * trans, GstBuffer * in)
   if (filter->audio_level_meta) {
     gdouble RMS = sqrt (CS_tot / num_int_samples);
     gdouble RMSdB = 20 * log10 (RMS + EPSILON);
-
-    gst_level_rtp_audio_level_meta (filter, in, -RMSdB);
+    guint8 level;
+
+    /* -127db is considered silent in audio level meta, clip anything below and
+     * avoid possible integer overflow */
+    if (RMSdB < -127.0)
+      level = 127;
+    else if (RMSdB > 0.0)
+      level = 0;
+    else
+      level = -RMSdB;
+
+    gst_level_rtp_audio_level_meta (filter, in, level);
   }
 
   GST_OBJECT_UNLOCK (filter);