Index: ext/gnomevfs/gstgnomevfssrc.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/ext/gnomevfs/gstgnomevfssrc.c,v
retrieving revision 1.77
diff -u -p -u -p -r1.77 gstgnomevfssrc.c
--- ext/gnomevfs/gstgnomevfssrc.c	27 Dec 2005 21:58:28 -0000	1.77
+++ ext/gnomevfs/gstgnomevfssrc.c	5 Jan 2006 10:57:40 -0000
@@ -131,6 +131,8 @@ static void gst_gnome_vfs_src_set_proper
 static void gst_gnome_vfs_src_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
+static gboolean gst_gnome_vfs_src_fake_activate_pull (GstPad *pad, gboolean active);
+
 static gboolean gst_gnome_vfs_src_stop (GstBaseSrc * src);
 static gboolean gst_gnome_vfs_src_start (GstBaseSrc * src);
 static gboolean gst_gnome_vfs_src_is_seekable (GstBaseSrc * src);
@@ -376,6 +378,12 @@ gst_gnome_vfs_src_uri_handler_init (gpoi
   iface->set_uri = gst_gnome_vfs_src_uri_set_uri;
 }
 
+static gboolean
+gst_gnome_vfs_src_fake_activate_pull (GstPad *pad, gboolean active)
+{
+  return FALSE;
+}
+
 static void
 gst_gnome_vfs_src_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
@@ -436,6 +444,15 @@ gst_gnome_vfs_src_set_property (GObject 
       break;
     case ARG_IRADIO_MODE:
       src->iradio_mode = g_value_get_boolean (value);
+      if (src->iradio_mode) {
+	/* if we allow basesrc to attempt pull mode activation (which fails),
+	 * we'll end up connecting to the streaming server twice fairly quickly.
+	 * this seems to annoy shoutcast servers into not sending us metadata.
+	 * so instead, we don't even try pull mode activation.
+	 */
+	gst_pad_set_activatepull_function (GST_BASE_SRC (src)->srcpad,
+	    GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_fake_activate_pull));
+      }
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -595,13 +612,31 @@ audiocast_do_notifications (GstGnomeVFSS
   /* Send any pending notifications we got from the UDP thread. */
   if (src->iradio_mode) {
     GList *entry;
+    GstTagList *taglist = NULL;
 
     g_mutex_lock (src->audiocast_queue_mutex);
-    for (entry = src->audiocast_notify_queue; entry; entry = entry->next)
+    for (entry = src->audiocast_notify_queue; entry; entry = entry->next) {
+      if (!taglist)
+	taglist = gst_tag_list_new ();
+
       g_object_notify (G_OBJECT (src), (const gchar *) entry->data);
+
+      if (strcmp (entry->data, "iradio-url") == 0) {
+	gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_LOCATION,
+	    src->iradio_url, NULL);
+      } else if (strcmp (entry->data, "iradio-title") == 0) {
+	gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_TITLE,
+	    src->iradio_title, NULL);
+      }
+    }
     g_list_free (src->audiocast_notify_queue);
     src->audiocast_notify_queue = NULL;
     g_mutex_unlock (src->audiocast_queue_mutex);
+
+    if (taglist) {
+      GstMessage *message = gst_message_new_tag ((GstObject *) src, taglist);
+      gst_element_post_message (GST_ELEMENT (src), message);
+    }
   }
 }
 
@@ -764,11 +799,15 @@ gst_gnome_vfs_src_received_headers_callb
   GstGnomeVFSSrc *src = GST_GNOME_VFS_SRC (callback_data);
   GnomeVFSModuleCallbackReceivedHeadersIn *in_args =
       (GnomeVFSModuleCallbackReceivedHeadersIn *) in;
+  GstTagList *taglist;
+  gboolean send_tag_list = FALSE;
 
   /* This is only used for internet radio stuff right now */
   if (!src->iradio_mode)
     return;
 
+  taglist = gst_tag_list_new ();
+
   for (i = in_args->headers; i; i = i->next) {
     char *data = (char *) i->data;
     char *key = data;
@@ -804,20 +843,37 @@ gst_gnome_vfs_src_received_headers_callb
     if (!strncmp (key, "name", 4)) {
       g_free (src->iradio_name);
       src->iradio_name = gst_gnome_vfs_src_unicodify (value);
-      if (src->iradio_name)
+      if (src->iradio_name) {
         g_object_notify (G_OBJECT (src), "iradio-name");
+	gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_COMMENT,
+	    src->iradio_name, NULL);
+	send_tag_list = TRUE;
+      }
     } else if (!strncmp (key, "genre", 5)) {
       g_free (src->iradio_genre);
       src->iradio_genre = gst_gnome_vfs_src_unicodify (value);
-      if (src->iradio_genre)
+      if (src->iradio_genre) {
         g_object_notify (G_OBJECT (src), "iradio-genre");
+	gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_GENRE,
+	    src->iradio_genre, NULL);
+	send_tag_list = TRUE;
+      }
     } else if (!strncmp (key, "url", 3)) {
       g_free (src->iradio_url);
       src->iradio_url = gst_gnome_vfs_src_unicodify (value);
-      if (src->iradio_url)
+      if (src->iradio_url) {
         g_object_notify (G_OBJECT (src), "iradio-url");
+	gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_LOCATION,
+	    src->iradio_url, NULL);
+	send_tag_list = TRUE;
+      }
     }
   }
