diff options
author | Yoann Lopes <yoann.lopes@theqtcompany.com> | 2016-09-01 12:29:35 +0200 |
---|---|---|
committer | Yoann Lopes <yoann.lopes@theqtcompany.com> | 2016-09-01 12:29:35 +0200 |
commit | 9fb4597d5c0d3fa3340ae74ed2eb6bb8e3ee2d17 (patch) | |
tree | cc82491fc856e3d184b3b00727a06139d73c550b /src/multimedia/audio | |
parent | 29232a2bc207fb7dc44532f64bbe35d9181340c6 (diff) | |
parent | da7d462e315fb101fc9112a294b5ca2e3bd35a75 (diff) | |
download | qtmultimedia-9fb4597d5c0d3fa3340ae74ed2eb6bb8e3ee2d17.tar.gz |
Merge remote-tracking branch 'origin/5.7' into 5.8
Conflicts:
src/multimedia/audio/qaudiosystemplugin.cpp
src/plugins/directshow/helpers/directshowobject.cpp
src/plugins/directshow/player/directshowiosource.cpp
src/plugins/directshow/player/directshowiosource.h
Change-Id: I0e4632c7705128f81429ddbcb0d4abbc04858a8b
Diffstat (limited to 'src/multimedia/audio')
-rw-r--r-- | src/multimedia/audio/qaudiosystemplugin.cpp | 2 | ||||
-rw-r--r-- | src/multimedia/audio/qsoundeffect_pulse_p.cpp | 49 | ||||
-rw-r--r-- | src/multimedia/audio/qsoundeffect_pulse_p.h | 10 |
3 files changed, 50 insertions, 11 deletions
diff --git a/src/multimedia/audio/qaudiosystemplugin.cpp b/src/multimedia/audio/qaudiosystemplugin.cpp index 438b8b7bb..636b614d4 100644 --- a/src/multimedia/audio/qaudiosystemplugin.cpp +++ b/src/multimedia/audio/qaudiosystemplugin.cpp @@ -77,7 +77,7 @@ QAudioSystemPluginExtension::~QAudioSystemPluginExtension() \sa QAbstractAudioDeviceInfo, QAbstractAudioOutput, QAbstractAudioInput - Qt comes with plugins for Windows (WinMM and WASAPI), Linux (ALSA and PulseAudio), OS X / iOS + Qt comes with plugins for Windows (WinMM and WASAPI), Linux (ALSA and PulseAudio), \macos / iOS (CoreAudio), Android (OpenSL ES) and QNX. If no audio plugins are available, a fallback dummy backend will be used. diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.cpp b/src/multimedia/audio/qsoundeffect_pulse_p.cpp index 79d1d96ab..6e4aadd0b 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/audio/qsoundeffect_pulse_p.cpp @@ -419,7 +419,13 @@ void QSoundEffectPrivate::setSource(const QUrl &url) #ifdef QT_PA_DEBUG qDebug() << this << "setSource =" << url; #endif + + // Make sure the stream is empty before loading a new source (otherwise whatever is there will + // be played before the new source) + emptyStream(); + stop(); + if (m_sample) { if (!m_sampleReady) { disconnect(m_sample, SIGNAL(error()), this, SLOT(decoderError())); @@ -594,7 +600,7 @@ void QSoundEffectPrivate::playAvailable() setLoopsRemaining(0); m_playQueued = true; Q_ASSERT(m_pulseStream); - emptyStream(); + emptyStream(ReloadSampleWhenDone); return; } setLoopsRemaining(m_loopCount); @@ -604,18 +610,25 @@ void QSoundEffectPrivate::playAvailable() setPlaying(true); } -void QSoundEffectPrivate::emptyStream() +void QSoundEffectPrivate::emptyStream(EmptyStreamOptions options) { #ifdef QT_PA_DEBUG qDebug() << this << "emptyStream"; #endif + if (!m_pulseStream || m_emptying) + return; + + const bool reloadSample = options.testFlag(ReloadSampleWhenDone); + pa_stream_success_cb_t flushCompleteCb = reloadSample ? stream_flush_reload_callback + : stream_flush_callback; + m_emptying = true; pa_stream_set_write_callback(m_pulseStream, 0, 0); pa_stream_set_underflow_callback(m_pulseStream, 0, 0); - pa_operation_unref(pa_stream_flush(m_pulseStream, stream_flush_callback, m_ref->getRef())); + pa_operation_unref(pa_stream_flush(m_pulseStream, flushCompleteCb, m_ref->getRef())); } -void QSoundEffectPrivate::emptyComplete(void *stream) +void QSoundEffectPrivate::emptyComplete(void *stream, bool reload) { PulseDaemonLocker locker; #ifdef QT_PA_DEBUG @@ -625,7 +638,7 @@ void QSoundEffectPrivate::emptyComplete(void *stream) m_emptying = false; if ((pa_stream *)stream == m_pulseStream) - pa_operation_unref(pa_stream_cork(m_pulseStream, 1, stream_cork_callback, m_ref->getRef())); + pa_operation_unref(pa_stream_cork(m_pulseStream, 1, reload ? stream_cork_callback : 0, m_ref->getRef())); } void QSoundEffectPrivate::sampleReady() @@ -729,6 +742,10 @@ void QSoundEffectPrivate::prepare() if (!m_pulseStream || !m_sampleReady) return; PulseDaemonLocker locker; + + if (pa_stream_get_state(m_pulseStream) != PA_STREAM_READY) + return; + pa_stream_set_write_callback(m_pulseStream, stream_write_callback, this); pa_stream_set_underflow_callback(m_pulseStream, stream_underrun_callback, this); m_stopping = false; @@ -857,7 +874,7 @@ void QSoundEffectPrivate::stop() PulseDaemonLocker locker; m_stopping = true; if (m_pulseStream) { - emptyStream(); + emptyStream(ReloadSampleWhenDone); if (m_reloadCategory) { unloadPulseStream(); // upon play we reconnect anyway } @@ -1100,10 +1117,26 @@ void QSoundEffectPrivate::stream_flush_callback(pa_stream *s, int success, void if (!success) qWarning("QSoundEffect(pulseaudio): faild to drain"); + + QMetaObject::invokeMethod(self, "emptyComplete", Qt::QueuedConnection, Q_ARG(void*, s), Q_ARG(bool, false)); +} + +void QSoundEffectPrivate::stream_flush_reload_callback(pa_stream *s, int success, void *userdata) +{ #ifdef QT_PA_DEBUG - qDebug() << self << "stream_flush_callback"; + qDebug() << "stream_flush_reload_callback"; #endif - QMetaObject::invokeMethod(self, "emptyComplete", Qt::QueuedConnection, Q_ARG(void*, s)); + Q_UNUSED(s); + QSoundEffectRef *ref = reinterpret_cast<QSoundEffectRef*>(userdata); + QSoundEffectPrivate *self = ref->soundEffect(); + ref->release(); + if (!self) + return; + + if (!success) + qWarning("QSoundEffect(pulseaudio): faild to drain"); + + QMetaObject::invokeMethod(self, "emptyComplete", Qt::QueuedConnection, Q_ARG(void*, s), Q_ARG(bool, true)); } void QSoundEffectPrivate::stream_write_done_callback(void *p) diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.h b/src/multimedia/audio/qsoundeffect_pulse_p.h index 6bf2416cf..020aa031a 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.h +++ b/src/multimedia/audio/qsoundeffect_pulse_p.h @@ -117,7 +117,7 @@ private Q_SLOTS: void underRun(); void prepare(); void streamReady(); - void emptyComplete(void *stream); + void emptyComplete(void *stream, bool reload); void handleAvailabilityChanged(bool available); @@ -125,7 +125,12 @@ private: void playAvailable(); void playSample(); - void emptyStream(); + enum EmptyStreamOption { + ReloadSampleWhenDone = 0x1 + }; + Q_DECLARE_FLAGS(EmptyStreamOptions, EmptyStreamOption) + void emptyStream(EmptyStreamOptions options = EmptyStreamOptions()); + void createPulseStream(); void unloadPulseStream(); @@ -140,6 +145,7 @@ private: static void stream_underrun_callback(pa_stream *s, void *userdata); static void stream_cork_callback(pa_stream *s, int success, void *userdata); static void stream_flush_callback(pa_stream *s, int success, void *userdata); + static void stream_flush_reload_callback(pa_stream *s, int success, void *userdata); static void stream_write_done_callback(void *p); static void stream_adjust_prebuffer_callback(pa_stream *s, int success, void *userdata); static void stream_reset_buffer_callback(pa_stream *s, int success, void *userdata); |