Gstreamer media backend cleanup.
authorDmytro Poplavskiy <dmytro.poplavskiy@nokia.com>
Tue, 2 Aug 2011 04:33:38 +0000 (14:33 +1000)
committerQt by Nokia <qt-info@nokia.com>
Fri, 5 Aug 2011 05:50:59 +0000 (07:50 +0200)
Moved controls specific bus/sync messages handling from
player/camera/capture session to corresponding controls.

Reviewed-by: Michael Goddard
Change-Id: Ieb67976ed335b0ef1cde87dc60e8ad8da3409526
Reviewed-on: http://codereview.qt.nokia.com/2535
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
20 files changed:
src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp
src/plugins/gstreamer/camerabin/camerabinimagecapture.h
src/plugins/gstreamer/camerabin/camerabinservice.cpp
src/plugins/gstreamer/camerabin/camerabinsession.cpp
src/plugins/gstreamer/camerabin/camerabinsession.h
src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
src/plugins/gstreamer/qgstreamerbushelper.cpp
src/plugins/gstreamer/qgstreamerbushelper.h
src/plugins/gstreamer/qgstreamergltexturerenderer.cpp
src/plugins/gstreamer/qgstreamergltexturerenderer.h
src/plugins/gstreamer/qgstreamervideorenderer.h
src/plugins/gstreamer/qgstreamervideorendererinterface.h
src/plugins/gstreamer/qgstreamervideowidget.cpp
src/plugins/gstreamer/qgstreamervideowidget.h
src/plugins/gstreamer/qgstreamervideowindow.cpp
src/plugins/gstreamer/qgstreamervideowindow.h

index 910c6c2ce499657361faa6b3e59916482b6bd3c3..f27cd7f35f841bc77f83ad51a1f8a7b39f192e27 100644 (file)
@@ -82,8 +82,8 @@ CameraBinImageCapture::CameraBinImageCapture(CameraBinSession *session)
     connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateState()));
     connect(m_session, SIGNAL(imageExposed(int)), this, SIGNAL(imageExposed(int)));
     connect(m_session, SIGNAL(imageCaptured(int,QImage)), this, SIGNAL(imageCaptured(int,QImage)));
-    connect(m_session, SIGNAL(busMessage(QGstreamerMessage)), SLOT(handleBusMessage(QGstreamerMessage)));
 
+    m_session->bus()->installMessageFilter(this);
     g_signal_connect(G_OBJECT(m_session->cameraBin()), IMAGE_DONE_SIGNAL, G_CALLBACK(handleImageSaved), this);
 }
 
@@ -281,7 +281,7 @@ gboolean CameraBinImageCapture::jpegBufferProbe(GstPad *pad, GstBuffer *buffer,
     return destination & QCameraImageCapture::CaptureToFile;
 }
 
-void CameraBinImageCapture::handleBusMessage(const QGstreamerMessage &message)
+bool CameraBinImageCapture::processBusMessage(const QGstreamerMessage &message)
 {
     //Install metadata event and buffer probes
 
@@ -298,7 +298,7 @@ void CameraBinImageCapture::handleBusMessage(const QGstreamerMessage &message)
         if (newState == GST_STATE_READY) {
             GstElement *element = GST_ELEMENT(GST_MESSAGE_SRC(gm));
             if (!element)
-                return;
+                return false;
 
             QString elementName = QString::fromLatin1(gst_element_get_name(element));
             if (elementName.contains("jpegenc") && element != m_jpegEncoderElement) {
@@ -339,4 +339,6 @@ void CameraBinImageCapture::handleBusMessage(const QGstreamerMessage &message)
             }
         }
     }
+
+    return false;
 }
index 6cc910dbe9ab1925812e2be42621fe9e5605e52c..ddb04e1ea4c3a8a6257bacb38d6efe9e81617f4c 100644 (file)
 
 QT_USE_NAMESPACE
 
-class CameraBinImageCapture : public QCameraImageCaptureControl
+class CameraBinImageCapture : public QCameraImageCaptureControl, public QGstreamerBusMessageFilter
 {
     Q_OBJECT
+    Q_INTERFACES(QGstreamerBusMessageFilter)
 public:
     CameraBinImageCapture(CameraBinSession *session);
     virtual ~CameraBinImageCapture();
@@ -62,9 +63,10 @@ public:
     int capture(const QString &fileName);
     void cancelCapture();
 
+    bool processBusMessage(const QGstreamerMessage &message);
+
 private slots:
     void updateState();
-    void handleBusMessage(const QGstreamerMessage &message);
 
 private:
     static gboolean metadataEventProbe(GstPad *pad, GstEvent *event, CameraBinImageCapture *);
index 75d820bfd873c0430b9856e995929fac853cc56c..93bcc69939f9c319ff0d4124e306d639f0d47d70 100644 (file)
@@ -160,17 +160,16 @@ QMediaControl *CameraBinService::requestControl(const char *name)
     if (!m_videoOutput) {
         if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
             m_videoOutput = m_videoRenderer;
-            m_captureSession->setViewfinder(m_videoRenderer);
         } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
             m_videoOutput = m_videoWindow;
-            m_captureSession->setViewfinder(m_videoWindow);
         } else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
