diff options
Diffstat (limited to 'src/multimedia')
-rw-r--r-- | src/multimedia/effects/qsoundeffect.cpp | 2 | ||||
-rw-r--r-- | src/multimedia/effects/qsoundeffect_pulse_p.cpp | 167 | ||||
-rw-r--r-- | src/multimedia/effects/qsoundeffect_pulse_p.h | 4 | ||||
-rw-r--r-- | src/multimedia/effects/qsoundeffect_qmedia_p.cpp | 5 | ||||
-rw-r--r-- | src/multimedia/effects/qsoundeffect_qmedia_p.h | 2 |
5 files changed, 158 insertions, 22 deletions
diff --git a/src/multimedia/effects/qsoundeffect.cpp b/src/multimedia/effects/qsoundeffect.cpp index 7cfcdce70..19021fd0c 100644 --- a/src/multimedia/effects/qsoundeffect.cpp +++ b/src/multimedia/effects/qsoundeffect.cpp @@ -173,7 +173,7 @@ QSoundEffect::QSoundEffect(QObject *parent) : QSoundEffect::~QSoundEffect() { - d->deleteLater(); + d->release(); } QStringList QSoundEffect::supportedMimeTypes() diff --git a/src/multimedia/effects/qsoundeffect_pulse_p.cpp b/src/multimedia/effects/qsoundeffect_pulse_p.cpp index da617287a..aa88f4c4b 100644 --- a/src/multimedia/effects/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/effects/qsoundeffect_pulse_p.cpp @@ -276,6 +276,67 @@ public: }; } +class QSoundEffectRef +{ +public: + QSoundEffectRef(QSoundEffectPrivate *target) + : m_ref(1) + , m_target(target) + { +#ifdef QT_PA_DEBUG + qDebug() << "QSoundEffectRef(" << this << ") ctor"; +#endif + } + + QSoundEffectRef *getRef() + { +#ifdef QT_PA_DEBUG + qDebug() << "QSoundEffectRef(" << this << ") getRef"; +#endif + QMutexLocker locker(&m_mutex); + m_ref++; + return this; + } + + void release() + { +#ifdef QT_PA_DEBUG + qDebug() << "QSoundEffectRef(" << this << ") Release"; +#endif + m_mutex.lock(); + --m_ref; + if (m_ref == 0) { + m_mutex.unlock(); +#ifdef QT_PA_DEBUG + qDebug() << "QSoundEffectRef(" << this << ") deleted"; +#endif + delete this; + return; + } + m_mutex.unlock(); + } + + QSoundEffectPrivate* soundEffect() const + { + QMutexLocker locker(&m_mutex); + return m_target; + } + + void notifyDeleted() + { +#ifdef QT_PA_DEBUG + qDebug() << "QSoundEffectRef(" << this << ") notifyDeleted"; +#endif + QMutexLocker locker(&m_mutex); + m_target = NULL; + } + +private: + int m_ref; + mutable QMutex m_mutex; + QSoundEffectPrivate *m_target; +}; + QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): QObject(parent), m_pulseStream(0), @@ -293,15 +354,28 @@ QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): m_sample(0) , m_position(0) { + m_ref = new QSoundEffectRef(this); pa_sample_spec_init(&m_pulseSpec); } -QSoundEffectPrivate::~QSoundEffectPrivate() +void QSoundEffectPrivate::release() { +#ifdef QT_PA_DEBUG + qDebug() << this << "release"; +#endif + m_ref->notifyDeleted(); unloadPulseStream(); - - if (m_sample) + if (m_sample) { m_sample->release(); + m_sample = 0; + } + + this->deleteLater(); +} + +QSoundEffectPrivate::~QSoundEffectPrivate() +{ + m_ref->release(); } QStringList QSoundEffectPrivate::supportedMimeTypes() @@ -396,7 +470,7 @@ void QSoundEffectPrivate::updateVolume() PulseDaemonLocker locker; pa_cvolume volume; volume.channels = m_pulseSpec.channels; - pa_operation_unref(pa_context_set_sink_input_volume(daemon()->context(), m_sinkInputId, daemon()->calcVolume(&volume, m_volume), setvolume_callback, this)); + pa_operation_unref(pa_context_set_sink_input_volume(daemon()->context(), m_sinkInputId, daemon()->calcVolume(&volume, m_volume), setvolume_callback, m_ref->getRef())); Q_ASSERT(pa_cvolume_valid(&volume)); #ifdef QT_PA_DEBUG qDebug() << this << "updateVolume =" << pa_cvolume_max(&volume); @@ -420,9 +494,9 @@ void QSoundEffectPrivate::updateMuted() if (m_sinkInputId < 0) return; PulseDaemonLocker locker; - pa_operation_unref(pa_context_set_sink_input_mute(daemon()->context(), m_sinkInputId, m_muted, setmuted_callback, this)); + pa_operation_unref(pa_context_set_sink_input_mute(daemon()->context(), m_sinkInputId, m_muted, setmuted_callback, m_ref->getRef())); #ifdef QT_PA_DEBUG - qDebug() << this << "updateMuted = " << daemon()->calcMuted(m_muted); + qDebug() << this << "updateMuted = " << m_muted; #endif } @@ -502,17 +576,20 @@ void QSoundEffectPrivate::play() void QSoundEffectPrivate::emptyStream() { +#ifdef QT_PA_DEBUG + qDebug() << this << "emptyStream"; +#endif m_emptying = true; - pa_stream_set_write_callback(m_pulseStream, 0, this); - pa_stream_set_underflow_callback(m_pulseStream, 0, this); - pa_operation_unref(pa_stream_flush(m_pulseStream, stream_flush_callback, this)); + 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())); } void QSoundEffectPrivate::emptyComplete() { PulseDaemonLocker locker; m_emptying = false; - pa_operation_unref(pa_stream_cork(m_pulseStream, 1, stream_cork_callback, this)); + pa_operation_unref(pa_stream_cork(m_pulseStream, 1, stream_cork_callback, m_ref->getRef())); } void QSoundEffectPrivate::sampleReady() @@ -546,7 +623,7 @@ void QSoundEffectPrivate::sampleReady() pa_buffer_attr newBufferAttr; newBufferAttr = *bufferAttr; newBufferAttr.prebuf = m_sample->data().size(); - pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, this); + pa_operation_unref(pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, m_ref->getRef())); } else { streamReady(); } @@ -559,12 +636,12 @@ void QSoundEffectPrivate::sampleReady() newBufferAttr.minreq = bufferAttr->tlength / 2; newBufferAttr.prebuf = -1; newBufferAttr.fragsize = -1; - pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_reset_buffer_callback, this); + pa_operation_unref(pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_reset_buffer_callback, m_ref->getRef())); } else if (bufferAttr->prebuf > uint32_t(m_sample->data().size())) { pa_buffer_attr newBufferAttr; newBufferAttr = *bufferAttr; newBufferAttr.prebuf = m_sample->data().size(); - pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, this); + pa_operation_unref(pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, m_ref->getRef())); } else { streamReady(); } @@ -801,7 +878,7 @@ void QSoundEffectPrivate::contextReady() void QSoundEffectPrivate::stream_write_callback(pa_stream *s, size_t length, void *userdata) { Q_UNUSED(length); - Q_UNUSED(s) + Q_UNUSED(s); QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata); #ifdef QT_PA_DEBUG @@ -825,7 +902,7 @@ void QSoundEffectPrivate::stream_state_callback(pa_stream *s, void *userdata) pa_buffer_attr newBufferAttr; newBufferAttr = *bufferAttr; newBufferAttr.prebuf = self->m_sample->data().size(); - pa_stream_set_buffer_attr(self->m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, userdata); + pa_stream_set_buffer_attr(self->m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, self->m_ref->getRef()); } else { QMetaObject::invokeMethod(self, "streamReady", Qt::QueuedConnection); } @@ -851,10 +928,18 @@ void QSoundEffectPrivate::stream_state_callback(pa_stream *s, void *userdata) void QSoundEffectPrivate::stream_reset_buffer_callback(pa_stream *s, int success, void *userdata) { +#ifdef QT_PA_DEBUG + qDebug() << "stream_reset_buffer_callback"; +#endif 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 reset buffer attribute"); - QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata); #ifdef QT_PA_DEBUG qDebug() << self << "stream_reset_buffer_callback"; #endif @@ -872,10 +957,18 @@ void QSoundEffectPrivate::stream_reset_buffer_callback(pa_stream *s, int success void QSoundEffectPrivate::stream_adjust_prebuffer_callback(pa_stream *s, int success, void *userdata) { +#ifdef QT_PA_DEBUG + qDebug() << "stream_adjust_prebuffer_callback"; +#endif 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 adjust pre-buffer attribute"); - QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata); #ifdef QT_PA_DEBUG qDebug() << self << "stream_adjust_prebuffer_callback"; #endif @@ -884,10 +977,18 @@ void QSoundEffectPrivate::stream_adjust_prebuffer_callback(pa_stream *s, int suc void QSoundEffectPrivate::setvolume_callback(pa_context *c, int success, void *userdata) { +#ifdef QT_PA_DEBUG + qDebug() << "setvolume_callback"; +#endif Q_UNUSED(c); Q_UNUSED(userdata); + QSoundEffectRef *ref = reinterpret_cast<QSoundEffectRef*>(userdata); + QSoundEffectPrivate *self = ref->soundEffect(); + ref->release(); + if (!self) + return; #ifdef QT_PA_DEBUG - qDebug() << reinterpret_cast<QSoundEffectPrivate*>(userdata) << "setvolume_callback"; + qDebug() << self << "setvolume_callback"; #endif if (!success) { qWarning("QSoundEffect(pulseaudio): faild to set volume"); @@ -896,10 +997,18 @@ void QSoundEffectPrivate::setvolume_callback(pa_context *c, int success, void *u void QSoundEffectPrivate::setmuted_callback(pa_context *c, int success, void *userdata) { +#ifdef QT_PA_DEBUG + qDebug() << "setmuted_callback"; +#endif Q_UNUSED(c); Q_UNUSED(userdata); + QSoundEffectRef *ref = reinterpret_cast<QSoundEffectRef*>(userdata); + QSoundEffectPrivate *self = ref->soundEffect(); + ref->release(); + if (!self) + return; #ifdef QT_PA_DEBUG - qDebug() << reinterpret_cast<QSoundEffectPrivate*>(userdata) << "setmuted_callback"; + qDebug() << self << "setmuted_callback"; #endif if (!success) { qWarning("QSoundEffect(pulseaudio): faild to set muted"); @@ -923,10 +1032,18 @@ void QSoundEffectPrivate::stream_underrun_callback(pa_stream *s, void *userdata) void QSoundEffectPrivate::stream_cork_callback(pa_stream *s, int success, void *userdata) { +#ifdef QT_PA_DEBUG + qDebug() << "stream_cork_callback"; +#endif 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 stop"); - QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata); #ifdef QT_PA_DEBUG qDebug() << self << "stream_cork_callback"; #endif @@ -935,10 +1052,18 @@ void QSoundEffectPrivate::stream_cork_callback(pa_stream *s, int success, void * void QSoundEffectPrivate::stream_flush_callback(pa_stream *s, int success, void *userdata) { +#ifdef QT_PA_DEBUG + qDebug() << "stream_flush_callback"; +#endif 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"); - QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata); #ifdef QT_PA_DEBUG qDebug() << self << "stream_flush_callback"; #endif diff --git a/src/multimedia/effects/qsoundeffect_pulse_p.h b/src/multimedia/effects/qsoundeffect_pulse_p.h index eaf78e8dd..3992617ba 100644 --- a/src/multimedia/effects/qsoundeffect_pulse_p.h +++ b/src/multimedia/effects/qsoundeffect_pulse_p.h @@ -68,6 +68,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Multimedia) +class QSoundEffectRef; class QSoundEffectPrivate : public QObject { @@ -90,6 +91,8 @@ public: bool isPlaying() const; QSoundEffect::Status status() const; + void release(); + public Q_SLOTS: void play(); void stop(); @@ -154,6 +157,7 @@ private: QSample *m_sample; int m_position; + QSoundEffectRef *m_ref; }; QT_END_NAMESPACE diff --git a/src/multimedia/effects/qsoundeffect_qmedia_p.cpp b/src/multimedia/effects/qsoundeffect_qmedia_p.cpp index dfd56b09c..64a1754a9 100644 --- a/src/multimedia/effects/qsoundeffect_qmedia_p.cpp +++ b/src/multimedia/effects/qsoundeffect_qmedia_p.cpp @@ -76,6 +76,11 @@ QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): connect(m_player, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged())); } +void QSoundEffectPrivate::release() +{ + this->deleteLater(); +} + QSoundEffectPrivate::~QSoundEffectPrivate() { } diff --git a/src/multimedia/effects/qsoundeffect_qmedia_p.h b/src/multimedia/effects/qsoundeffect_qmedia_p.h index 3e448f718..b93f47ce3 100644 --- a/src/multimedia/effects/qsoundeffect_qmedia_p.h +++ b/src/multimedia/effects/qsoundeffect_qmedia_p.h @@ -88,6 +88,8 @@ public: bool isPlaying() const; QSoundEffect::Status status() const; + void release(); + public Q_SLOTS: void play(); void stop(); |