RTP Player: UI improvements

Changes:
- all waveforms has common scale therefore louder/quiter signal is visible
- when stream/streams are deleted from view, Y axis is rescaled and
  waveforms are rearranged to reuse empty space
This commit is contained in:
Jirka Novak 2021-03-23 09:48:20 +01:00 committed by Wireshark GitLab Utility
parent 2e6d3b571b
commit 2a4859bd14
5 changed files with 49 additions and 7 deletions

View File

@ -52,6 +52,7 @@ RtpAudioStream::RtpAudioStream(QObject *parent, rtpstream_info_t *rtpstream, boo
audio_resampler_(0),
audio_output_(0),
max_sample_val_(1),
max_sample_val_used_(1),
color_(0),
jitter_buffer_size_(50),
timing_mode_(RtpAudioStream::JitterBuffer),
@ -457,6 +458,7 @@ void RtpAudioStream::decodeVisual()
}
}
max_sample_val_used_ = max_sample_val_;
g_free(resample_buff);
g_free(read_buff);
}
@ -480,18 +482,15 @@ const QVector<double> RtpAudioStream::visualTimestamps(bool relative)
return adj_timestamps;
}
// Scale the height of the waveform (max_sample_val_) and adjust its Y
// offset so that they overlap slightly (stack_offset_).
// XXX This means that waveforms can be misleading with respect to relative
// amplitude. We might want to add a "global" max_sample_val_.
// Scale the height of the waveform to global scale (max_sample_val_used_)
// and adjust its Y offset so that they overlap slightly (stack_offset_).
static const double stack_offset_ = G_MAXINT16 / 3;
const QVector<double> RtpAudioStream::visualSamples(int y_offset)
{
QVector<double> adj_samples;
double scaled_offset = y_offset * stack_offset_;
for (int i = 0; i < visual_samples_.size(); i++) {
adj_samples.append(((double)visual_samples_[i] * G_MAXINT16 / max_sample_val_) + scaled_offset);
adj_samples.append(((double)visual_samples_[i] * G_MAXINT16 / max_sample_val_used_) + scaled_offset);
}
return adj_samples;
}

View File

@ -144,6 +144,8 @@ public:
void pausePlaying();
void stopPlaying();
void setStereoRequired(bool stereo_required) { stereo_required_ = stereo_required; }
qint16 getMaxSampleValue() { return max_sample_val_; }
void setMaxSampleValue(gint16 max_sample_val) { max_sample_val_used_ = max_sample_val; }
signals:
void processedSecs(double secs);
@ -181,6 +183,7 @@ private:
QVector<double> wrong_timestamp_timestamps_;
QVector<double> silence_timestamps_;
qint16 max_sample_val_;
qint16 max_sample_val_used_;
QRgb color_;
int jitter_buffer_size_;

View File

@ -411,6 +411,7 @@ void RtpPlayerDialog::createPlot(bool rescale_axes)
bool legend_inserted_silences = false;
bool relative_timestamps = !ui->todCheckBox->isChecked();
int row_count = ui->streamTreeWidget->topLevelItemCount();
gint16 total_max_sample_value = 1;
ui->audioPlot->clearGraphs();
@ -420,6 +421,17 @@ void RtpPlayerDialog::createPlot(bool rescale_axes)
ui->audioPlot->xAxis->setTicker(datetime_ticker_);
}
// Calculate common Y scale for graphs
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*>();
gint16 max_sample_value = audio_stream->getMaxSampleValue();
if (max_sample_value > total_max_sample_value) {
total_max_sample_value = max_sample_value;
}
}
// Clear existing graphs
for (int row = 0; row < row_count; row++) {
QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row);
@ -433,6 +445,9 @@ void RtpPlayerDialog::createPlot(bool rescale_axes)
ti->setData(graph_timestamp_data_col_, Qt::UserRole, QVariant());
ti->setData(graph_silence_data_col_, Qt::UserRole, QVariant());
// Set common scale
audio_stream->setMaxSampleValue(total_max_sample_value);
// Waveform
RtpAudioGraph *audio_graph = new RtpAudioGraph(ui->audioPlot, audio_stream->color());
audio_graph->setMuted(audio_routing.isMuted());
@ -933,6 +948,22 @@ void RtpPlayerDialog::resetXAxis()
ap->replot();
}
void RtpPlayerDialog::updateGraphs()
{
QCustomPlot *ap = ui->audioPlot;
// Create new plots, just existing ones
createPlot(false);
// Rescale Y axis
double pixel_pad = 10.0; // per side
double axis_pixels = ap->yAxis->axisRect()->height();
ap->yAxis->rescale(true);
ap->yAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels, ap->yAxis->range().center());
ap->replot();
}
void RtpPlayerDialog::playFinished(RtpAudioStream *stream)
{
playing_streams_.removeOne(stream);
@ -1287,7 +1318,12 @@ void RtpPlayerDialog::on_actionRemoveStream_triggered()
delete ti;
}
ui->audioPlot->replot();
// 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
// Redraw existing waveforms and rescale Y axis
updateGraphs();
updateWidgets();
}

View File

@ -97,6 +97,7 @@ private slots:
void plotClicked(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event);
void updateHintLabel();
void resetXAxis();
void updateGraphs();
void playFinished(RtpAudioStream *stream);
void setPlayPosition(double secs);

View File

@ -134,6 +134,9 @@ gboolean rtpstream_save(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rt
*/
void rtpstream_mark(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtpstream_info_t* stream_fwd, rtpstream_info_t* stream_rev);
/* Constant based on fix for bug 4119/5902: don't insert too many silence
* frames.
*/
#define MAX_SILENCE_FRAMES 14400000
#ifdef __cplusplus