[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    kdereview/phonon/gstreamer
From:       Jens Bache-Wiig <jbache () trolltech ! com>
Date:       2008-03-07 16:23:04
Message-ID: 1204906984.505838.8039.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 783276 by jbache:

* A bit more debug info
* Larger max-buffers for streams
* Fixed some x11 resizing issues


 M  +1 -2      audiooutput.cpp  
 M  +13 -8     backend.cpp  
 M  +8 -11     medianode.cpp  
 M  +49 -20    mediaobject.cpp  
 M  +2 -1      mediaobject.h  
 M  +3 -2      videowidget.cpp  
 M  +6 -0      x11renderer.cpp  


--- trunk/kdereview/phonon/gstreamer/audiooutput.cpp #783275:783276
@@ -126,8 +126,7 @@
 {
     if (root()) {
         root()->stop();  // We cannot currently change audiodevice while the stream \
                is playing
-        if (gst_element_get_state (root()->pipeline(), NULL, NULL, 3000) != \
                GST_STATE_CHANGE_SUCCESS)
-            return false;
+        root()->invalidateGraph();
     }
 
     bool success = false;
--- trunk/kdereview/phonon/gstreamer/backend.cpp #783275:783276
@@ -315,6 +315,7 @@
         MediaNode *sinkNode = qobject_cast<MediaNode *>(sink);
         if (sourceNode && sinkNode) {
             if (sourceNode->connectNode(sink)) {
+                sourceNode->root()->invalidateGraph();
                 logMessage(QString("Backend connected %0 to \
%1").arg(source->metaObject()->className()).arg(sink->metaObject()->className()));  \
return true;  }
@@ -411,16 +412,20 @@
 {
     if (debugLevel() > 0) {
         QString output;
-        if (obj)
-            output = QString("%0 (%1 \
                %2)").arg(message).arg(obj->objectName()).arg(obj->metaObject()->className());
                
-        else
+        if (obj) {
+            // Strip away namespace from className
+            QString className(obj->metaObject()->className());
+            int nameLength = className.length() - className.lastIndexOf(':') - 1;
+            className = className.right(nameLength);
+            output.sprintf("%s %s (%s %p)", message.toLatin1().constData(), 
+                                          obj->objectName().toLatin1().constData(), 
+                                          className.toLatin1().constData(), obj);
+        }
+        else {
             output = message;
-
+        }
         if (priority <= (int)debugLevel()) {
-            if (priority == Backend::Warning)
-                qDebug() << "PHONON_GST(warn): " << output;
-            else
-                qDebug() << "PHONON_GST(info): " << output;
+            qDebug() << QString("PGST(%1): %2").arg(priority).arg(output);
         }
     }
 }
--- trunk/kdereview/phonon/gstreamer/medianode.cpp #783275:783276
@@ -293,6 +293,7 @@
     if (!sinkElement)
         return false;
 
+    GstState state = GST_STATE (root()->pipeline());
     GstPad *srcPad = gst_element_get_request_pad (tee, "src%d");
     GstPad *sinkPad = gst_element_get_pad (sinkElement, "sink");
 
@@ -304,14 +305,6 @@
         return true;
     }
 
-    // Sync state with pipeline before adding
-    // and fail if this is not possible
-    GstState state = GST_STATE (root()->pipeline());
-    if (gst_element_set_state(sinkElement, state) == GST_STATE_CHANGE_FAILURE) {
-        success = false;
-        m_backend->logMessage("Could not sync element state with pipeline, \
                connection failed");
-    }
-
     if (success) {
         if (output->description() & AudioSink)
             gst_bin_add(GST_BIN(root()->audioGraph()), sinkElement);
@@ -319,10 +312,12 @@
             gst_bin_add(GST_BIN(root()->videoGraph()), sinkElement);
     }
 
-    if (success)
+    if (success) {
         gst_pad_link(srcPad, sinkPad);
-    else
+        gst_element_set_state(sinkElement, state);
+    } else {
         gst_element_release_request_pad(tee, srcPad);
+    }
 
     gst_object_unref (GST_OBJECT (srcPad));
     gst_object_unref (GST_OBJECT (sinkPad));
@@ -344,9 +339,10 @@
 
     GstPad *srcPad = gst_element_get_request_pad (tee, "src%d");
     gst_bin_add(GST_BIN(bin), sink);
-    success = (gst_element_set_state(sink, GST_STATE(bin)) != \
GST_STATE_CHANGE_FAILURE);  if (success)
         success = (gst_pad_link (srcPad, sinkPad) == GST_PAD_LINK_OK);
+    if (success)
+        success = (gst_element_set_state(sink, GST_STATE(bin)) != \
GST_STATE_CHANGE_FAILURE);  gst_object_unref (srcPad);
     gst_object_unref (sinkPad);
     return success;
@@ -379,6 +375,7 @@
         gst_bin_add(GST_BIN(bin), tee);
         if (!gst_element_link_pads(src, "src", tee, "sink"))
             return false;
+        gst_element_set_state(tee, GST_STATE(bin));
     }
     if (list.isEmpty()) {
         //connect node to a fake sink to avoid clogging the pipeline
--- trunk/kdereview/phonon/gstreamer/mediaobject.cpp #783275:783276
@@ -35,6 +35,7 @@
 #include <QApplication>
 
 #define ABOUT_TO_FINNISH_TIME 2000
+#define MAX_QUEUE_TIME 20 * GST_SECOND
 
 QT_BEGIN_NAMESPACE
 
@@ -71,6 +72,7 @@
         , m_audioGraph(0)
         , m_videoGraph(0)
         , m_previousTickTime(-1)
+        , m_resetNeeded(false)
 {
     qRegisterMetaType<GstCaps*>("GstCaps*");
 
@@ -222,15 +224,15 @@
     if (addToPipeline(m_videoGraph)) {
         GstPad *videopad = gst_element_get_pad (m_videoGraph, "sink");
         if (!GST_PAD_IS_LINKED (videopad) && (gst_pad_link (pad, videopad) == \
GST_PAD_LINK_OK)) { +            gst_element_set_state(m_videoGraph, \
GST_STATE_PAUSED);  m_videoStreamFound = true;
-            m_backend->logMessage("Video track connected");
+            m_backend->logMessage("Video track connected", Backend::Info, this);
             // Note that the notify::caps _must_ be installed after linking to work \
                with Dapper
             m_capsHandler = g_signal_connect(pad, "notify::caps", \
                G_CALLBACK(notifyVideoCaps), this);
-            gst_element_set_state(m_videoGraph, GST_STATE_PAUSED);
         }
         gst_object_unref (videopad);
     } else {
-        m_backend->logMessage("The video stream could not be plugged.");
+        m_backend->logMessage("The video stream could not be plugged.", \
Backend::Info, this);  }
 }
 
@@ -239,13 +241,13 @@
     if (addToPipeline(m_audioGraph)) {
         GstPad *audiopad = gst_element_get_pad (m_audioGraph, "sink");
         if (!GST_PAD_IS_LINKED (audiopad) && (gst_pad_link (pad, \
audiopad)==GST_PAD_LINK_OK)) { +            gst_element_set_state(m_audioGraph, \
GST_STATE_PAUSED);  m_hasAudio = true;
-            m_backend->logMessage("Audio track connected");
-            gst_element_set_state(m_audioGraph, GST_STATE_PAUSED);
+            m_backend->logMessage("Audio track connected", Backend::Info, this);
         }
         gst_object_unref (audiopad);
     } else {
-        m_backend->logMessage("The audio stream could not be plugged.");
+        m_backend->logMessage("The audio stream could not be plugged.", \
Backend::Info, this);  }
 }
 
@@ -332,7 +334,12 @@
     gst_object_ref (GST_OBJECT (m_audioGraph));
     gst_object_sink (GST_OBJECT (m_audioGraph));
 
-    m_audioPipe = gst_element_factory_make("identity", NULL);
+    // Note that these queues are only required for streaming content
+    // And should ideally be created on demand as they will disable
+    // pull-mode access. Also note that the max-size-time are increased to
+    // reduce buffer overruns as these are not gracefully handled at the moment.
+    m_audioPipe = gst_element_factory_make("queue", NULL);
+    g_object_set(G_OBJECT(m_audioPipe), "max-size-time",  MAX_QUEUE_TIME, NULL);
     gst_bin_add(GST_BIN(m_audioGraph), m_audioPipe);
     GstPad *audiopad = gst_element_get_pad (m_audioPipe, "sink");
     gst_element_add_pad (m_audioGraph, gst_ghost_pad_new ("sink", audiopad));
@@ -343,7 +350,8 @@
     gst_object_ref (GST_OBJECT (m_videoGraph));
     gst_object_sink (GST_OBJECT (m_videoGraph));
 
-    m_videoPipe = gst_element_factory_make("identity", NULL);
+    m_videoPipe = gst_element_factory_make("queue", NULL);
+    g_object_set(G_OBJECT(m_videoPipe), "max-size-time", MAX_QUEUE_TIME, NULL);
     gst_bin_add(GST_BIN(m_videoGraph), m_videoPipe);
     GstPad *videopad = gst_element_get_pad (m_videoPipe, "sink");
     gst_element_add_pad (m_videoGraph, gst_ghost_pad_new ("sink", videopad));
@@ -494,6 +502,14 @@
         break;
 
     case Phonon::PlayingState:
+       if (m_resetNeeded) {
+            // ### Note this is a workaround and it should really be gracefully
+            // handled by medianode when we implement live connections.
+            // This generally happens if medianodes have been connected after the \
MediaSource was set +            // Note that a side-effect of this is that we resend \
all meta data. +            gst_element_set_state(m_pipeline, GST_STATE_NULL);
+            m_resetNeeded = false; 
+        }
         m_backend->logMessage("phonon state request: Playing", Backend::Info, this);
         if (m_atEndOfStream) {
             m_backend->logMessage("EOS already reached", Backend::Info, this);
@@ -570,7 +586,14 @@
     m_error = error;
     m_tickTimer->stop();
 
-    changeState(Phonon::ErrorState);
+    if (error == Phonon::FatalError) {
+        emit hasVideoChanged(false);
+        gst_element_set_state(m_pipeline, GST_STATE_READY);
+        changeState(Phonon::ErrorState);
+    } else {
+        //Flag error after loading has completed
+        m_pendingState = Phonon::ErrorState;
+    }
 }
 
 qint64 MediaObject::totalTime() const
@@ -648,11 +671,11 @@
         }
 
         if (m_seekable)
