volume: Expose the volume-full-range as another property

In https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5063
the range of volume value has changed which breaks backward compatibility
when  using a GstDirectControlBinding which is not acceptable. To avoid
breaking compatibility add the feature of allowing the full range  using
another property with the full range. When using that full range, the
value of the `volume` property might end up being out of its valid
range but we do not really have a good solution for that.

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3257
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6222>
This commit is contained in:
Thibault Saunier 2024-02-26 12:38:55 -03:00 committed by GStreamer Marge Bot
parent cf2238a522
commit 1baa36c14a
3 changed files with 69 additions and 25 deletions

View file

@ -15847,6 +15847,20 @@
"construct-only": false,
"controllable": true,
"default": "1",
"max": "10",
"min": "0",
"mutable": "null",
"readable": true,
"type": "gdouble",
"writable": true
},
"volume-full-range": {
"blurb": "volume factor with a full range of values, 1.0=100%%",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": true,
"default": "1",
"max": "1.79769e+308",
"min": "0",
"mutable": "null",

View file

@ -96,7 +96,8 @@ enum
{
PROP_0,
PROP_MUTE,
PROP_VOLUME
PROP_VOLUME,
PROP_VOLUME_FULL_RANGE
};
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
@ -380,13 +381,26 @@ gst_volume_class_init (GstVolumeClass * klass)
DEFAULT_PROP_MUTE,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
/* The volume factor is a range from 0.0 to G_MAXDOUBLE.
* The choice of G_MAXDOUBLE is somewhat arbitrary,
* but it should be *very* inclusive, e.g. gain of +48 dB is very reasonable.
/**
* GstVolume:volume-full-range:
*
* The volume-full-range factor is a range from 0.0 to G_MAXDOUBLE so
* it is *very* inclusive, e.g. gain of +48 dB is very reasonable. This
* property allows setting higher value than the #GstVolume:volume property.
*
* Since: 1.24
*/
/* This property has been exposed as another property to keep the backward compatibility
* when using #GstDirectControlBinding with GstDirectControlBinding:absolute set to FALSE. */
g_object_class_install_property (gobject_class, PROP_VOLUME_FULL_RANGE,
g_param_spec_double ("volume-full-range", "Volume",
"volume factor with a full range of values, 1.0=100%", 0.0,
G_MAXDOUBLE, DEFAULT_PROP_VOLUME,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_VOLUME,
g_param_spec_double ("volume", "Volume", "volume factor, 1.0=100%",
0.0, G_MAXDOUBLE, DEFAULT_PROP_VOLUME,
0.0, 10.0, DEFAULT_PROP_VOLUME,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
gst_element_class_set_static_metadata (element_class, "Volume",
@ -981,6 +995,11 @@ volume_set_property (GObject * object, guint prop_id, const GValue * value,
self->volume = g_value_get_double (value);
GST_OBJECT_UNLOCK (self);
break;
case PROP_VOLUME_FULL_RANGE:
GST_OBJECT_LOCK (self);
self->volume = g_value_get_double (value);
GST_OBJECT_UNLOCK (self);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1000,6 +1019,17 @@ volume_get_property (GObject * object, guint prop_id, GValue * value,
GST_OBJECT_UNLOCK (self);
break;
case PROP_VOLUME:
GST_OBJECT_LOCK (self);
if (self->volume > 10.0) {
GST_WARNING_OBJECT (object,
"Volume is greater than its max value 10.0, reporting as 10.0");
g_value_set_double (value, 10.0);
} else {
g_value_set_double (value, self->volume);
}
GST_OBJECT_UNLOCK (self);
break;
case PROP_VOLUME_FULL_RANGE:
GST_OBJECT_LOCK (self);
g_value_set_double (value, self->volume);
GST_OBJECT_UNLOCK (self);

View file

@ -385,7 +385,7 @@ GST_START_TEST (test_fifteen_s8)
volume = setup_volume ();
// Maximal volume that is supported by the fixed point multiplication.
g_object_set (G_OBJECT (volume), "volume", 15.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 15.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -436,7 +436,7 @@ GST_START_TEST (test_sixteen_s8)
volume = setup_volume ();
// No longer using fixed point multiplication.
g_object_set (G_OBJECT (volume), "volume", 16.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 16.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -487,7 +487,7 @@ GST_START_TEST (test_max_s8)
volume = setup_volume ();
// No longer using fixed point multiplication.
g_object_set (G_OBJECT (volume), "volume", G_MAXDOUBLE, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", G_MAXDOUBLE, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -771,7 +771,7 @@ GST_START_TEST (test_fifteen_s16)
GstMapInfo map;
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", 15.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 15.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -821,7 +821,7 @@ GST_START_TEST (test_sixteen_s16)
GstMapInfo map;
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", 16.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 16.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -871,7 +871,7 @@ GST_START_TEST (test_max_s16)
GstMapInfo map;
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", G_MAXDOUBLE, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", G_MAXDOUBLE, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -1200,7 +1200,7 @@ GST_START_TEST (test_fifteen_s24)
write_unaligned_u24 (in + 9, in_32[3]);
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", 15.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 15.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -1262,7 +1262,7 @@ GST_START_TEST (test_sixteen_s24)
write_unaligned_u24 (in + 9, in_32[3]);
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", 16.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 16.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -1324,7 +1324,7 @@ GST_START_TEST (test_4095_s24)
write_unaligned_u24 (in + 9, in_32[3]);
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", 4095.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 4095.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -1386,7 +1386,7 @@ GST_START_TEST (test_4096_s24)
write_unaligned_u24 (in + 9, in_32[3]);
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", 4096.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 4096.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -1448,7 +1448,7 @@ GST_START_TEST (test_max_s24)
write_unaligned_u24 (in + 9, in_32[3]);
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", G_MAXDOUBLE, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", G_MAXDOUBLE, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -1746,7 +1746,7 @@ GST_START_TEST (test_fifteen_s32)
GstMapInfo map;
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", 15.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 15.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -1796,7 +1796,7 @@ GST_START_TEST (test_sixteen_s32)
GstMapInfo map;
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", 16.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 16.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -1846,7 +1846,7 @@ GST_START_TEST (test_max_s32)
GstMapInfo map;
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", G_MAXDOUBLE, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", G_MAXDOUBLE, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -2135,7 +2135,7 @@ GST_START_TEST (test_fifteen_f32)
GstMapInfo map;
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", 15.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 15.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -2188,7 +2188,7 @@ GST_START_TEST (test_sixteen_f32)
GstMapInfo map;
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", 16.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 16.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -2243,7 +2243,7 @@ GST_START_TEST (test_max_f32)
GstMapInfo map;
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", G_MAXDOUBLE, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", G_MAXDOUBLE, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -2536,7 +2536,7 @@ GST_START_TEST (test_fifteen_f64)
GstMapInfo map;
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", 15.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 15.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -2589,7 +2589,7 @@ GST_START_TEST (test_sixteen_f64)
GstMapInfo map;
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", 16.0, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", 16.0, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");
@ -2644,7 +2644,7 @@ GST_START_TEST (test_max_f64)
GstMapInfo map;
volume = setup_volume ();
g_object_set (G_OBJECT (volume), "volume", G_MAXDOUBLE, NULL);
g_object_set (G_OBJECT (volume), "volume-full-range", G_MAXDOUBLE, NULL);
fail_unless (gst_element_set_state (volume, GST_STATE_PLAYING) ==
GST_STATE_CHANGE_SUCCESS, "could not set to playing");