void RtpPlayerDialog::rescanPackets(bool rescale_axes) { int row_count = ui->streamTreeWidget->topLevelItemCount(); // Clear existing graphs and reset stream values 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_); ti->setData(graph_data_col_, Qt::UserRole, QVariant()); } ui->audioPlot->clearGraphs(); bool show_legend = false; bool relative_timestamps = !ui->todCheckBox->isChecked(); ui->audioPlot->xAxis->setTickLabelType(relative_timestamps ? QCPAxis::ltNumber : QCPAxis::ltDateTime); 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*>(); int y_offset = row_count - row - 1; audio_stream->setJitterBufferSize((int) ui->jitterSpinBox->value()); RtpAudioStream::TimingMode timing_mode = RtpAudioStream::JitterBuffer; switch (ui->timingComboBox->currentIndex()) { case RtpAudioStream::RtpTimestamp: timing_mode = RtpAudioStream::RtpTimestamp; break; case RtpAudioStream::Uninterrupted: timing_mode = RtpAudioStream::Uninterrupted; break; default: break; } audio_stream->setTimingMode(timing_mode); audio_stream->decode(); // Waveform QCPGraph *audio_graph = ui->audioPlot->addGraph(); QPen wf_pen(audio_stream->color()); wf_pen.setWidthF(wf_graph_normal_width_); audio_graph->setPen(wf_pen); wf_pen.setWidthF(wf_graph_selected_width_); audio_graph->setSelectedPen(wf_pen); audio_graph->setSelectable(false); audio_graph->setData(audio_stream->visualTimestamps(relative_timestamps), audio_stream->visualSamples(y_offset)); audio_graph->removeFromLegend(); ti->setData(graph_data_col_, Qt::UserRole, QVariant::fromValue<QCPGraph *>(audio_graph)); RTP_STREAM_DEBUG("Plotting %s, %d samples", ti->text(src_addr_col_).toUtf8().constData(), audio_graph->data()->keys().length()); QString span_str = QString("%1 - %2 (%3)") .arg(QString::number(audio_stream->startRelTime(), 'g', 3)) .arg(QString::number(audio_stream->stopRelTime(), 'g', 3)) .arg(QString::number(audio_stream->stopRelTime() - audio_stream->startRelTime(), 'g', 3)); ti->setText(time_span_col_, span_str); ti->setText(sample_rate_col_, QString::number(audio_stream->sampleRate())); ti->setText(payload_col_, audio_stream->payloadNames().join(", ")); if (audio_stream->outOfSequence() > 0) { // Sequence numbers QCPGraph *seq_graph = ui->audioPlot->addGraph(); seq_graph->setLineStyle(QCPGraph::lsNone); seq_graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssSquare, tango_aluminium_6, Qt::white, 4)); // Arbitrary seq_graph->setSelectable(false); seq_graph->setData(audio_stream->outOfSequenceTimestamps(relative_timestamps), audio_stream->outOfSequenceSamples(y_offset)); if (row < 1) { seq_graph->setName(tr("Out of Sequence")); show_legend = true; } else { seq_graph->removeFromLegend(); } } if (audio_stream->jitterDropped() > 0) { // Jitter drops QCPGraph *seq_graph = ui->audioPlot->addGraph(); seq_graph->setLineStyle(QCPGraph::lsNone); seq_graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, tango_scarlet_red_5, Qt::white, 4)); // Arbitrary seq_graph->setSelectable(false); seq_graph->setData(audio_stream->jitterDroppedTimestamps(relative_timestamps), audio_stream->jitterDroppedSamples(y_offset)); if (row < 1) { seq_graph->setName(tr("Jitter Drops")); show_legend = true; } else { seq_graph->removeFromLegend(); } } if (audio_stream->wrongTimestamps() > 0) { // Wrong timestamps QCPGraph *seq_graph = ui->audioPlot->addGraph(); seq_graph->setLineStyle(QCPGraph::lsNone); seq_graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDiamond, tango_sky_blue_5, Qt::white, 4)); // Arbitrary seq_graph->setSelectable(false); seq_graph->setData(audio_stream->wrongTimestampTimestamps(relative_timestamps), audio_stream->wrongTimestampSamples(y_offset)); if (row < 1) { seq_graph->setName(tr("Wrong Timestamps")); show_legend = true; } else { seq_graph->removeFromLegend(); } } if (audio_stream->insertedSilences() > 0) { // Inserted silence QCPGraph *seq_graph = ui->audioPlot->addGraph(); seq_graph->setLineStyle(QCPGraph::lsNone); seq_graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssTriangle, tango_butter_5, Qt::white, 4)); // Arbitrary seq_graph->setSelectable(false); seq_graph->setData(audio_stream->insertedSilenceTimestamps(relative_timestamps), audio_stream->insertedSilenceSamples(y_offset)); if (row < 1) { seq_graph->setName(tr("Inserted Silence")); show_legend = true; } else { seq_graph->removeFromLegend(); } } } ui->audioPlot->legend->setVisible(show_legend); for (int col = 0; col < ui->streamTreeWidget->columnCount() - 1; col++) { ui->streamTreeWidget->resizeColumnToContents(col); } ui->audioPlot->replot(); if (rescale_axes) resetXAxis(); updateWidgets(); }
void RtpPlayerDialog::retapPackets(bool rescale_axes) { int row_count = ui->streamTreeWidget->topLevelItemCount(); // Clear existing graphs and reset stream values 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_); ti->setData(graph_data_col_, Qt::UserRole, QVariant()); } ui->audioPlot->clearGraphs(); register_tap_listener("rtp", this, NULL, 0, NULL, tapPacket, NULL); cap_file_.retapPackets(); remove_tap_listener(this); bool show_legend = false; bool relative_timestamps = !ui->todCheckBox->isChecked(); ui->audioPlot->xAxis->setTickLabelType(relative_timestamps ? QCPAxis::ltNumber : QCPAxis::ltDateTime); 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*>(); int y_offset = row_count - row - 1; // Waveform QCPGraph *audio_graph = ui->audioPlot->addGraph(); QPen wf_pen(audio_stream->color()); wf_pen.setWidthF(wf_graph_normal_width_); audio_graph->setPen(wf_pen); wf_pen.setWidthF(wf_graph_selected_width_); audio_graph->setSelectedPen(wf_pen); audio_graph->setSelectable(false); audio_graph->setData(audio_stream->visualTimestamps(relative_timestamps), audio_stream->visualSamples(y_offset)); audio_graph->removeFromLegend(); ti->setData(graph_data_col_, Qt::UserRole, QVariant::fromValue<QCPGraph *>(audio_graph)); // RTP_STREAM_DEBUG("Plotting %s, %d samples", ti->text(src_addr_col_).toUtf8().constData(), audio_graph->data()->keys().length()); QString span_str = QString("%1 - %2 (%3)") .arg(QString::number(audio_stream->startRelTime(), 'g', 3)) .arg(QString::number(audio_stream->stopRelTime(), 'g', 3)) .arg(QString::number(audio_stream->stopRelTime() - audio_stream->startRelTime(), 'g', 3)); ti->setText(time_span_col_, span_str); ti->setText(sample_rate_col_, QString::number(audio_stream->sampleRate())); ti->setText(payload_col_, audio_stream->payloadNames().join(", ")); if (audio_stream->outOfSequence() > 0) { // Sequence numbers QCPGraph *seq_graph = ui->audioPlot->addGraph(); seq_graph->setLineStyle(QCPGraph::lsNone); seq_graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssSquare, tango_aluminium_6, Qt::white, 4)); // Arbitrary seq_graph->setSelectable(false); seq_graph->setData(audio_stream->outOfSequenceTimestamps(relative_timestamps), audio_stream->outOfSequenceSamples(y_offset)); if (row < 1) { seq_graph->setName(tr("Out of Sequence")); show_legend = true; } else { seq_graph->removeFromLegend(); } } } ui->audioPlot->legend->setVisible(show_legend); for (int col = 0; col < ui->streamTreeWidget->columnCount() - 1; col++) { ui->streamTreeWidget->resizeColumnToContents(col); } ui->audioPlot->replot(); if (rescale_axes) resetXAxis(); updateWidgets(); }