(在Qt 4.8.2 4.8.3,Qt MultimediaKit 1.2,Linux(编辑:Kubuntu 12.10,qt from packages)
我有一个 QAudioOutput ,它每20毫秒提供一次数据。 如果我通过 :: stop()停止它,它会发出 stateChanged()信号它已被停止(立即;它的线程与控制线程相同)。即使它们都在GUI线程中或两者都存在,症状仍然存在。)
然后我将其删除,但每10次尝试中有一次或两次,它会因以下回溯而崩溃:
#0 0x00007fab18000148 in ?? ()
#1 0x00007fab47b51eef in QMetaObject::activate (sender=0x7fab1800b060, m=<optimized out>, local_signal_index=<optimized out>, argv=0x7fab2b0e8850) at kernel/qobject.cpp:3541
#2 0x00007fab4aa46eae in QAbstractAudioOutput::stateChanged(QAudio::State) () from /usr/lib/x86_64-linux-gnu/libQtMultimediaKit.so.1
#3 0x00007fab2b0f38c8 in ?? () from /usr/lib/x86_64-linux-gnu/qt4/plugins/audio/libqtmedia_pulse.so
#4 0x00007fab2b0f33ad in ?? () from /usr/lib/x86_64-linux-gnu/qt4/plugins/audio/libqtmedia_pulse.so
#5 0x00007fab420a475b in ?? () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#6 0x00007fab3b1749fd in pa_pdispatch_run () from /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-2.1.so
#7 0x00007fab42086e1d in ?? () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#8 0x00007fab3b178a2b in ?? () from /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-2.1.so
#9 0x00007fab4209a374 in pa_mainloop_dispatch () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#10 0x00007fab4209a725 in pa_mainloop_iterate () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#11 0x00007fab4209a7d0 in pa_mainloop_run () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#12 0x00007fab420a8b1f in ?? () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#13 0x00007fab3b186543 in ?? () from /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-2.1.so
#14 0x00007fab477aee9a in start_thread (arg=0x7fab2b0e9700) at pthread_create.c:308
#15 0x00007fab46cc6cbd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#16 0x0000000000000000 in ?? ()
这似乎是某种脉冲线程仍在尝试访问旧的 QAudioOutput (没有运气)。通过信号/插槽,这应该是线程安全的(根据QObject::~QObject,我没有做任何错误,从控制线程中删除它(由外部信号调用,而不是通过 QAudioOutput 顺便说一句信号。)
即使我调用 deleteLater(),也会发生崩溃。我做错了什么,或者这可能是Qt中的一个错误?如果这是一个错误,我的理论是它不会再获得任何数据,这会导致 Idle 状态出现 BufferUnderflow 错误,该错误来自Pulse而没有正确的同步。作为一种解决方法,我会停止喂它并在停止前等待空闲,但我仍然不明白这种崩溃是怎么发生的。
编辑:工作示例(更改简单的gui应用)
在实际应用中发生VoIP呼叫;它大部分时间都关闭,但有时会崩溃。下面的例子尝试模拟一个20ms的数据包播放(前面有音频init,音频停止之后;我们等待22ms使缓冲器下溢/状态变为空闲,在我看来这是关键。崩溃本身确实如此不会因为低时间值而出现(它只会有助于更快地崩溃),在生产代码中它可能会因真实呼叫而崩溃。)
将项目文件附加到:
QT += mobility
MOBILITY += multimedia
CONFIG += mobility