-            m_captureSession->setViewfinder(m_videoWidgetControl);
             m_videoOutput = m_videoWidgetControl;
         }
 
-        if (m_videoOutput)
+        if (m_videoOutput) {
+            m_captureSession->setViewfinder(m_videoOutput);
             return m_videoOutput;
+        }
     }
 
     if (qstrcmp(name,QAudioEndpointSelector_iid) == 0)
index d1552c0af0b83ee69e1710880b6bc54efedef2df..fbcc85266fd19d4fb76ed781ede9b6f35d16df96 100644 (file)
@@ -145,8 +145,8 @@ CameraBinSession::CameraBinSession(QObject *parent)
     m_bus = gst_element_get_bus(m_pipeline);
 
     m_busHelper = new QGstreamerBusHelper(m_bus, this);
-    m_busHelper->installSyncEventFilter(this);
-    connect(m_busHelper, SIGNAL(message(QGstreamerMessage)), SLOT(handleBusMessage(QGstreamerMessage)));
+    m_busHelper->installMessageFilter(this);
+
     m_audioEncodeControl = new CameraBinAudioEncoder(this);
     m_videoEncodeControl = new CameraBinVideoEncoder(this);
     m_imageEncodeControl = new CameraBinImageEncoder(this);
@@ -534,6 +534,8 @@ void CameraBinSession::setViewfinder(QObject *viewfinder)
                        this, SLOT(handleViewfinderChange()));
             disconnect(m_viewfinder, SIGNAL(readyChanged(bool)),
                        this, SIGNAL(readyChanged(bool)));
+
+            m_busHelper->removeMessageFilter(m_viewfinder);
         }
 
         m_viewfinder = viewfinder;
@@ -544,6 +546,8 @@ void CameraBinSession::setViewfinder(QObject *viewfinder)
                        this, SLOT(handleViewfinderChange()));
             connect(m_viewfinder, SIGNAL(readyChanged(bool)),
                     this, SIGNAL(readyChanged(bool)));
+
+            m_busHelper->installMessageFilter(m_viewfinder);
         }
 
         emit viewfinderChanged();
@@ -795,24 +799,14 @@ bool CameraBinSession::processSyncMessage(const QGstreamerMessage &message)
             }
         }
 
-        if (gst_structure_has_name(gm->structure, "prepare-xwindow-id")) {
-            if (m_viewfinderInterface)
-                m_viewfinderInterface->precessNewStream();
-
-            return true;
-        }
-
         if (gst_structure_has_name(gm->structure, GST_PHOTOGRAPHY_AUTOFOCUS_DONE))
             m_cameraFocusControl->handleFocusMessage(gm);
-
-        if (m_viewfinderInterface && GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_viewfinderElement))
-            m_viewfinderInterface->handleSyncMessage(gm);
     }
 
     return false;
 }
 
-void CameraBinSession::handleBusMessage(const QGstreamerMessage &message)
+bool CameraBinSession::processBusMessage(const QGstreamerMessage &message)
 {
     GstMessage* gm = message.rawMessage();
 
@@ -911,12 +905,9 @@ void CameraBinSession::handleBusMessage(const QGstreamerMessage &message)
             }
             //qDebug() << "New session state:" << ENUM_NAME(CameraBinSession,"State",m_state);
         }
-
-        if (m_viewfinderInterface && GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_viewfinderElement))
-            m_viewfinderInterface->handleBusMessage(gm);
-
-        emit busMessage(message);
     }
+
+    return false;
 }
 
 void CameraBinSession::recordVideo()
index 5504bb505ecdb0076ca64572749ee67ab80232ea..cc646cbfd0ddc0e6db8374130ceb02e21b61cd24 100644 (file)
@@ -76,10 +76,13 @@ public:
     virtual GstElement *buildElement() = 0;
 };
 