-            m_backend->logMessage("Stream is seekable");
+            m_backend->logMessage("Stream is seekable", Backend::Info, this);
         else
-            m_backend->logMessage("Stream is non-seekable");
+            m_backend->logMessage("Stream is non-seekable", Backend::Info, this);
     } else {
-        m_backend->logMessage("updateSeekable query failed");
+        m_backend->logMessage("updateSeekable query failed", Backend::Info, this);
     }
     gst_query_unref (query);
 }
@@ -689,9 +712,6 @@
     if (!isValid())
         return;
 
-    if (errorType() == FatalError)
-        return;
-
     // We have to reset the state completely here, otherwise
     // remnants of the old pipeline can result in strangenes
     // such as failing duration queries etc
@@ -709,6 +729,7 @@
     // Go into to loading state
     changeState(Phonon::LoadingState);
     m_loading = true;
+    m_resetNeeded = false;
     m_pendingState = Phonon::StoppedState;
 
      // Make sure we start out unconnected
@@ -784,7 +805,7 @@
 void MediaObject::beginLoad()
 {
     if (gst_element_set_state(m_pipeline, GST_STATE_PAUSED) != \
                GST_STATE_CHANGE_FAILURE) {
-        m_backend->logMessage("Begin source load");
+        m_backend->logMessage("Begin source load", Backend::Info, this);
     } else {
         setError(tr("Could not load source"));
     }
@@ -985,6 +1006,14 @@
     GstMessage *gstMessage = message.rawMessage();
     Q_ASSERT(m_pipeline);
 
+    if (m_backend->debugLevel() >= Backend::Debug) {
+        int type = GST_MESSAGE_TYPE(gstMessage);
+        gchar* name = gst_element_get_name(gstMessage->src);
+        QString message = QString("Bus: %0 (%1)").arg(gst_message_type_get_name \
((GstMessageType)type)).arg(name); +        g_free(name);
+        m_backend->logMessage(message, Backend::Debug, this);
+    }
+
     switch (GST_MESSAGE_TYPE (gstMessage)) {
 
     case GST_MESSAGE_EOS: 
@@ -1065,7 +1094,10 @@
             QString message;
             message.sprintf("Error: %s", err->message);
             m_backend->logMessage(message, Backend::Warning);
-            setError(QString(err->message));
+            if (err->domain == GST_STREAM_ERROR) //Cannot continue
+                setError(QString(err->message), Phonon::FatalError);
+            else
+                setError(QString(err->message), Phonon::NormalError);
             g_error_free (err);
             break;
         }
@@ -1122,9 +1154,6 @@
         //case GST_MESSAGE_LATENCY: only from 0.10.12
         //case GST_MESSAGE_ASYNC_DONE: only from 0.10.13
     default: 
-        int type = GST_MESSAGE_TYPE(gstMessage);
-        QString message = QString("Bus: %0").arg(gst_message_type_get_name \
                ((GstMessageType)type));
-        //m_backend->logMessage(message, Backend::Debug, this);
         break; 
     }
 }
