Add a partial gstreamer based audio decoder service.
authorMichael Goddard <michael.goddard@nokia.com>
Tue, 14 Feb 2012 06:14:08 +0000 (16:14 +1000)
committerQt by Nokia <qt-info@nokia.com>
Fri, 17 Feb 2012 06:27:47 +0000 (07:27 +0100)
Doesn't work yet.

Change-Id: Iebd085d68346cb73af8df59c84e8e52a17de2a52
Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
12 files changed:
src/plugins/gstreamer/audiodecoder/audiodecoder.pri [new file with mode: 0644]
src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodercontrol.cpp [new file with mode: 0644]
src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodercontrol.h [new file with mode: 0644]
src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderservice.cpp [new file with mode: 0644]
src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderservice.h [new file with mode: 0644]
src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp [new file with mode: 0644]
src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.h [new file with mode: 0644]
src/plugins/gstreamer/gstreamer.pro
src/plugins/gstreamer/mediaplayer/mediaplayer.pri
src/plugins/gstreamer/qgstappsrc.cpp [moved from src/plugins/gstreamer/mediaplayer/qgstappsrc.cpp with 100% similarity]
src/plugins/gstreamer/qgstappsrc.h [moved from src/plugins/gstreamer/mediaplayer/qgstappsrc.h with 100% similarity]
src/plugins/gstreamer/qgstreamerserviceplugin.cpp