+
+  if (send_tag_list) {
+    GstMessage *message = gst_message_new_tag ((GstObject *) src, taglist);
+    gst_element_post_message (GST_ELEMENT (src), message);
+  }
 }
 
 static void
@@ -860,6 +916,8 @@ gst_gnome_vfs_src_get_icy_metadata (GstG
   guchar *data;
   guchar *pos;
   gchar **tags;
+  GstTagList *taglist;
+  gboolean send_tag_list = FALSE;
   int i;
 
   GST_DEBUG_OBJECT (src, "reading icecast metadata");
@@ -892,6 +950,7 @@ gst_gnome_vfs_src_get_icy_metadata (GstG
 
   data[metadata_length] = 0;
   tags = g_strsplit ((gchar *) data, "';", 0);
+  taglist = gst_tag_list_new ();
 
   for (i = 0; tags[i]; i++) {
     if (!g_ascii_strncasecmp (tags[i], "StreamTitle=", 12)) {
@@ -900,6 +959,9 @@ gst_gnome_vfs_src_get_icy_metadata (GstG
       if (src->iradio_title) {
         GST_DEBUG_OBJECT (src, "sending notification on icecast title");
         g_object_notify (G_OBJECT (src), "iradio-title");
+	gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_TITLE,
+	    src->iradio_title, NULL);
+	send_tag_list = TRUE;
       } else
         g_print ("Unable to convert icecast title \"%s\" to UTF-8!\n",
             tags[i] + 13);
@@ -911,12 +973,20 @@ gst_gnome_vfs_src_get_icy_metadata (GstG
       if (src->iradio_url) {
         GST_DEBUG_OBJECT (src, "sending notification on icecast url");
         g_object_notify (G_OBJECT (src), "iradio-url");
+	gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_LOCATION,
+	    src->iradio_url, NULL);
+	send_tag_list = TRUE;
       } else
         g_print ("Unable to convert icecast url \"%s\" to UTF-8!\n",
             tags[i] + 11);
     }
   }
 
+  if (send_tag_list) {
+    GstMessage *message = gst_message_new_tag ((GstObject *) src, taglist);
+    gst_element_post_message (GST_ELEMENT (src), message);
+  }
+
   g_strfreev (tags);
 }
 
@@ -958,6 +1028,7 @@ gst_gnome_vfs_src_create (GstBaseSrc * b
   audiocast_do_notifications (src);
 
   if (src->iradio_mode && src->icy_metaint > 0) {
+    GnomeVFSFileSize readsize;
     buf = gst_buffer_new_and_alloc (src->icy_metaint);
 
     data = GST_BUFFER_DATA (buf);
@@ -966,8 +1037,11 @@ gst_gnome_vfs_src_create (GstBaseSrc * b
     GST_DEBUG_OBJECT (src, "doing read: icy_count: %" G_GINT64_FORMAT,
         src->icy_count);
 
-    res = gnome_vfs_read (src->handle, data,
-        src->icy_metaint - src->icy_count, &readbytes);
+    readsize = src->icy_metaint - src->icy_count;
+    if (readsize > size)
+	    readsize = size;
+    res = gnome_vfs_read (src->handle, data, readsize,
+        &readbytes);
 
     if (res != GNOME_VFS_OK)
       goto read_failed;
@@ -1151,6 +1225,7 @@ gst_gnome_vfs_src_stop (GstBaseSrc * bas
   }
   src->size = (GnomeVFSFileSize) - 1;
   src->curoffset = 0;
+  src->icy_metaint = 0;
 
   return TRUE;
 }
Index: gst/playback/gstplaybasebin.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/gst/playback/gstplaybasebin.c,v
retrieving revision 1.94
diff -u -p -u -p -r1.94 gstplaybasebin.c
--- gst/playback/gstplaybasebin.c	15 Dec 2005 09:48:19 -0000	1.94
+++ gst/playback/gstplaybasebin.c	5 Jan 2006 10:57:42 -0000
@@ -1091,6 +1091,11 @@ gen_source_element (GstPlayBaseBin * pla
       !strncmp (play_base_bin->uri, "rtp://", 6) ||
       !strncmp (play_base_bin->uri, "rtsp://", 7);
 
+  /* enable iradio mode for HTTP streams to get icecast metadata */
+  if (!strncmp (play_base_bin->uri, "http://", 7) &&
+      g_object_class_find_property (G_OBJECT_GET_CLASS (source), "iradio-mode"))
+    g_object_set (source, "iradio-mode", TRUE, NULL);
+
   return source;
 }
 