-class CameraBinSession : public QObject, public QGstreamerSyncEventFilter
+class CameraBinSession : public QObject,
+                         public QGstreamerBusMessageFilter,
+                         public QGstreamerSyncMessageFilter
 {
     Q_OBJECT
     Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
+    Q_INTERFACES(QGstreamerBusMessageFilter QGstreamerSyncMessageFilter)
 public:
     enum CameraRole {
        FrontCamera, // Secondary camera
@@ -91,6 +94,7 @@ public:
 
     GstPhotography *photography();
     GstElement *cameraBin() { return m_pipeline; }
+    QGstreamerBusHelper *bus() { return m_busHelper; }
 
     CameraRole cameraRole() const;
 
@@ -146,6 +150,7 @@ public:
     bool isMuted() const;
 
     bool processSyncMessage(const QGstreamerMessage &message);
+    bool processBusMessage(const QGstreamerMessage &message);
 
 signals:
     void stateChanged(QCamera::State state);
@@ -157,7 +162,6 @@ signals:
     void viewfinderChanged();
     void readyChanged(bool);
     void busyChanged(bool);
-    void busMessage(const QGstreamerMessage &message);
 
 public slots:
     void setDevice(const QString &device);
@@ -167,7 +171,6 @@ public slots:
     void setMuted(bool);
 
 private slots:
-    void handleBusMessage(const QGstreamerMessage &message);
     void handleViewfinderChange();
 
 private:
index eb4338b3f592928f8286994f388a3173d27486ea..d063b0e1310fe04b38c60fa0f80e92f6fef0bbc2 100644 (file)
@@ -160,17 +160,16 @@ QMediaControl *QGstreamerCaptureService::requestControl(const char *name)
     if (!m_videoOutput) {
         if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
             m_videoOutput = m_videoRenderer;
-            m_captureSession->setVideoPreview(m_videoRenderer);
         } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
             m_videoOutput = m_videoWindow;
-            m_captureSession->setVideoPreview(m_videoWindow);
         } else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
-            m_captureSession->setVideoPreview(m_videoWidgetControl);
             m_videoOutput = m_videoWidgetControl;
         }
 
-        if (m_videoOutput)
+        if (m_videoOutput) {
+            m_captureSession->setVideoPreview(m_videoOutput);
             return m_videoOutput;
+        }
     }
 
     return 0;
index b092af281077042ca2e303802bb116c16d41980b..b685f5466481eb30e437cee258d9364fe1179072 100644 (file)
@@ -96,8 +96,8 @@ QGstreamerCaptureSession::QGstreamerCaptureSession(QGstreamerCaptureSession::Cap
 
     m_bus = gst_element_get_bus(m_pipeline);
     m_busHelper = new QGstreamerBusHelper(m_bus, this);
-    m_busHelper->installSyncEventFilter(this);
-    connect(m_busHelper, SIGNAL(message(QGstreamerMessage)), SLOT(busMessage(QGstreamerMessage)));
+    m_busHelper->installMessageFilter(this);
+
     m_audioEncodeControl = new QGstreamerAudioEncode(this);
     m_videoEncodeControl = new QGstreamerVideoEncode(this);
     m_imageEncodeControl = new QGstreamerImageEncode(this);
@@ -735,6 +735,8 @@ void QGstreamerCaptureSession::setVideoPreview(QObject *viewfinder)
                        this, SIGNAL(viewfinderChanged()));
             disconnect(m_viewfinder, SIGNAL(readyChanged(bool)),
                        this, SIGNAL(readyChanged(bool)));
+
+            m_busHelper->removeMessageFilter(m_viewfinder);
         }
 
         m_viewfinder = viewfinder;
@@ -745,6 +747,8 @@ void QGstreamerCaptureSession::setVideoPreview(QObject *viewfinder)
                        this, SIGNAL(viewfinderChanged()));
             connect(m_viewfinder, SIGNAL(readyChanged(bool)),
                     this, SIGNAL(readyChanged(bool)));
+
+            m_busHelper->installMessageFilter(m_viewfinder);
         }
 
         emit viewfinderChanged();
@@ -917,29 +921,7 @@ void QGstreamerCaptureSession::setMetaData(const QMap<QByteArray, QVariant> &dat
     }
 }
 
-bool QGstreamerCaptureSession::processSyncMessage(const QGstreamerMessage &message)
-{
-    GstMessage* gm = message.rawMessage();
-
-    if (gm && GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) {
-        if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoPreview))
-            m_viewfinderInterface->handleSyncMessage(gm);
-
-        if (gst_structure_has_name(gm->structure, "prepare-xwindow-id")) {
-            if (m_audioPreviewFactory)
-                m_audioPreviewFactory->prepareWinId();
-
-            if (m_viewfinderInterface)
-                m_viewfinderInterface->precessNewStream();
-
-            return true;
-        }
-    }
-
-    return false;
-}
-
-void QGstreamerCaptureSession::busMessage(const QGstreamerMessage &message)
+bool QGstreamerCaptureSession::processBusMessage(const QGstreamerMessage &message)
 {
     GstMessage* gm = message.rawMessage();
 
@@ -1027,11 +1009,8 @@ void QGstreamerCaptureSession::busMessage(const QGstreamerMessage &message)
             }
             //qDebug() << "New session state:" << ENUM_NAME(QGstreamerCaptureSession,"State",m_state);
         }
-
-        if (m_videoPreview && m_viewfinderInterface &&
-                GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoPreview))
-            m_viewfinderInterface->handleBusMessage(gm);
     }
+    return false;
 }
 
 void QGstreamerCaptureSession::setMuted(bool muted)
index 63d1b0bf6e8302fb0a30d886a1dd506471d56311..e4c73460071a11e0df5f50268720d304e4053ffa 100644 (file)
@@ -76,12 +76,13 @@ public:
     virtual QList<QSize> supportedResolutions(qreal frameRate = -1) const = 0;
 };
 