diff --git a/src/plugins/gstreamer/audiodecoder/audiodecoder.pri b/src/plugins/gstreamer/audiodecoder/audiodecoder.pri
new file mode 100644 (file)
index 0000000..d2711e0
--- /dev/null
@@ -0,0 +1,15 @@
+INCLUDEPATH += $$PWD
+
+DEFINES += QMEDIA_GSTREAMER_AUDIO_DECODER
+
+HEADERS += \
+    $$PWD/qgstreameraudiodecodercontrol.h \
+    $$PWD/qgstreameraudiodecoderservice.h \
+    $$PWD/qgstreameraudiodecodersession.h
+
+SOURCES += \
+    $$PWD/qgstreameraudiodecodercontrol.cpp \
+    $$PWD/qgstreameraudiodecoderservice.cpp \
+    $$PWD/qgstreameraudiodecodersession.cpp
+
+
diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodercontrol.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodercontrol.cpp
new file mode 100644 (file)
index 0000000..db1b716
--- /dev/null
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgstreameraudiodecodercontrol.h"
+#include "qgstreameraudiodecodersession.h"
+
+#include <QtCore/qdir.h>
+#include <QtCore/qsocketnotifier.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qdebug.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+QT_BEGIN_NAMESPACE
+
+QGstreamerAudioDecoderControl::QGstreamerAudioDecoderControl(QGstreamerAudioDecoderSession *session, QObject *parent)
+    : QAudioDecoderControl(parent)
+    , m_session(session)
+{
+    connect(m_session, SIGNAL(bufferAvailableChanged(bool)), this, SIGNAL(bufferAvailableChanged(bool)));
+    connect(m_session, SIGNAL(bufferReady()), this, SIGNAL(bufferReady()));
+    connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString)));
+    connect(m_session, SIGNAL(formatChanged(QAudioFormat)), this, SIGNAL(formatChanged(QAudioFormat)));
+    connect(m_session, SIGNAL(stateChanged(QAudioDecoder::State)), this, SIGNAL(stateChanged(QAudioDecoder::State)));
+}
+
+QGstreamerAudioDecoderControl::~QGstreamerAudioDecoderControl()
+{
+
+}
+
+QAudioDecoder::State QGstreamerAudioDecoderControl::state() const
+{
+    return m_session->state();
+}
+
+QString QGstreamerAudioDecoderControl::sourceFilename() const
+{
+    return m_session->sourceFilename();
+}
+
+void QGstreamerAudioDecoderControl::setSourceFilename(const QString &fileName)
+{
+    m_session->setSourceFilename(fileName);
+}
+
+QIODevice* QGstreamerAudioDecoderControl::sourceDevice() const
+{
+    return m_session->sourceDevice();
+}
+
+void QGstreamerAudioDecoderControl::setSourceDevice(QIODevice *device)
+{
+    m_session->setSourceDevice(device);
+}
+
+void QGstreamerAudioDecoderControl::start()
+{
+    m_session->start();
+}
+
+void QGstreamerAudioDecoderControl::stop()
+{
+    m_session->stop();
+}
+
+QAudioFormat QGstreamerAudioDecoderControl::audioFormat() const
+{
+    return m_session->audioFormat();
+}
+
+void QGstreamerAudioDecoderControl::setAudioFormat(const QAudioFormat &format)
+{
+    m_session->setAudioFormat(format);
+}
+
+QAudioBuffer QGstreamerAudioDecoderControl::read(bool *ok)
+{
+    return m_session->read(ok);
+}
+
+bool QGstreamerAudioDecoderControl::bufferAvailable() const
+{
+    return m_session->bufferAvailable();
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodercontrol.h b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodercontrol.h
new file mode 100644 (file)
index 0000000..40699b6
--- /dev/null
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGSTREAMERPLAYERCONTROL_H
+#define QGSTREAMERPLAYERCONTROL_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstack.h>
+
+#include <qaudioformat.h>
+#include <qaudiobuffer.h>
+#include <private/qaudiodecoder_p.h>
+#include <private/qaudiodecodercontrol_p.h>
+
+#include <limits.h>
+
+
+QT_BEGIN_NAMESPACE
+
+class QGstreamerAudioDecoderSession;
+class QGstreamerAudioDecoderService;
+
+class QGstreamerAudioDecoderControl : public QAudioDecoderControl
+{
+    Q_OBJECT
+
+public:
+    QGstreamerAudioDecoderControl(QGstreamerAudioDecoderSession *session, QObject *parent = 0);
+    ~QGstreamerAudioDecoderControl();
+
+    QAudioDecoder::State state() const;
+
+    QString sourceFilename() const;
+    void setSourceFilename(const QString &fileName);
+
+    QIODevice* sourceDevice() const;
+    void setSourceDevice(QIODevice *device);
+
+    void start();
+    void stop();
+
+    QAudioFormat audioFormat() const;
+    void setAudioFormat(const QAudioFormat &format);
+
+    QAudioBuffer read(bool *ok);
+    bool bufferAvailable() const;
+
+private:
+    // Stuff goes here
+
+    QGstreamerAudioDecoderSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderservice.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderservice.cpp
new file mode 100644 (file)
index 0000000..afe0dff
--- /dev/null
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qvariant.h>
+#include <QtCore/qdebug.h>
+
+#include "qgstreameraudiodecoderservice.h"
+#include "qgstreameraudiodecodercontrol.h"
+#include "qgstreameraudiodecodersession.h"
+
+QT_BEGIN_NAMESPACE
+
+QGstreamerAudioDecoderService::QGstreamerAudioDecoderService(QObject *parent)
+    : QMediaService(parent)
+{
+    m_session = new QGstreamerAudioDecoderSession(this);
+    m_control = new QGstreamerAudioDecoderControl(m_session, this);
+}
+
+QGstreamerAudioDecoderService::~QGstreamerAudioDecoderService()
+{
+}
+
+QMediaControl *QGstreamerAudioDecoderService::requestControl(const char *name)
+{
+    if (qstrcmp(name, QAudioDecoderControl_iid) == 0)
+        return m_control;
+
+    return 0;
+}
+
+void QGstreamerAudioDecoderService::releaseControl(QMediaControl *control)
+{
+    Q_UNUSED(control);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderservice.h b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderservice.h
new file mode 100644 (file)
index 0000000..ebc2443
--- /dev/null
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGSTREAMERAUDIODECODERSERVICE_H
+#define QGSTREAMERAUDIODECODERSERVICE_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qiodevice.h>
+
+#include <qmediaservice.h>
+
+QT_BEGIN_NAMESPACE
+class QGstreamerAudioDecoderControl;
+class QGstreamerAudioDecoderSession;
+
+class QGstreamerAudioDecoderService : public QMediaService
+{
+    Q_OBJECT
+public:
+    QGstreamerAudioDecoderService(QObject *parent = 0);
+    ~QGstreamerAudioDecoderService();
+
+    QMediaControl *requestControl(const char *name);
+    void releaseControl(QMediaControl *control);
+
+private:
+    QGstreamerAudioDecoderControl *m_control;
+    QGstreamerAudioDecoderSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp
new file mode 100644 (file)
index 0000000..4afee23
--- /dev/null
@@ -0,0 +1,380 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgstreameraudiodecodersession.h"
+#include <private/qgstreamerbushelper_p.h>
+
+#include <private/qgstutils_p.h>
+
+#include <gst/gstvalue.h>
+#include <gst/base/gstbasesrc.h>
+
+#include <QtCore/qdatetime.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qstandardpaths.h>
+
+QT_BEGIN_NAMESPACE
+
+QGstreamerAudioDecoderSession::QGstreamerAudioDecoderSession(QObject *parent)
+    : QObject(parent),
+     m_state(QAudioDecoder::StoppedState),
+     m_pendingState(QAudioDecoder::StoppedState),
+     m_busHelper(0),
+     m_bus(0),
+     m_playbin(0),
+#if defined(HAVE_GST_APPSRC)
+     m_appSrc(0),
+#endif
+     mDevice(0)
+{
+    // Default format
+    mFormat.setChannels(2);
+    mFormat.setSampleSize(16);
+    mFormat.setFrequency(48000);
+    mFormat.setCodec("audio/x-raw");
+    mFormat.setSampleType(QAudioFormat::UnSignedInt);
+
+
+    // Create pipeline here
+#if 0
+    if (m_playbin != 0) {
+        // Sort out messages
+        m_bus = gst_element_get_bus(m_playbin);
+        m_busHelper = new QGstreamerBusHelper(m_bus, this);
+        m_busHelper->installMessageFilter(this);
+    }
+#endif
+}
+
+QGstreamerAudioDecoderSession::~QGstreamerAudioDecoderSession()
+{
+    if (m_playbin) {
+        stop();
+
+        delete m_busHelper;
+        gst_object_unref(GST_OBJECT(m_bus));
+        gst_object_unref(GST_OBJECT(m_playbin));
+    }
+}
+
+#if defined(HAVE_GST_APPSRC)
+void QGstreamerAudioDecoderSession::configureAppSrcElement(GObject* object, GObject *orig, GParamSpec *pspec, QGstreamerAudioDecoderSession* self)
+{
+    Q_UNUSED(object);
+    Q_UNUSED(pspec);
+
+    if (self->appsrc()->isReady())
+        return;
+
+    GstElement *appsrc;
+    g_object_get(orig, "source", &appsrc, NULL);
+
+    if (!self->appsrc()->setup(appsrc))
+        qWarning()<<"Could not setup appsrc element";
+}
+#endif
+
+#if 0
+void QGstreamerAudioDecoderSession::loadFromStream(const QNetworkRequest &request, QIODevice *appSrcStream)
+{
+#if defined(HAVE_GST_APPSRC)
+#ifdef DEBUG_PLAYBIN
+    qDebug() << Q_FUNC_INFO;
+#endif
+    m_request = request;
+    m_duration = -1;
+    m_lastPosition = 0;
+    m_haveQueueElement = false;
+
+    if (m_appSrc)
+        m_appSrc->deleteLater();
+    m_appSrc = new QGstAppSrc(this);
+    m_appSrc->setStream(appSrcStream);
+
+    if (m_playbin) {
+        m_tags.clear();
+        emit tagsChanged();
+
+        g_signal_connect(G_OBJECT(m_playbin), "deep-notify::source", (GCallback) &QGstreamerAudioDecoderSession::configureAppSrcElement, (gpointer)this);
+        g_object_set(G_OBJECT(m_playbin), "uri", "appsrc://", NULL);
+
+        if (!m_streamTypes.isEmpty()) {
+            m_streamProperties.clear();
+            m_streamTypes.clear();
+
+            emit streamsChanged();
+        }
+    }
+#endif
+}
+
+void QGstreamerAudioDecoderSession::loadFromUri(const QNetworkRequest &request)
+{
+#ifdef DEBUG_PLAYBIN
+    qDebug() << Q_FUNC_INFO << request.url();
+#endif
+    m_request = request;
+    m_duration = -1;
+    m_lastPosition = 0;
+    m_haveQueueElement = false;
+
+    if (m_playbin) {
+        m_tags.clear();
+        emit tagsChanged();
+
+        g_object_set(G_OBJECT(m_playbin), "uri", m_request.url().toEncoded().constData(), NULL);
+
+        if (!m_streamTypes.isEmpty()) {
+            m_streamProperties.clear();
+            m_streamTypes.clear();
+
+            emit streamsChanged();
+        }
+    }
+}
+#endif
+
+bool QGstreamerAudioDecoderSession::processBusMessage(const QGstreamerMessage &message)
+{
+    GstMessage* gm = message.rawMessage();
+    if (gm) {
+        if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_playbin)) {
+            switch (GST_MESSAGE_TYPE(gm))  {
+            case GST_MESSAGE_STATE_CHANGED:
+                {
+                    GstState    oldState;
+                    GstState    newState;
+                    GstState    pending;
+
+                    gst_message_parse_state_changed(gm, &oldState, &newState, &pending);
+
+#ifdef DEBUG_PLAYBIN
+                    QStringList states;
+                    states << "GST_STATE_VOID_PENDING" <<  "GST_STATE_NULL" << "GST_STATE_READY" << "GST_STATE_PAUSED" << "GST_STATE_PLAYING";
+
+                    qDebug() << QString("state changed: old: %1  new: %2  pending: %3") \
+                            .arg(states[oldState]) \
+                            .arg(states[newState]) \
+                            .arg(states[pending]);
+#endif
+
+                    switch (newState) {
+                    case GST_STATE_VOID_PENDING:
+                    case GST_STATE_NULL:
+                        if (m_state != QAudioDecoder::StoppedState)
+                            emit stateChanged(m_state = QAudioDecoder::StoppedState);
+                        break;
+                    case GST_STATE_READY:
+                        if (m_state != QAudioDecoder::StoppedState)
+                            emit stateChanged(m_state = QAudioDecoder::StoppedState);
+                        break;
+                    case GST_STATE_PLAYING:
+                        if (m_state != QAudioDecoder::DecodingState)
+                            emit stateChanged(m_state = QAudioDecoder::DecodingState);
+
+                        break;
+                    case GST_STATE_PAUSED:
+                        if (m_state != QAudioDecoder::WaitingState)
+                            emit stateChanged(m_state = QAudioDecoder::WaitingState);
+                        break;
+                    }
+                }
+                break;
+
+            case GST_MESSAGE_EOS:
+                emit stateChanged(m_state = QAudioDecoder::StoppedState);
+                break;
+
+            case GST_MESSAGE_TAG:
+            case GST_MESSAGE_STREAM_STATUS:
+            case GST_MESSAGE_UNKNOWN:
+                break;
+            case GST_MESSAGE_ERROR: {
+                    GError *err;
+                    gchar *debug;
+                    gst_message_parse_error(gm, &err, &debug);
+                    if (err->domain == GST_STREAM_ERROR && err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND)
+                        processInvalidMedia(QAudioDecoder::FormatError, tr("Cannot play stream of type: <unknown>"));
+                    else
+                        processInvalidMedia(QAudioDecoder::ResourceError, QString::fromUtf8(err->message));
+                    qWarning() << "Error:" << QString::fromUtf8(err->message);
+                    g_error_free(err);
+                    g_free(debug);
+                }
+                break;
+            case GST_MESSAGE_WARNING:
+                {
+                    GError *err;
+                    gchar *debug;
+                    gst_message_parse_warning (gm, &err, &debug);
+                    qWarning() << "Warning:" << QString::fromUtf8(err->message);
+                    g_error_free (err);
+                    g_free (debug);
+                }
+                break;
+            case GST_MESSAGE_INFO:
+#ifdef DEBUG_PLAYBIN
+                {
+                    GError *err;
+                    gchar *debug;
+                    gst_message_parse_info (gm, &err, &debug);
+                    qDebug() << "Info:" << QString::fromUtf8(err->message);
+                    g_error_free (err);
+                    g_free (debug);
+                }
+#endif
+                break;
+            case GST_MESSAGE_BUFFERING:
+            case GST_MESSAGE_STATE_DIRTY:
+            case GST_MESSAGE_STEP_DONE:
+            case GST_MESSAGE_CLOCK_PROVIDE:
+            case GST_MESSAGE_CLOCK_LOST:
+            case GST_MESSAGE_NEW_CLOCK:
+            case GST_MESSAGE_STRUCTURE_CHANGE:
+            case GST_MESSAGE_APPLICATION:
+            case GST_MESSAGE_ELEMENT:
+                break;
+            case GST_MESSAGE_SEGMENT_START:
+            case GST_MESSAGE_SEGMENT_DONE:
+                break;
+            case GST_MESSAGE_LATENCY:
+#if (GST_VERSION_MAJOR >= 0) &&  (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 13)
+            case GST_MESSAGE_ASYNC_START:
+            case GST_MESSAGE_ASYNC_DONE:
+#if GST_VERSION_MICRO >= 23
+            case GST_MESSAGE_REQUEST_STATE:
+#endif
+#endif
+            case GST_MESSAGE_ANY:
+                break;
+            default:
+                break;
+            }
+        } else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ERROR) {
+            GError *err;
+            gchar *debug;
+            gst_message_parse_error(gm, &err, &debug);
+            // If the source has given up, so do we.
+            if (qstrcmp(GST_OBJECT_NAME(GST_MESSAGE_SRC(gm)), "source") == 0) {
+                processInvalidMedia(QAudioDecoder::ResourceError, QString::fromUtf8(err->message));
+            } else if (err->domain == GST_STREAM_ERROR
+                       && (err->code == GST_STREAM_ERROR_DECRYPT || err->code == GST_STREAM_ERROR_DECRYPT_NOKEY)) {
+                processInvalidMedia(QAudioDecoder::AccessDeniedError, QString::fromUtf8(err->message));
+            }
+            g_error_free(err);
+            g_free(debug);
+        }
+    }
+
+    return false;
+}
+
+QString QGstreamerAudioDecoderSession::sourceFilename() const
+{
+    return mSource;
+}
+
+void QGstreamerAudioDecoderSession::setSourceFilename(const QString &fileName)
+{
+    stop();
+    mDevice = 0;
+    mSource = fileName;
+}
+
+QIODevice *QGstreamerAudioDecoderSession::sourceDevice() const
+{
+    return mDevice;
+}
+
+void QGstreamerAudioDecoderSession::setSourceDevice(QIODevice *device)
+{
+    stop();
+    mSource.clear();
+    mDevice = device;
+}
+
+void QGstreamerAudioDecoderSession::start()
+{
+    // TODO
+}
+
+void QGstreamerAudioDecoderSession::stop()
+{
+    // TODO
+}
+
+QAudioFormat QGstreamerAudioDecoderSession::audioFormat() const
+{
+    return mFormat;
+}
+
+void QGstreamerAudioDecoderSession::setAudioFormat(const QAudioFormat &format)
+{
+    if (mFormat != format) {
+        mFormat = format;
+        emit formatChanged(mFormat);
+    }
+}
+
+QAudioBuffer QGstreamerAudioDecoderSession::read(bool *ok)
+{
+    // TODO
+    if (ok)
+        *ok = false;
+    return QAudioBuffer();
+}
+
+bool QGstreamerAudioDecoderSession::bufferAvailable() const
+{
+    return false;
+}
+
+void QGstreamerAudioDecoderSession::processInvalidMedia(QAudioDecoder::Error errorCode, const QString& errorString)
+{
+    stop();
+    emit error(int(errorCode), errorString);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.h b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.h
new file mode 100644 (file)
index 0000000..b6ac751
--- /dev/null
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGSTREAMERPLAYERSESSION_H
+#define QGSTREAMERPLAYERSESSION_H
+
+#include <QObject>
+#include "qgstreameraudiodecodercontrol.h"
+#include <private/qgstreamerbushelper_p.h>
+#include <private/qaudiodecoder_p.h>
+
+#if defined(HAVE_GST_APPSRC)
+#include "qgstappsrc.h"
+#endif
+
+#include <gst/gst.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGstreamerBusHelper;
+class QGstreamerMessage;
+
+class QGstreamerAudioDecoderSession : public QObject,
+                                public QGstreamerBusMessageFilter
+{
+Q_OBJECT
+Q_INTERFACES(QGstreamerBusMessageFilter)
+
+public:
+    QGstreamerAudioDecoderSession(QObject *parent);
+    virtual ~QGstreamerAudioDecoderSession();
+
+    QGstreamerBusHelper *bus() const { return m_busHelper; }
+
+    QAudioDecoder::State state() const { return m_state; }
+    QAudioDecoder::State pendingState() const { return m_pendingState; }
+
+    bool processBusMessage(const QGstreamerMessage &message);
+
+#if defined(HAVE_GST_APPSRC)
+    QGstAppSrc *appsrc() const { return m_appSrc; }
+    static void configureAppSrcElement(GObject*, GObject*, GParamSpec*,QGstreamerAudioDecoderSession* _this);
+#endif
+
+    QString sourceFilename() const;
+    void setSourceFilename(const QString &fileName);
+
+    QIODevice* sourceDevice() const;
+    void setSourceDevice(QIODevice *device);
+
+    void start();
+    void stop();
+
+    QAudioFormat audioFormat() const;
+    void setAudioFormat(const QAudioFormat &format);
+
+    QAudioBuffer read(bool *ok);
+    bool bufferAvailable() const;
+
+signals:
+    void stateChanged(QAudioDecoder::State newState);
+    void formatChanged(const QAudioFormat &format);
+
+    void error(int error, const QString &errorString);
+
+    void bufferReady();
+    void bufferAvailableChanged(bool available);
+
+private:
+
+    void processInvalidMedia(QAudioDecoder::Error errorCode, const QString& errorString);
+
+    QAudioDecoder::State m_state;
+    QAudioDecoder::State m_pendingState;
+    QGstreamerBusHelper* m_busHelper;
+    GstBus* m_bus;
+    GstElement* m_playbin;
+
+#if defined(HAVE_GST_APPSRC)
+    QGstAppSrc *m_appSrc;
+#endif
+
+    QString mSource;
+    QIODevice *mDevice; // QWeakPointer perhaps
+    QAudioFormat mFormat;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGSTREAMERPLAYERSESSION_H
index 14d40fd..77f7da9 100644 (file)
@@ -33,7 +33,6 @@ PKGCONFIG += \
     gstreamer-pbutils-0.10
 
 maemo*:PKGCONFIG +=gstreamer-plugins-bad-0.10
-contains(config_test_gstreamer_appsrc, yes): PKGCONFIG += gstreamer-app-0.10
 
 contains(config_test_resourcepolicy, yes) {
     DEFINES += HAVE_RESOURCE_POLICY
@@ -97,6 +96,18 @@ contains(config_test_xvideo, yes):!isEmpty(QT.widgets.name): {
 }
 include(mediaplayer/mediaplayer.pri)
 include(mediacapture/mediacapture.pri)
+include(audiodecoder/audiodecoder.pri)
+
+contains(config_test_gstreamer_appsrc, yes) {
+    PKGCONFIG += gstreamer-app-0.10
+    HEADERS += $$PWD/qgstappsrc.h
+    SOURCES += $$PWD/qgstappsrc.cpp
+
+    DEFINES += HAVE_GST_APPSRC
+
+    LIBS += -lgstapp-0.10
+}
+
 
 #Camerabin2 based camera backend is untested and currently disabled
 #contains(config_test_gstreamer_photography, yes) {
index 310ed6f..92cd790 100644 (file)
@@ -2,15 +2,6 @@ INCLUDEPATH += $$PWD
 
 DEFINES += QMEDIA_GSTREAMER_PLAYER
 
-contains(config_test_gstreamer_appsrc, yes) {
-    HEADERS += $$PWD/qgstappsrc.h
-    SOURCES += $$PWD/qgstappsrc.cpp
-
-    DEFINES += HAVE_GST_APPSRC
-
-    LIBS += -lgstapp-0.10
-}
-
 HEADERS += \
     $$PWD/qgstreamerplayercontrol.h \
     $$PWD/qgstreamerplayerservice.h \
index d765fd7..7c66eac 100644 (file)
 #include "camerabinservice.h"
 #endif
 
+#ifdef QMEDIA_GSTREAMER_AUDIO_DECODER
+#include "qgstreameraudiodecoderservice.h"
+#endif
+
 #include <qmediaserviceproviderplugin.h>
 
 #include <linux/types.h>
@@ -81,7 +85,9 @@ QStringList QGstreamerServicePlugin::keys() const
 #ifdef QMEDIA_GSTREAMER_PLAYER
             << QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)
 #endif
-
+#ifdef QMEDIA_GSTREAMER_AUDIO_DECODER
+            << QLatin1String(Q_MEDIASERVICE_AUDIODECODER)
+#endif
 #ifdef QMEDIA_GSTREAMER_CAPTURE
             << QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE)
             << QLatin1String(Q_MEDIASERVICE_CAMERA)
@@ -110,6 +116,11 @@ QMediaService* QGstreamerServicePlugin::create(const QString &key)
         return new CameraBinService(key);
 #endif
 
+#ifdef QMEDIA_GSTREAMER_AUDIO_DECODER
+    if (key == QLatin1String(Q_MEDIASERVICE_AUDIODECODER))
+        return new QGstreamerAudioDecoderService;
+#endif
+
 #ifdef QMEDIA_GSTREAMER_CAPTURE
     if (key == QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE))
         return new QGstreamerCaptureService(key);