[rhythmbox] add player 'redirect' signal for dealing with GStreamer redirects (bug #581885)



commit 4ae911249b516b59e80c434fda102cb352e805ea
Author: Robert Ancell <robert ancell gmail com>
Date:   Tue Jun 22 19:41:33 2010 +1000

    add player 'redirect' signal for dealing with GStreamer redirects (bug #581885)
    
    The main use for these at present is for redirects from mms:// URIs to rtsp://,
    which happens when mmssrc fails to connect to an mms stream.  We handle the redirect
    by stopping the current stream, updating the URI for the database entry, then trying to
    play it again.

 backends/gstreamer/rb-player-gst.c |    5 +++-
 backends/rb-player.c               |   35 ++++++++++++++++++++++++++++++++++
 backends/rb-player.h               |    4 +++
 lib/rb-marshal.list                |    1 +
 shell/rb-shell-player.c            |   37 +++++++++++++++++++++++++++++++++--
 5 files changed, 78 insertions(+), 4 deletions(-)
---
diff --git a/backends/gstreamer/rb-player-gst.c b/backends/gstreamer/rb-player-gst.c
index 2cb42c5..671395c 100644
--- a/backends/gstreamer/rb-player-gst.c
+++ b/backends/gstreamer/rb-player-gst.c
@@ -613,6 +613,9 @@ bus_cb (GstBus *bus, GstMessage *message, RBPlayerGst *mp)
 			rb_debug ("got playbin2-stream-changed message");
 			mp->priv->playbin_stream_changing = FALSE;
 			emit_playing_stream_and_tags (mp, TRUE);
+		} else if (gst_structure_has_name (structure, "redirect")) {
+			const char *uri = gst_structure_get_string (structure, "new-location");
+			_rb_player_emit_redirect (RB_PLAYER (mp), mp->priv->stream_data, uri);
 		}
 		break;
 
@@ -786,7 +789,7 @@ impl_close (RBPlayer *player, const char *uri, GError **error)
 	}
 
 	if (mp->priv->playbin != NULL) {
-		start_state_change (mp, GST_STATE_READY, PLAYER_SHUTDOWN);
+		start_state_change (mp, GST_STATE_NULL, PLAYER_SHUTDOWN);
 	}
 	return TRUE;
 }
diff --git a/backends/rb-player.c b/backends/rb-player.c
index 41d3016..08a8f5f 100644
--- a/backends/rb-player.c
+++ b/backends/rb-player.c
@@ -44,6 +44,7 @@ enum {
 	PLAYING_STREAM,
 	VOLUME_CHANGED,
 	IMAGE,
+	REDIRECT,
 	LAST_SIGNAL
 };
 
@@ -274,6 +275,25 @@ rb_player_interface_init (RBPlayerIface *iface)
 			      G_TYPE_NONE,
 			      2,
 			      G_TYPE_POINTER, GDK_TYPE_PIXBUF);
+
+	/**
+	 * RBPlayer::redirect:
+	 * @player: the #RBPlayer
+	 * @stream_data: data associated with the stream
+	 * @uri: URI to redirect to
+	 *
+	 * The 'redirect' signal is emitted to indicate when a stream has change URI.
+	 */
+	signals[REDIRECT] =
+		g_signal_new ("redirect",
+			      G_TYPE_FROM_INTERFACE (iface),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (RBPlayerIface, redirect),
+			      NULL, NULL,
+			      rb_marshal_VOID__POINTER_STRING,
+			      G_TYPE_NONE,
+			      2,
+			      G_TYPE_POINTER, G_TYPE_STRING);
 }
 
 GType
@@ -691,6 +711,21 @@ _rb_player_emit_image (RBPlayer *player, gpointer stream_data, GdkPixbuf *image)
 	g_signal_emit (player, signals[IMAGE], 0, stream_data, image);
 }
 
+/**
+ * _rb_player_emit_redirect:
+ * @player: a #RBPlayer implementation
+ * @stream_data: data associated with the stream
+ * @uri: URI to redirect to
+ *
+ * Emits the 'redirect' signal to notify listeners that the stream has been
+ * redirected. To be used by implementations only.
+ */
+void
+_rb_player_emit_redirect (RBPlayer *player, gpointer stream_data, const char *uri)
+{
+	g_signal_emit (player, signals[REDIRECT], 0, stream_data, uri);
+}
+
 GQuark
 rb_player_error_quark (void)
 {
diff --git a/backends/rb-player.h b/backends/rb-player.h
index f03a414..24f001f 100644
--- a/backends/rb-player.h
+++ b/backends/rb-player.h
@@ -130,6 +130,9 @@ struct _RBPlayerIface
 	void		(*image)		(RBPlayer *player,
 						 gpointer stream_data,
 						 GdkPixbuf *image);
+	void		(*redirect)		(RBPlayer *player,
+						 gpointer stream_data,
+						 const gchar *uri);
 };
 
 GType		rb_player_get_type   (void);