-class QGstreamerCaptureSession : public QObject, public QGstreamerSyncEventFilter
+class QGstreamerCaptureSession : public QObject, public QGstreamerBusMessageFilter
 {
     Q_OBJECT
     Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
     Q_ENUMS(State)
     Q_ENUMS(CaptureMode)
+    Q_INTERFACES(QGstreamerBusMessageFilter)
 public:
     enum CaptureMode { Audio = 1, Video = 2, Image=4, AudioAndVideo = Audio | Video };
     enum State { StoppedState, PreviewState, PausedState, RecordingState };
@@ -89,6 +90,8 @@ public:
     QGstreamerCaptureSession(CaptureMode captureMode, QObject *parent);
     ~QGstreamerCaptureSession();
 
+    QGstreamerBusHelper *bus() { return m_busHelper; }
+
     CaptureMode captureMode() const { return m_captureMode; }
     void setCaptureMode(CaptureMode);
 
@@ -122,7 +125,7 @@ public:
 
     bool isReady() const;
 
-    bool processSyncMessage(const QGstreamerMessage &message);
+    bool processBusMessage(const QGstreamerMessage &message);
 
 signals:
     void stateChanged(QGstreamerCaptureSession::State state);
@@ -144,9 +147,6 @@ public slots:
     void setMetaData(const QMap<QByteArray, QVariant>&);
     void setMuted(bool);
 
-private slots:
-    void busMessage(const QGstreamerMessage &message);
-
 private:
     enum PipelineMode { EmptyPipeline, PreviewPipeline, RecordingPipeline, PreviewAndRecordingPipeline };
 
index 7cb5a661bb53576e461ae0e2efc020e11895a733..9e4e8bc69e07ca6c686ab788cf7f7d0ef93ab0ee 100644 (file)
@@ -155,8 +155,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
         // Sort out messages
         m_bus = gst_element_get_bus(m_playbin);
         m_busHelper = new QGstreamerBusHelper(m_bus, this);
-        connect(m_busHelper, SIGNAL(message(QGstreamerMessage)), SLOT(busMessage(QGstreamerMessage)));
-        m_busHelper->installSyncEventFilter(this);
+        m_busHelper->installMessageFilter(this);
 
         g_object_set(G_OBJECT(m_playbin), "video-sink", m_videoOutputBin, NULL);
 
@@ -188,6 +187,11 @@ QGstreamerPlayerSession::~QGstreamerPlayerSession()
     }
 }
 
+GstElement *QGstreamerPlayerSession::playbin() const
+{
+    return m_playbin;
+}
+
 #if defined(HAVE_GST_APPSRC)
 void QGstreamerPlayerSession::configureAppSrcElement(GObject* object, GObject *orig, GParamSpec *pspec, QGstreamerPlayerSession* self)
 {
@@ -444,16 +448,20 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
                        this, SLOT(updateVideoRenderer()));
             disconnect(m_videoOutput, SIGNAL(readyChanged(bool)),
                    this, SLOT(updateVideoRenderer()));
+
+            m_busHelper->removeMessageFilter(m_videoOutput);
         }
 
-        if (videoOutput) {
-            connect(videoOutput, SIGNAL(sinkChanged()),
+        m_videoOutput = videoOutput;
+
+        if (m_videoOutput) {
+            connect(m_videoOutput, SIGNAL(sinkChanged()),
                     this, SLOT(updateVideoRenderer()));
-            connect(videoOutput, SIGNAL(readyChanged(bool)),
+            connect(m_videoOutput, SIGNAL(readyChanged(bool)),
                    this, SLOT(updateVideoRenderer()));
-        }
 
-        m_videoOutput = videoOutput;
+            m_busHelper->installMessageFilter(m_videoOutput);
+        }
     }
 
     QGstreamerVideoRendererInterface* renderer = qobject_cast<QGstreamerVideoRendererInterface*>(videoOutput);   
@@ -877,29 +885,9 @@ void QGstreamerPlayerSession::setSeekable(bool seekable)
     }
 }
 
-bool QGstreamerPlayerSession::processSyncMessage(const QGstreamerMessage &message)
+bool QGstreamerPlayerSession::processBusMessage(const QGstreamerMessage &message)
 {
     GstMessage* gm = message.rawMessage();
-
-    if (gm && GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) {
-        if (m_renderer) {
-            if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSink))
-                m_renderer->handleSyncMessage(gm);
-
-            if (gst_structure_has_name(gm->structure, "prepare-xwindow-id")) {
-                m_renderer->precessNewStream();
-                return true;
-            }
-        }
-    }
-
-    return false;
-}
-
-void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message)
-{
-    GstMessage* gm = message.rawMessage();
-
     if (gm) {
         //tag message comes from elements inside playbin, not from playbin itself
         if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_TAG) {
@@ -1111,19 +1099,6 @@ void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message)
             default:
                 break;
             }
