summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-05-12 16:05:20 +0200
committerLars Knoll <lars.knoll@qt.io>2021-05-18 08:42:13 +0000
commitabb3d5589cdb640527e2ab4cd01d7845984c0305 (patch)
treeb933272b88e6649b585d508d0e3e84b0fa7ada65
parent202ce66b89e3924a81f5d2d63f217c8a72a41478 (diff)
Fix some code that was not thread safe
new_sample() could get called from a different thread, but would write into the object living on the main thread without any protection. Fix that by posting the GstSample to the main thread and processing it there. Change-Id: I6e8b8cb84c956794aac3ac00e89178d03bbf3f92 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: André de la Rocha <andre.rocha@qt.io>
-rw-r--r--src/multimedia/platform/gstreamer/audio/qaudioinput_gstreamer.cpp46
-rw-r--r--src/multimedia/platform/gstreamer/audio/qaudioinput_gstreamer_p.h7
2 files changed, 35 insertions, 18 deletions
diff --git a/src/multimedia/platform/gstreamer/audio/qaudioinput_gstreamer.cpp b/src/multimedia/platform/gstreamer/audio/qaudioinput_gstreamer.cpp
index 57f701e47..40396b097 100644
--- a/src/multimedia/platform/gstreamer/audio/qaudioinput_gstreamer.cpp
+++ b/src/multimedia/platform/gstreamer/audio/qaudioinput_gstreamer.cpp
@@ -48,13 +48,17 @@
#include <unistd.h>
#include <gst/gst.h>
+Q_DECLARE_OPAQUE_POINTER(GstSample *);
+Q_DECLARE_METATYPE(GstSample *);
QT_BEGIN_NAMESPACE
+
QGStreamerAudioInput::QGStreamerAudioInput(const QAudioDeviceInfo &device)
: m_info(device),
m_device(device.id())
{
+ qRegisterMetaType<GstSample *>();
}
QGStreamerAudioInput::~QGStreamerAudioInput()
@@ -330,29 +334,37 @@ QGstElement QGStreamerAudioInput::createAppSink()
return sink;
}
+void QGStreamerAudioInput::newDataAvailable(GstSample *sample)
+{
+ if (m_audioSink) {
+ GstBuffer *buffer = gst_sample_get_buffer(sample);
+ GstMapInfo mapInfo;
+ gst_buffer_map(buffer, &mapInfo, GST_MAP_READ);
+ const char *bufferData = (const char*)mapInfo.data;
+ gsize bufferSize = mapInfo.size;
+
+ if (!m_pullMode) {
+ // need to store that data in the QBuffer
+ m_buffer.append(bufferData, bufferSize);
+ m_audioSink->readyRead();
+ } else {
+ m_bytesWritten += bufferSize;
+ m_audioSink->write(bufferData, bufferSize);
+ }
+
+ gst_buffer_unmap(buffer, &mapInfo);
+ }
+
+ gst_sample_unref(sample);
+}
+
GstFlowReturn QGStreamerAudioInput::new_sample(GstAppSink *sink, gpointer user_data)
{
// "Note that the preroll buffer will also be returned as the first buffer when calling gst_app_sink_pull_buffer()."
QGStreamerAudioInput *control = static_cast<QGStreamerAudioInput*>(user_data);
GstSample *sample = gst_app_sink_pull_sample(sink);
- GstBuffer *buffer = gst_sample_get_buffer(sample);
- GstMapInfo mapInfo;
- gst_buffer_map(buffer, &mapInfo, GST_MAP_READ);
- const char *bufferData = (const char*)mapInfo.data;
- gsize bufferSize = mapInfo.size;
-
- if (!control->m_pullMode) {
- // need to store that data in the QBuffer
- control->m_buffer.append(bufferData, bufferSize);
- control->m_audioSink->readyRead();
- } else {
- control->m_bytesWritten += bufferSize;
- control->m_audioSink->write(bufferData, bufferSize);
- }
-
- gst_buffer_unmap(buffer, &mapInfo);
- gst_sample_unref(sample);
+ QMetaObject::invokeMethod(control, "newDataAvailable", Qt::AutoConnection, Q_ARG(GstSample *, sample));
return GST_FLOW_OK;
}
diff --git a/src/multimedia/platform/gstreamer/audio/qaudioinput_gstreamer_p.h b/src/multimedia/platform/gstreamer/audio/qaudioinput_gstreamer_p.h
index 7134c697a..2997b0084 100644
--- a/src/multimedia/platform/gstreamer/audio/qaudioinput_gstreamer_p.h
+++ b/src/multimedia/platform/gstreamer/audio/qaudioinput_gstreamer_p.h
@@ -57,6 +57,8 @@
#include <QtCore/qstringlist.h>
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qiodevice.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qatomic.h>
#include <QtCore/private/qringbuffer_p.h>
#include "qaudio.h"
@@ -98,6 +100,9 @@ public:
void setVolume(qreal volume) override;
qreal volume() const override;
+private Q_SLOTS:
+ void newDataAvailable(GstSample *sample);
+
private:
void setState(QAudio::State state);
void setError(QAudio::Error error);
@@ -120,7 +125,7 @@ private:
qreal m_volume = 1.;
QRingBuffer m_buffer;
- bool m_pullMode = true;
+ QAtomicInteger<bool> m_pullMode = true;
bool m_opened = false;
int m_bufferSize = 0;
qint64 m_elapsedTimeOffset = 0;