*** rb-player-gst.c	2007-02-09 00:00:02.000000000 +0100
--- rb-player-gst.c.old	2007-02-08 23:42:25.000000000 +0100
***************
*** 740,745 ****
--- 740,792 ----
  		g_list_free (mp->priv->waiting_filters);
  		mp->priv->waiting_filters = NULL;
  	}
+ 
+ 	{
+ 		GstPad *pad;
+ 		GList *l;
+ 		GstElement *queue;
+ 		GstElement *audioconvert;
+ 		GstPad *ghostpad;
+ 
+ 		/* setup filterbin,and insert the leading audioconvert */
+ 		mp->priv->filterbin = gst_bin_new (NULL);
+ 		audioconvert = gst_element_factory_make ("audioconvert", NULL);
+ 		gst_bin_add (GST_BIN (mp->priv->filterbin), audioconvert);
+ 	
+ 		/* ghost it to the bin */
+ 		ghostpad = gst_ghost_pad_new ("sink", gst_element_get_pad (audioconvert, "sink"));
+ 		gst_element_add_pad (mp->priv->filterbin, ghostpad);
+ 		ghostpad = gst_ghost_pad_new ("src", gst_element_get_pad (audioconvert, "src"));
+ 		gst_element_add_pad (mp->priv->filterbin, ghostpad);
+ 
+ 
+ 		/* set up the sinkbin with it's tee element */
+ 		mp->priv->sinkbin = gst_bin_new (NULL);
+ 		mp->priv->tee = gst_element_factory_make ("tee", NULL);
+ 		queue = gst_element_factory_make ("queue", NULL);
+ 
+ 		/* link it all together and insert */
+ 		gst_bin_add_many (GST_BIN (mp->priv->sinkbin), mp->priv->filterbin, mp->priv->tee, queue, sink, NULL);
+ 		gst_element_link_many (mp->priv->filterbin, mp->priv->tee, queue, sink, NULL);
+ 
+ 		pad = gst_ghost_pad_new ("sink", gst_element_get_pad (mp->priv->filterbin, "sink"));
+ 		gst_element_add_pad (mp->priv->sinkbin, pad);
+ 		g_object_set (G_OBJECT (mp->priv->playbin), "audio-sink", mp->priv->sinkbin, NULL);
+ 
+ 
+ 		/* add any tees and filters that were waiting for us */
+ 		for (l = mp->priv->waiting_tees; l != NULL; l = g_list_next (l)) {
+ 			rb_player_gst_tee_add_tee (RB_PLAYER_GST_TEE (mp), GST_ELEMENT (l->data));
+ 		}
+ 		g_list_free (mp->priv->waiting_tees);
+ 		mp->priv->waiting_tees = NULL;
+ 
+ 		for (l = mp->priv->waiting_filters; l != NULL; l = g_list_next (l)) {
+ 			rb_player_gst_filter_add_filter (RB_PLAYER_GST_FILTER(mp), GST_ELEMENT (l->data));
+ 		}
+ 		g_list_free (mp->priv->waiting_filters);
+ 		mp->priv->waiting_filters = NULL;
+ 	}
  #endif
  
  	/* Use fakesink for video if there's no video sink yet */
