aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorJirka Novak <j.novak@netsystem.cz>2020-01-02 00:38:35 +0100
committerAnders Broman <a.broman58@gmail.com>2020-01-07 09:38:14 +0000
commit71fb8bebfe6b8f76ccfa48ec3cc598e0ddef14ba (patch)
tree8a227fbd4484e183cc2682e0075b787a662b61cc /ui
parentc1f5b4d2d91d7a1113d0206237fff55669b87727 (diff)
rtp_player: Player is able to set start of audio play by double click
Patch adds ability to set start of audio play by double clicking on waveform. Patch fixes unreported issue with placing waveform at incorrect place when switched relative/absolute time mode (check/uncheck Time of Day). Change-Id: Ib8ce24aea870e2443e033afbb6d6e9fbcf222431 Reviewed-on: https://code.wireshark.org/review/35621 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'ui')
-rw-r--r--ui/qt/rtp_analysis_dialog.cpp9
-rw-r--r--ui/qt/rtp_audio_stream.cpp39
-rw-r--r--ui/qt/rtp_audio_stream.h4
-rw-r--r--ui/qt/rtp_player_dialog.cpp199
-rw-r--r--ui/qt/rtp_player_dialog.h17
-rw-r--r--ui/qt/voip_calls_dialog.cpp1
-rw-r--r--ui/rtp_stream.h1
-rw-r--r--ui/tap-rtp-common.c1
-rw-r--r--ui/voip_calls.c1
9 files changed, 212 insertions, 60 deletions
diff --git a/ui/qt/rtp_analysis_dialog.cpp b/ui/qt/rtp_analysis_dialog.cpp
index 19ed25e4dc..f14e7e809e 100644
--- a/ui/qt/rtp_analysis_dialog.cpp
+++ b/ui/qt/rtp_analysis_dialog.cpp
@@ -1022,6 +1022,8 @@ void RtpAnalysisDialog::showPlayer()
stream_info.packet_count = fwd_statinfo_.packet_count;
stream_info.setup_frame_number = fwd_statinfo_.setup_frame_number;
nstime_copy(&stream_info.start_rel_time, &fwd_statinfo_.start_rel_time);
+ nstime_copy(&stream_info.stop_rel_time, &fwd_statinfo_.stop_rel_time);
+ nstime_copy(&stream_info.start_abs_time, &fwd_statinfo_.start_abs_time);
rtp_player_dialog->addRtpStream(&stream_info);
if (num_streams_ > 1) {
@@ -1030,6 +1032,8 @@ void RtpAnalysisDialog::showPlayer()
stream_info.packet_count = rev_statinfo_.packet_count;
stream_info.setup_frame_number = rev_statinfo_.setup_frame_number;
nstime_copy(&stream_info.start_rel_time, &rev_statinfo_.start_rel_time);
+ nstime_copy(&stream_info.stop_rel_time, &rev_statinfo_.stop_rel_time);
+ nstime_copy(&stream_info.start_abs_time, &rev_statinfo_.start_abs_time);
rtp_player_dialog->addRtpStream(&stream_info);
}
@@ -1037,6 +1041,7 @@ void RtpAnalysisDialog::showPlayer()
rtp_player_dialog->setWindowModality(Qt::ApplicationModal);
rtp_player_dialog->setAttribute(Qt::WA_DeleteOnClose);
+ rtp_player_dialog->setMarkers();
rtp_player_dialog->show();
#endif // QT_MULTIMEDIA_LIB
}
@@ -1695,6 +1700,8 @@ void RtpAnalysisDialog::findStreams()
fwd_statinfo_.packet_count = strinfo->packet_count;
fwd_statinfo_.setup_frame_number = strinfo->setup_frame_number;
nstime_copy(&fwd_statinfo_.start_rel_time, &strinfo->start_rel_time);
+ nstime_copy(&fwd_statinfo_.stop_rel_time, &strinfo->stop_rel_time);
+ nstime_copy(&fwd_statinfo_.start_abs_time, &strinfo->start_abs_time);
num_streams_++;
}
@@ -1703,6 +1710,8 @@ void RtpAnalysisDialog::findStreams()
rev_statinfo_.packet_count = strinfo->packet_count;
rev_statinfo_.setup_frame_number = strinfo->setup_frame_number;
nstime_copy(&rev_statinfo_.start_rel_time, &strinfo->start_rel_time);
+ nstime_copy(&rev_statinfo_.stop_rel_time, &strinfo->stop_rel_time);
+ nstime_copy(&rev_statinfo_.start_abs_time, &strinfo->start_abs_time);
num_streams_++;
if (rev_statinfo_.id.ssrc == 0) {
rev_statinfo_.id.ssrc = strinfo->id.ssrc;
diff --git a/ui/qt/rtp_audio_stream.cpp b/ui/qt/rtp_audio_stream.cpp
index fc04257bc0..443f18d1af 100644
--- a/ui/qt/rtp_audio_stream.cpp
+++ b/ui/qt/rtp_audio_stream.cpp
@@ -133,9 +133,9 @@ void RtpAudioStream::addRtpPacket(const struct _packet_info *pinfo, const struct
rtp_packets_ << rtp_packet;
}
-void RtpAudioStream::reset(double start_rel_time)
+void RtpAudioStream::reset(double global_start_time)
{
- global_start_rel_time_ = start_rel_time;
+ global_start_rel_time_ = global_start_time;
stop_rel_time_ = start_rel_time_;
audio_out_rate_ = 0;
max_sample_val_ = 1;
@@ -158,6 +158,7 @@ static const int sample_bytes_ = sizeof(SAMPLE) / sizeof(char);
* XXX - is there a better thing to do here?
*/
static const int max_silence_samples_ = MAX_SILENCE_FRAMES;
+
void RtpAudioStream::decode()
{
if (rtp_packets_.size() < 1) return;
@@ -402,7 +403,7 @@ const QVector<double> RtpAudioStream::visualTimestamps(bool relative)
QVector<double> adj_timestamps;
for (int i = 0; i < ts_keys.size(); i++) {
- adj_timestamps.append(ts_keys[i] + start_abs_offset_);
+ adj_timestamps.append(ts_keys[i] + start_abs_offset_ - start_rel_time_);
}
return adj_timestamps;
}
@@ -429,7 +430,7 @@ const QVector<double> RtpAudioStream::outOfSequenceTimestamps(bool relative)
QVector<double> adj_timestamps;
for (int i = 0; i < out_of_seq_timestamps_.size(); i++) {
- adj_timestamps.append(out_of_seq_timestamps_[i] + start_abs_offset_);
+ adj_timestamps.append(out_of_seq_timestamps_[i] + start_abs_offset_ - start_rel_time_);
}
return adj_timestamps;
}
@@ -450,7 +451,7 @@ const QVector<double> RtpAudioStream::jitterDroppedTimestamps(bool relative)
QVector<double> adj_timestamps;
for (int i = 0; i < jitter_drop_timestamps_.size(); i++) {
- adj_timestamps.append(jitter_drop_timestamps_[i] + start_abs_offset_);
+ adj_timestamps.append(jitter_drop_timestamps_[i] + start_abs_offset_ - start_rel_time_);
}
return adj_timestamps;
}
@@ -471,7 +472,7 @@ const QVector<double> RtpAudioStream::wrongTimestampTimestamps(bool relative)
QVector<double> adj_timestamps;
for (int i = 0; i < wrong_timestamp_timestamps_.size(); i++) {
- adj_timestamps.append(wrong_timestamp_timestamps_[i] + start_abs_offset_);
+ adj_timestamps.append(wrong_timestamp_timestamps_[i] + start_abs_offset_ - start_rel_time_);
}
return adj_timestamps;
}
@@ -492,7 +493,7 @@ const QVector<double> RtpAudioStream::insertedSilenceTimestamps(bool relative)
QVector<double> adj_timestamps;
for (int i = 0; i < silence_timestamps_.size(); i++) {
- adj_timestamps.append(silence_timestamps_[i] + start_abs_offset_);
+ adj_timestamps.append(silence_timestamps_[i] + start_abs_offset_ - start_rel_time_);
}
return adj_timestamps;
}
@@ -548,6 +549,8 @@ const QString RtpAudioStream::formatDescription(const QAudioFormat &format)
void RtpAudioStream::startPlaying()
{
+ qint64 start_pos;
+
if (audio_output_) return;
if (audio_out_rate_ == 0) {
@@ -586,12 +589,20 @@ void RtpAudioStream::startPlaying()
audio_output_->setNotifyInterval(65); // ~15 fps
connect(audio_output_, SIGNAL(stateChanged(QAudio::State)), this, SLOT(outputStateChanged(QAudio::State)));
connect(audio_output_, SIGNAL(notify()), this, SLOT(outputNotify()));
- tempfile_->seek(0);
- audio_output_->start(tempfile_);
- emit startedPlaying();
- // QTBUG-6548 StoppedState is not always emitted on error, force a cleanup
- // in case playback fails immediately.
- if (audio_output_ && audio_output_->state() == QAudio::StoppedState) {
+ start_pos = (qint64)(start_play_time_ * sample_bytes_ * audio_out_rate_);
+ // Round to sample_bytes_ boundary
+ start_pos = (start_pos / sample_bytes_) * sample_bytes_;
+ if (start_pos < tempfile_->size()) {
+ tempfile_->seek(start_pos);
+ audio_output_->start(tempfile_);
+ emit startedPlaying();
+ // QTBUG-6548 StoppedState is not always emitted on error, force a cleanup
+ // in case playback fails immediately.
+ if (audio_output_ && audio_output_->state() == QAudio::StoppedState) {
+ outputStateChanged(QAudio::StoppedState);
+ }
+ } else {
+ // Report stopped audio if start position is later than stream ends
outputStateChanged(QAudio::StoppedState);
}
}
@@ -648,7 +659,7 @@ void RtpAudioStream::outputStateChanged(QAudio::State new_state)
void RtpAudioStream::outputNotify()
{
- emit processedSecs(audio_output_->processedUSecs() / 1000000.0);
+ emit processedSecs((audio_output_->processedUSecs() / 1000000.0) + start_play_time_);
}
#endif // QT_MULTIMEDIA_LIB
diff --git a/ui/qt/rtp_audio_stream.h b/ui/qt/rtp_audio_stream.h
index 33d56fd5db..64948065a1 100644
--- a/ui/qt/rtp_audio_stream.h
+++ b/ui/qt/rtp_audio_stream.h
@@ -45,7 +45,7 @@ public:
bool isMatch(const struct _packet_info *pinfo, const struct _rtp_info *rtp_info) const;
//void addRtpStream(const rtpstream_info_t *rtpstream);
void addRtpPacket(const struct _packet_info *pinfo, const struct _rtp_info *rtp_info);
- void reset(double start_rel_time);
+ void reset(double global_start_time);
void decode();
double startRelTime() const { return start_rel_time_; }
@@ -127,6 +127,7 @@ public:
void setJitterBufferSize(int jitter_buffer_size) { jitter_buffer_size_ = jitter_buffer_size; }
void setTimingMode(TimingMode timing_mode) { timing_mode_ = timing_mode; }
+ void setStartPlayTime(double start_play_time) { start_play_time_ = start_play_time; }
signals:
void startedPlaying();
@@ -168,6 +169,7 @@ private:
int jitter_buffer_size_;
TimingMode timing_mode_;
+ double start_play_time_;
void writeSilence(int samples);
const QString formatDescription(const QAudioFormat & format);
diff --git a/ui/qt/rtp_player_dialog.cpp b/ui/qt/rtp_player_dialog.cpp
index eb9777d2e0..3be1d397df 100644
--- a/ui/qt/rtp_player_dialog.cpp
+++ b/ui/qt/rtp_player_dialog.cpp
@@ -91,7 +91,11 @@ RtpPlayerDialog::RtpPlayerDialog(QWidget &parent, CaptureFile &cf) :
WiresharkDialog(parent, cf)
#ifdef QT_MULTIMEDIA_LIB
, ui(new Ui::RtpPlayerDialog)
- , start_rel_time_(0.0)
+ , first_stream_rel_start_time_(0.0)
+ , first_stream_abs_start_time_(0.0)
+ , first_stream_rel_stop_time_(0.0)
+ , streams_length_(0.0)
+ , start_marker_time_(0.0)
#endif // QT_MULTIMEDIA_LIB
, number_ticker_(new QCPAxisTicker)
, datetime_ticker_(new QCPAxisTickerDateTime)
@@ -125,10 +129,18 @@ RtpPlayerDialog::RtpPlayerDialog(QWidget &parent, CaptureFile &cf) :
this, SLOT(updateHintLabel()));
connect(ui->audioPlot, SIGNAL(mousePress(QMouseEvent*)),
this, SLOT(graphClicked(QMouseEvent*)));
+ connect(ui->audioPlot, SIGNAL(mouseDoubleClick(QMouseEvent*)),
+ this, SLOT(graphDoubleClicked(QMouseEvent*)));
cur_play_pos_ = new QCPItemStraightLine(ui->audioPlot);
cur_play_pos_->setVisible(false);
+ start_marker_pos_ = new QCPItemStraightLine(ui->audioPlot);
+ start_marker_pos_->setPen(QPen(Qt::green,4));
+ setStartPlayMarker(0);
+ drawStartPlayMarker();
+ start_marker_pos_->setVisible(true);
+
datetime_ticker_->setDateTimeFormat("yyyy-MM-dd\nhh:mm:ss.zzz");
ui->audioPlot->xAxis->setNumberFormat("gb");
@@ -229,7 +241,7 @@ void RtpPlayerDialog::rescanPackets(bool rescale_axes)
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->reset(start_rel_time_);
+ audio_stream->reset(first_stream_rel_start_time_);
ti->setData(graph_data_col_, Qt::UserRole, QVariant());
}
@@ -404,20 +416,23 @@ void RtpPlayerDialog::addRtpStream(rtpstream_info_t *rtpstream)
connect(audio_stream, SIGNAL(playbackError(QString)), this, SLOT(setPlaybackError(QString)));
connect(audio_stream, SIGNAL(processedSecs(double)), this, SLOT(setPlayPosition(double)));
}
- // TODO: does not do anything
- // audio_stream->addRtpStream(rtpstream);
- double start_rel_time = nstime_to_sec(&rtpstream->start_rel_time);
- if (tli_count < 2) {
- start_rel_time_ = start_rel_time;
- } else {
- start_rel_time_ = qMin(start_rel_time_, start_rel_time);
- }
+
+ // Update start/stop time nevertheless stream is new or already seen
+ // because voip_calls_dialog.cpp splits same stream to multiple pieces
+ updateStartStopTime(rtpstream, tli_count);
+
RTP_STREAM_DEBUG("adding stream %d to layout, %u packets, start %u",
ui->streamTreeWidget->topLevelItemCount(),
rtpstream->packet_count,
rtpstream->start_fd ? rtpstream->start_fd->num : 0);
}
+void RtpPlayerDialog::setMarkers()
+{
+ setStartPlayMarker(0);
+ drawStartPlayMarker();
+}
+
void RtpPlayerDialog::showEvent(QShowEvent *)
{
QList<int> split_sizes = ui->splitter->sizes();
@@ -517,14 +532,34 @@ void RtpPlayerDialog::graphClicked(QMouseEvent *event)
ui->audioPlot->setFocus();
}
+void RtpPlayerDialog::graphDoubleClicked(QMouseEvent *event)
+{
+ updateWidgets();
+ if (event->button() == Qt::LeftButton) {
+ // Move start play line
+ double ts = ui->audioPlot->xAxis->pixelToCoord(ui->audioPlot->mapFromGlobal(QCursor::pos()).x());
+
+ setStartPlayMarker(ts);
+ drawStartPlayMarker();
+
+ ui->audioPlot->replot();
+ }
+ ui->audioPlot->setFocus();
+}
+
void RtpPlayerDialog::updateHintLabel()
{
int packet_num = getHoveredPacket();
QString hint = "<small><i>";
-
- if (packet_num > 0) {
- hint += tr("%1. Press \"G\" to go to packet %2")
- .arg(getHoveredTime())
+ double start_pos = getStartPlayMarker();
+
+ if (packet_num == 0) {
+ hint += tr("Start: %1. Double click to set start of playback.")
+ .arg(getFormatedTime(start_pos));
+ } else if (packet_num > 0) {
+ hint += tr("Start: %1, cursor: %2. Press \"G\" to go to packet %3. Double click to set start of playback.")
+ .arg(getFormatedTime(start_pos))
+ .arg(getFormatedHoveredTime())
.arg(packet_num);
} else if (!playback_error_.isEmpty()) {
hint += playback_error_;
@@ -554,8 +589,13 @@ void RtpPlayerDialog::resetXAxis()
void RtpPlayerDialog::setPlayPosition(double secs)
{
- secs+= start_rel_time_;
double cur_secs = cur_play_pos_->point1->key();
+
+ if (ui->todCheckBox->isChecked()) {
+ secs += first_stream_abs_start_time_;
+ } else {
+ secs += first_stream_rel_start_time_;
+ }
if (secs > cur_secs) {
cur_play_pos_->point1->setCoords(secs, 0.0);
cur_play_pos_->point2->setCoords(secs, 1.0);
@@ -626,11 +666,27 @@ void RtpPlayerDialog::panXAxis(int x_pixels)
void RtpPlayerDialog::on_playButton_clicked()
{
- double left = start_rel_time_;
- cur_play_pos_->point1->setCoords(left, 0.0);
- cur_play_pos_->point2->setCoords(left, 1.0);
+ double start_time;
+
+ cur_play_pos_->point1->setCoords(start_marker_time_, 0.0);
+ cur_play_pos_->point2->setCoords(start_marker_time_, 1.0);
cur_play_pos_->setVisible(true);
playback_error_.clear();
+
+ if (ui->todCheckBox->isChecked()) {
+ start_time = start_marker_time_;
+ } else {
+ start_time = start_marker_time_ - first_stream_rel_start_time_;
+ }
+
+ int row_count = ui->streamTreeWidget->topLevelItemCount();
+ 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*>();
+ // All streams starts at first_stream_rel_start_time_
+ audio_stream->setStartPlayTime(start_time);
+ }
+
ui->audioPlot->replot();
}
@@ -691,41 +747,32 @@ void RtpPlayerDialog::on_streamTreeWidget_itemSelectionChanged()
}
}
ui->audioPlot->replot();
+ ui->audioPlot->setFocus();
}
-double RtpPlayerDialog::getLowestTimestamp()
+const QString RtpPlayerDialog::getFormatedTime(double time)
{
- double lowest = QCPRange::maxRange;
+ QString time_str;
- for (int i = 0; i < ui->audioPlot->graphCount(); i++) {
- QCPGraph *graph = ui->audioPlot->graph(i);
- if (!graph->visible()) continue;
- QSharedPointer<QCPGraphDataContainer> dm = graph->data();
- bool foundRange = false;
- QCPRange range = dm->keyRange(foundRange);
- if (foundRange) {
- lowest = qMin(lowest, range.lower);
- }
+ if (ui->todCheckBox->isChecked()) {
+ QDateTime date_time = QDateTime::fromMSecsSinceEpoch(time * 1000.0);
+ time_str = date_time.toString("yyyy-MM-dd hh:mm:ss.zzz");
+ } else {
+ time_str = QString::number(time, 'f', 3);
+ time_str += " s";
}
- return lowest;
+
+ return time_str;
}
-const QString RtpPlayerDialog::getHoveredTime()
+const QString RtpPlayerDialog::getFormatedHoveredTime()
{
QTreeWidgetItem *ti = ui->streamTreeWidget->currentItem();
if (!ti) return tr("Unknown");
- QString time_str;
double ts = ui->audioPlot->xAxis->pixelToCoord(ui->audioPlot->mapFromGlobal(QCursor::pos()).x());
- if (ui->todCheckBox->isChecked()) {
- QDateTime date_time = QDateTime::fromMSecsSinceEpoch(ts * 1000.0);
- time_str = date_time.toString("yyyy-MM-dd hh:mm:ss.zzz");
- } else {
- time_str = QString::number(ts, 'f', 3);
- time_str += " s";
- }
- return time_str;
+ return getFormatedTime(ts);
}
int RtpPlayerDialog::getHoveredPacket()
@@ -765,10 +812,22 @@ void RtpPlayerDialog::on_timingComboBox_currentIndexChanged(int)
void RtpPlayerDialog::on_todCheckBox_toggled(bool)
{
QCPAxis *x_axis = ui->audioPlot->xAxis;
- double old_lowest = getLowestTimestamp();
+ double move;
rescanPackets();
- x_axis->moveRange(getLowestTimestamp() - old_lowest);
+ if (ui->todCheckBox->isChecked()) {
+ // rel -> abs
+ // based on abs time of first sample
+ setStartPlayMarker(first_stream_abs_start_time_ + start_marker_time_ - first_stream_rel_start_time_);
+ move = first_stream_abs_start_time_ - first_stream_rel_start_time_;
+ } else {
+ // abs -> rel
+ // based on 0s
+ setStartPlayMarker(first_stream_rel_start_time_ + start_marker_time_);
+ move = - first_stream_abs_start_time_ + first_stream_rel_start_time_;
+ }
+ x_axis->moveRange(move);
+ drawStartPlayMarker();
ui->audioPlot->replot();
}
@@ -777,6 +836,62 @@ void RtpPlayerDialog::on_buttonBox_helpRequested()
wsApp->helpTopicAction(HELP_TELEPHONY_RTP_PLAYER_DIALOG);
}
+double RtpPlayerDialog::getStartPlayMarker()
+{
+ double start_pos;
+
+ if (ui->todCheckBox->isChecked()) {
+ start_pos = start_marker_time_ + first_stream_abs_start_time_;
+ } else {
+ start_pos = start_marker_time_;
+ }
+
+ return start_pos;
+}
+
+void RtpPlayerDialog::drawStartPlayMarker()
+{
+ double pos = getStartPlayMarker();
+
+ start_marker_pos_->point1->setCoords(pos, 0.0);
+ start_marker_pos_->point2->setCoords(pos, 1.0);
+
+ updateHintLabel();
+}
+
+void RtpPlayerDialog::setStartPlayMarker(double time)
+{
+ if (ui->todCheckBox->isChecked()) {
+ time = qBound(first_stream_abs_start_time_, time, first_stream_abs_start_time_ + streams_length_);
+ // start_play_time is relative, we must calculate it
+ start_marker_time_ = time - first_stream_abs_start_time_;
+ } else {
+ time = qBound(first_stream_rel_start_time_, time, first_stream_rel_start_time_ + streams_length_);
+ start_marker_time_ = time;
+ }
+}
+
+void RtpPlayerDialog::updateStartStopTime(rtpstream_info_t *rtpstream, int tli_count)
+{
+ // Calculate start time of first stream and end time of last stream
+ double stream_rel_start_time = nstime_to_sec(&rtpstream->start_rel_time);
+ double stream_abs_start_time = nstime_to_sec(&rtpstream->start_abs_time);
+ double stream_rel_stop_time = nstime_to_sec(&rtpstream->stop_rel_time);
+
+ if (tli_count == 0) {
+ // Take start/stop time for first stream
+ first_stream_rel_start_time_ = stream_rel_start_time;
+ first_stream_abs_start_time_ = stream_abs_start_time;
+ first_stream_rel_stop_time_ = stream_rel_stop_time;
+ } else {
+ // Calculate min/max for start/stop time for other streams
+ first_stream_rel_start_time_ = qMin(first_stream_rel_start_time_, stream_rel_start_time);
+ first_stream_abs_start_time_ = qMin(first_stream_abs_start_time_, stream_abs_start_time);
+ first_stream_rel_stop_time_ = qMax(first_stream_rel_stop_time_, stream_rel_stop_time);
+ }
+ streams_length_ = first_stream_rel_stop_time_ - first_stream_rel_start_time_;
+}
+
#if 0
// This also serves as a title in RtpAudioFrame.
static const QString stream_key_tmpl_ = "%1:%2 " UTF8_RIGHTWARDS_ARROW " %3:%4 0x%5";
diff --git a/ui/qt/rtp_player_dialog.h b/ui/qt/rtp_player_dialog.h
index fe8f833231..d30066e144 100644
--- a/ui/qt/rtp_player_dialog.h
+++ b/ui/qt/rtp_player_dialog.h
@@ -63,6 +63,7 @@ public:
* @param rtpstream struct with rtpstream info
*/
void addRtpStream(rtpstream_info_t *rtpstream);
+ void setMarkers();
public slots:
@@ -83,6 +84,7 @@ private slots:
void rescanPackets(bool rescale_axes = false);
void updateWidgets();
void graphClicked(QMouseEvent *event);
+ void graphDoubleClicked(QMouseEvent *event);
void updateHintLabel();
void resetXAxis();
@@ -111,8 +113,13 @@ private slots:
private:
Ui::RtpPlayerDialog *ui;
QMenu *ctx_menu_;
- double start_rel_time_;
+ double first_stream_rel_start_time_; // Relative start time of first stream
+ double first_stream_abs_start_time_; // Absolute start time of first stream
+ double first_stream_rel_stop_time_; // Relative end time of first stream (ued for streams_length_ calculation
+ double streams_length_; // Difference between start of first stream and end of last stream
+ double start_marker_time_; // Always relative time to start of the capture
QCPItemStraightLine *cur_play_pos_;
+ QCPItemStraightLine *start_marker_pos_;
QString playback_error_;
QSharedPointer<QCPAxisTicker> number_ticker_;
QSharedPointer<QCPAxisTickerDateTime> datetime_ticker_;
@@ -128,10 +135,14 @@ private:
void addPacket(packet_info *pinfo, const struct _rtp_info *rtpinfo);
void zoomXAxis(bool in);
void panXAxis(int x_pixels);
- double getLowestTimestamp();
- const QString getHoveredTime();
+ const QString getFormatedTime(double time);
+ const QString getFormatedHoveredTime();
int getHoveredPacket();
QString currentOutputDeviceName();
+ double getStartPlayMarker();
+ void drawStartPlayMarker();
+ void setStartPlayMarker(double time);
+ void updateStartStopTime(rtpstream_info_t *rtpstream, int tli_count);
#else // QT_MULTIMEDIA_LIB
private:
diff --git a/ui/qt/voip_calls_dialog.cpp b/ui/qt/voip_calls_dialog.cpp
index 3806825a7e..c854296f0f 100644
--- a/ui/qt/voip_calls_dialog.cpp
+++ b/ui/qt/voip_calls_dialog.cpp
@@ -437,6 +437,7 @@ void VoipCallsDialog::showPlayer()
rtp_player_dialog->setWindowModality(Qt::ApplicationModal);
rtp_player_dialog->setAttribute(Qt::WA_DeleteOnClose);
+ rtp_player_dialog->setMarkers();
rtp_player_dialog->show();
#endif // QT_MULTIMEDIA_LIB
}
diff --git a/ui/rtp_stream.h b/ui/rtp_stream.h
index 0858f888b8..3542070e30 100644
--- a/ui/rtp_stream.h
+++ b/ui/rtp_stream.h
@@ -55,6 +55,7 @@ typedef struct _rtpstream_info {
frame_data *stop_fd;
nstime_t start_rel_time; /**< relative start time from pinfo */
nstime_t stop_rel_time; /**< relative stop time from pinfo */
+ nstime_t start_abs_time; /**< abs start time from pinfo */
guint16 vlan_id;
gboolean tag_vlan_error;
gboolean tag_diffserv_error;
diff --git a/ui/tap-rtp-common.c b/ui/tap-rtp-common.c
index 175592d7f6..613f8c5b1b 100644
--- a/ui/tap-rtp-common.c
+++ b/ui/tap-rtp-common.c
@@ -396,6 +396,7 @@ tap_packet_status rtpstream_packet_cb(void *arg, packet_info *pinfo, epan_dissec
if (!stream_info) {
new_stream_info.start_fd = pinfo->fd;
new_stream_info.start_rel_time = pinfo->rel_ts;
+ new_stream_info.start_abs_time = pinfo->abs_ts;
new_stream_info.first_payload_type = rtpinfo->info_payload_type;
new_stream_info.first_payload_type_name = rtpinfo->info_payload_type_str;
diff --git a/ui/voip_calls.c b/ui/voip_calls.c
index 4b9e7b7419..737c01a6ee 100644
--- a/ui/voip_calls.c
+++ b/ui/voip_calls.c
@@ -659,6 +659,7 @@ rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void c
}
strinfo->start_fd = pinfo->fd;
strinfo->start_rel_time = pinfo->rel_ts;
+ strinfo->start_abs_time = pinfo->abs_ts;
strinfo->setup_frame_number = rtp_info->info_setup_frame_num;
strinfo->call_num = -1;
strinfo->rtp_event = -1;