-        } else if (m_videoSink
-                   && m_renderer
-                   && GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSink)) {
-
-            m_renderer->handleBusMessage(gm);
-            if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED) {
-                GstState oldState;
-                GstState newState;
-                gst_message_parse_state_changed(gm, &oldState, &newState, 0);
-
-                if (oldState == GST_STATE_READY && newState == GST_STATE_PAUSED)
-                    m_renderer->precessNewStream();
-            }
         } else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ERROR) {
             GError *err;
             gchar *debug;
@@ -1196,6 +1171,8 @@ void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message)
             }
         }
     }
+
+    return false;
 }
 
 void QGstreamerPlayerSession::getStreamsInfo()
index be32f5f79d0593cf71a27d1d1887f2e348744456..297754b936d4e2c249c71aa981b01fd8bcacfba7 100644 (file)
@@ -62,14 +62,19 @@ class QGstreamerVideoRendererInterface;
 
 QT_USE_NAMESPACE
 
-class QGstreamerPlayerSession : public QObject, public QGstreamerSyncEventFilter
+class QGstreamerPlayerSession : public QObject,
+                                public QGstreamerBusMessageFilter
 {
 Q_OBJECT
+Q_INTERFACES(QGstreamerBusMessageFilter)
 
 public:
     QGstreamerPlayerSession(QObject *parent);
     virtual ~QGstreamerPlayerSession();
 
+    GstElement *playbin() const;
+    QGstreamerBusHelper *bus() const { return m_busHelper; }
+
     QNetworkRequest request() const;
 
     QMediaPlayer::State state() const { return m_state; }
@@ -105,7 +110,7 @@ public:
     int activeStream(QMediaStreamsControl::StreamType streamType) const;
     void setActiveStream(QMediaStreamsControl::StreamType streamType, int streamNumber);
 
-    bool processSyncMessage(const QGstreamerMessage &message);
+    bool processBusMessage(const QGstreamerMessage &message);
 
 #if defined(HAVE_GST_APPSRC)
     QGstAppSrc *appsrc() const { return m_appSrc; }
@@ -145,7 +150,6 @@ signals:
     void playbackRateChanged(qreal);
 
 private slots:
-    void busMessage(const QGstreamerMessage &message);
     void getStreamsInfo();
     void setSeekable(bool);
     void finishVideoOutputChange();
index 76cc83ada245fbe0a7b0e12af9706bbe5362e86f..92f2ee8b737a0da54a4beb0dadb9197e76080880 100644 (file)
 **
 ****************************************************************************/
 
-#include <QMap>
-#include <QTimer>
-#include <QMutex>
+#include <QtCore/qmap.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qlist.h>
 
 #include "qgstreamerbushelper.h"
 
@@ -57,7 +58,6 @@ public:
         setParent(helper);
         m_tag = gst_bus_add_watch_full(bus, 0, busCallback, this, NULL);
         m_helper = helper;
-        filter = 0;
     }
 
     void removeWatch(QGstreamerBusHelper* helper)
@@ -75,7 +75,12 @@ private:
     void processMessage(GstBus* bus, GstMessage* message)
     {
         Q_UNUSED(bus);
-        emit m_helper->message(message);
+        QGstreamerMessage msg(message);
+        foreach (QGstreamerBusMessageFilter *filter, busFilters) {
+            if (filter->processBusMessage(msg))
+                break;
+        }
+        emit m_helper->message(msg);
     }
 
     static gboolean busCallback(GstBus *bus, GstMessage *message, gpointer data)
@@ -89,8 +94,9 @@ private:
 
 public:
     GstBus* bus;
-    QGstreamerSyncEventFilter *filter;
     QMutex filterMutex;
+    QList<QGstreamerSyncMessageFilter*> syncFilters;
+    QList<QGstreamerBusMessageFilter*> busFilters;
 };
 
 #else
@@ -131,7 +137,13 @@ private slots:
             GstMessage* message;
 
             while ((message = gst_bus_poll(it.value(), GST_MESSAGE_ANY, 0)) != 0) {
-                emit it.key()->message(message);
+                QGstreamerMessage msg(message);
+                foreach (QGstreamerBusMessageFilter *filter, busFilters) {
+                    if (filter->processBusMessage(msg))
+                        break;
+                }
+                emit it.key()->message(msg);
+
                 gst_message_unref(message);
             }
 
@@ -153,8 +165,9 @@ private:
 
 public:
     GstBus* bus;
-    QGstreamerSyncEventFilter *filter;
     QMutex filterMutex;
+    QList<QGstreamerSyncMessageFilter*> syncFilters;
+    QList<QGstreamerBusMessageFilter*> busFilters;
 };
 #endif
 
