2

(在 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 中的错误?如果这是一个错误,我的理论是它没有获得更多数据,这会导致带有BufferUnderflow错误的空闲状态,该错误来自没有正确同步的 Pulse。作为一种解决方法,我将停止喂它并在停止之前等待空闲,但我仍然不明白这种崩溃是如何发生的。

编辑:工作示例(更改一个简单的 gui 应用程序)

在实际应用中会发生 VoIP 呼叫;大多数时候它关闭正常,但有时它会崩溃。以下示例尝试模拟单个 20ms 数据包播放(之前音频初始化,之后音频停止;我们等待 22ms 使缓冲区下溢/状态更改为空闲,在我看来这是关键。崩溃本身确实由于时序值低(它只是有助于更快地崩溃)而不会发生,在生产代码中它可能会因实际调用而崩溃。)

主窗口.h主窗口 .cpp

附加项目文件:

QT += mobility
MOBILITY += multimedia
CONFIG += mobility
4

0 回答 0