Re: [Rhythmbox-devel] merging monkey-medias



On Sat, 2003-05-10 at 14:33, Jorn Baayen wrote:

> Well, I don't like what you did there as you know 

I don't like it either :/

But I still much prefer hacks over not releasing at all.  Not just
releasing even, but having it easily testable from CVS.

> - but I see these
> hacks are necessary for the time being. So what I propose is to include
> a -gst.c and -gst-tmp.c.

That sounds like a good solution to me.

> But, we'd need to update the one in HEAD to include the buffering stuff
> - could you make a patch for HEAD that only adds the buffering without
> changing any of the other things? Then we can also add your gst.c and
> add a configure option.

Attached.

Index: monkey-media-player-gst.c
===================================================================
RCS file: /cvs/gnome/monkey-media/src/monkey-media-player-gst.c,v
retrieving revision 1.11
diff -u -d -u -r1.11 monkey-media-player-gst.c
--- monkey-media-player-gst.c	19 Apr 2003 14:45:50 -0000	1.11
+++ monkey-media-player-gst.c	10 May 2003 20:37:04 -0000
@@ -22,6 +22,7 @@
 
 #ifdef HAVE_GSTREAMER
 #include <gst/gst.h>
+#include <gst/gstqueue.h>
 #include <gst/gconf/gconf.h>
 #include <gst/control/control.h>
 #include <gst/control/dparam_smooth.h>
@@ -43,6 +44,10 @@
 	char *uri;
 
 	GstElement *pipeline;
+	GstElement *srcthread;
+	GstElement *queue;
+	GstElement *waiting_bin;
+
 	GstElement *src;
 	GstElement *audiocd_src;
 	GstElement *decoder;
@@ -68,6 +73,8 @@
 {
 	EOS,
 	INFO,
+	BUFFERING_BEGIN,
+	BUFFERING_END,	
 	ERROR,
 	TICK,
 	LAST_SIGNAL
@@ -141,6 +148,24 @@
 			      2,
 			      MONKEY_MEDIA_TYPE_STREAM_INFO_FIELD,
 			      G_TYPE_POINTER);