@@ -164,12 +177,12 @@ static GstBusSyncReply syncGstBusFilter(GstBus* bus, GstMessage* message, QGstre
     Q_UNUSED(bus);
     QMutexLocker lock(&d->filterMutex);
 
-    bool res = false;
-
-    if (d->filter)
-        res = d->filter->processSyncMessage(QGstreamerMessage(message));
+    foreach (QGstreamerSyncMessageFilter *filter, d->syncFilters) {
+        if (filter->processSyncMessage(QGstreamerMessage(message)))
+            return GST_BUS_DROP;
+    }
 
-    return res ? GST_BUS_DROP : GST_BUS_PASS;
+    return GST_BUS_PASS;
 }
 
 
@@ -194,10 +207,31 @@ QGstreamerBusHelper::~QGstreamerBusHelper()
     gst_bus_set_sync_handler(d->bus,0,0);
 }
 
-void QGstreamerBusHelper::installSyncEventFilter(QGstreamerSyncEventFilter *filter)
+void QGstreamerBusHelper::installMessageFilter(QObject *filter)
 {
-    QMutexLocker lock(&d->filterMutex);
-    d->filter = filter;
+    QGstreamerSyncMessageFilter *syncFilter = qobject_cast<QGstreamerSyncMessageFilter*>(filter);
+    if (syncFilter) {
+        QMutexLocker lock(&d->filterMutex);
+        if (!d->syncFilters.contains(syncFilter))
+            d->syncFilters.append(syncFilter);
+    }
+
+    QGstreamerBusMessageFilter *busFilter = qobject_cast<QGstreamerBusMessageFilter*>(filter);
+    if (busFilter && !d->busFilters.contains(busFilter))
+        d->busFilters.append(busFilter);
+}
+
+void QGstreamerBusHelper::removeMessageFilter(QObject *filter)
+{
+    QGstreamerSyncMessageFilter *syncFilter = qobject_cast<QGstreamerSyncMessageFilter*>(filter);
+    if (syncFilter) {
+        QMutexLocker lock(&d->filterMutex);
+        d->syncFilters.removeAll(syncFilter);
+    }
+
+    QGstreamerBusMessageFilter *busFilter = qobject_cast<QGstreamerBusMessageFilter*>(filter);
+    if (busFilter)
+        d->busFilters.removeAll(busFilter);
 }
 
 #include "qgstreamerbushelper.moc"
index cfe6a6b1c12e51fb28e3eb96c7aa3de9b388b2c7..d09192a4241a23ed55f96d463c711c7adc8239ec 100644 (file)
 #include <qgstreamermessage.h>
 #include <gst/gst.h>
 
-class QGstreamerSyncEventFilter {
+class QGstreamerSyncMessageFilter {
 public:
     //returns true if message was processed and should be dropped, false otherwise
     virtual bool processSyncMessage(const QGstreamerMessage &message) = 0;
 };
+#define QGstreamerSyncMessageFilter_iid "com.nokia.Qt.QGstreamerSyncMessageFilter/1.0"
+Q_DECLARE_INTERFACE(QGstreamerSyncMessageFilter, QGstreamerSyncMessageFilter_iid)
+
+
+class QGstreamerBusMessageFilter {
+public:
+    //returns true if message was processed and should be dropped, false otherwise
+    virtual bool processBusMessage(const QGstreamerMessage &message) = 0;
+};
+#define QGstreamerBusMessageFilter_iid "com.nokia.Qt.QGstreamerBusMessageFilter/1.0"
+Q_DECLARE_INTERFACE(QGstreamerBusMessageFilter, QGstreamerBusMessageFilter_iid)
+
 
 class QGstreamerBusHelperPrivate;
 
@@ -64,12 +76,12 @@ public:
     QGstreamerBusHelper(GstBus* bus, QObject* parent = 0);
     ~QGstreamerBusHelper();
 
-    void installSyncEventFilter(QGstreamerSyncEventFilter *filter);
+    void installMessageFilter(QObject *filter);
+    void removeMessageFilter(QObject *filter);
 
 signals:
     void message(QGstreamerMessage const& message);
 
-
 private:
     QGstreamerBusHelperPrivate*   d;
 };
index 2f5919f83c8453cefcbb534a2c8bdba1b632080d..af68096bd6ec8be63f72c078dc84f924fc75695c 100644 (file)
@@ -364,13 +364,16 @@ bool QGstreamerGLTextureRenderer::isReady() const
     return m_surface->supportedPixelFormats(EGLImageTextureHandle).isEmpty();
 }
 
-void QGstreamerGLTextureRenderer::handleBusMessage(GstMessage* gm)
+bool QGstreamerGLTextureRenderer::processBusMessage(const QGstreamerMessage &message)
 {
+    GstMessage* gm = message.rawMessage();
+
 #ifdef GL_TEXTURE_SINK_DEBUG
     qDebug() << Q_FUNC_INFO << GST_MESSAGE_TYPE_NAME(gm);
 #endif
 
-    if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED) {
+    if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED &&
+            GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSink)) {
         GstState oldState;
         GstState newState;
         gst_message_parse_state_changed(gm, &oldState, &newState, 0);
@@ -387,22 +390,20 @@ void QGstreamerGLTextureRenderer::handleBusMessage(GstMessage* gm)
             updateNativeVideoSize();
         }
     }
