[gst-devel] queue full patch in 0.6.1?

Benjamin Otte in7y118 at public.uni-hamburg.de
Thu Apr 17 07:38:16 CEST 2003


On 17 Apr 2003, Colin Walters wrote:

Hi Colin,

> BTW if anyone can try the netRhythmbox CVS and figure out why it just
> locks up for me after the queue's full I'd very much appreciate it :)
>
It locks up because the GstThread implementation is beyond broken if you
try anything unusual. I'm actually surprised that it works that well.

I hacked around it as good as I could and actually got net-rb working with
buffering, the patch (which does a lot more than just fix this) is
attached.
The brokenness of GstThread is described in #111025. I hate to connect the
EOS signal to the sink instead of the pipeline because of this mess.
(I'm slightly annoyed after trying to dodge bugs for like 6 hours here,
you might hear that in my tone ;)

Ok, the attached patch does:
- Improve debugging output. "** DEBUG **" looks nice for a while but is
absolutely useless. (This includes copying of a GStreamer m4 into
configure.in)
- Patches to the files you forgot to submit. (net-rb CVS doesn't compile
atm)
- Make buffering work. And yes, it's hacky. The currently used pipeline is
{ src ! queue } ! { decoder ! sink }
because changing states with threads inside threads is close to
impossible.
- Detecting of musicbrainz via pkg-config. If you don't have a .pc file
for it, you might still run version 2.0.0. It's only included in
musicbrainz >= 2.0.1

I have since played around with this patch applied. It works fine here so
far. And I'm having it run for > 10 minutes now.

Benjamin
-------------- next part --------------
? diff
? hack-macros/Makefile
? hack-macros/Makefile.in
? help/C/omf_timestamp
? iradio/Makefile
? iradio/Makefile.in
? shell/net-rhythmbox
? shell/netRhythmboxShell-common.c
? shell/netRhythmboxShell-skels.c
? shell/netRhythmboxShell-stubs.c
? shell/netRhythmboxShell.h
Index: configure.in
===================================================================
RCS file: /cvs/gnome/net-rhythmbox/configure.in,v
retrieving revision 1.6
diff -u -r1.6 configure.in
--- configure.in	15 Apr 2003 05:42:58 -0000	1.6
+++ configure.in	17 Apr 2003 14:17:15 -0000
@@ -55,6 +55,70 @@
 RHYTHMBOX_CFLAGS="$RHYTHMBOX_CFLAGS $SOUNDSYSTEM_CFLAGS -DHAVE_GSTREAMER"
 RHYTHMBOX_LIBS="$RHYTHMBOX_LIBS $SOUNDSYSTEM_LIBS"
 
