Add a partial gstreamer based audio decoder service.
Doesn't work yet. Change-Id: Iebd085d68346cb73af8df59c84e8e52a17de2a52 Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
This commit is contained in:
committed by
Qt by Nokia
parent
d5042c1ec7
commit
696e434129
@@ -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 \
|
||||
|
||||
@@ -1,227 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QDebug>
|
||||
|
||||
#include "qgstappsrc.h"
|
||||
#include <QtNetwork>
|
||||
|
||||
QGstAppSrc::QGstAppSrc(QObject *parent)
|
||||
:QObject(parent)
|
||||
,m_stream(0)
|
||||
,m_appSrc(0)
|
||||
,m_sequential(false)
|
||||
,m_maxBytes(0)
|
||||
,m_setup(false)
|
||||
,m_dataRequestSize(-1)
|
||||
,m_dataRequested(false)
|
||||
,m_enoughData(false)
|
||||
,m_forceData(false)
|
||||
{
|
||||
m_callbacks.need_data = &QGstAppSrc::on_need_data;
|
||||
m_callbacks.enough_data = &QGstAppSrc::on_enough_data;
|
||||
m_callbacks.seek_data = &QGstAppSrc::on_seek_data;
|
||||
}
|
||||
|
||||
QGstAppSrc::~QGstAppSrc()
|
||||
{
|
||||
if (m_appSrc)
|
||||
gst_object_unref(G_OBJECT(m_appSrc));
|
||||
}
|
||||
|
||||
bool QGstAppSrc::setup(GstElement* appsrc)
|
||||
{
|
||||
if (m_setup || m_stream == 0 || appsrc == 0)
|
||||
return false;
|
||||
|
||||
m_appSrc = GST_APP_SRC(appsrc);
|
||||
gst_app_src_set_callbacks(m_appSrc, (GstAppSrcCallbacks*)&m_callbacks, this, (GDestroyNotify)&QGstAppSrc::destroy_notify);
|
||||
|
||||
g_object_get(G_OBJECT(m_appSrc), "max-bytes", &m_maxBytes, NULL);
|
||||
|
||||
if (m_sequential)
|
||||
m_streamType = GST_APP_STREAM_TYPE_STREAM;
|
||||
else
|
||||
m_streamType = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
|
||||
gst_app_src_set_stream_type(m_appSrc, m_streamType);
|
||||
gst_app_src_set_size(m_appSrc, (m_sequential) ? -1 : m_stream->size());
|
||||
|
||||
return m_setup = true;
|
||||
}
|
||||
|
||||
void QGstAppSrc::setStream(QIODevice *stream)
|
||||
{
|
||||
if (stream == 0)
|
||||
return;
|
||||
if (m_stream) {
|
||||
disconnect(m_stream, SIGNAL(readyRead()), this, SLOT(onDataReady()));
|
||||
disconnect(m_stream, SIGNAL(destroyed()), this, SLOT(streamDestroyed()));
|
||||
}
|
||||
if (m_appSrc)
|
||||
gst_object_unref(G_OBJECT(m_appSrc));
|
||||
|
||||
m_dataRequestSize = -1;
|
||||
m_dataRequested = false;
|
||||
m_enoughData = false;
|
||||
m_forceData = false;
|
||||
m_maxBytes = 0;
|
||||
|
||||
m_appSrc = 0;
|
||||
m_stream = stream;
|
||||
connect(m_stream, SIGNAL(destroyed()), SLOT(streamDestroyed()));
|
||||
connect(m_stream, SIGNAL(readyRead()), this, SLOT(onDataReady()));
|
||||
m_sequential = m_stream->isSequential();
|
||||
m_setup = false;
|
||||
}
|
||||
|
||||
QIODevice *QGstAppSrc::stream() const
|
||||
{
|
||||
return m_stream;
|
||||
}
|
||||
|
||||
GstAppSrc *QGstAppSrc::element()
|
||||
{
|
||||
return m_appSrc;
|
||||
}
|
||||
|
||||
void QGstAppSrc::onDataReady()
|
||||
{
|
||||
if (!m_enoughData) {
|
||||
m_dataRequested = true;
|
||||
pushDataToAppSrc();
|
||||
}
|
||||
}
|
||||
|
||||
void QGstAppSrc::streamDestroyed()
|
||||
{
|
||||
if (sender() == m_stream) {
|
||||
m_stream = 0;
|
||||
sendEOS();
|
||||
}
|
||||
}
|
||||
|
||||
void QGstAppSrc::pushDataToAppSrc()
|
||||
{
|
||||
if (!isStreamValid() || !m_setup)
|
||||
return;
|
||||
|
||||
if (m_dataRequested && !m_enoughData) {
|
||||
qint64 size;
|
||||
if (m_dataRequestSize == (unsigned int)-1)
|
||||
size = qMin(m_stream->bytesAvailable(), queueSize());
|
||||
else
|
||||
size = qMin(m_stream->bytesAvailable(), (qint64)m_dataRequestSize);
|
||||
void *data = g_malloc(size);
|
||||
GstBuffer* buffer = gst_app_buffer_new(data, size, g_free, data);
|
||||
buffer->offset = m_stream->pos();
|
||||
qint64 bytesRead = m_stream->read((char*)GST_BUFFER_DATA(buffer), size);
|
||||
buffer->offset_end = buffer->offset + bytesRead - 1;
|
||||
|
||||
if (bytesRead > 0) {
|
||||
m_dataRequested = false;
|
||||
m_enoughData = false;
|
||||
GstFlowReturn ret = gst_app_src_push_buffer (GST_APP_SRC (element()), buffer);
|
||||
if (ret == GST_FLOW_ERROR) {
|
||||
qWarning()<<"appsrc: push buffer error";
|
||||
} else if (ret == GST_FLOW_WRONG_STATE) {
|
||||
qWarning()<<"appsrc: push buffer wrong state";
|
||||
} else if (ret == GST_FLOW_RESEND) {
|
||||
qWarning()<<"appsrc: push buffer resend";
|
||||
}
|
||||
}
|
||||
} else if (m_stream->atEnd()) {
|
||||
sendEOS();
|
||||
}
|
||||
}
|
||||
|
||||
bool QGstAppSrc::doSeek(qint64 value)
|
||||
{
|
||||
if (isStreamValid())
|
||||
return stream()->seek(value);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
gboolean QGstAppSrc::on_seek_data(GstAppSrc *element, guint64 arg0, gpointer userdata)
|
||||
{
|
||||
Q_UNUSED(element);
|
||||
QGstAppSrc *self = reinterpret_cast<QGstAppSrc*>(userdata);
|
||||
if (self && self->isStreamValid()) {
|
||||
if (!self->stream()->isSequential())
|
||||
QMetaObject::invokeMethod(self, "doSeek", Qt::AutoConnection, Q_ARG(qint64, arg0));
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QGstAppSrc::on_enough_data(GstAppSrc *element, gpointer userdata)
|
||||
{
|
||||
Q_UNUSED(element);
|
||||
QGstAppSrc *self = reinterpret_cast<QGstAppSrc*>(userdata);
|
||||
if (self)
|
||||
self->enoughData() = true;
|
||||
}
|
||||
|
||||
void QGstAppSrc::on_need_data(GstAppSrc *element, guint arg0, gpointer userdata)
|
||||
{
|
||||
Q_UNUSED(element);
|
||||
QGstAppSrc *self = reinterpret_cast<QGstAppSrc*>(userdata);
|
||||
if (self) {
|
||||
self->dataRequested() = true;
|
||||
self->enoughData() = false;
|
||||
self->dataRequestSize()= arg0;
|
||||
QMetaObject::invokeMethod(self, "pushDataToAppSrc", Qt::AutoConnection);
|
||||
}
|
||||
}
|
||||
|
||||
void QGstAppSrc::destroy_notify(gpointer data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
}
|
||||
|
||||
void QGstAppSrc::sendEOS()
|
||||
{
|
||||
gst_app_src_end_of_stream(GST_APP_SRC(m_appSrc));
|
||||
if (isStreamValid() && !stream()->isSequential())
|
||||
stream()->reset();
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTAPPSRC_H
|
||||
#define QGSTAPPSRC_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qiodevice.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/app/gstappsrc.h>
|
||||
#include <gst/app/gstappbuffer.h>
|
||||
|
||||
class QGstAppSrc : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstAppSrc(QObject *parent = 0);
|
||||
~QGstAppSrc();
|
||||
|
||||
bool setup(GstElement *);
|
||||
bool isReady() const { return m_setup; }
|
||||
|
||||
void setStream(QIODevice *);
|
||||
QIODevice *stream() const;
|
||||
|
||||
GstAppSrc *element();
|
||||
|
||||
qint64 queueSize() const { return m_maxBytes; }
|
||||
|
||||
bool& enoughData() { return m_enoughData; }
|
||||
bool& dataRequested() { return m_dataRequested; }
|
||||
unsigned int& dataRequestSize() { return m_dataRequestSize; }
|
||||
|
||||
bool isStreamValid() const
|
||||
{
|
||||
return m_stream != 0 &&
|
||||
m_stream->isOpen();
|
||||
}
|
||||
|
||||
private slots:
|
||||
void pushDataToAppSrc();
|
||||
bool doSeek(qint64);
|
||||
void onDataReady();
|
||||
|
||||
void streamDestroyed();
|
||||
private:
|
||||
static gboolean on_seek_data(GstAppSrc *element, guint64 arg0, gpointer userdata);
|
||||
static void on_enough_data(GstAppSrc *element, gpointer userdata);
|
||||
static void on_need_data(GstAppSrc *element, uint arg0, gpointer userdata);
|
||||
static void destroy_notify(gpointer data);
|
||||
|
||||
void sendEOS();
|
||||
|
||||
QIODevice *m_stream;
|
||||
GstAppSrc *m_appSrc;
|
||||
bool m_sequential;
|
||||
GstAppStreamType m_streamType;
|
||||
GstAppSrcCallbacks m_callbacks;
|
||||
qint64 m_maxBytes;
|
||||
bool m_setup;
|
||||
unsigned int m_dataRequestSize;
|
||||
bool m_dataRequested;
|
||||
bool m_enoughData;
|
||||
bool m_forceData;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user