***************
*** 1247,1253 ****
  		if (gst_element_set_state (mp->priv->playbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_ASYNC) {
  			/* FIXME: Use a timeout on get_state. Post a GError somewhere on failed? */
  			if (gst_element_get_state (mp->priv->playbin, NULL, NULL, 3 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
! 				g_warning ("Failed to pause pipeline before tee insertion");
  				return FALSE;
  			}
  		}
--- 1294,1300 ----
  		if (gst_element_set_state (mp->priv->playbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_ASYNC) {
  			/* FIXME: Use a timeout on get_state. Post a GError somewhere on failed? */
  			if (gst_element_get_state (mp->priv->playbin, NULL, NULL, 3 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
! 				g_warning ("Failed to pause pipeline before teee insertion");
  				return FALSE;
  			}
  		}
***************
*** 1291,1297 ****
  		if (gst_element_set_state (mp->priv->playbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_ASYNC) {
  			/* FIXME: Use a timeout on get_state. Post a GError somewhere on failed? */
  			if (gst_element_get_state (mp->priv->playbin, NULL, NULL, 3 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
! 				g_warning ("Failed to pause pipeline before tee removal");
  				return FALSE;
  			}
  		}
--- 1338,1344 ----
  		if (gst_element_set_state (mp->priv->playbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_ASYNC) {
  			/* FIXME: Use a timeout on get_state. Post a GError somewhere on failed? */
  			if (gst_element_get_state (mp->priv->playbin, NULL, NULL, 3 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
! 				g_warning ("Failed to pause pipeline before teee insertion");
  				return FALSE;
  			}
  		}
***************
*** 1303,1309 ****
  	if (gst_element_set_state (bin, GST_STATE_NULL) == GST_STATE_CHANGE_ASYNC) {
  		/* FIXME: Use a timeout on get_state. Post a GError somewhere on failed? */
  		if (gst_element_get_state (bin, NULL, NULL, 3 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
! 			g_warning ("Failed to pause pipeline before tee removal");
  			return FALSE;
  		}
  	}
--- 1350,1356 ----
  	if (gst_element_set_state (bin, GST_STATE_NULL) == GST_STATE_CHANGE_ASYNC) {
  		/* FIXME: Use a timeout on get_state. Post a GError somewhere on failed? */
  		if (gst_element_get_state (bin, NULL, NULL, 3 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
! 			g_warning ("Failed to pause pipeline before teee insertion");
  			return FALSE;
  		}
  	}
***************
*** 1322,1328 ****
  {
  	RBPlayerGst *mp;
  	GstElement *audioconvert, *bin;
! 	GstPad *ghostpad, *realpad, *element_sink_pad;
  
  	mp = RB_PLAYER_GST (player);
  
--- 1369,1375 ----
  {
  	RBPlayerGst *mp;
  	GstElement *audioconvert, *bin;
! 	GstPad *ghostpad, *realpad;
  
  	mp = RB_PLAYER_GST (player);
  
***************
*** 1335,1341 ****
  		if (gst_element_set_state (mp->priv->playbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_ASYNC) {
  			/* FIXME: Use a timeout on get_state. Post a GError somewhere on failed? */
  			if (gst_element_get_state (mp->priv->playbin, NULL, NULL, 3 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
! 				g_warning ("Failed to pause pipeline before filter insertion");
  				return FALSE;
  			}
  		}
--- 1382,1388 ----
  		if (gst_element_set_state (mp->priv->playbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_ASYNC) {
  			/* FIXME: Use a timeout on get_state. Post a GError somewhere on failed? */
  			if (gst_element_get_state (mp->priv->playbin, NULL, NULL, 3 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
! 				g_warning ("Failed to pause pipeline before teee insertion");
  				return FALSE;
  			}
  		}
***************
*** 1350,1391 ****
  	gst_element_link_many (element, audioconvert, NULL);
  
  	/* ghost to the bin */
!         /* first try to retrieve a pad named "sink" */
!         element_sink_pad = gst_element_get_pad (element, "sink");
! 
!         if (element_sink_pad == NULL) { /* fallback to the first unliked source pad */
!             GstIterator *sink_pads;
!             gboolean sink_pad_found, stop_scan;
!     
!             sink_pad_found = FALSE;
!             stop_scan = FALSE;
!             sink_pads = gst_element_iterate_sink_pads (element);
!             while (!sink_pad_found && !stop_scan) {
!                 switch (gst_iterator_next (sink_pads, &element_sink_pad)) {
!                     case GST_ITERATOR_OK:
!                         sink_pad_found = ! gst_pad_is_linked (element_sink_pad);
!                     break;
!                     case GST_ITERATOR_RESYNC:
!                         gst_iterator_resync (sink_pads);
!                     break;
!                     case GST_ITERATOR_ERROR:
!                     case GST_ITERATOR_DONE:
!                         stop_scan = TRUE;
!                 }
!             }
!             gst_iterator_free (sink_pads);
! 
!             if (!sink_pad_found) {
!                 g_warning ("Could not find a free sink pad on filter");
!                 return FALSE;
!             }
!         }
! 
! 	ghostpad = gst_ghost_pad_new ("sink", element_sink_pad);
  	gst_element_add_pad (bin, ghostpad);
  	ghostpad = gst_ghost_pad_new ("src", gst_element_get_pad (audioconvert, "src"));
  	gst_element_add_pad (bin, ghostpad);
!     
  	/* replace the filter chain ghost with the new bin */
  	gst_bin_add (GST_BIN (mp->priv->filterbin), bin);
  
--- 1397,1407 ----
  	gst_element_link_many (element, audioconvert, NULL);
  
  	/* ghost to the bin */
! 	ghostpad = gst_ghost_pad_new ("sink", gst_element_get_pad (element, "sink"));
  	gst_element_add_pad (bin, ghostpad);
  	ghostpad = gst_ghost_pad_new ("src", gst_element_get_pad (audioconvert, "src"));
  	gst_element_add_pad (bin, ghostpad);
! 
  	/* replace the filter chain ghost with the new bin */
  	gst_bin_add (GST_BIN (mp->priv->filterbin), bin);
  
***************
*** 1427,1433 ****
  		if (gst_element_set_state (mp->priv->playbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_ASYNC) {
  			/* FIXME: Use a timeout on get_state. Post a GError somewhere on failed? */
  			if (gst_element_get_state (mp->priv->playbin, NULL, NULL, 3 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
! 				g_warning ("Failed to pause pipeline before filter removal");
  				return FALSE;
  			}
  		}
--- 1443,1449 ----
  		if (gst_element_set_state (mp->priv->playbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_ASYNC) {
  			/* FIXME: Use a timeout on get_state. Post a GError somewhere on failed? */
  			if (gst_element_get_state (mp->priv->playbin, NULL, NULL, 3 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
! 				g_warning ("Failed to pause pipeline before teee insertion");
  				return FALSE;
  			}
  		}
***************
*** 1439,1445 ****
  	if (gst_element_set_state (bin, GST_STATE_NULL) == GST_STATE_CHANGE_ASYNC) {
  		/* FIXME: Use a timeout on get_state. Post a GError somewhere on failed? */
  		if (gst_element_get_state (bin, NULL, NULL, 3 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
! 			g_warning ("Failed to pause pipeline before filter removal");
  			return FALSE;
  		}
  	}
--- 1455,1461 ----
  	if (gst_element_set_state (bin, GST_STATE_NULL) == GST_STATE_CHANGE_ASYNC) {
  		/* FIXME: Use a timeout on get_state. Post a GError somewhere on failed? */
  		if (gst_element_get_state (bin, NULL, NULL, 3 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
! 			g_warning ("Failed to pause pipeline before teee insertion");
  			return FALSE;
  		}
  	}