+
+    return false;
 }
 
-void QGstreamerGLTextureRenderer::handleSyncMessage(GstMessage* gm)
+bool QGstreamerGLTextureRenderer::processSyncMessage(const QGstreamerMessage &message)
 {
+    GstMessage* gm = message.rawMessage();
+
+    if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
+            gst_structure_has_name(gm->structure, "prepare-xwindow-id") &&
+            m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
 #ifdef GL_TEXTURE_SINK_DEBUG
     qDebug() << Q_FUNC_INFO;
 #endif
-
-    if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT &&
-            gst_structure_has_name(gm->structure, "prepare-xwindow-id"))
-        precessNewStream();
-}
-
-void QGstreamerGLTextureRenderer::precessNewStream()
-{
-    if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
         GstXOverlay *overlay = GST_X_OVERLAY(m_videoSink);
 
         gst_x_overlay_set_xwindow_id(overlay, m_winId);
@@ -417,7 +418,11 @@ void QGstreamerGLTextureRenderer::precessNewStream()
 
         GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
         m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this);
+
+        return true;
     }
+
+    return false;
 }
 
 void QGstreamerGLTextureRenderer::stopRenderer()
index 330fb463011719d616bc5779635b3618135c89b2..7a1bc65dfe0908a0cc882f34c3c6fa63a738f309 100644 (file)
@@ -44,6 +44,7 @@
 
 #include <qvideorenderercontrol.h>
 #include "qvideosurfacegstsink.h"
+#include "qgstreamerbushelper.h"
 
 #include "qgstreamervideorendererinterface.h"
 #include <QtGui/qcolor.h>
@@ -54,10 +55,13 @@ QT_USE_NAMESPACE
 
 class QGLContext;
 
-class QGstreamerGLTextureRenderer : public QVideoRendererControl, public QGstreamerVideoRendererInterface
+class QGstreamerGLTextureRenderer : public QVideoRendererControl,
+        public QGstreamerVideoRendererInterface,
+        public QGstreamerSyncMessageFilter,
+        public QGstreamerBusMessageFilter
 {
     Q_OBJECT
-    Q_INTERFACES(QGstreamerVideoRendererInterface)
+    Q_INTERFACES(QGstreamerVideoRendererInterface QGstreamerSyncMessageFilter QGstreamerBusMessageFilter)
 
     Q_PROPERTY(bool overlayEnabled READ overlayEnabled WRITE setOverlayEnabled)
     Q_PROPERTY(qulonglong winId READ winId WRITE setWinId)
@@ -75,9 +79,8 @@ public:
     GstElement *videoSink();
 
     bool isReady() const;
-    void handleBusMessage(GstMessage* gm);
-    void handleSyncMessage(GstMessage* gm);
-    void precessNewStream();
+    bool processBusMessage(const QGstreamerMessage &message);
+    bool processSyncMessage(const QGstreamerMessage &message);
     void stopRenderer();
 
     int framebufferNumber() const;
index 298ad944821a0e81fd06a354ff072b254dfdb36b..4fb8dda3566db8a35bfc1bb546aa94bde74d8e4e 100644 (file)
@@ -61,7 +61,6 @@ public:
     void setSurface(QAbstractVideoSurface *surface);
 
     GstElement *videoSink();
-    void precessNewStream() {}
 
     bool isReady() const { return m_surface != 0; }
 
index 600f0dfe588ac4bb6fa9828af4bdfa43ebb5da43..da5107e07ae53e7c86fdbc198ed03cdacadf4b3b 100644 (file)
@@ -51,7 +51,6 @@ class QGstreamerVideoRendererInterface
 public:
     virtual ~QGstreamerVideoRendererInterface();
     virtual GstElement *videoSink() = 0;
-    virtual void precessNewStream() {}
 
     //stopRenderer() is called when the renderer element is stopped.
     //it can be reimplemented when video renderer can't detect
@@ -62,10 +61,6 @@ public:
     //(winId is known,
     virtual bool isReady() const { return true; }
 
-    //video renderer may handle video sink specific gstreamer messages.
-    virtual void handleBusMessage(GstMessage*) {};
-    virtual void handleSyncMessage(GstMessage*) {};
-
     //signals:
     //void sinkChanged();
     //void readyChanged(bool);
index 2f92e990a66b09025c5e724cd85d7f46c0447e7b..e1bf0037d09281c67e03f7e3b93a8ae7b7f557aa 100644 (file)
@@ -179,10 +179,36 @@ bool QGstreamerVideoWidgetControl::eventFilter(QObject *object, QEvent *e)
     return false;
 }
 
