diff options
Diffstat (limited to 'src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp')
-rw-r--r-- | src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp | 102 |
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 |