Sophie

Sophie

distrib > Mandriva > 2009.0 > x86_64 > media > main-testing-src > by-pkgid > 870d9436efcd1352b27ef87300ae1490 > files > 5

phonon-4.3.1-0.1mdv2009.0.src.rpm

--- gstreamer/mediaobject.h.orig	2009-02-27 12:49:33.000000000 +0100
+++ gstreamer/mediaobject.h	2009-02-27 12:50:21.000000000 +0100
@@ -232,6 +232,7 @@
     MediaSource m_nextSource;
     qint32 m_prefinishMark;
     qint32 m_transitionTime;
+    bool m_is_stream;
 
     qint64 m_posAtSeek;
 
--- gstreamer/mediaobject.cpp.orig	2009-02-27 12:43:23.000000000 +0100
+++ gstreamer/mediaobject.cpp	2009-02-27 12:49:15.000000000 +0100
@@ -55,6 +55,7 @@
         , m_tickTimer(new QTimer(this))
         , m_prefinishMark(0)
         , m_transitionTime(0)
+        , m_is_stream(false)
         , m_posAtSeek(-1)
         , m_prefinishMarkReachedNotEmitted(true)
         , m_aboutToFinishEmitted(false)
@@ -371,6 +372,14 @@
     if (!m_datasource)
         return false;
 
+    /* make HTTP sources send extra headers so we get icecast
+     * metadata in case the stream is an icecast stream */
+    if (encoded_cstr_url.startsWith("http://")
+        && g_object_class_find_property (G_OBJECT_GET_CLASS (m_datasource), "iradio-mode")) {
+        g_object_set (m_datasource, "iradio-mode", TRUE, NULL);
+        m_is_stream = true;
+    }
+
     // Link data source into pipeline
     gst_bin_add(GST_BIN(m_pipeline), m_datasource);
     if (!gst_element_link(m_datasource, m_decodebin)) {
@@ -873,6 +882,8 @@
     // Clear exising meta tags
     m_metaData.clear();
 
+    m_is_stream = false;
+
     switch (source.type()) {
     case MediaSource::Url: {            
             QString urlString = source.url().toEncoded();
@@ -1161,13 +1172,98 @@
             GstTagList* tag_list = 0;
             gst_message_parse_tag(gstMessage, &tag_list);
             if (tag_list) {
-                TagMap oldMap = m_metaData; // Keep a copy of the old one for reference
-                // Append any new meta tags to the existing tag list
-                gst_tag_list_foreach (tag_list, &foreach_tag_function, &m_metaData);
-                m_backend->logMessage("Meta tags found", Backend::Info, this);
-                if (oldMap != m_metaData && !m_loading)
-                    emit metaDataChanged(m_metaData);
+                TagMap newTags;
+                gst_tag_list_foreach (tag_list, &foreach_tag_function, &newTags);
                 gst_tag_list_free(tag_list);
+
+                // Determin if we should no fake the album/artist tags.
+                // This is a little confusing as we want to fake it on initial
+                // connection where title, album and artist are all missing.
+                // There are however times when we get just other information,
+                // e.g. codec, and so we want to only do clever stuff if we
+                // have a commonly available tag (ORGANIZATION) or we have a
+                // change in title
+                bool fake_it =
+                   (m_is_stream
+                    && ((!newTags.contains("TITLE")
+                         && newTags.contains("ORGANIZATION"))
+                        || (newTags.contains("TITLE")
+                            && m_metaData.value("TITLE") != newTags.value("TITLE")))
+                    && !newTags.contains("ALBUM")
+                    && !newTags.contains("ARTIST"));
+
+	    TagMap oldMap = m_metaData; // Keep a copy of the old one for reference
+
+                // Now we've checked the new data, append any new meta tags to the existing tag list
+                // We cannot use TagMap::iterator as this is a multimap and when streaming data
+                // could in theory be lost.
+                QList<QString> keys = newTags.keys();
+                for (QList<QString>::iterator i = keys.begin(); i != keys.end(); ++i) {
+                    QString key = *i;
+                    if (m_is_stream) {
+                        // If we're streaming, we need to remove data in m_metaData
+                        // in order to stop it filling up indefinitely (as it's a multimap)
+                        m_metaData.remove(key);
+                    }
+                    QList<QString> values = newTags.values(key);
+                    for (QList<QString>::iterator j = values.begin(); j != values.end(); ++j) {
+                        QString value = *j;
+                        QString currVal = m_metaData.value(key);
+                        if (!m_metaData.contains(key) || currVal != value) {
+                            m_metaData.insert(key, value);
+                        }
+                    }
+                }
+
+                m_backend->logMessage("Meta tags found", Backend::Info, this);
+                if (oldMap != m_metaData) {
+                    // This is a bit of a hack to ensure that stream metadata is
+                    // returned. We get as much as we can from the Shoutcast server's
+                    // StreamTitle= header. If further info is decoded from the stream
+                    // itself later, then it will overwrite this info.
+                    if (m_is_stream && fake_it) {
+                        m_metaData.remove("ALBUM");
+                        m_metaData.remove("ARTIST");
+
+                        // Detect whether we want to "fill in the blanks"
+                        QString str;
+                        if (m_metaData.contains("TITLE"))
+                        {
+                            str = m_metaData.value("TITLE");
+                            int splitpoint;
+                            // Check to see if our title matches "%s - %s"
+                            // Where neither %s are empty...
+                            if ((splitpoint = str.indexOf(" - ")) > 0
+                                && str.size() > (splitpoint+3)) {
+                                m_metaData.insert("ARTIST", str.left(splitpoint));
+                                m_metaData.replace("TITLE", str.mid(splitpoint+3));
+                            }
+                        } else {
+                            str = m_metaData.value("GENRE");
+                            if (!str.isEmpty())
+                                m_metaData.insert("TITLE", str);
+                            else
+                                m_metaData.insert("TITLE", "Streaming Data");
+                        }
+                        if (!m_metaData.contains("ARTIST")) {
+                            str = m_metaData.value("LOCATION");
+                            if (!str.isEmpty())
+                                m_metaData.insert("ARTIST", str);
+                            else
+                                m_metaData.insert("ARTIST", "Streaming Data");
+                        }
+                        str = m_metaData.value("ORGANIZATION");
+                        if (!str.isEmpty())
+                            m_metaData.insert("ALBUM", str);
+                        else
+                            m_metaData.insert("ALBUM", "Streaming Data");
+                    }
+                    // As we manipulate the title, we need to recompare
+                    // oldMap and m_metaData here...
+                    if (oldMap != m_metaData && !m_loading)
+                        emit metaDataChanged(m_metaData);
+                }
+
             }
         }
         break;