-void QGstreamerVideoWidgetControl::precessNewStream()
+bool QGstreamerVideoWidgetControl::processSyncMessage(const QGstreamerMessage &message)
 {
-    setOverlay();
-    QMetaObject::invokeMethod(this, "updateNativeVideoSize", Qt::QueuedConnection);
+    GstMessage* gm = message.rawMessage();
+
+    if (gm && (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
+            gst_structure_has_name(gm->structure, "prepare-xwindow-id")) {
+
+        setOverlay();
+        QMetaObject::invokeMethod(this, "updateNativeVideoSize", Qt::QueuedConnection);
+        return true;
+    }
+
+    return false;
+}
+
+bool QGstreamerVideoWidgetControl::processBusMessage(const QGstreamerMessage &message)
+{
+    GstMessage* gm = message.rawMessage();
+
+    if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED &&
+            GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSink)) {
+        GstState oldState;
+        GstState newState;
+        gst_message_parse_state_changed(gm, &oldState, &newState, 0);
+
+        if (oldState == GST_STATE_READY && newState == GST_STATE_PAUSED)
+            updateNativeVideoSize();
+    }
+
+    return false;
 }
 
 void QGstreamerVideoWidgetControl::setOverlay()
index 0f0adea0d0a9eb0d8e5bf9ebe098c238db97dbf2..8f3d62316259b6df6012579b99361d74b583f708 100644 (file)
@@ -45,6 +45,7 @@
 #include <qvideowidgetcontrol.h>
 
 #include "qgstreamervideorendererinterface.h"
+#include "qgstreamerbushelper.h"
 
 QT_USE_NAMESPACE
 
@@ -53,15 +54,16 @@ class QGstreamerVideoWidget;
 class QGstreamerVideoWidgetControl
         : public QVideoWidgetControl
         , public QGstreamerVideoRendererInterface
+        , public QGstreamerSyncMessageFilter
+        , public QGstreamerBusMessageFilter
 {
     Q_OBJECT
-    Q_INTERFACES(QGstreamerVideoRendererInterface)
+    Q_INTERFACES(QGstreamerVideoRendererInterface QGstreamerSyncMessageFilter QGstreamerBusMessageFilter)
 public:
     QGstreamerVideoWidgetControl(QObject *parent = 0);
     virtual ~QGstreamerVideoWidgetControl();
 
     GstElement *videoSink();
-    void precessNewStream();
 
     QWidget *videoWidget();
 
@@ -86,6 +88,8 @@ public:
     void setOverlay();
 
     bool eventFilter(QObject *object, QEvent *event);
+    bool processSyncMessage(const QGstreamerMessage &message);
+    bool processBusMessage(const QGstreamerMessage &message);
 
 public slots:
     void updateNativeVideoSize();
index 0f92d76a91ff343a7e76fe0e46b3bbfd82e29f49..d8d822269c3ff8474359017972a1e8d9034ee87d 100644 (file)
@@ -115,14 +115,23 @@ void QGstreamerVideoWindow::setWinId(WId id)
         emit readyChanged(false);
 }
 
-void QGstreamerVideoWindow::precessNewStream()
+bool QGstreamerVideoWindow::processSyncMessage(const QGstreamerMessage &message)
 {
-    if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
+    GstMessage* gm = message.rawMessage();
+
+    if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
+            gst_structure_has_name(gm->structure, "prepare-xwindow-id") &&
+            m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
+
         gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId);
 
         GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
         m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this);
+
+        return true;
     }
+
+    return false;
 }
 
 QRect QGstreamerVideoWindow::displayRect() const
index acc22cdcae88f2aecd628419d8889810eda583a7..3a483e2c151413d7281cc86c6cbe223b7974e94b 100644 (file)
@@ -45,6 +45,7 @@
 #include <qvideowindowcontrol.h>
 
 #include "qgstreamervideorendererinterface.h"
+#include "qgstreamerbushelper.h"
 
 QT_BEGIN_NAMESPACE
 class QAbstractVideoSurface;
@@ -55,10 +56,12 @@ class QX11VideoSurface;
 
 QT_USE_NAMESPACE
 
-class QGstreamerVideoWindow : public QVideoWindowControl, public QGstreamerVideoRendererInterface
+class QGstreamerVideoWindow : public QVideoWindowControl,
+        public QGstreamerVideoRendererInterface,
+        public QGstreamerSyncMessageFilter
 {
     Q_OBJECT
-    Q_INTERFACES(QGstreamerVideoRendererInterface)
+    Q_INTERFACES(QGstreamerVideoRendererInterface QGstreamerSyncMessageFilter)
     Q_PROPERTY(QColor colorKey READ colorKey WRITE setColorKey)
     Q_PROPERTY(bool autopaintColorKey READ autopaintColorKey WRITE setAutopaintColorKey)
 public:
@@ -103,7 +106,7 @@ public:
 
     GstElement *videoSink();
 
-    void precessNewStream();
+    bool processSyncMessage(const QGstreamerMessage &message);
     bool isReady() const { return m_windowId != 0; }
 
 signals: