Sophie

Sophie

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

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

#
# SVN commit 941287 by jbache:
# 
# Phonon/Gstreamer: Add support for audio CD tracks
# through the MediaController interface.
# 
# This patch adds basic support for cdda to the
# GStreamer backend. It's still somewhat limited
# by the limited autodetection of CD media but should
# be enough to make KSCD work with GStreamer.
#
#
#
# M  +96 -4     mediaobject.cpp
# M  +35 -14    mediaobject.h
#

Index: gstreamer/mediaobject.h
===================================================================
--- gstreamer/mediaobject.h	(revision 941286)
+++ gstreamer/mediaobject.h	(revision 941287)
@@ -21,7 +21,6 @@
 #include "backend.h"
 #include "common.h"
 #include "medianode.h"
-
 #include <phonon/mediaobjectinterface.h>
 #include <phonon/addoninterface.h>
 
@@ -32,7 +31,6 @@
 #include <QtCore/QDate>
 #include <QtCore/QEvent>
 #include <QtCore/QUrl>
-
 #include <gst/gst.h>
 
 QT_BEGIN_NAMESPACE
@@ -50,11 +48,20 @@
 class VideoPath;
 class AudioOutput;
 
-class MediaObject : public QObject, public MediaObjectInterface, public AddonInterface, public MediaNode
+class MediaObject : public QObject, public MediaObjectInterface
+#ifndef QT_NO_PHONON_MEDIACONTROLLER
+        , public AddonInterface
+#endif
+        , public MediaNode
 {
     friend class Stream;
     Q_OBJECT
-    Q_INTERFACES(Phonon::MediaObjectInterface Phonon::AddonInterface Phonon::Gstreamer::MediaNode)
+    Q_INTERFACES(Phonon::MediaObjectInterface
+#ifndef QT_NO_PHONON_MEDIACONTROLLER
+                 Phonon::AddonInterface
+#endif
+                 Phonon::Gstreamer::MediaNode
+    )
 
 public:
 
@@ -93,16 +100,10 @@
     MediaSource source() const;
 
     // No additional interfaces currently supported
-    bool hasInterface(Interface) const
-    {
-        return false;
-    }
-
-    QVariant interfaceCall(Interface, int, const QList<QVariant> &)
-    {
-        return QVariant();
-    }
-
+#ifndef QT_NO_PHONON_MEDIACONTROLLER
+    bool hasInterface(Interface) const;
+    QVariant interfaceCall(Interface, int, const QList<QVariant> &);
+#endif
     bool isLoading()
     {
         return m_loading;
@@ -176,6 +177,19 @@
     QMultiMap<QString, QString> metaData();
     void setMetaData(QMultiMap<QString, QString> newData);
 
+    // AddonInterface:
+    void titleChanged(int);
+    void availableTitlesChanged(int);
+
+    // Not implemented
+    void chapterChanged(int);
+    void availableChaptersChanged(int);
+    void angleChanged(int);
+    void availableAnglesChanged(int);
+
+    void availableSubtitlesChanged();
+    void availableAudioChannelsChanged();
+
 protected:
     void beginLoad();
     void loadingComplete();
@@ -219,6 +233,10 @@
     void updateSeekable();
     qint64 getPipelinePos() const;
 
+    int _iface_availableTitles() const;
+    int _iface_currentTitle() const;
+    void _iface_setCurrentTitle(int title);
+
     bool m_resumeState;
     State m_oldState;
     quint64 m_oldPos;
@@ -264,6 +282,9 @@
     bool m_resetNeeded;
     QStringList m_missingCodecs;
     QMultiMap<QString, QString> m_metaData;
+    bool m_autoplayTitles;
+    int m_availableTitles;
+    int m_currentTitle;
 };
 }
 } //namespace Phonon::Gstreamer

--- gstreamer/mediaobject.cpp~	2009-03-20 01:01:06.000000000 +0100
+++ gstreamer/mediaobject.cpp	2009-03-20 01:10:25.000000000 +0100
@@ -81,6 +81,9 @@
         , m_videoGraph(0)
         , m_previousTickTime(-1)
         , m_resetNeeded(false)
