summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-05-19 14:59:36 +0200
committerLars Knoll <lars.knoll@qt.io>2021-05-20 07:46:51 +0000
commit7083a5d93a99945bfae6010eee6ab5207ba97cf0 (patch)
treef52a0c04d714fc18830840eed0331d42f7e63ec8
parent424614afde0ca3cb7479296c093689e98a0c6f13 (diff)
Fixes for qaudiooutput on gstreamer
Add a queue element into the pipeline to decouple things between input and output. Add ability to suspend/resume the QGstAppSrc. This finally makes the autotest pass consistently. Change-Id: Ib20d1f9e6932aa9459085ad46fe78fdd03749723 Reviewed-by: Doris Verria <doris.verria@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r--src/multimedia/platform/gstreamer/audio/qaudiooutput_gstreamer.cpp8
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstappsrc.cpp6
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstappsrc_p.h7
-rw-r--r--tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp1
4 files changed, 17 insertions, 5 deletions
diff --git a/src/multimedia/platform/gstreamer/audio/qaudiooutput_gstreamer.cpp b/src/multimedia/platform/gstreamer/audio/qaudiooutput_gstreamer.cpp
index 1b0fec46a..1d1e94ff6 100644
--- a/src/multimedia/platform/gstreamer/audio/qaudiooutput_gstreamer.cpp
+++ b/src/multimedia/platform/gstreamer/audio/qaudiooutput_gstreamer.cpp
@@ -67,6 +67,7 @@ QGStreamerAudioOutput::QGStreamerAudioOutput(const QAudioDeviceInfo &device)
gstAppSrc = m_appSrc->element();
// gstDecodeBin = gst_element_factory_make ("decodebin", "dec");
+ QGstElement queue("queue", "queue");
QGstElement conv("audioconvert", "conv");
gstVolume = QGstElement("volume", "volume");
if (m_volume != 1.)
@@ -78,8 +79,8 @@ QGStreamerAudioOutput::QGStreamerAudioOutput(const QAudioDeviceInfo &device)
const auto *audioInfo = static_cast<const QGStreamerAudioDeviceInfo *>(device.handle());
gstOutput = gst_device_create_element(audioInfo->gstDevice, nullptr);
- gstPipeline.add(gstAppSrc, /*gstDecodeBin, */ conv, gstVolume, gstOutput);
- gstAppSrc.link(conv, gstVolume, gstOutput);
+ gstPipeline.add(gstAppSrc, queue, /*gstDecodeBin, */ conv, gstVolume, gstOutput);
+ gstAppSrc.link(queue, conv, gstVolume, gstOutput);
}
QGStreamerAudioOutput::~QGStreamerAudioOutput()
@@ -258,6 +259,7 @@ qint64 QGStreamerAudioOutput::write(const char *data, qint64 len)
return 0;
if (m_errorState == QAudio::UnderrunError)
m_errorState = QAudio::NoError;
+
m_appSrc->write(data, len);
return len;
}
@@ -305,6 +307,7 @@ qint64 QGStreamerAudioOutput::processedUSecs() const
void QGStreamerAudioOutput::resume()
{
if (m_deviceState == QAudio::SuspendedState) {
+ m_appSrc->resume();
gstPipeline.setState(GST_STATE_PLAYING);
setState(m_pullMode ? QAudio::ActiveState : QAudio::IdleState);
@@ -329,6 +332,7 @@ void QGStreamerAudioOutput::suspend()
setState(QAudio::SuspendedState);
gstPipeline.setState(GST_STATE_PAUSED);
+ m_appSrc->suspend();
// ### elapsed time
}
}
diff --git a/src/multimedia/platform/gstreamer/common/qgstappsrc.cpp b/src/multimedia/platform/gstreamer/common/qgstappsrc.cpp
index 801db5aff..027cc1850 100644
--- a/src/multimedia/platform/gstreamer/common/qgstappsrc.cpp
+++ b/src/multimedia/platform/gstreamer/common/qgstappsrc.cpp
@@ -78,6 +78,7 @@ bool QGstAppSrc::setup(QIODevice *stream, qint64 offset)
gst_app_src_set_callbacks(appSrc, (GstAppSrcCallbacks*)&m_callbacks, this, nullptr);
m_maxBytes = gst_app_src_get_max_bytes(appSrc);
+ m_suspended = false;
if (m_sequential)
m_streamType = GST_APP_STREAM_TYPE_STREAM;
@@ -87,6 +88,7 @@ bool QGstAppSrc::setup(QIODevice *stream, qint64 offset)
gst_app_src_set_size(appSrc, m_sequential ? -1 : m_stream->size() - m_offset);
m_networkReply = qobject_cast<QNetworkReply *>(m_stream);
+ m_noMoreData = true;
return true;
}
@@ -164,8 +166,10 @@ void QGstAppSrc::streamDestroyed()
void QGstAppSrc::pushData()
{
- if (m_appSrc.isNull() || !m_dataRequestSize)
+ if (m_appSrc.isNull() || !m_dataRequestSize || m_suspended) {
+ qCDebug(qLcAppSrc) << "push data: return immediately" << m_appSrc.isNull() << m_dataRequestSize << m_suspended;
return;
+ }
qCDebug(qLcAppSrc) << "pushData" << (m_stream ? m_stream : nullptr) << m_buffer.size();
if ((m_stream && m_stream->atEnd())) {
diff --git a/src/multimedia/platform/gstreamer/common/qgstappsrc_p.h b/src/multimedia/platform/gstreamer/common/qgstappsrc_p.h
index 4a1ad5003..3a978454c 100644
--- a/src/multimedia/platform/gstreamer/common/qgstappsrc_p.h
+++ b/src/multimedia/platform/gstreamer/common/qgstappsrc_p.h
@@ -57,6 +57,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qiodevice.h>
#include <QtCore/private/qringbuffer_p.h>
+#include <QtCore/qatomic.h>
#include <private/qgst_p.h>
#include <gst/app/gstappsrc.h>
@@ -82,6 +83,9 @@ public:
bool canAcceptMoreData() { return m_noMoreData || m_dataRequestSize != 0; }
+ void suspend() { m_suspended = true; }
+ void resume() { m_suspended = false; m_noMoreData = true; }
+
Q_SIGNALS:
void bytesProcessed(int bytes);
void noMoreData();
@@ -113,12 +117,13 @@ private:
QGstElement m_appSrc;
bool m_sequential = true;
+ bool m_suspended = false;
bool m_noMoreData = false;
GstAppStreamType m_streamType = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
qint64 m_offset = 0;
qint64 m_maxBytes = 0;
qint64 bytesReadSoFar = 0;
- unsigned int m_dataRequestSize = 0;
+ QAtomicInteger<unsigned int> m_dataRequestSize = 0;
int streamedSamples = 0;
};
diff --git a/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp
index 2cd59f472..8b20649b9 100644
--- a/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp
+++ b/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp
@@ -626,7 +626,6 @@ void tst_QAudioOutput::pushSuspendResume()
qint64 written = 0;
bool firstBuffer = true;
- QByteArray buffer(AUDIO_BUFFER, 0);
// Play half of the clip
while (written < (audioFile->size() - QWaveDecoder::headerLength()) / 2) {