aboutsummaryrefslogtreecommitdiffstats
path: root/ui/qt
diff options
context:
space:
mode:
Diffstat (limited to 'ui/qt')
-rw-r--r--ui/qt/rtp_analysis_dialog.cpp34
-rw-r--r--ui/qt/rtp_analysis_dialog.h1
-rw-r--r--ui/qt/rtp_analysis_dialog.ui29
-rw-r--r--ui/qt/rtp_audio_stream.cpp5
-rw-r--r--ui/qt/rtp_audio_stream.h1
-rw-r--r--ui/qt/rtp_player_dialog.cpp77
-rw-r--r--ui/qt/rtp_player_dialog.h4
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);