summaryrefslogtreecommitdiffstats
path: root/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp')
-rw-r--r--src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp102
1 files changed, 57 insertions, 45 deletions
diff --git a/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp b/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp
index 0cfa28169..046775b77 100644
--- a/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp
+++ b/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp
@@ -21,11 +21,9 @@
#include <QtCore/qurl.h>
#include <QtCore/qloggingcategory.h>
-#define MAX_BUFFERS_IN_QUEUE 4
-
QT_BEGIN_NAMESPACE
-static Q_LOGGING_CATEGORY(qLcGstreamerAudioDecoder, "qt.multimedia.gstreameraudiodecoder");
+Q_STATIC_LOGGING_CATEGORY(qLcGstreamerAudioDecoder, "qt.multimedia.gstreameraudiodecoder");
typedef enum {
GST_PLAY_FLAG_VIDEO = 0x00000001,
@@ -42,23 +40,21 @@ typedef enum {
QMaybe<QPlatformAudioDecoder *> QGstreamerAudioDecoder::create(QAudioDecoder *parent)
{
- QGstElement audioconvert = QGstElement::createFromFactory("audioconvert", "audioconvert");
- if (!audioconvert)
- return errorMessageCannotFindElement("audioconvert");
-
- QGstPipeline playbin = QGstPipeline::adopt(
- GST_PIPELINE_CAST(QGstElement::createFromFactory("playbin", "playbin").element()));
- if (!playbin)
- return errorMessageCannotFindElement("playbin");
+ static const auto error = qGstErrorMessageIfElementsNotAvailable("audioconvert", "playbin");
+ if (error)
+ return *error;
- return new QGstreamerAudioDecoder(playbin, audioconvert, parent);
+ return new QGstreamerAudioDecoder(parent);
}
-QGstreamerAudioDecoder::QGstreamerAudioDecoder(QGstPipeline playbin, QGstElement audioconvert,
- QAudioDecoder *parent)
+QGstreamerAudioDecoder::QGstreamerAudioDecoder(QAudioDecoder *parent)
: QPlatformAudioDecoder(parent),
- m_playbin(std::move(playbin)),
- m_audioConvert(std::move(audioconvert))
+ m_playbin{
+ QGstPipeline::createFromFactory("playbin", "playbin"),
+ },
+ m_audioConvert{
+ QGstElement::createFromFactory("audioconvert", "audioconvert"),
+ }
{
// Sort out messages
m_playbin.installMessageFilter(this);
@@ -88,12 +84,9 @@ QGstreamerAudioDecoder::~QGstreamerAudioDecoder()
m_playbin.removeMessageFilter(this);
-#if QT_CONFIG(gstreamer_app)
delete m_appSrc;
-#endif
}
-#if QT_CONFIG(gstreamer_app)
void QGstreamerAudioDecoder::configureAppSrcElement([[maybe_unused]] GObject *object, GObject *orig,
[[maybe_unused]] GParamSpec *pspec,
QGstreamerAudioDecoder *self)
@@ -112,7 +105,6 @@ void QGstreamerAudioDecoder::configureAppSrcElement([[maybe_unused]] GObject *ob
});
qAppSrc->setup(self->mDevice);
}
-#endif
bool QGstreamerAudioDecoder::processBusMessage(const QGstreamerMessage &message)
{
@@ -336,14 +328,14 @@ void QGstreamerAudioDecoder::stop()
bufferAvailableChanged(false);
}
- if (m_position != -1) {
- m_position = -1;
- positionChanged(m_position);
+ if (m_position != invalidPosition) {
+ m_position = invalidPosition;
+ positionChanged(m_position.count());
}
- if (m_duration != -1) {
- m_duration = -1;
- durationChanged(m_duration);
+ if (m_duration != invalidDuration) {
+ m_duration = invalidDuration;
+ durationChanged(m_duration.count());
}
setIsDecoding(false);
@@ -364,6 +356,8 @@ void QGstreamerAudioDecoder::setAudioFormat(const QAudioFormat &format)
QAudioBuffer QGstreamerAudioDecoder::read()
{
+ using namespace std::chrono;
+
QAudioBuffer audioBuffer;
if (m_buffersAvailable == 0)
@@ -385,12 +379,16 @@ QAudioBuffer QGstreamerAudioDecoder::read()
if (format.isValid()) {
// XXX At the moment we have to copy data from GstBuffer into QAudioBuffer.
// We could improve performance by implementing QAbstractAudioBuffer for GstBuffer.
- qint64 position = getPositionFromBuffer(buffer);
- audioBuffer = QAudioBuffer(QByteArray(bufferData, bufferSize), format, position);
- position /= 1000; // convert to milliseconds
+ nanoseconds position = getPositionFromBuffer(buffer);
+ audioBuffer = QAudioBuffer{
+ QByteArray(bufferData, bufferSize),
+ format,
+ round<microseconds>(position).count(),
+ };
+ milliseconds positionInMs = round<milliseconds>(position);
if (position != m_position) {
- m_position = position;
- positionChanged(m_position);
+ m_position = positionInMs;
+ positionChanged(m_position.count());
}
}
gst_buffer_unmap(buffer, &mapInfo);
@@ -400,12 +398,12 @@ QAudioBuffer QGstreamerAudioDecoder::read()
qint64 QGstreamerAudioDecoder::position() const
{
- return m_position;
+ return m_position.count();
}
qint64 QGstreamerAudioDecoder::duration() const
{
- return m_duration;
+ return m_duration.count();
}
void QGstreamerAudioDecoder::processInvalidMedia(QAudioDecoder::Error errorCode, const QString& errorString)
@@ -452,6 +450,8 @@ void QGstreamerAudioDecoder::setAudioFlags(bool wantNativeAudio)
void QGstreamerAudioDecoder::addAppSink()
{
+ using namespace std::chrono_literals;
+
if (m_appSink)
return;
@@ -460,8 +460,17 @@ void QGstreamerAudioDecoder::addAppSink()
GstAppSinkCallbacks callbacks{};
callbacks.new_sample = new_sample;
m_appSink.setCallbacks(callbacks, this, nullptr);
- gst_app_sink_set_max_buffers(m_appSink.appSink(), MAX_BUFFERS_IN_QUEUE);
- gst_base_sink_set_sync(m_appSink.baseSink(), FALSE);
+
+#if GST_CHECK_VERSION(1, 24, 0)
+ static constexpr auto maxBufferTime = 500ms;
+ m_appSink.setMaxBufferTime(maxBufferTime);
+#else
+ static constexpr int maxBuffers = 16;
+ m_appSink.setMaxBuffers(maxBuffers);
+#endif
+
+ static constexpr bool sync = false;
+ m_appSink.setSync(sync);
QGstPipeline::modifyPipelineWhileNotRunning(m_playbin.getPipeline(), [&] {
m_outputBin.add(m_appSink);
@@ -485,14 +494,16 @@ void QGstreamerAudioDecoder::removeAppSink()
void QGstreamerAudioDecoder::updateDuration()
{
- int duration = m_playbin.duration() / 1000000;
+ std::optional<std::chrono::milliseconds> duration = m_playbin.durationInMs();
+ if (!duration)
+ duration = invalidDuration;
if (m_duration != duration) {
- m_duration = duration;
- durationChanged(m_duration);
+ m_duration = *duration;
+ durationChanged(m_duration.count());
}
- if (m_duration > 0)
+ if (m_duration.count() > 0)
m_durationQueries = 0;
if (m_durationQueries > 0) {
@@ -503,14 +514,15 @@ void QGstreamerAudioDecoder::updateDuration()
}
}
-qint64 QGstreamerAudioDecoder::getPositionFromBuffer(GstBuffer* buffer)
+std::chrono::nanoseconds QGstreamerAudioDecoder::getPositionFromBuffer(GstBuffer *buffer)
{
- qint64 position = GST_BUFFER_TIMESTAMP(buffer);
- if (position >= 0)
- position = position / G_GINT64_CONSTANT(1000); // microseconds
+ using namespace std::chrono;
+ using namespace std::chrono_literals;
+ nanoseconds position{ GST_BUFFER_TIMESTAMP(buffer) };
+ if (position >= 0ns)
+ return position;
else
- position = -1;
- return position;
+ return invalidPosition;
}
QT_END_NAMESPACE