diff options
author | Peter Wu <peter@lekensteyn.nl> | 2015-11-17 18:54:41 +0100 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 2015-11-17 22:49:47 +0000 |
commit | d92a5fa7b3404723cc23b9a83988c5e5bdd5456b (patch) | |
tree | b5831f7a6756a1ca93a05eeabff8f68ae63dd7f6 | |
parent | 804ee98b32bfd3fe39e67210da5569da8336ecda (diff) | |
download | wireshark-d92a5fa7b3404723cc23b9a83988c5e5bdd5456b.tar.gz |
Fix crash in RTP Player on stop and close
When dragging the UI, this somehow causes a great lag. Then by
spam-clicking on the Stop button, a double free seems to occur.
Fix this by moving the audio cleanup to the outputStateChanged callback
as documented at https://doc.qt.io/qt-5/qaudiooutput.html. Note that
calling stop() in the IdleState also triggers a change event, resulting
in the desired cleanup.
Stop streams before the dialog is closed (via accept/reject). This
*cannot* be done in the destrutor of RtpPlayerDialog because destructing
QAudioOutput processes events from the event queue, resulting in
preature destruction of other objects... crash.
Change-Id: I6bfb33c9396e9bc1ffd346519d22390a97b6bdaf
Reviewed-on: https://code.wireshark.org/review/11894
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Gerald Combs <gerald@wireshark.org>
(cherry picked from commit 0fef9d752f801986a81b7c294143eae21cd0de97)
Reviewed-on: https://code.wireshark.org/review/11930
-rw-r--r-- | ui/qt/rtp_audio_stream.cpp | 16 | ||||
-rw-r--r-- | ui/qt/rtp_player_dialog.cpp | 17 | ||||
-rw-r--r-- | ui/qt/rtp_player_dialog.h | 3 |
3 files changed, 28 insertions, 8 deletions
diff --git a/ui/qt/rtp_audio_stream.cpp b/ui/qt/rtp_audio_stream.cpp index 94149fe3ca..c16eca903c 100644 --- a/ui/qt/rtp_audio_stream.cpp +++ b/ui/qt/rtp_audio_stream.cpp @@ -539,10 +539,7 @@ void RtpAudioStream::stopPlaying() { if (audio_output_) { audio_output_->stop(); - delete audio_output_; - audio_output_ = NULL; } - emit finishedPlaying(); } void RtpAudioStream::writeSilence(int samples) @@ -564,20 +561,23 @@ void RtpAudioStream::writeSilence(int samples) void RtpAudioStream::outputStateChanged() { - if (!audio_output_) return; - - if (audio_output_->state() == QAudio::IdleState) { + switch (audio_output_->state()) { + case QAudio::StoppedState: // RTP_STREAM_DEBUG("stopped %f", audio_output_->processedUSecs() / 100000.0); delete audio_output_; audio_output_ = NULL; - emit finishedPlaying(); + break; + case QAudio::IdleState: + audio_output_->stop(); + break; + default: + break; } } void RtpAudioStream::outputNotify() { - if (!audio_output_) return; emit processedSecs(audio_output_->processedUSecs() / 1000000.0); } diff --git a/ui/qt/rtp_player_dialog.cpp b/ui/qt/rtp_player_dialog.cpp index e5545c99d9..9b26c1fb5a 100644 --- a/ui/qt/rtp_player_dialog.cpp +++ b/ui/qt/rtp_player_dialog.cpp @@ -177,6 +177,23 @@ RtpPlayerDialog::~RtpPlayerDialog() delete ui; } +void RtpPlayerDialog::accept() +{ + int row_count = ui->streamTreeWidget->topLevelItemCount(); + // Stop all streams before the dialogs are closed. + for (int row = 0; row < row_count; row++) { + QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row); + RtpAudioStream *audio_stream = ti->data(stream_data_col_, Qt::UserRole).value<RtpAudioStream*>(); + audio_stream->stopPlaying(); + } + WiresharkDialog::accept(); +} + +void RtpPlayerDialog::reject() +{ + RtpPlayerDialog::accept(); +} + void RtpPlayerDialog::retapPackets() { register_tap_listener("rtp", this, NULL, 0, NULL, tapPacket, NULL); diff --git a/ui/qt/rtp_player_dialog.h b/ui/qt/rtp_player_dialog.h index be3f2c57c1..5f214682da 100644 --- a/ui/qt/rtp_player_dialog.h +++ b/ui/qt/rtp_player_dialog.h @@ -61,6 +61,9 @@ public: #ifdef QT_MULTIMEDIA_LIB ~RtpPlayerDialog(); + void accept(); + void reject(); + /** Add an RTP stream to play. * MUST be called before exec(). * Requires src_addr, src_port, dest_addr, dest_port, ssrc, packet_count, |