@@ -172,6 +175,7 @@ void	_rb_player_emit_event (RBPlayer *player, gpointer stream_data, const char *
 void	_rb_player_emit_playing_stream (RBPlayer *player, gpointer stream_data);
 void	_rb_player_emit_volume_changed (RBPlayer *player, float volume);
 void	_rb_player_emit_image (RBPlayer *player, gpointer stream_data, GdkPixbuf *image);
+void	_rb_player_emit_redirect (RBPlayer *player, gpointer stream_data, const char *uri);
 
 G_END_DECLS
 
diff --git a/lib/rb-marshal.list b/lib/rb-marshal.list
index 2e1a9fe..73fa151 100644
--- a/lib/rb-marshal.list
+++ b/lib/rb-marshal.list
@@ -41,6 +41,7 @@ VOID:POINTER,LONG,LONG
 VOID:POINTER,OBJECT
 VOID:POINTER,POINTER
 VOID:POINTER,POINTER,POINTER
+VOID:POINTER,STRING
 VOID:POINTER,UINT
 VOID:POINTER,ULONG
 VOID:STRING,DOUBLE
diff --git a/shell/rb-shell-player.c b/shell/rb-shell-player.c
index 1157b78..7a36201 100644
--- a/shell/rb-shell-player.c
+++ b/shell/rb-shell-player.c
@@ -183,6 +183,10 @@ static void rb_shell_player_extra_metadata_cb (RhythmDB *db,
 					       GValue *metadata,
 					       RBShellPlayer *player);
 
+static gboolean rb_shell_player_open_location (RBShellPlayer *player,
+					       RhythmDBEntry *entry,
+					       RBPlayerPlayType play_type,
+					       GError **error);
 static gboolean rb_shell_player_do_next_internal (RBShellPlayer *player,
 						  gboolean from_eos,
 						  gboolean allow_stop,
@@ -956,6 +960,31 @@ rb_shell_player_handle_eos (RBPlayer *player,
 	GDK_THREADS_LEAVE ();
 }
 
+
+static void
+rb_shell_player_handle_redirect (RBPlayer *player,
+				 RhythmDBEntry *entry,
+				 const gchar *uri,
+				 RBShellPlayer *shell_player)
+{
+	GValue val = { 0 };
+
+	rb_debug ("redirect to %s", uri);
+
+	/* Stop existing stream */
+	rb_player_close (shell_player->priv->mmplayer, NULL, NULL);
+
+	/* Update entry */
+	g_value_init (&val, G_TYPE_STRING);
+	g_value_set_string (&val, uri);
+	rhythmdb_entry_set (shell_player->priv->db, entry, RHYTHMDB_PROP_LOCATION, &val);
+	g_value_unset (&val);
+	rhythmdb_commit (shell_player->priv->db);
+
+	/* Play new URI */
+	rb_shell_player_open_location (shell_player, entry, RB_PLAYER_PLAY_REPLACE, NULL);
+}
+
 static void
 rb_shell_player_init (RBShellPlayer *player)
 {
@@ -1004,6 +1033,11 @@ rb_shell_player_init (RBShellPlayer *player)
 				 player, 0);
 
 	g_signal_connect_object (player->priv->mmplayer,
+				 "redirect",
+				 G_CALLBACK (rb_shell_player_handle_redirect),
+				 player, 0);
+
+	g_signal_connect_object (player->priv->mmplayer,
 				 "tick",
 				 G_CALLBACK (tick_cb),
 				 player, 0);
@@ -1565,7 +1599,6 @@ rb_shell_player_open_location (RBShellPlayer *player,
 			       GError **error)
 {
 	char *location;
-	gboolean was_playing;
 	gboolean ret = TRUE;
 
 	/* dispose of any existing playlist urls */
@@ -1585,8 +1618,6 @@ rb_shell_player_open_location (RBShellPlayer *player,
 		return FALSE;
 	}
 
-	was_playing = rb_player_playing (player->priv->mmplayer);
-
 	if (rb_source_try_playlist (player->priv->source)) {
 		OpenLocationThreadData *data;
 



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