+        , m_autoplayTitles(true)
+        , m_availableTitles(0)
+        , m_currentTitle(1)
 {
     qRegisterMetaType<GstCaps*>("GstCaps*");
     qRegisterMetaType<State>("State");
@@ -953,8 +956,13 @@
         break;
 
     case MediaSource::Disc: // CD tracks can be specified by setting the url in the following way uri=cdda:4
-        m_backend->logMessage("Source type Disc not currently supported", Backend::Warning, this);
-        setError(tr("Could not open media source."), Phonon::NormalError);
+        {
+            QUrl cdurl(QLatin1String("cdda://"));
+            if (createPipefromURL(cdurl))
+                m_loading = true;
+            else
+                setError(tr("Could not open media source."));
+        }
         break;
 
     default:
@@ -1005,6 +1013,18 @@
         m_hasVideo = m_videoStreamFound;
         emit hasVideoChanged(m_hasVideo);
     }
+
+    m_availableTitles = 1;
+    gint64 titleCount;
+    GstFormat format = gst_format_get_by_nick("track");
+    if (gst_element_query_duration (m_pipeline, &format, &titleCount)) {
+        int oldAvailableTitles = m_availableTitles;
+        m_availableTitles = (int)titleCount;
+        if (m_availableTitles != oldAvailableTitles) {
+            emit availableTitlesChanged(m_availableTitles);
+            m_backend->logMessage(QString("Available titles changed: %0").arg(m_availableTitles), Backend::Info, this);
+        }
+    }
 }
 
 void MediaObject::setPrefinishMark(qint32 newPrefinishMark)
@@ -1487,6 +1507,13 @@
     if (!m_seekable)
         m_atEndOfStream = true;
 
+    if (m_autoplayTitles &&
+        m_availableTitles > 1 &&
+        m_currentTitle < m_availableTitles) {
+        _iface_setCurrentTitle(m_currentTitle + 1);
+        return;
+    }
+
     if (m_nextSource.type() != MediaSource::Invalid
         && m_nextSource.type() != MediaSource::Empty) {  // We only emit finish when the queue is actually empty
         QTimer::singleShot (qMax(0, transitionTime()), this, SLOT(beginPlay()));
@@ -1515,6 +1542,71 @@
     notify(&event);
 }
 
+#ifndef QT_NO_PHONON_MEDIACONTROLLER
+//interface management
+bool MediaObject::hasInterface(Interface iface) const
+{
+    return iface == AddonInterface::TitleInterface;
+}
+
+QVariant MediaObject::interfaceCall(Interface iface, int command, const QList<QVariant> &params)
+{
+   if (hasInterface(iface)) {
+
+        switch (iface)
+        {
+        case TitleInterface:
+            switch (command)
+            {
+            case availableTitles:
+                return _iface_availableTitles();
+            case title:
+                return _iface_currentTitle();
+            case setTitle:
+                _iface_setCurrentTitle(params.first().toInt());
+               break;
+            case autoplayTitles:
+                return m_autoplayTitles;
+            case setAutoplayTitles:
+                m_autoplayTitles = params.first().toBool();
+                break;
+            }
+            break;
+                default:
+            break;
+        }
+    }
+    return QVariant();
+}
+#endif
+
+int MediaObject::_iface_availableTitles() const
+{
+    return m_availableTitles;
+}
+
+int MediaObject::_iface_currentTitle() const
+{
+    return m_currentTitle;
+}
+
+void MediaObject::_iface_setCurrentTitle(int title)
+{
+    GstFormat trackFormat = gst_format_get_by_nick("track");
+    m_backend->logMessage(QString("setCurrentTitle %0").arg(title), Backend::Info, this);
+    if ((title == m_currentTitle) || (title < 1) || (title > m_availableTitles))
+        return;
+
+    m_currentTitle = title;
+
+    //let's seek to the beginning of the song
+    if (gst_element_seek_simple(m_pipeline, trackFormat, GST_SEEK_FLAG_FLUSH, m_currentTitle - 1)) {
+        updateTotalTime();
+        m_atEndOfStream = false;
+        emit titleChanged(title);
+        emit totalTimeChanged(totalTime());
+   }
+}
 } // ns Gstreamer
 } // ns Phonon