diff options
Diffstat (limited to 'ui/qt')
-rw-r--r-- | ui/qt/rtp_analysis_dialog.cpp | 34 | ||||
-rw-r--r-- | ui/qt/rtp_analysis_dialog.h | 1 | ||||
-rw-r--r-- | ui/qt/rtp_analysis_dialog.ui | 29 | ||||
-rw-r--r-- | ui/qt/rtp_audio_stream.cpp | 5 | ||||
-rw-r--r-- | ui/qt/rtp_audio_stream.h | 1 | ||||
-rw-r--r-- | ui/qt/rtp_player_dialog.cpp | 77 | ||||
-rw-r--r-- | ui/qt/rtp_player_dialog.h | 4 |
7 files changed, 118 insertions, 33 deletions
diff --git a/ui/qt/rtp_analysis_dialog.cpp b/ui/qt/rtp_analysis_dialog.cpp index c57d508f98..632f0e2bef 100644 --- a/ui/qt/rtp_analysis_dialog.cpp +++ b/ui/qt/rtp_analysis_dialog.cpp @@ -429,7 +429,7 @@ int RtpAnalysisDialog::addTabUI(tab_info_t *new_tab) new_tab->graphHorizontalLayout->setStretch(6, 1); - ui->verticalLayout_2->addLayout(new_tab->graphHorizontalLayout); + ui->layout->addLayout(new_tab->graphHorizontalLayout); return new_tab_no; } @@ -504,6 +504,7 @@ void RtpAnalysisDialog::updateWidgets() ui->actionNextProblem->setEnabled(enable_nav); if (enable_nav) { + hint.append(tr(" %1 streams, ").arg(tabs_.count() - 1)); hint.append(tr(" G: Go to packet, N: Next problem packet")); } @@ -653,10 +654,13 @@ tap_packet_status RtpAnalysisDialog::tapPacket(void *tapinfo_ptr, packet_info *p return TAP_PACKET_DONT_REDRAW; /* is it the forward direction? */ else { - for(int i=0; i<rtp_analysis_dialog->tabs_.count(); i++) { - tab_info_t *tab = rtp_analysis_dialog->tabs_[i]; - if (rtpstream_id_equal_pinfo_rtp_info(&(tab->stream.id),pinfo,rtpinfo)) { + // Search tab in hash key, if there are multiple tabs with same hash + QList<tab_info_t *> tabs = rtp_analysis_dialog->tab_hash_.values(pinfo_rtp_info_to_hash(pinfo, rtpinfo)); + for (int i = 0; i < tabs.size(); i++) { + tab_info_t *tab = tabs.at(i); + if (rtpstream_id_equal_pinfo_rtp_info(&tab->stream.id, pinfo, rtpinfo)) { rtp_analysis_dialog->addPacket(tab, pinfo, rtpinfo); + break; } } } @@ -930,6 +934,7 @@ void RtpAnalysisDialog::closeTab(int index) if (index != tabs_.count()) { QWidget *remove_tab = qobject_cast<QWidget *>(ui->tabWidget->widget(index)); tab_info_t *tab = tabs_[index]; + tab_hash_.remove(rtpstream_to_hash(&tab->stream), tab); ui->tabWidget->removeTab(index); ui->streamGraph->removeGraph(tab->jitter_graph); ui->streamGraph->removeGraph(tab->diff_graph); @@ -1089,11 +1094,16 @@ void RtpAnalysisDialog::addRtpStreamsPrivate(QVector<rtpstream_info_t *> stream_ { int first_tab_no = -1; + setUpdatesEnabled(false); foreach(rtpstream_info_t *rtpstream, stream_infos) { bool found = false; - for(int i=0; i < tabs_.count(); i++) { - if (rtpstream_id_equal(&(tabs_[i]->stream.id), &(rtpstream->id), RTPSTREAM_ID_EQUAL_SSRC)) { + + QList<tab_info_t *> tabs = tab_hash_.values(rtpstream_to_hash(rtpstream)); + for (int i = 0; i < tabs.size(); i++) { + tab_info_t *tab = tabs.at(i); + if (rtpstream_id_equal(&tab->stream.id, &rtpstream->id, RTPSTREAM_ID_EQUAL_SSRC)) { found = true; + break; } } @@ -1108,6 +1118,7 @@ void RtpAnalysisDialog::addRtpStreamsPrivate(QVector<rtpstream_info_t *> stream_ new_tab->delta_vals = new QVector<double>(); tabs_ << new_tab; cur_tab_no = addTabUI(new_tab); + tab_hash_.insert(rtpstream_to_hash(rtpstream), new_tab); if (first_tab_no == -1) { first_tab_no = cur_tab_no; } @@ -1116,6 +1127,7 @@ void RtpAnalysisDialog::addRtpStreamsPrivate(QVector<rtpstream_info_t *> stream_ if (first_tab_no != -1) { ui->tabWidget->setCurrentIndex(first_tab_no); } + setUpdatesEnabled(true); registerTapListener("rtp", this, NULL, 0, tapReset, tapPacket, tapDraw); cap_file_.retapPackets(); removeTapListeners(); @@ -1125,13 +1137,17 @@ void RtpAnalysisDialog::addRtpStreamsPrivate(QVector<rtpstream_info_t *> stream_ void RtpAnalysisDialog::removeRtpStreams(QVector<rtpstream_info_t *> stream_infos _U_) { + setUpdatesEnabled(false); foreach(rtpstream_info_t *rtpstream, stream_infos) { - for(int i=0; i < tabs_.count(); i++) { - if (rtpstream_id_equal(&(tabs_[i]->stream.id), &(rtpstream->id), RTPSTREAM_ID_EQUAL_SSRC)) { - closeTab(i); + QList<tab_info_t *> tabs = tab_hash_.values(rtpstream_to_hash(rtpstream)); + for (int i = 0; i < tabs.size(); i++) { + tab_info_t *tab = tabs.at(i); + if (rtpstream_id_equal(&tab->stream.id, &rtpstream->id, RTPSTREAM_ID_EQUAL_SSRC)) { + closeTab(tabs_.indexOf(tab)); } } } + setUpdatesEnabled(true); updateGraph(); } diff --git a/ui/qt/rtp_analysis_dialog.h b/ui/qt/rtp_analysis_dialog.h index b3c0cafa13..cb9016ba1e 100644 --- a/ui/qt/rtp_analysis_dialog.h +++ b/ui/qt/rtp_analysis_dialog.h @@ -115,6 +115,7 @@ private: int tab_seq; QVector<tab_info_t *> tabs_; + QMultiHash<guint, tab_info_t *> tab_hash_; QPushButton *player_button_; diff --git a/ui/qt/rtp_analysis_dialog.ui b/ui/qt/rtp_analysis_dialog.ui index 33df9bfa11..1ce64d9c79 100644 --- a/ui/qt/rtp_analysis_dialog.ui +++ b/ui/qt/rtp_analysis_dialog.ui @@ -25,10 +25,37 @@ <attribute name="title"> <string>Graph</string> </attribute> - <layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,0,0"> + <layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,0"> <item> <widget class="QCustomPlot" name="streamGraph" native="true"/> </item> + <item> + <widget class="QScrollArea" name="scrollarea"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>200</height> + </size> + </property> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="qwidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>606</width> + <height>298</height> + </rect> + </property> + <layout class="QVBoxLayout" name="layout"/> + </widget> + </widget> + </item> </layout> </widget> </widget> diff --git a/ui/qt/rtp_audio_stream.cpp b/ui/qt/rtp_audio_stream.cpp index 5fc8d1c9f5..41a848ed1d 100644 --- a/ui/qt/rtp_audio_stream.cpp +++ b/ui/qt/rtp_audio_stream.cpp @@ -36,6 +36,7 @@ #include <QVariant> #include <QTimer> #include <QDebug> +#include <QBuffer> // To do: // - Only allow one rtpstream_info_t per RtpAudioStream? @@ -80,7 +81,7 @@ RtpAudioStream::RtpAudioStream(QObject *parent, rtpstream_info_t *rtpstream, boo qWarning() << "Can't create temp file in " << tempname; throw -1; } - sample_file_frame_ = new QTemporaryFile(tempname, this); + sample_file_frame_ = new QBuffer(this); if (! sample_file_frame_->open(QIODevice::ReadWrite)) { // We are out of file resources delete sample_file_; @@ -179,7 +180,7 @@ void RtpAudioStream::reset(double global_start_time) if (!sample_file_->open(QIODevice::ReadWrite)) { qWarning() << "Can't create temp file in " << tempname << " during retap"; } - sample_file_frame_ = new QTemporaryFile(tempname, this); + sample_file_frame_ = new QBuffer(this); if (!sample_file_frame_->open(QIODevice::ReadWrite)) { qWarning() << "Can't create temp file in " << tempname << " during retap"; } diff --git a/ui/qt/rtp_audio_stream.h b/ui/qt/rtp_audio_stream.h index 60a5b2e4fd..5fa14ec65e 100644 --- a/ui/qt/rtp_audio_stream.h +++ b/ui/qt/rtp_audio_stream.h @@ -154,6 +154,7 @@ public: qint64 getLeadSilenceSamples() { return prepend_samples_; } qint64 getTotalSamples() { return (sample_file_->size()/(qint64)sizeof(SAMPLE)); } bool savePayload(QIODevice *file); + guint getHash() { return rtpstream_id_to_hash(&id_); } QString getIDAsQString(); signals: diff --git a/ui/qt/rtp_player_dialog.cpp b/ui/qt/rtp_player_dialog.cpp index d634b9a83b..19c7763cb0 100644 --- a/ui/qt/rtp_player_dialog.cpp +++ b/ui/qt/rtp_player_dialog.cpp @@ -8,6 +8,7 @@ */ #include <ui/rtp_media.h> +#include <ui/tap-rtp-common.h> #include "rtp_player_dialog.h" #include <ui_rtp_player_dialog.h> @@ -149,6 +150,8 @@ RtpPlayerDialog::RtpPlayerDialog(QWidget &parent, CaptureFile &cf) : , marker_stream_requested_out_rate_(0) , last_ti_(0) , listener_removed_(true) + , block_redraw_(false) + , lock_ui_(0) { ui->setupUi(this); loadGeometry(parent.width(), parent.height()); @@ -414,6 +417,7 @@ void RtpPlayerDialog::retapPackets() void RtpPlayerDialog::rescanPackets(bool rescale_axes) { + lockUI(); // Show information for a user - it can last long time... ui->hintLabel->setText("<i><small>" + tr("Decoding streams...") + "</i></small>"); wsApp->processEvents(); @@ -453,6 +457,7 @@ void RtpPlayerDialog::rescanPackets(bool rescale_axes) createPlot(rescale_axes); updateWidgets(); + unlockUI(); } void RtpPlayerDialog::createPlot(bool rescale_axes) @@ -600,6 +605,8 @@ void RtpPlayerDialog::createPlot(bool rescale_axes) void RtpPlayerDialog::addSingleRtpStream(rtpstream_info_t *rtpstream) { + bool found = false; + AudioRouting audio_routing = AudioRouting(AUDIO_UNMUTED, channel_mono); if (!rtpstream) return; @@ -607,23 +614,24 @@ void RtpPlayerDialog::addSingleRtpStream(rtpstream_info_t *rtpstream) // Find the RTP streams associated with this conversation. // gtk/rtp_player.c:mark_rtp_stream_to_play does this differently. - RtpAudioStream *audio_stream = NULL; - int tli_count = ui->streamTreeWidget->topLevelItemCount(); - for (int row = 0; row < tli_count; row++) { - QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row); - RtpAudioStream *row_stream = ti->data(stream_data_col_, Qt::UserRole).value<RtpAudioStream*>(); + QList<RtpAudioStream *> streams = stream_hash_.values(rtpstream_to_hash(rtpstream)); + for (int i = 0; i < streams.size(); i++) { + RtpAudioStream *row_stream = streams.at(i); if (row_stream->isMatch(rtpstream)) { - audio_stream = row_stream; + found = true; break; } } - if (!audio_stream) { + int tli_count = ui->streamTreeWidget->topLevelItemCount(); + + if (!found) { try { - audio_stream = new RtpAudioStream(this, rtpstream, stereo_available_); + RtpAudioStream *audio_stream = new RtpAudioStream(this, rtpstream, stereo_available_); audio_stream->setColor(ColorUtils::graphColor(tli_count)); QTreeWidgetItem *ti = new RtpPlayerTreeWidgetItem(ui->streamTreeWidget); + stream_hash_.insert(rtpstream_to_hash(rtpstream), audio_stream); ti->setText(src_addr_col_, address_to_qstring(&rtpstream->id.src_addr)); ti->setText(src_port_col_, QString::number(rtpstream->id.src_port)); ti->setText(dst_addr_col_, address_to_qstring(&rtpstream->id.dst_addr)); @@ -686,15 +694,19 @@ void RtpPlayerDialog::addSingleRtpStream(rtpstream_info_t *rtpstream) void RtpPlayerDialog::lockUI() { - if (playing_streams_.count() > 0) { - on_stopButton_clicked(); + if (0 == lock_ui_++) { + if (playing_streams_.count() > 0) { + on_stopButton_clicked(); + } + setEnabled(false); } - setEnabled(false); } void RtpPlayerDialog::unlockUI() { - setEnabled(true); + if (--lock_ui_ == 0) { + setEnabled(true); + } } void RtpPlayerDialog::replaceRtpStreams(QVector<rtpstream_info_t *> stream_infos) @@ -1197,15 +1209,16 @@ tap_packet_status RtpPlayerDialog::tapPacket(void *tapinfo_ptr, packet_info *pin void RtpPlayerDialog::addPacket(packet_info *pinfo, const _rtp_info *rtpinfo) { - for (int row = 0; row < ui->streamTreeWidget->topLevelItemCount(); row++) { - QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row); - RtpAudioStream *row_stream = ti->data(stream_data_col_, Qt::UserRole).value<RtpAudioStream*>(); - + // Search stream in hash key, if there are multiple streams with same hash + QList<RtpAudioStream *> streams = stream_hash_.values(pinfo_rtp_info_to_hash(pinfo, rtpinfo)); + for (int i = 0; i < streams.size(); i++) { + RtpAudioStream *row_stream = streams.at(i); if (row_stream->isMatch(pinfo, rtpinfo)) { row_stream->addRtpPacket(pinfo, rtpinfo); - return; + break; } } + // qDebug() << "=ap no match!" << address_to_qstring(&pinfo->src) << address_to_qstring(&pinfo->dst); } @@ -1448,8 +1461,10 @@ void RtpPlayerDialog::on_streamTreeWidget_itemSelectionChanged() ui->actionSavePayload->setEnabled(false); } - ui->audioPlot->replot(); - updateHintLabel(); + if (!block_redraw_) { + ui->audioPlot->replot(); + updateHintLabel(); + } } // Change channel audio routing if double clicked channel column @@ -1471,6 +1486,7 @@ void RtpPlayerDialog::removeRow(QTreeWidgetItem *ti) { RtpAudioStream *audio_stream = ti->data(stream_data_col_, Qt::UserRole).value<RtpAudioStream*>(); if (audio_stream) { + stream_hash_.remove(audio_stream->getHash(), audio_stream); ti->setData(stream_data_col_, Qt::UserRole, QVariant()); delete audio_stream; } @@ -1513,13 +1529,16 @@ void RtpPlayerDialog::on_actionRemoveStream_triggered() { QList<QTreeWidgetItem *> items = ui->streamTreeWidget->selectedItems(); + block_redraw_ = true; if (last_ti_) { highlightItem(last_ti_, false); last_ti_ = NULL; } - for(int i = 0; i<items.count(); i++ ) { + //for(int i = 0; i<items.count(); i++ ) { + for(int i = items.count() - 1; i>=0; i-- ) { removeRow(items[i]); } + block_redraw_ = false; // TODO: Recalculate legend // - Graphs used for legend could be removed above and we must add new // - If no legend is required, it should be removed @@ -1551,7 +1570,9 @@ void RtpPlayerDialog::changeAudioRoutingOnItem(QTreeWidgetItem *ti, AudioRouting audio_graph->setSelected(ti->isSelected()); audio_graph->setMuted(audio_routing.isMuted()); - ui->audioPlot->replot(); + if (!block_redraw_) { + ui->audioPlot->replot(); + } } } @@ -1560,11 +1581,14 @@ void RtpPlayerDialog::changeAudioRouting(AudioRouting new_audio_routing) { QList<QTreeWidgetItem *> items = ui->streamTreeWidget->selectedItems(); + block_redraw_ = true; for(int i = 0; i<items.count(); i++ ) { QTreeWidgetItem *ti = items[i]; changeAudioRoutingOnItem(ti, new_audio_routing); } + block_redraw_ = false; + ui->audioPlot->replot(); updateHintLabel(); } @@ -1621,11 +1645,14 @@ void RtpPlayerDialog::on_actionAudioRoutingMuteInvert_triggered() { QList<QTreeWidgetItem *> items = ui->streamTreeWidget->selectedItems(); + block_redraw_ = true; for(int i = 0; i<items.count(); i++ ) { QTreeWidgetItem *ti = items[i]; invertAudioMutingOnItem(ti); } + block_redraw_ = false; + ui->audioPlot->replot(); updateHintLabel(); } @@ -1695,6 +1722,7 @@ void RtpPlayerDialog::cleanupMarkerStream() void RtpPlayerDialog::on_outputDeviceComboBox_currentIndexChanged(const QString &) { + lockUI(); stereo_available_ = isStereoAvailable(); for (int row = 0; row < ui->streamTreeWidget->topLevelItemCount(); row++) { QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row); @@ -1709,10 +1737,12 @@ void RtpPlayerDialog::on_outputDeviceComboBox_currentIndexChanged(const QString cleanupMarkerStream(); fillAudioRateMenu(); rescanPackets(); + unlockUI(); } void RtpPlayerDialog::on_outputAudioRate_currentIndexChanged(const QString & rate_string) { + lockUI(); // Any unconvertable string is converted to 0 => used as Automatic rate unsigned selected_rate = rate_string.toInt(); @@ -1727,6 +1757,7 @@ void RtpPlayerDialog::on_outputAudioRate_currentIndexChanged(const QString & rat marker_stream_requested_out_rate_ = selected_rate; cleanupMarkerStream(); rescanPackets(); + unlockUI(); } void RtpPlayerDialog::on_jitterSpinBox_valueChanged(double) @@ -1844,10 +1875,14 @@ bool RtpPlayerDialog::isStereoAvailable() void RtpPlayerDialog::invertSelection() { + block_redraw_ = true; for (int row = 0; row < ui->streamTreeWidget->topLevelItemCount(); row++) { QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row); ti->setSelected(!ti->isSelected()); } + block_redraw_ = false; + ui->audioPlot->replot(); + updateHintLabel(); } void RtpPlayerDialog::on_actionSelectAll_triggered() diff --git a/ui/qt/rtp_player_dialog.h b/ui/qt/rtp_player_dialog.h index 21b47f6fc1..c3f0c8e659 100644 --- a/ui/qt/rtp_player_dialog.h +++ b/ui/qt/rtp_player_dialog.h @@ -20,6 +20,7 @@ #include "rtp_audio_stream.h" #include <QMap> +#include <QMultiHash> #include <QTreeWidgetItem> #include <QMetaType> #include <ui/qt/widgets/qcustomplot.h> @@ -177,6 +178,9 @@ private: QTreeWidgetItem *last_ti_; bool listener_removed_; QPushButton *export_btn_; + QMultiHash<guint, RtpAudioStream *> stream_hash_; + bool block_redraw_; + int lock_ui_; // const QString streamKey(const rtpstream_info_t *rtpstream); // const QString streamKey(const packet_info *pinfo, const struct _rtp_info *rtpinfo); |