--- trunk/kdereview/phonon/gstreamer/mediaobject.h #783275:783276
@@ -143,6 +143,7 @@
     void handleBusMessage(const Message &msg);
     void handleEndOfStream();
     void setState(State);
+    void invalidateGraph() {m_resetNeeded = true;}
     static void cb_newpad (GstElement *decodebin, GstPad *pad, gboolean last, \
                gpointer data);
     static void cb_unknown_type (GstElement *decodebin, GstPad *pad, GstCaps *caps, \
gpointer data);  
@@ -237,7 +238,7 @@
     GstElement *m_audioGraph;
     GstElement *m_videoGraph;
     int m_previousTickTime;
-
+    bool m_resetNeeded;
     QMultiMap<QString, QString> m_metaData;
 };
 }
--- trunk/kdereview/phonon/gstreamer/videowidget.cpp #783275:783276
@@ -134,11 +134,10 @@
 
     // Disable overlays for graphics view
     if (root() && parentWidget() && \
parentWidget()->testAttribute(Qt::WA_DontShowOnScreen) && \
                !m_renderer->paintsOnWidget()) {
-        m_backend->logMessage(QString("Overlays disabled"), Backend::Info);
+        m_backend->logMessage(QString("Widget rendering forced"), Backend::Info, \
this);  GstElement *videoSink = m_renderer->videoSink();
         Q_ASSERT(videoSink);
 
-        gst_element_set_state (root()->pipeline(), GST_STATE_READY);
         gst_element_set_state (videoSink, GST_STATE_NULL);
         gst_bin_remove(GST_BIN(m_videoBin), videoSink);
         delete m_renderer;
@@ -148,8 +147,10 @@
         videoSink = m_renderer->videoSink();
         gst_bin_add(GST_BIN(m_videoBin), videoSink);
         gst_element_link(m_videoplug, videoSink);
+        gst_element_set_state (videoSink, GST_STATE_PAUSED);
 
         // Request return to current state
+        root()->invalidateGraph();
         root()->setState(root()->state());
     }
     QWidget::setVisible(val);    
--- trunk/kdereview/phonon/gstreamer/x11renderer.cpp #783275:783276
@@ -124,7 +124,13 @@
     if (e->type() == QEvent::Show) {
         m_videoWidget->setAttribute(Qt::WA_PaintOnScreen, true);
         setOverlay();
+    } else if (e->type() == QEvent::Resize) {
+        // This is a workaround for missing background repaints
+        // when reducing window size
+        QApplication::syncX();
+        windowExposed();
     }
+
     return false;
 }
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic