aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
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;