From 11dacbb1a8f2f592f21d36620807c46020b3cb5c Mon Sep 17 00:00:00 2001 From: Gabriel Burt Date: Thu, 17 Jun 2010 13:44:08 -0700 Subject: [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(-) (limited to 'libbanshee') diff --git a/libbanshee/banshee-player-pipeline.c b/libbanshee/banshee-player-pipeline.c index c95208f90..b12202c68 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 7f5c00f0a..b449aa8b5 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 cca6b6387..42c73b85c 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 406bf9473..7c3c65028 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); } -- cgit v1.2.3