diff --git a/subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json b/subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json index 571c004911..cc5d060ab2 100644 --- a/subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json +++ b/subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json @@ -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", diff --git a/subprojects/gst-plugins-base/gst/volume/gstvolume.c b/subprojects/gst-plugins-base/gst/volume/gstvolume.c index a0427479b5..1e0e6c4763 100644 --- a/subprojects/gst-plugins-base/gst/volume/gstvolume.c +++ b/subprojects/gst-plugins-base/gst/volume/gstvolume.c @@ -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); diff --git a/subprojects/gst-plugins-base/tests/check/elements/volume.c b/subprojects/gst-plugins-base/tests/check/elements/volume.c index 1da0aa5663..303162ed31 100644 --- a/subprojects/gst-plugins-base/tests/check/elements/volume.c +++ b/subprojects/gst-plugins-base/tests/check/elements/volume.c @@ -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");