+dnl coppy of gst-function.m4 of GStreamer source.
+dnl
+dnl Check for compiler mechanism to show functions in debugging
+dnl copied from an Ali patch floating on the internet
+dnl
+  dnl #1: __PRETTY_FUNCTION__
+  AC_MSG_CHECKING(whether $CC implements __PRETTY_FUNCTION__)
+  AC_CACHE_VAL(have_pretty_function,[
+    AC_TRY_LINK([#include <stdio.h>],
+                [printf("%s", __PRETTY_FUNCTION__);],
+                have_pretty_function=yes,
+                have_pretty_function=no)
+  ])
+  AC_MSG_RESULT($have_pretty_function)
+  if test "$have_pretty_function" = yes; then
+    AC_DEFINE(HAVE_PRETTY_FUNCTION, 1,
+              [defined if the compiler implements __PRETTY_FUNCTION__])
+  fi
+
+dnl #2: __FUNCTION__
+  AC_MSG_CHECKING(whether $CC implements __FUNCTION__)
+  AC_CACHE_VAL(have_function,[
+    AC_TRY_LINK([#include <stdio.h>],
+                [printf("%s", __FUNCTION__);],
+                have_function=yes,
+                have_function=no)
+  ])
+  AC_MSG_RESULT($have_function)
+  if test "$have_function" = yes; then
+    AC_DEFINE(HAVE_FUNCTION, 1,
+              [defined if the compiler implements __FUNCTION__])
+  fi
+
+dnl #3: __func__
+  AC_MSG_CHECKING(whether $CC implements __func__)
+  AC_CACHE_VAL(have_func,[
+    AC_TRY_LINK([#include <stdio.h>],
+                [printf("%s", __func__);],
+                have_func=yes,
+                have_func=no)
+  ])
+  AC_MSG_RESULT($have_func)
+  if test "$have_func" = yes; then
+    AC_DEFINE(HAVE_FUNC, 1,
+              [defined if the compiler implements __func__])
+  fi
+
+dnl now define FUNCTION to whatever works, and fallback to ""
+  if test "$have_pretty_function" = yes; then
+    function=__PRETTY_FUNCTION__
+  else
+    if test "$have_function" = yes; then
+      function=__FUNCTION__
+    else
+      if test "$have_func" = yes; then
+        function=__func__
+      else
+        function=\"\"
+      fi
+    fi
+  fi
+  AC_DEFINE_UNQUOTED(FUNCTION, $function, [macro to use to show function name])
+
+
 AC_ARG_ENABLE(lirc, AC_HELP_STRING([--disable-lirc],
 				[don't build with lirc support]))
 if test "x$enable_lirc" != "xno"; then
@@ -105,17 +169,11 @@
 
 dnl Check for Musicbrainz
 
-AC_CHECK_HEADER(musicbrainz/mb_c.h,,
-	AC_MSG_ERROR(musicbrainz needed!))
-
-AC_MSG_CHECKING([for musicbrainz version 2])
-AC_COMPILE_IFELSE([
-	#include <musicbrainz/mb_c.h>
-	char *query = MBI_VARIOUS_ARTIST_ID;
-	],,AC_MSG_ERROR([musicbrainz version 2 required]))
-AC_MSG_RESULT([found])
+PKG_CHECK_MODULES(MUSICBRAINZ,
+		  libmusicbrainz >= 2.0.0)
 
-RHYTHMBOX_LIBS="$RHYTHMBOX_LIBS -lmusicbrainz -lstdc++"
+RHYTHMBOX_CFLAGS="$RHYTHMBOX_CFLAGS $MUSICBRAINZ_CFLAGS"
+RHYTHMBOX_LIBS="$RHYTHMBOX_LIBS $MUSICBRAINZ_LIBS"
 
 AC_SUBST(RHYTHMBOX_CFLAGS)
 AC_SUBST(RHYTHMBOX_LIBS)
Index: lib/rb-debug.c
===================================================================
RCS file: /cvs/gnome/net-rhythmbox/lib/rb-debug.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 rb-debug.c
--- lib/rb-debug.c	9 Feb 2003 08:11:26 -0000	1.1.1.1
+++ lib/rb-debug.c	17 Apr 2003 14:17:15 -0000
@@ -41,6 +41,8 @@
  */
 void
 rb_debug_real (const char *func,
+	       const char *file,
+	       const int line,
 	       const char *format, ...)
 {
 	va_list args;
@@ -60,7 +62,7 @@
 	str_time = g_new0 (char, 255);
 	strftime (str_time, 254, "%H:%M:%S", localtime (&the_time));
 
-	fprintf (stderr, "** DEBUG ** [%s] (%s): %s\n", func, str_time, buffer);
+	g_printerr ("[%s] %s:%d (%s): %s\n", func, file, line, str_time, buffer);
 	
 	g_free (str_time);
 }
@@ -183,7 +185,6 @@
 {
 	long elapsed;
 	double seconds;
-	char *tmp;
 
 	if (debugging == FALSE)
 		return;
@@ -192,10 +193,8 @@
 
 	seconds = g_timer_elapsed (profiler->timer, &elapsed);
 	
-	tmp = g_strdup_printf ("Profiler %s", profiler->name);
-	rb_debug_real (tmp, "%ld ms (%f s) elapsed",
-		       elapsed / (G_USEC_PER_SEC / 1000), seconds);
-	g_free (tmp);
+	rb_debug ("PROFILER %s %ld ms (%f s) elapsed", profiler->name, 
+		  elapsed / (G_USEC_PER_SEC / 1000), seconds);
 }
 
 void
Index: lib/rb-debug.h
===================================================================
RCS file: /cvs/gnome/net-rhythmbox/lib/rb-debug.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 rb-debug.h
--- lib/rb-debug.h	9 Feb 2003 08:11:26 -0000	1.1.1.1
+++ lib/rb-debug.h	17 Apr 2003 14:17:16 -0000
@@ -24,13 +24,37 @@
 #include <stdarg.h>
 #include <glib.h>
 
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+/* FIXME: make it possible to use monkey-media-debug.h here, duplicating work sucks. */
+
 G_BEGIN_DECLS
 
-#define rb_debug(...) rb_debug_real (G_GNUC_PRETTY_FUNCTION, __VA_ARGS__)
+/* copied from gstreamer/gst/gstinfo.h */
+
+#ifndef FUNCTION
+#ifdef G_GNUC_PRETTY_FUNCTION
+#define FUNCTION G_GNUC_PRETTY_FUNCTION
+#elif HAVE_FUNC
+#define FUNCTION __func__
+#elif HAVE_PRETTY_FUNCTION
+#define FUNCTION __PRETTY_FUNCTION__
+#elif HAVE_FUNCTION
+#define FUNCTION __FUNCTION__
+#else
+#define FUNCTION ""
+#endif
+#endif /* ifndef FUNCTION */
+
+#define rb_debug(...) rb_debug_real (FUNCTION, __FILE__, __LINE__, __VA_ARGS__)
 
 void rb_debug_init             (gboolean debug);
 
 void rb_debug_real             (const char *func,
+				const char *file,
+				const int line,
 				const char *format, ...);
 
 void rb_debug_stop_in_debugger (void);
Index: monkey-media/monkey-media-debug.c
===================================================================
RCS file: /cvs/gnome/net-rhythmbox/monkey-media/monkey-media-debug.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 monkey-media-debug.c
--- monkey-media/monkey-media-debug.c	9 Feb 2003 08:10:19 -0000	1.1.1.1
+++ monkey-media/monkey-media-debug.c	17 Apr 2003 14:17:16 -0000
@@ -37,6 +37,8 @@
  */
 void
 monkey_media_debug_real (const char *func,
+		  	 const char *file,
+			 const int line,
 			 const char *format, ...)
 {
 	va_list args;
@@ -56,7 +58,7 @@
 	str_time = g_new0 (char, 255);
 	strftime (str_time, 254, "%H:%M:%S", localtime (&the_time));
 
-	fprintf (stderr, "** DEBUG ** [%s] (%s): %s\n", func, str_time, buffer);
+	g_printerr ("[%s] %s:%d (%s): %s\n", func, file, line, str_time, buffer);
 	
 	g_free (str_time);
 }
Index: monkey-media/monkey-media-debug.h
===================================================================
RCS file: /cvs/gnome/net-rhythmbox/monkey-media/monkey-media-debug.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 monkey-media-debug.h
--- monkey-media/monkey-media-debug.h	9 Feb 2003 08:10:18 -0000	1.1.1.1
+++ monkey-media/monkey-media-debug.h	17 Apr 2003 14:17:16 -0000
@@ -25,13 +25,36 @@
 #include <stdarg.h>
 #include <glib.h>
 
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 G_BEGIN_DECLS
 
-#define monkey_media_debug(...)		 monkey_media_debug_real (G_GNUC_PRETTY_FUNCTION, __VA_ARGS__)
+/* copied from gstreamer/gst/gstinfo.h */
+
+#ifndef FUNCTION
+#ifdef G_GNUC_PRETTY_FUNCTION
+#define FUNCTION G_GNUC_PRETTY_FUNCTION
+#elif HAVE_FUNC
+#define FUNCTION __func__
+#elif HAVE_PRETTY_FUNCTION
+#define FUNCTION __PRETTY_FUNCTION__
+#elif HAVE_FUNCTION
+#define FUNCTION __FUNCTION__
+#else
+#define FUNCTION ""
+#endif
+#endif /* ifndef FUNCTION */
+
+/* FIXME: This needs #ifdef G_HAVE_ISO_VARARGS wrappers */
+#define monkey_media_debug(...)		 monkey_media_debug_real (FUNCTION, __FILE__, __LINE__, __VA_ARGS__)
 
 void monkey_media_debug_init             (gboolean debug);
 
 void monkey_media_debug_real             (const char *func,
+					  const char *file,
+					  const int line,
 					  const char *format, ...);
 
 G_END_DECLS
Index: monkey-media/monkey-media-player-gst.c
===================================================================
RCS file: /cvs/gnome/net-rhythmbox/monkey-media/monkey-media-player-gst.c,v
retrieving revision 1.10
diff -u -r1.10 monkey-media-player-gst.c
--- monkey-media/monkey-media-player-gst.c	17 Apr 2003 08:54:54 -0000	1.10
+++ monkey-media/monkey-media-player-gst.c	17 Apr 2003 14:17:18 -0000
@@ -36,7 +36,7 @@
 #include "monkey-media-marshal.h"
 #include "monkey-media-private.h"
 
-#define USE_BROKEN_QUEUE 0
+#define USE_BROKEN_QUEUE 1
 
 static void monkey_media_player_class_init (MonkeyMediaPlayerClass *klass);
 static void monkey_media_player_init (MonkeyMediaPlayer *mp);
@@ -51,6 +51,7 @@
 #if USE_BROKEN_QUEUE
 	GstElement *srcthread;
 	GstElement *queue;
+	GstElement *waiting_bin;
 	gboolean use_buffer;
 #endif
 	GstElement *src;
@@ -389,15 +390,14 @@
 {
 	MonkeyMediaPlayer *mp = MONKEY_MEDIA_PLAYER (data);
 
-	monkey_media_debug ("got queue full signal, buffering: %s pipeline state: %d",
+	monkey_media_debug ("got queue full signal, buffering: %s pipeline state: %s, waiting bin state: %s",
 			    mp->priv->use_buffer ? "TRUE" : "FALSE",
-			    gst_element_get_state (mp->priv->pipeline));
+			    gst_element_state_get_name (gst_element_get_state (mp->priv->pipeline)),
+			    gst_element_state_get_name (gst_element_get_state (mp->priv->waiting_bin)));
 	if (mp->priv->use_buffer
-	    && gst_element_get_state (mp->priv->pipeline) != GST_STATE_PLAYING)
+	    && gst_element_get_state (mp->priv->waiting_bin) != GST_STATE_PLAYING)
 	{
-		monkey_media_debug ("queue full; playing pipeline (signalling buffering end)");
-		g_signal_emit (G_OBJECT (mp), monkey_media_player_signals[BUFFERING_END], 0);
-		gst_element_set_state (mp->priv->pipeline, GST_STATE_PLAYING);
+		gst_element_set_state (mp->priv->waiting_bin, GST_STATE_PLAYING);
 	}
 }
 #endif
@@ -440,8 +440,11 @@
 	gst_element_link (mp->priv->typefind_src, mp->priv->typefind);
 
 	/* playback pipeline */
-	mp->priv->pipeline = gst_thread_new ("pipeline");
-
+#if USE_BROKEN_QUEUE
+	mp->priv->pipeline = gst_element_factory_make ("pipeline", "pipeline");
+#else
+	mp->priv->pipeline = gst_element_factory_make ("thread", "pipeline");
+#endif
 	g_signal_connect (G_OBJECT (mp->priv->pipeline),
 			  "deep_notify",
 			  G_CALLBACK (deep_notify_cb),
@@ -510,17 +513,20 @@
 	}
 
 #if USE_BROKEN_QUEUE
+        mp->priv->waiting_bin = gst_element_factory_make ("thread", "waiting_bin");
 	gst_bin_add_many (GST_BIN (mp->priv->srcthread),
 			  mp->priv->src, mp->priv->queue, NULL);
+	gst_bin_add_many (GST_BIN (mp->priv->waiting_bin),
+			  mp->priv->volume, mp->priv->sink, NULL);
 	gst_bin_add_many (GST_BIN (mp->priv->pipeline),
-			  mp->priv->srcthread, mp->priv->volume, mp->priv->sink, NULL);
+			  mp->priv->srcthread, mp->priv->waiting_bin, NULL);
 #else
 	gst_bin_add_many (GST_BIN (mp->priv->pipeline),
 			  mp->priv->src, mp->priv->volume, mp->priv->sink, NULL);
 #endif	
 	gst_element_connect (mp->priv->volume, mp->priv->sink);
 
-	g_signal_connect (G_OBJECT (mp->priv->pipeline), "eos",
+	g_signal_connect (G_OBJECT (mp->priv->sink), "eos",
 			  G_CALLBACK (eos_cb), mp);
 
 	g_object_set (G_OBJECT (mp->priv->volume_dparam),
@@ -719,7 +725,11 @@
 					 mp->priv->volume,
 					 NULL);
 
+#if USE_BROKEN_QUEUE					 
+		gst_bin_remove (GST_BIN (mp->priv->waiting_bin), mp->priv->decoder);
+#else
 		gst_bin_remove (GST_BIN (mp->priv->pipeline), mp->priv->decoder);
+#endif					 
 	}
 
 	/* Internet radio support */
@@ -740,13 +750,14 @@
 	
 	mp->priv->uri = g_strdup (uri);
 
-	gst_bin_add (GST_BIN (mp->priv->pipeline), mp->priv->decoder);
 #if USE_BROKEN_QUEUE
+	gst_bin_add (GST_BIN (mp->priv->waiting_bin), mp->priv->decoder);
 	mp->priv->use_buffer = use_buffer;
 	gst_element_link_many (mp->priv->src, mp->priv->queue, mp->priv->decoder,
-			       mp->priv->volume);
+			       mp->priv->volume, NULL);
 #else
-	gst_element_link_many (mp->priv->src, mp->priv->decoder, mp->priv->volume);
+	gst_bin_add (GST_BIN (mp->priv->pipeline), mp->priv->decoder);
+	gst_element_link_many (mp->priv->src, mp->priv->decoder, mp->priv->volume, NULL);
 #endif
 
 	monkey_media_player_sync_pipeline (mp);
Index: monkey-media/monkey-media-player.h
===================================================================
RCS file: /cvs/gnome/net-rhythmbox/monkey-media/monkey-media-player.h,v
retrieving revision 1.3
diff -u -r1.3 monkey-media-player.h
--- monkey-media/monkey-media-player.h	11 Apr 2003 20:00:33 -0000	1.3
+++ monkey-media/monkey-media-player.h	17 Apr 2003 14:17:18 -0000
@@ -68,6 +68,8 @@
 		       GValue *value);
 	void (*error) (MonkeyMediaPlayer *mp, GError *error);
 	void (*tick)  (MonkeyMediaPlayer *mp, long elapsed);
+	void (*buffering_begin)  (MonkeyMediaPlayer *mp);
+	void (*buffering_end)  (MonkeyMediaPlayer *mp);
 } MonkeyMediaPlayerClass;
 
 GType              monkey_media_player_get_type   (void);
@@ -76,6 +78,7 @@
 
 void               monkey_media_player_open       (MonkeyMediaPlayer *mp,
 						   const char *uri,
+                        			   gboolean use_buffer,
 		                                   GError **error);
 
 const char	  *monkey_media_player_get_uri    (MonkeyMediaPlayer *mp);
Index: shell/rb-shell-player.c
===================================================================
RCS file: /cvs/gnome/net-rhythmbox/shell/rb-shell-player.c,v
retrieving revision 1.6
diff -u -r1.6 rb-shell-player.c
--- shell/rb-shell-player.c	12 Apr 2003 03:37:26 -0000	1.6
+++ shell/rb-shell-player.c	17 Apr 2003 14:17:20 -0000
@@ -683,7 +683,7 @@
 		g_free (unescaped);
 		g_free (msg);
 		monkey_media_player_close (player->priv->mmplayer);
-		monkey_media_player_open (player->priv->mmplayer, uri, &error);
+		monkey_media_player_open (player->priv->mmplayer, uri, TRUE, &error);
 		if (error != NULL)
 		{
 			fprintf(stderr, "Got error opening \"%s\": %s", uri, error->message);


More information about the gstreamer-devel mailing list