Index: metadata/rb-metadata-gst.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/metadata/rb-metadata-gst.c,v
retrieving revision 1.58
diff -u -u -r1.58 rb-metadata-gst.c
--- metadata/rb-metadata-gst.c	17 Jan 2006 07:54:11 -0000	1.58
+++ metadata/rb-metadata-gst.c	22 Jan 2006 04:19:41 -0000
@@ -112,66 +112,46 @@
 	return tagger;
 }
 
+
+static void
+id3_pad_added_cb (GstElement *demux, GstPad *pad, GstElement *mux)
+{
+	GstPad *mux_pad;
+
+	mux_pad = gst_element_get_compatible_pad (mux, pad, NULL);
+	if (gst_pad_link (pad, mux_pad) != GST_PAD_LINK_OK)
+		rb_debug ("unable to link pad");
+}
+
 static GstElement *
 rb_add_id3_tagger (GstBin *pipeline, GstElement *element)
 {
-        GstElement *tagger = NULL;
-	GstElement *spider = NULL;
-	GstElement *identity = NULL;
-#ifdef HAVE_GSTREAMER_0_10
-	GstElement *filter = NULL;
-#endif
-	GstCaps *filtercaps = NULL;
+	GstElement *demux = NULL;
+	GstElement *mux = NULL;
 
-        if (!(tagger = gst_element_factory_make("id3tag", "tagger"))) 
-                return NULL;
+	demux = gst_element_factory_make ("id3demux", NULL);
+	mux =  gst_element_factory_make ("id3mux", NULL);
 
-        if (!(identity = gst_element_factory_make("identity", "identity"))) {
-                gst_object_unref( GST_OBJECT(tagger) );
-                return NULL;
-        }
-	if (!(spider = gst_element_factory_make ("spider", "spider")) ||
-	    !(tagger = gst_element_factory_make ("id3mux", "id3mux")) ||
-	    !(filtercaps = gst_caps_new_simple ("application/x-id3", NULL))) {
-		gst_object_unref (GST_OBJECT (spider));
-		gst_object_unref (GST_OBJECT (tagger));
-		gst_caps_unref (filtercaps);
-		return NULL;
-	}
+	if (demux == NULL || mux == NULL)
+		goto error;
 
-#ifdef HAVE_GSTREAMER_0_10
-	if (! (filter = gst_element_factory_make ("capsfilter", NULL))) {
-		gst_object_unref (GST_OBJECT (spider));
-		gst_object_unref (GST_OBJECT (tagger));
-		gst_caps_unref (filtercaps);
-		return NULL;
-	}
-	g_object_set (GST_OBJECT (tagger), "v1-tag", TRUE, NULL);
-#else
-	gst_element_set (tagger, "v1-tag", TRUE, NULL);
-#endif
-        
-        gst_bin_add_many (GST_BIN (pipeline), tagger, identity, NULL);
+	gst_bin_add_many (pipeline, demux, mux, NULL);
+	if (!gst_element_link (element, demux))
+		goto error;
 
 #ifdef HAVE_GSTREAMER_0_8
-	if (!gst_element_link_filtered (tagger, identity, filtercaps)) {
+	g_signal_connect (demux, "new-pad", (GCallback)id3_pad_added_cb, mux);
 #endif
 #ifdef HAVE_GSTREAMER_0_10
-	g_object_set (G_OBJECT (filter), "filter-caps", filtercaps, NULL);
-	if (!gst_element_link_many (tagger, filter, identity, NULL)) {
+	g_signal_connect (demux, "pad-added", (GCallback)id3_pad_added_cb, mux);
 #endif
 
-		g_warning("Linking id3tag and identity failed");
-                gst_caps_unref(filtercaps);
-                gst_object_unref(GST_OBJECT(tagger));
-                gst_object_unref(GST_OBJECT(identity));
-                return NULL;
-        }
-	gst_caps_unref (filtercaps);
+	return mux;
 
-        gst_element_link_many (element, tagger, NULL);
-        
-	return identity;
+error:
+	g_object_unref (demux);
+	g_object_unref (mux);
+	return NULL;
 }
 
 static void
@@ -192,6 +172,7 @@
 {
 	RBAddTaggerElem tagger;
 	gboolean has_gnomevfssink;
+	gboolean has_id3;
         
 	md->priv = RB_METADATA_GET_PRIVATE (md);
 
@@ -206,9 +187,10 @@
  	 * only registering types we have plugins for defeats the second 
 	 * purpose.
  	 */
-	has_gnomevfssink = (gst_element_factory_find ("gnomevfssink") != NULL);
+	has_gnomevfssink = gst_element_factory_find ("gnomevfssrc") && gst_element_factory_find ("gnomevfssink");
+	has_id3 = gst_element_factory_find ("id3mux") && gst_element_factory_find ("id3demux");
 
-	tagger = (has_gnomevfssink && gst_element_factory_find ("id3tag")) ?  rb_add_id3_tagger : NULL;
+	tagger = (has_gnomevfssink && has_id3) ?  rb_add_id3_tagger : NULL;
 	add_supported_type (md, "application/x-id3", tagger, "MP3");
 	add_supported_type (md, "audio/mpeg", tagger, "MP3");
 
@@ -1038,12 +1020,6 @@
 	g_signal_connect_object (md->priv->sink, "eos", G_CALLBACK (rb_metadata_gst_eos_cb), md, 0);
 #endif
 
-	/* FIXME: gst_bin_add (GST_BIN (pipeline, md->priv->sink)) really
-	 * should be called here, but weird crashes happen when unreffing the
-	 * pipeline if it's not moved after the creation of the tagging
-	 * elements 
-	 */
-
 	/* Tagger element(s) */
 	add_tagger_func = rb_metadata_gst_type_to_tag_function (md, md->priv->type);
 	
@@ -1088,11 +1064,21 @@
 	       && md->priv->error == NULL
 	       && !md->priv->eos)
 		;
+	gst_element_set_state (pipeline, GST_STATE_NULL);
 #endif
 #ifdef HAVE_GSTREAMER_0_10
 	rb_metadata_event_loop (md, GST_ELEMENT (pipeline));
+	if (gst_element_set_state (pipeline, GST_STATE_NULL) == GST_STATE_CHANGE_ASYNC) {
+		if (gst_element_get_state (pipeline, NULL, NULL, 3 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
+			g_set_error (error,
+				     RB_METADATA_ERROR,
+				     RB_METADATA_ERROR_INTERNAL,
+				     "Timeout while setting pipeline to NULL");
+			goto out_error;
+		}
+	}
 #endif
-	gst_element_set_state (pipeline, GST_STATE_NULL);
+
 	if (md->priv->error) {
 		g_propagate_error (error, md->priv->error);
 		goto out_error;
@@ -1100,6 +1086,8 @@
 	if (handle != NULL) {
 		if ((result = gnome_vfs_close (handle)) != GNOME_VFS_OK)
 			goto vfs_error;
+		handle = NULL;
+
 		/* check to ensure the file isn't corrupt */
 		if (!rb_metadata_file_valid (md->priv->uri, tmpname)) {
 			g_set_error (error,