+	monkey_media_player_signals[BUFFERING_BEGIN] =
+		g_signal_new ("buffering_begin",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (MonkeyMediaPlayerClass, buffering_begin),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
+	monkey_media_player_signals[BUFFERING_END] =
+		g_signal_new ("buffering_end",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (MonkeyMediaPlayerClass, buffering_end),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
 	monkey_media_player_signals[ERROR] =
 		g_signal_new ("error",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -341,13 +366,57 @@
 	g_type_class_unref (class);
 }
 
+static gboolean
+buffering_begin_signal_idle (MonkeyMediaPlayer *mp)
+{
+	g_signal_emit (G_OBJECT (mp), monkey_media_player_signals[BUFFERING_BEGIN], 0);
+
+	g_object_unref (G_OBJECT (mp));
+
+	return FALSE;
+}
+
+static gboolean
+buffering_end_signal_idle (MonkeyMediaPlayer *mp)
+{
+	g_signal_emit (G_OBJECT (mp), monkey_media_player_signals[BUFFERING_END], 0);
+
+	g_object_unref (G_OBJECT (mp));
+
+	return FALSE;
+}
+
+#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR == 6
+static void
+queue_full_cb (GstQueue *queue,
+	       int level,
+	       gpointer data)
+#else
+static void
+queue_full_cb (GstQueue *queue,
+	       gpointer data)     
+#endif
+{
+	MonkeyMediaPlayer *mp = MONKEY_MEDIA_PLAYER (data);
+
+	g_signal_handlers_block_by_func (G_OBJECT (mp->priv->queue),
+					 G_CALLBACK (queue_full_cb),
+					 mp);
+	gst_element_set_state (mp->priv->waiting_bin, GST_STATE_PLAYING);
+	g_object_ref (G_OBJECT (mp));
+	g_idle_add ((GSourceFunc) buffering_end_signal_idle, mp);
+}
+
 static void
 monkey_media_player_construct (MonkeyMediaPlayer *mp,
 			       GError **error)
 {
 	GstDParamManager *dpman;
 
-	/* playback pipeline */
+	/**
+	 * The main playback pipeline at the end this looks like:
+	 *  { src ! queue } ! { decoder ! volume ! sink }
+	 */
 	mp->priv->pipeline = gst_thread_new ("pipeline");
 
 	g_signal_connect (G_OBJECT (mp->priv->pipeline),
@@ -363,14 +432,22 @@
 
 	mp->priv->audiocd_mode = FALSE;
 
+	mp->priv->waiting_bin = gst_element_factory_make ("thread", "waiting_bin");
+	mp->priv->srcthread = gst_element_factory_make ("thread", "srcthread");
+	gst_bin_add_many (GST_BIN (mp->priv->pipeline),
+				  mp->priv->srcthread, mp->priv->waiting_bin, NULL);
+
 	mp->priv->src = gst_element_factory_make ("gnomevfssrc", "src");
 	if (mp->priv->src == NULL) {
 		g_set_error (error,
 			     MONKEY_MEDIA_PLAYER_ERROR,
 			     MONKEY_MEDIA_PLAYER_ERROR_NO_INPUT_PLUGIN,
 			     _("Failed to create gnomevfssrc input element; check your installation"));
+		gst_object_unref (GST_OBJECT (mp->priv->pipeline));
 		return;
 	}
+	gst_bin_add (GST_BIN (mp->priv->srcthread), mp->priv->src);
+	gst_object_ref (GST_OBJECT (mp->priv->src));
 
 	mp->priv->audiocd_src = gst_element_factory_make ("cdparanoia", "src");
 	if (mp->priv->audiocd_src == NULL) {
@@ -380,9 +457,11 @@
 			     _("Failed to create cdparanoia input element; check your installation"));
 
 		gst_object_unref (GST_OBJECT (mp->priv->src));
+		gst_object_unref (GST_OBJECT (mp->priv->pipeline));
 
 		return;
 	}
+	gst_object_ref (GST_OBJECT (mp->priv->audiocd_src));
 
 	g_object_set (G_OBJECT (mp->priv->audiocd_src),
 		      "paranoia-mode",
@@ -393,6 +472,31 @@
 		      monkey_media_get_cd_drive (),
 		      NULL);
 
+	mp->priv->queue = gst_element_factory_make ("queue", "queue");
+	if (mp->priv->queue == NULL) {
+		g_set_error (error,
+			     MONKEY_MEDIA_PLAYER_ERROR,
+			     MONKEY_MEDIA_PLAYER_ERROR_NO_QUEUE_PLUGIN,
+			     _("Failed to create queue element; check your installation"));
+
+		gst_object_unref (GST_OBJECT (mp->priv->src));
+		gst_object_unref (GST_OBJECT (mp->priv->audiocd_src));
+		gst_object_unref (GST_OBJECT (mp->priv->pipeline));
+		return;
+	}
+
+#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR == 6
+	g_signal_connect (G_OBJECT (mp->priv->queue), "high_watermark",
+			  G_CALLBACK (queue_full_cb), mp);
+#else
+	g_signal_connect (G_OBJECT (mp->priv->queue), "full",
+			  G_CALLBACK (queue_full_cb), mp);
+#endif	
+	g_signal_handlers_block_by_func (G_OBJECT (mp->priv->queue),
+					 G_CALLBACK (queue_full_cb),
+					 mp);
+	gst_bin_add (GST_BIN (mp->priv->srcthread), mp->priv->queue);
+
 	mp->priv->decoder = gst_element_factory_make ("spider", "autoplugger");
 	if (mp->priv->decoder == NULL) {
 		g_set_error (error,
@@ -402,9 +506,11 @@
 
 		gst_object_unref (GST_OBJECT (mp->priv->src));
 		gst_object_unref (GST_OBJECT (mp->priv->audiocd_src));
+		gst_object_unref (GST_OBJECT (mp->priv->pipeline));
 
 		return;
 	}
+	gst_bin_add (GST_BIN (mp->priv->waiting_bin), mp->priv->decoder);
 
 	mp->priv->volume = gst_element_factory_make ("volume", "volume");
 	if (mp->priv->volume == NULL) {
@@ -415,10 +521,11 @@
 
 		gst_object_unref (GST_OBJECT (mp->priv->src));
 		gst_object_unref (GST_OBJECT (mp->priv->audiocd_src));
-		gst_object_unref (GST_OBJECT (mp->priv->decoder));
+		gst_object_unref (GST_OBJECT (mp->priv->pipeline));
 
 		return;
 	}
+	gst_bin_add (GST_BIN (mp->priv->waiting_bin), mp->priv->volume);
 
 	dpman = gst_dpman_get_manager (mp->priv->volume);
 	gst_dpman_set_mode (dpman, "synchronous");
@@ -435,20 +542,15 @@
 
 		gst_object_unref (GST_OBJECT (mp->priv->src));
 		gst_object_unref (GST_OBJECT (mp->priv->audiocd_src));
-		gst_object_unref (GST_OBJECT (mp->priv->decoder));
-		gst_object_unref (GST_OBJECT (mp->priv->volume));
-
+		gst_object_unref (GST_OBJECT (mp->priv->pipeline));
 		return;
 	}
+	gst_bin_add (GST_BIN (mp->priv->waiting_bin), mp->priv->sink);
 
-	gst_bin_add_many (GST_BIN (mp->priv->pipeline),
-			  mp->priv->src, mp->priv->decoder,
-			  mp->priv->volume, mp->priv->sink, NULL);
-	gst_element_link_many (mp->priv->src, mp->priv->decoder,
+	gst_element_link_many (mp->priv->src, mp->priv->queue, mp->priv->decoder,
 			       mp->priv->volume, mp->priv->sink, NULL);
 
-	/* FIXME on the sink doesnt work? */
-	g_signal_connect (G_OBJECT (mp->priv->volume), "eos",
+	g_signal_connect (G_OBJECT (mp->priv->sink), "eos",
 			  G_CALLBACK (eos_cb), mp);
 
 	g_object_set (G_OBJECT (mp->priv->volume_dparam),
@@ -526,14 +628,12 @@
 		}
 
 		if (!mp->priv->audiocd_mode) {
-			gst_element_unlink (mp->priv->decoder, mp->priv->volume);
-			gst_bin_remove (GST_BIN (mp->priv->pipeline),
+			gst_element_unlink (mp->priv->src, mp->priv->queue);
+			gst_bin_remove (GST_BIN (mp->priv->srcthread),
 					mp->priv->src);
-			gst_bin_remove (GST_BIN (mp->priv->pipeline),
-					mp->priv->decoder);
-			gst_bin_add (GST_BIN (mp->priv->pipeline),
+			gst_bin_add (GST_BIN (mp->priv->srcthread),
 				     mp->priv->audiocd_src);
-			gst_element_link (mp->priv->audiocd_src, mp->priv->volume);
+			gst_element_link (mp->priv->audiocd_src, mp->priv->queue);
 
 			mp->priv->audiocd_mode = TRUE;
 		}
@@ -553,14 +653,12 @@
 		gst_element_send_event (mp->priv->sink, event);
 	} else {
 		if (mp->priv->audiocd_mode) {
-			gst_element_unlink (mp->priv->audiocd_src, mp->priv->volume);
-			gst_bin_remove (GST_BIN (mp->priv->pipeline),
+			gst_element_unlink (mp->priv->audiocd_src, mp->priv->queue);
+			gst_bin_remove (GST_BIN (mp->priv->srcthread),
 					mp->priv->audiocd_src);
-			gst_bin_add_many (GST_BIN (mp->priv->pipeline),
-					  mp->priv->src,
-					  mp->priv->decoder,
-					  NULL);
-			gst_element_link (mp->priv->decoder, mp->priv->volume);
+			gst_bin_add (GST_BIN (mp->priv->srcthread),
+				     mp->priv->src);
+			gst_element_link (mp->priv->src, mp->priv->queue);
 
 			mp->priv->audiocd_mode = FALSE;
 		}
@@ -576,8 +674,14 @@
 
 	mp->priv->uri = g_strdup (uri);
 
+	g_signal_handlers_unblock_by_func (G_OBJECT (mp->priv->queue),
+					   G_CALLBACK (queue_full_cb),
+					   mp);
+
 	if (mp->priv->playing) {
-		gst_element_set_state (mp->priv->pipeline,
+		g_object_ref (G_OBJECT (mp));
+		g_idle_add ((GSourceFunc) buffering_begin_signal_idle, mp);
+		gst_element_set_state (mp->priv->srcthread,
 				       GST_STATE_PLAYING);
 	} else {
 		gst_element_set_state (mp->priv->pipeline,
@@ -615,9 +719,13 @@
 {
 	g_return_if_fail (MONKEY_MEDIA_IS_PLAYER (mp));
 
+	monkey_media_player_pause (mp);
+
 	mp->priv->playing = TRUE;
 
-	gst_element_set_state (mp->priv->pipeline,
+	g_object_ref (G_OBJECT (mp));
+	g_idle_add ((GSourceFunc) buffering_begin_signal_idle, mp);
+	gst_element_set_state (mp->priv->srcthread,
 			       GST_STATE_PLAYING);
 }
 


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