[banshee] [libbanshee] Fix up some volume handling issues



commit 11dacbb1a8f2f592f21d36620807c46020b3cb5c
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Thu Jun 17 13:44:08 2010 -0700

    [libbanshee] Fix up some volume handling issues
    
    Check the audiosink recursively for a 'volume' property.  If it exists,
    then we assume the sink will save/restore its own volume - so expose
    that information to the managed PlayerEngine so it can decide whether to
    restore the last volume from gconf.  Also, listen to the
    deep-notify::volume signal like RB does.

 libbanshee/banshee-player-pipeline.c |   19 +++++++++++++++++--
 libbanshee/banshee-player-pipeline.h |    1 +
 libbanshee/banshee-player-private.h  |    1 +
 libbanshee/banshee-player.c          |   12 ++++++++++++
 4 files changed, 31 insertions(+), 2 deletions(-)
---
diff --git a/libbanshee/banshee-player-pipeline.c b/libbanshee/banshee-player-pipeline.c
index c95208f..b12202c 100644
--- a/libbanshee/banshee-player-pipeline.c
+++ b/libbanshee/banshee-player-pipeline.c
@@ -258,7 +258,7 @@ static void bp_about_to_finish_callback (GstElement *playbin, BansheePlayer *pla
 }
 #endif //ENABLE_GAPLESS
 
-static void bp_volume_changed_callback (GstElement *playbin, GParamSpec *spec, BansheePlayer *player)
+void bp_volume_changed_callback (GstElement *playbin, GParamSpec *spec, BansheePlayer *player)
 {
     gdouble volume;
 
@@ -309,7 +309,7 @@ _bp_pipeline_construct (BansheePlayer *player)
 
     g_return_val_if_fail (player->playbin != NULL, FALSE);
 
-    g_signal_connect (player->playbin, "notify::volume", G_CALLBACK (bp_volume_changed_callback), player);
+    g_signal_connect (player->playbin, "deep-notify::volume", G_CALLBACK (bp_volume_changed_callback), player);
     g_signal_connect (player->playbin, "video-changed", G_CALLBACK (playbin_stream_changed_cb), player);
     g_signal_connect (player->playbin, "audio-changed", G_CALLBACK (playbin_stream_changed_cb), player);
     g_signal_connect (player->playbin, "text-changed", G_CALLBACK (playbin_stream_changed_cb), player);
@@ -330,6 +330,21 @@ _bp_pipeline_construct (BansheePlayer *player)
     }
     
     g_return_val_if_fail (audiosink != NULL, FALSE);
+
+    // See if the audiosink has a 'volume' property.  If it does, we assume it saves and restores
+    // its volume information - and that we shouldn't
+    player->audiosink_has_volume = FALSE;
+    if (!GST_IS_BIN (audiosink)) {
+        player->audiosink_has_volume = g_object_class_find_property (G_OBJECT_GET_CLASS (audiosink), "volume") != NULL;
+    } else {
+        GstIterator *elem_iter = gst_bin_iterate_recurse (GST_BIN (audiosink));
+        BANSHEE_GST_ITERATOR_ITERATE (elem_iter, GstElement *, element, TRUE, {
+            player->audiosink_has_volume |= g_object_class_find_property (G_OBJECT_GET_CLASS (element), "volume") != NULL;
+            gst_object_unref (element);
+        });
+    }
+    bp_debug ("Audiosink has volume: %s",
+        player->audiosink_has_volume ? "YES" : "NO");
         
     // Set the profile to "music and movies" (gst-plugins-good 0.10.3)
     if (g_object_class_find_property (G_OBJECT_GET_CLASS (audiosink), "profile")) {
diff --git a/libbanshee/banshee-player-pipeline.h b/libbanshee/banshee-player-pipeline.h
index 7f5c00f..b449aa8 100644
--- a/libbanshee/banshee-player-pipeline.h
+++ b/libbanshee/banshee-player-pipeline.h
@@ -34,5 +34,6 @@
 gboolean  _bp_pipeline_construct (BansheePlayer *player);
 void      _bp_pipeline_destroy   (BansheePlayer *player);
 void      _bp_pipeline_rebuild   (BansheePlayer* player);
+void       bp_volume_changed_callback (GstElement *playbin, GParamSpec *spec, BansheePlayer *player);
 
 #endif /* _BANSHEE_PLAYER_PIPELINE_H */
diff --git a/libbanshee/banshee-player-private.h b/libbanshee/banshee-player-private.h
index cca6b63..42c73b8 100644
--- a/libbanshee/banshee-player-private.h
+++ b/libbanshee/banshee-player-private.h
@@ -149,6 +149,7 @@ struct BansheePlayer {
     gchar *cdda_device;
     gboolean in_gapless_transition;
     gboolean supports_stream_volume;
+    gboolean audiosink_has_volume;
     
     // Video State
     BpVideoDisplayContextType video_display_context_type;
diff --git a/libbanshee/banshee-player.c b/libbanshee/banshee-player.c
index 406bf94..7c3c650 100644
--- a/libbanshee/banshee-player.c
+++ b/libbanshee/banshee-player.c
@@ -260,12 +260,23 @@ bp_supports_stream_volume (BansheePlayer *player)
     return player->supports_stream_volume;
 }
 
+P_INVOKE gboolean
+bp_audiosink_has_volume (BansheePlayer *player)
+{
+    g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
+    return player->audiosink_has_volume;
+}
+
 P_INVOKE void
 bp_set_volume (BansheePlayer *player, gdouble volume)
 {
     g_return_if_fail (IS_BANSHEE_PLAYER (player));
     g_return_if_fail (GST_IS_ELEMENT (player->playbin));
 
+    // Idea taken from RB: ignore the deep-notify we get directly from the sink, as it causes deadlock, and we'll
+    // get another anyway
+    g_signal_handlers_block_by_func (player->playbin, bp_volume_changed_callback, player);
+
     if (bp_supports_stream_volume (player)) {
         #if BANSHEE_CHECK_GST_VERSION(0,10,25)
         gst_stream_volume_set_volume (GST_STREAM_VOLUME (player->playbin),
@@ -275,6 +286,7 @@ bp_set_volume (BansheePlayer *player, gdouble volume)
         g_object_set (player->playbin, "volume", CLAMP (volume, 0.0, 1.0), NULL);
     }
 
+    g_signal_handlers_unblock_by_func (player->playbin, bp_volume_changed_callback, player);
     _bp_rgvolume_print_volume (player);
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]