forked from osmocom/wireshark
parent
d2b6b89b94
commit
b8d85227f6
|
@ -1210,12 +1210,13 @@ if(BUILD_wireshark OR BUILD_logray)
|
|||
Qt${qtver}Core
|
||||
Qt${qtver}Gui
|
||||
Qt${qtver}LinguistTools
|
||||
# Our code currently does not compile with Qt6Multimedia
|
||||
# Qt${qtver}Multimedia
|
||||
Qt${qtver}PrintSupport
|
||||
Qt${qtver}Widgets
|
||||
Qt${qtver}Concurrent
|
||||
)
|
||||
set(QT_OPTIONAL_PACKAGELIST
|
||||
Qt${qtver}Multimedia
|
||||
)
|
||||
if(USE_qt6)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
# Setting CMAKE_CXX_STANDARD is not sufficient with MSVC, see
|
||||
|
@ -1226,7 +1227,6 @@ if(BUILD_wireshark OR BUILD_logray)
|
|||
endif()
|
||||
list(APPEND QT_PACKAGELIST Qt6Core5Compat)
|
||||
else()
|
||||
list(APPEND QT_PACKAGELIST Qt5Multimedia)
|
||||
if(WIN32)
|
||||
list(APPEND QT_PACKAGELIST Qt5WinExtras)
|
||||
endif()
|
||||
|
@ -1237,6 +1237,12 @@ if(BUILD_wireshark OR BUILD_logray)
|
|||
list(APPEND QT_INCLUDE_DIRS ${${_qt_package}_INCLUDE_DIRS})
|
||||
list(APPEND QT_COMPILE_DEFINITIONS ${${_qt_package}_COMPILE_DEFINITIONS})
|
||||
endforeach()
|
||||
foreach(_qt_package IN LISTS QT_OPTIONAL_PACKAGELIST)
|
||||
find_package(${_qt_package} ${QT_FIND_PACKAGE_OPTIONS})
|
||||
list(APPEND QT_LIBRARIES ${${_qt_package}_LIBRARIES})
|
||||
list(APPEND QT_INCLUDE_DIRS ${${_qt_package}_INCLUDE_DIRS})
|
||||
list(APPEND QT_COMPILE_DEFINITIONS ${${_qt_package}_COMPILE_DEFINITIONS})
|
||||
endforeach()
|
||||
if(APPLE AND "/usr/local/opt/qt5/lib/QtCore.framework" IN_LIST Qt5Core_INCLUDE_DIRS)
|
||||
# When qt@6 and qt@5 are both installed via Homebrew,
|
||||
# /usr/local/include/QtCore/qvariant.h points to Qt 6 headers.
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
#include <ui/qt/utils/rtp_audio_routing_filter.h>
|
||||
#include <ui/qt/utils/rtp_audio_file.h>
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
#include <QAudioDevice>
|
||||
#include <QAudioSink>
|
||||
#endif
|
||||
#include <QAudioFormat>
|
||||
#include <QAudioOutput>
|
||||
#include <QVariant>
|
||||
|
@ -54,13 +58,13 @@ RtpAudioStream::RtpAudioStream(QObject *parent, rtpstream_id_t *id, bool stereo_
|
|||
, audio_out_rate_(0)
|
||||
, audio_requested_out_rate_(0)
|
||||
, audio_resampler_(0)
|
||||
, audio_output_(NULL)
|
||||
, max_sample_val_(1)
|
||||
, max_sample_val_used_(1)
|
||||
, color_(0)
|
||||
, jitter_buffer_size_(50)
|
||||
, timing_mode_(RtpAudioStream::JitterBuffer)
|
||||
, start_play_time_(0)
|
||||
, audio_output_(NULL)
|
||||
{
|
||||
rtpstream_id_copy(id, &id_);
|
||||
memset(&rtpstream_, 0, sizeof(rtpstream_));
|
||||
|
@ -181,7 +185,11 @@ void RtpAudioStream::setAudioRouting(AudioRouting audio_routing)
|
|||
audio_routing_ = audio_routing;
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
void RtpAudioStream::decode(QAudioDevice out_device)
|
||||
#else
|
||||
void RtpAudioStream::decode(QAudioDeviceInfo out_device)
|
||||
#endif
|
||||
{
|
||||
if (rtp_packets_.size() < 1) return;
|
||||
|
||||
|
@ -200,7 +208,11 @@ void RtpAudioStream::decode(QAudioDeviceInfo out_device)
|
|||
}
|
||||
|
||||
// Side effect: it creates and initiates resampler if needed
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
quint32 RtpAudioStream::calculateAudioOutRate(QAudioDevice out_device, unsigned int sample_rate, unsigned int requested_out_rate)
|
||||
#else
|
||||
quint32 RtpAudioStream::calculateAudioOutRate(QAudioDeviceInfo out_device, unsigned int sample_rate, unsigned int requested_out_rate)
|
||||
#endif
|
||||
{
|
||||
quint32 out_rate;
|
||||
|
||||
|
@ -208,19 +220,30 @@ quint32 RtpAudioStream::calculateAudioOutRate(QAudioDeviceInfo out_device, unsig
|
|||
// our audio hardware.
|
||||
QAudioFormat format;
|
||||
format.setSampleRate(sample_rate);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
// Must match rtp_media.h.
|
||||
format.setSampleFormat(QAudioFormat::Int16);
|
||||
#else
|
||||
format.setSampleSize(SAMPLE_BYTES * 8); // bits
|
||||
format.setSampleType(QAudioFormat::SignedInt);
|
||||
#endif
|
||||
if (stereo_required_) {
|
||||
format.setChannelCount(2);
|
||||
} else {
|
||||
format.setChannelCount(1);
|
||||
}
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
format.setCodec("audio/pcm");
|
||||
#endif
|
||||
|
||||
if (!out_device.isFormatSupported(format) &&
|
||||
(requested_out_rate==0)
|
||||
) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
out_rate = out_device.preferredFormat().sampleRate();
|
||||
#else
|
||||
out_rate = out_device.nearestFormat(format).sampleRate();
|
||||
#endif
|
||||
audio_resampler_ = speex_resampler_init(1, sample_rate, out_rate, 10, NULL);
|
||||
RTP_STREAM_DEBUG("Started resampling from %u to (out) %u Hz.", sample_rate, out_rate);
|
||||
} else {
|
||||
|
@ -240,7 +263,11 @@ quint32 RtpAudioStream::calculateAudioOutRate(QAudioDeviceInfo out_device, unsig
|
|||
return out_rate;
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
void RtpAudioStream::decodeAudio(QAudioDevice out_device)
|
||||
#else
|
||||
void RtpAudioStream::decodeAudio(QAudioDeviceInfo out_device)
|
||||
#endif
|
||||
{
|
||||
// XXX This is more messy than it should be.
|
||||
|
||||
|
@ -607,10 +634,10 @@ const QVector<double> RtpAudioStream::insertedSilenceSamples(int y_offset)
|
|||
|
||||
quint32 RtpAudioStream::nearestPacket(double timestamp, bool is_relative)
|
||||
{
|
||||
if (packet_timestamps_.keys().count() < 1) return 0;
|
||||
if (packet_timestamps_.size() < 1) return 0;
|
||||
|
||||
if (!is_relative) timestamp -= start_abs_offset_;
|
||||
QMap<double, quint32>::const_iterator it = packet_timestamps_.lowerBound(timestamp);
|
||||
QMap<double, quint32>::iterator it = packet_timestamps_.lowerBound(timestamp);
|
||||
if (it == packet_timestamps_.end()) return 0;
|
||||
return it.value();
|
||||
}
|
||||
|
@ -624,12 +651,16 @@ QAudio::State RtpAudioStream::outputState() const
|
|||
const QString RtpAudioStream::formatDescription(const QAudioFormat &format)
|
||||
{
|
||||
QString fmt_descr = QString("%1 Hz, ").arg(format.sampleRate());
|
||||
switch (format.sampleType()) {
|
||||
case QAudioFormat::SignedInt:
|
||||
fmt_descr += "Int";
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
switch (format.sampleFormat()) {
|
||||
case QAudioFormat::UInt8:
|
||||
fmt_descr += "UInt8";
|
||||
break;
|
||||
case QAudioFormat::UnSignedInt:
|
||||
fmt_descr += "UInt";
|
||||
case QAudioFormat::Int16:
|
||||
fmt_descr += "Int16";
|
||||
break;
|
||||
case QAudioFormat::Int32:
|
||||
fmt_descr += "Int32";
|
||||
break;
|
||||
case QAudioFormat::Float:
|
||||
fmt_descr += "Float";
|
||||
|
@ -638,8 +669,26 @@ const QString RtpAudioStream::formatDescription(const QAudioFormat &format)
|
|||
fmt_descr += "Unknown";
|
||||
break;
|
||||
}
|
||||
fmt_descr += QString::number(format.sampleSize());
|
||||
fmt_descr += format.byteOrder() == QAudioFormat::BigEndian ? "BE" : "LE";
|
||||
#else
|
||||
switch (format.sampleType()) {
|
||||
case QAudioFormat::SignedInt:
|
||||
fmt_descr += "Int";
|
||||
fmt_descr += QString::number(format.sampleSize());
|
||||
fmt_descr += format.byteOrder() == QAudioFormat::BigEndian ? "BE" : "LE";
|
||||
break;
|
||||
case QAudioFormat::UnSignedInt:
|
||||
fmt_descr += "UInt";
|
||||
fmt_descr += QString::number(format.sampleSize());
|
||||
fmt_descr += format.byteOrder() == QAudioFormat::BigEndian ? "BE" : "LE";
|
||||
break;
|
||||
case QAudioFormat::Float:
|
||||
fmt_descr += "Float";
|
||||
break;
|
||||
default:
|
||||
fmt_descr += "Unknown";
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return fmt_descr;
|
||||
}
|
||||
|
@ -660,7 +709,11 @@ QString RtpAudioStream::getIDAsQString()
|
|||
return str;
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
bool RtpAudioStream::prepareForPlay(QAudioDevice out_device)
|
||||
#else
|
||||
bool RtpAudioStream::prepareForPlay(QAudioDeviceInfo out_device)
|
||||
#endif
|
||||
{
|
||||
qint64 start_pos;
|
||||
qint64 size;
|
||||
|
@ -683,24 +736,36 @@ bool RtpAudioStream::prepareForPlay(QAudioDeviceInfo out_device)
|
|||
|
||||
QAudioFormat format;
|
||||
format.setSampleRate(audio_out_rate_);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
// Must match rtp_media.h.
|
||||
format.setSampleFormat(QAudioFormat::Int16);
|
||||
#else
|
||||
format.setSampleSize(SAMPLE_BYTES * 8); // bits
|
||||
format.setSampleType(QAudioFormat::SignedInt);
|
||||
#endif
|
||||
if (stereo_required_) {
|
||||
format.setChannelCount(2);
|
||||
} else {
|
||||
format.setChannelCount(1);
|
||||
}
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
format.setCodec("audio/pcm");
|
||||
#endif
|
||||
|
||||
// RTP_STREAM_DEBUG("playing %s %d samples @ %u Hz",
|
||||
// sample_file_->fileName().toUtf8().constData(),
|
||||
// (int) sample_file_->size(), audio_out_rate_);
|
||||
|
||||
if (!out_device.isFormatSupported(format)) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
QString playback_error = tr("%1 does not support PCM at %2. Preferred format is %3")
|
||||
.arg(out_device.description(), formatDescription(format), formatDescription(out_device.preferredFormat()));
|
||||
#else
|
||||
QString playback_error = tr("%1 does not support PCM at %2. Preferred format is %3")
|
||||
.arg(out_device.deviceName())
|
||||
.arg(formatDescription(format))
|
||||
.arg(formatDescription(out_device.nearestFormat(format)));
|
||||
#endif
|
||||
emit playbackError(playback_error);
|
||||
}
|
||||
|
||||
|
@ -718,8 +783,13 @@ bool RtpAudioStream::prepareForPlay(QAudioDeviceInfo out_device)
|
|||
temp_file_ = new AudioRoutingFilter(audio_file_, stereo_required_, audio_routing_);
|
||||
temp_file_->seek(start_pos);
|
||||
if (audio_output_) delete audio_output_;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
audio_output_ = new QAudioSink(out_device, format, this);
|
||||
connect(audio_output_, &QAudioSink::stateChanged, this, &RtpAudioStream::outputStateChanged);
|
||||
#else
|
||||
audio_output_ = new QAudioOutput(out_device, format, this);
|
||||
connect(audio_output_, &QAudioOutput::stateChanged, this, &RtpAudioStream::outputStateChanged);
|
||||
#endif
|
||||
return true;
|
||||
} else {
|
||||
// Report stopped audio if start position is later than stream ends
|
||||
|
|
|
@ -32,7 +32,11 @@
|
|||
#include <QAudioOutput>
|
||||
|
||||
class QAudioFormat;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
class QAudioSink;
|
||||
#else
|
||||
class QAudioOutput;
|
||||
#endif
|
||||
class QIODevice;
|
||||
|
||||
|
||||
|
@ -51,7 +55,11 @@ public:
|
|||
void reset(double global_start_time);
|
||||
AudioRouting getAudioRouting();
|
||||
void setAudioRouting(AudioRouting audio_routing);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
void decode(QAudioDevice out_device);
|
||||
#else
|
||||
void decode(QAudioDeviceInfo out_device);
|
||||
#endif
|
||||
|
||||
double startRelTime() const { return start_rel_time_; }
|
||||
double stopRelTime() const { return stop_rel_time_; }
|
||||
|
@ -78,7 +86,7 @@ public:
|
|||
* @return A set of timestamps suitable for passing to QCPGraph::setData.
|
||||
*/
|
||||
const QVector<double> outOfSequenceTimestamps(bool relative = true);
|
||||
int outOfSequence() { return out_of_seq_timestamps_.size(); }
|
||||
int outOfSequence() { return static_cast<int>(out_of_seq_timestamps_.size()); }
|
||||
/**
|
||||
* @brief Return a list of out-of-sequence samples. Y value is constant.
|
||||
* @param y_offset Y axis offset to be used for stacking graphs.
|
||||
|
@ -91,7 +99,7 @@ public:
|
|||
* @return A set of timestamps suitable for passing to QCPGraph::setData.
|
||||
*/
|
||||
const QVector<double> jitterDroppedTimestamps(bool relative = true);
|
||||
int jitterDropped() { return jitter_drop_timestamps_.size(); }
|
||||
int jitterDropped() { return static_cast<int>(jitter_drop_timestamps_.size()); }
|
||||
/**
|
||||
* @brief Return a list of jitter dropped samples. Y value is constant.
|
||||
* @param y_offset Y axis offset to be used for stacking graphs.
|
||||
|
@ -104,7 +112,7 @@ public:
|
|||
* @return A set of timestamps suitable for passing to QCPGraph::setData.
|
||||
*/
|
||||
const QVector<double> wrongTimestampTimestamps(bool relative = true);
|
||||
int wrongTimestamps() { return wrong_timestamp_timestamps_.size(); }
|
||||
int wrongTimestamps() { return static_cast<int>(wrong_timestamp_timestamps_.size()); }
|
||||
/**
|
||||
* @brief Return a list of wrong timestamp samples. Y value is constant.
|
||||
* @param y_offset Y axis offset to be used for stacking graphs.
|
||||
|
@ -117,7 +125,7 @@ public:
|
|||
* @return A set of timestamps suitable for passing to QCPGraph::setData.
|
||||
*/
|
||||
const QVector<double> insertedSilenceTimestamps(bool relative = true);
|
||||
int insertedSilences() { return silence_timestamps_.size(); }
|
||||
int insertedSilences() { return static_cast<int>(silence_timestamps_.size()); }
|
||||
/**
|
||||
* @brief Return a list of wrong timestamp samples. Y value is constant.
|
||||
* @param y_offset Y axis offset to be used for stacking graphs.
|
||||
|
@ -135,7 +143,11 @@ 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; }
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
bool prepareForPlay(QAudioDevice out_device);
|
||||
#else
|
||||
bool prepareForPlay(QAudioDeviceInfo out_device);
|
||||
#endif
|
||||
void startPlaying();
|
||||
void pausePlaying();
|
||||
void stopPlaying();
|
||||
|
@ -185,7 +197,6 @@ private:
|
|||
QSet<QString> payload_names_;
|
||||
struct SpeexResamplerState_ *audio_resampler_;
|
||||
struct SpeexResamplerState_ *visual_resampler_;
|
||||
QAudioOutput *audio_output_;
|
||||
QMap<double, quint32> packet_timestamps_;
|
||||
QVector<qint16> visual_samples_;
|
||||
QVector<double> out_of_seq_timestamps_;
|
||||
|
@ -203,9 +214,16 @@ private:
|
|||
const QString formatDescription(const QAudioFormat & format);
|
||||
QString currentOutputDevice();
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
QAudioSink *audio_output_;
|
||||
void decodeAudio(QAudioDevice out_device);
|
||||
quint32 calculateAudioOutRate(QAudioDevice out_device, unsigned int sample_rate, unsigned int requested_out_rate);
|
||||
#else
|
||||
QAudioOutput *audio_output_;
|
||||
void decodeAudio(QAudioDeviceInfo out_device);
|
||||
void decodeVisual();
|
||||
quint32 calculateAudioOutRate(QAudioDeviceInfo out_device, unsigned int sample_rate, unsigned int requested_out_rate);
|
||||
#endif
|
||||
void decodeVisual();
|
||||
SAMPLE *resizeBufferIfNeeded(SAMPLE *buff, gint32 *buff_bytes, qint64 requested_size);
|
||||
|
||||
private slots:
|
||||
|
|
|
@ -39,7 +39,13 @@
|
|||
#include "ui/qt/widgets/wireshark_file_dialog.h"
|
||||
|
||||
#include <QAudio>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
#include <QAudioDevice>
|
||||
#include <QAudioSink>
|
||||
#include <QMediaDevices>
|
||||
#else
|
||||
#include <QAudioDeviceInfo>
|
||||
#endif
|
||||
#include <QFrame>
|
||||
#include <QMenu>
|
||||
#include <QVBoxLayout>
|
||||
|
@ -216,6 +222,11 @@ RtpPlayerDialog::RtpPlayerDialog(QWidget &parent, CaptureFile &cf, bool capture_
|
|||
drawStartPlayMarker();
|
||||
start_marker_pos_->setVisible(true);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
notify_timer_.setInterval(100); // ~15 fps
|
||||
connect(¬ify_timer_, &QTimer::timeout, this, &RtpPlayerDialog::outputNotify);
|
||||
#endif
|
||||
|
||||
datetime_ticker_->setDateTimeFormat("yyyy-MM-dd\nhh:mm:ss.zzz");
|
||||
|
||||
ui->audioPlot->xAxis->setNumberFormat("gb");
|
||||
|
@ -264,12 +275,21 @@ RtpPlayerDialog::RtpPlayerDialog(QWidget &parent, CaptureFile &cf, bool capture_
|
|||
|
||||
// Ordered, unique device names starting with the system default
|
||||
QMap<QString, bool> out_device_map; // true == default device
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
out_device_map.insert(QMediaDevices::defaultAudioOutput().description(), true);
|
||||
foreach (QAudioDevice out_device, QMediaDevices::audioOutputs()) {
|
||||
if (!out_device_map.contains(out_device.description())) {
|
||||
out_device_map.insert(out_device.description(), false);
|
||||
}
|
||||
}
|
||||
#else
|
||||
out_device_map.insert(QAudioDeviceInfo::defaultOutputDevice().deviceName(), true);
|
||||
foreach (QAudioDeviceInfo out_device, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)) {
|
||||
if (!out_device_map.contains(out_device.deviceName())) {
|
||||
out_device_map.insert(out_device.deviceName(), false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ui->outputDeviceComboBox->blockSignals(true);
|
||||
foreach (QString out_name, out_device_map.keys()) {
|
||||
|
@ -460,7 +480,11 @@ void RtpPlayerDialog::rescanPackets(bool rescale_axes)
|
|||
ui->hintLabel->setText("<i><small>" + tr("Decoding streams...") + "</i></small>");
|
||||
mainApp->processEvents();
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
QAudioDevice cur_out_device = getCurrentDeviceInfo();
|
||||
#else
|
||||
QAudioDeviceInfo cur_out_device = getCurrentDeviceInfo();
|
||||
#endif
|
||||
int row_count = ui->streamTreeWidget->topLevelItemCount();
|
||||
|
||||
// Reset stream values
|
||||
|
@ -1000,7 +1024,7 @@ void RtpPlayerDialog::updateWidgets()
|
|||
bool enable_stop = false;
|
||||
bool enable_timing = true;
|
||||
int count = ui->streamTreeWidget->topLevelItemCount();
|
||||
int selected = ui->streamTreeWidget->selectedItems().count();
|
||||
qsizetype selected = ui->streamTreeWidget->selectedItems().count();
|
||||
|
||||
if (count < 1) {
|
||||
enable_play = false;
|
||||
|
@ -1177,7 +1201,7 @@ void RtpPlayerDialog::updateHintLabel()
|
|||
QString hint = "<small><i>";
|
||||
double start_pos = getStartPlayMarker();
|
||||
int row_count = ui->streamTreeWidget->topLevelItemCount();
|
||||
int selected = ui->streamTreeWidget->selectedItems().count();
|
||||
qsizetype selected = ui->streamTreeWidget->selectedItems().count();
|
||||
int not_muted = 0;
|
||||
|
||||
hint += tr("%1 streams").arg(row_count);
|
||||
|
@ -1368,7 +1392,11 @@ void RtpPlayerDialog::on_playButton_clicked()
|
|||
start_time = start_marker_time_play_ - first_stream_rel_start_time_;
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
QAudioDevice cur_out_device = getCurrentDeviceInfo();
|
||||
#else
|
||||
QAudioDeviceInfo cur_out_device = getCurrentDeviceInfo();
|
||||
#endif
|
||||
playing_streams_.clear();
|
||||
int row_count = ui->streamTreeWidget->topLevelItemCount();
|
||||
for (int row = 0; row < row_count; row++) {
|
||||
|
@ -1397,6 +1425,29 @@ void RtpPlayerDialog::on_playButton_clicked()
|
|||
updateWidgets();
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
QAudioDevice RtpPlayerDialog::getCurrentDeviceInfo()
|
||||
{
|
||||
QAudioDevice cur_out_device = QMediaDevices::defaultAudioOutput();
|
||||
QString cur_out_name = currentOutputDeviceName();
|
||||
foreach (QAudioDevice out_device, QMediaDevices::audioOutputs()) {
|
||||
if (cur_out_name == out_device.description()) {
|
||||
cur_out_device = out_device;
|
||||
}
|
||||
}
|
||||
|
||||
return cur_out_device;
|
||||
}
|
||||
|
||||
void RtpPlayerDialog::sinkStateChanged()
|
||||
{
|
||||
if (marker_stream_->state() == QAudio::ActiveState) {
|
||||
notify_timer_.start();
|
||||
} else {
|
||||
notify_timer_.stop();
|
||||
}
|
||||
}
|
||||
#else
|
||||
QAudioDeviceInfo RtpPlayerDialog::getCurrentDeviceInfo()
|
||||
{
|
||||
QAudioDeviceInfo cur_out_device = QAudioDeviceInfo::defaultOutputDevice();
|
||||
|
@ -1409,7 +1460,31 @@ QAudioDeviceInfo RtpPlayerDialog::getCurrentDeviceInfo()
|
|||
|
||||
return cur_out_device;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
QAudioSink *RtpPlayerDialog::getSilenceAudioOutput()
|
||||
{
|
||||
QAudioDevice cur_out_device = getCurrentDeviceInfo();
|
||||
|
||||
QAudioFormat format;
|
||||
if (marker_stream_requested_out_rate_ > 0) {
|
||||
format.setSampleRate(marker_stream_requested_out_rate_);
|
||||
} else {
|
||||
format.setSampleRate(8000);
|
||||
}
|
||||
// Must match rtp_media.h.
|
||||
format.setSampleFormat(QAudioFormat::Int16);
|
||||
format.setChannelCount(1);
|
||||
if (!cur_out_device.isFormatSupported(format)) {
|
||||
format = cur_out_device.preferredFormat();
|
||||
}
|
||||
|
||||
QAudioSink *sink = new QAudioSink(cur_out_device, format, this);
|
||||
connect(sink, &QAudioSink::stateChanged, this, &RtpPlayerDialog::sinkStateChanged);
|
||||
return sink;
|
||||
}
|
||||
#else
|
||||
QAudioOutput *RtpPlayerDialog::getSilenceAudioOutput()
|
||||
{
|
||||
QAudioOutput *o;
|
||||
|
@ -1431,10 +1506,11 @@ QAudioOutput *RtpPlayerDialog::getSilenceAudioOutput()
|
|||
|
||||
o = new QAudioOutput(cur_out_device, format, this);
|
||||
o->setNotifyInterval(100); // ~15 fps
|
||||
connect(o, SIGNAL(notify()), this, SLOT(outputNotify()));
|
||||
connect(o, &QAudioOutput::notify, this, &RtpPlayerDialog::outputNotify);
|
||||
|
||||
return o;
|
||||
}
|
||||
#endif
|
||||
|
||||
void RtpPlayerDialog::outputNotify()
|
||||
{
|
||||
|
@ -1591,7 +1667,7 @@ void RtpPlayerDialog::on_streamTreeWidget_itemSelectionChanged()
|
|||
}
|
||||
}
|
||||
|
||||
int selected = ui->streamTreeWidget->selectedItems().count();
|
||||
qsizetype selected = ui->streamTreeWidget->selectedItems().count();
|
||||
if (selected == 0) {
|
||||
analyze_btn_->setEnabled(false);
|
||||
prepare_btn_->setEnabled(false);
|
||||
|
@ -1682,7 +1758,7 @@ void RtpPlayerDialog::on_actionRemoveStream_triggered()
|
|||
QList<QTreeWidgetItem *> items = ui->streamTreeWidget->selectedItems();
|
||||
|
||||
block_redraw_ = true;
|
||||
for(int i = items.count() - 1; i>=0; i-- ) {
|
||||
for(int i = static_cast<int>(items.count()) - 1; i>=0; i-- ) {
|
||||
removeRow(items[i]);
|
||||
}
|
||||
block_redraw_ = false;
|
||||
|
@ -1859,9 +1935,22 @@ void RtpPlayerDialog::fillAudioRateMenu()
|
|||
ui->outputAudioRate->blockSignals(true);
|
||||
ui->outputAudioRate->clear();
|
||||
ui->outputAudioRate->addItem(tr("Automatic"));
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
// XXX QAudioDevice doesn't provide supportedSampleRates(). Fake it with
|
||||
// what's available.
|
||||
QAudioDevice cur_out_device = getCurrentDeviceInfo();
|
||||
QSet<int>sample_rates;
|
||||
sample_rates.insert(cur_out_device.minimumSampleRate());
|
||||
sample_rates.insert(cur_out_device.preferredFormat().sampleRate());
|
||||
sample_rates.insert(cur_out_device.maximumSampleRate());
|
||||
for (auto rate : sample_rates) {
|
||||
ui->outputAudioRate->addItem(QString::number(rate));
|
||||
}
|
||||
#else
|
||||
foreach (int rate, getCurrentDeviceInfo().supportedSampleRates()) {
|
||||
ui->outputAudioRate->addItem(QString::number(rate));
|
||||
}
|
||||
#endif
|
||||
ui->outputAudioRate->blockSignals(false);
|
||||
}
|
||||
|
||||
|
@ -2017,12 +2106,19 @@ void RtpPlayerDialog::formatAudioRouting(QTreeWidgetItem *ti, AudioRouting audio
|
|||
|
||||
bool RtpPlayerDialog::isStereoAvailable()
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
QAudioDevice cur_out_device = getCurrentDeviceInfo();
|
||||
if (cur_out_device.maximumChannelCount() > 1) {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
QAudioDeviceInfo cur_out_device = getCurrentDeviceInfo();
|
||||
foreach(int count, cur_out_device.supportedChannelCounts()) {
|
||||
if (count>1) {
|
||||
if (count > 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2075,7 +2171,7 @@ void RtpPlayerDialog::on_actionStop_triggered()
|
|||
}
|
||||
}
|
||||
|
||||
qint64 RtpPlayerDialog::saveAudioHeaderAU(QFile *save_file, int channels, unsigned audio_rate)
|
||||
qint64 RtpPlayerDialog::saveAudioHeaderAU(QFile *save_file, quint32 channels, unsigned audio_rate)
|
||||
{
|
||||
uint8_t pd[4];
|
||||
int64_t nchars;
|
||||
|
@ -2131,7 +2227,7 @@ qint64 RtpPlayerDialog::saveAudioHeaderAU(QFile *save_file, int channels, unsign
|
|||
return save_file->pos();
|
||||
}
|
||||
|
||||
qint64 RtpPlayerDialog::saveAudioHeaderWAV(QFile *save_file, int channels, unsigned audio_rate, qint64 samples)
|
||||
qint64 RtpPlayerDialog::saveAudioHeaderWAV(QFile *save_file, quint32 channels, unsigned audio_rate, qint64 samples)
|
||||
{
|
||||
uint8_t pd[4];
|
||||
int64_t nchars;
|
||||
|
@ -2464,12 +2560,12 @@ void RtpPlayerDialog::saveAudio(save_mode_t save_mode)
|
|||
} else {
|
||||
switch (format) {
|
||||
case save_audio_au:
|
||||
if (-1 == saveAudioHeaderAU(&file, streams.count(), save_audio_rate)) {
|
||||
if (-1 == saveAudioHeaderAU(&file, static_cast<quint32>(streams.count()), save_audio_rate)) {
|
||||
QMessageBox::warning(this, tr("Error"), tr("Can't write header of AU file"));
|
||||
return;
|
||||
}
|
||||
if (lead_silence_samples > 0) {
|
||||
if (!writeAudioSilenceSamples(&file, lead_silence_samples, streams.count())) {
|
||||
if (!writeAudioSilenceSamples(&file, lead_silence_samples, static_cast<int>(streams.count()))) {
|
||||
QMessageBox::warning(this, tr("Warning"), tr("Save failed!"));
|
||||
}
|
||||
}
|
||||
|
@ -2478,12 +2574,12 @@ void RtpPlayerDialog::saveAudio(save_mode_t save_mode)
|
|||
}
|
||||
break;
|
||||
case save_audio_wav:
|
||||
if (-1 == saveAudioHeaderWAV(&file, streams.count(), save_audio_rate, (maxSample - startSample) + lead_silence_samples)) {
|
||||
if (-1 == saveAudioHeaderWAV(&file, static_cast<quint32>(streams.count()), save_audio_rate, (maxSample - startSample) + lead_silence_samples)) {
|
||||
QMessageBox::warning(this, tr("Error"), tr("Can't write header of WAV file"));
|
||||
return;
|
||||
}
|
||||
if (lead_silence_samples > 0) {
|
||||
if (!writeAudioSilenceSamples(&file, lead_silence_samples, streams.count())) {
|
||||
if (!writeAudioSilenceSamples(&file, lead_silence_samples, static_cast<int>(streams.count()))) {
|
||||
QMessageBox::warning(this, tr("Warning"), tr("Save failed!"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,11 @@
|
|||
#include <ui/qt/widgets/qcustomplot.h>
|
||||
|
||||
#ifdef QT_MULTIMEDIA_LIB
|
||||
#include <QAudioDeviceInfo>
|
||||
# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
# include <QAudioDevice>
|
||||
# else
|
||||
# include <QAudioDeviceInfo>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace Ui {
|
||||
|
@ -199,6 +203,10 @@ private slots:
|
|||
void on_actionPrepareFilter_triggered();
|
||||
void on_actionReadCapture_triggered();
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
void sinkStateChanged();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
private:
|
||||
static RtpPlayerDialog *pinstance_;
|
||||
|
@ -222,7 +230,12 @@ private:
|
|||
QSharedPointer<QCPAxisTickerDateTime> datetime_ticker_;
|
||||
bool stereo_available_;
|
||||
QList<RtpAudioStream *> playing_streams_;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
QAudioSink *marker_stream_;
|
||||
QTimer notify_timer_;
|
||||
#else
|
||||
QAudioOutput *marker_stream_;
|
||||
#endif
|
||||
quint32 marker_stream_requested_out_rate_;
|
||||
QTreeWidgetItem *last_ti_;
|
||||
bool listener_removed_;
|
||||
|
@ -258,8 +271,13 @@ private:
|
|||
void updateStartStopTime(rtpstream_info_t *rtpstream, bool is_first);
|
||||
void formatAudioRouting(QTreeWidgetItem *ti, AudioRouting audio_routing);
|
||||
bool isStereoAvailable();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
QAudioSink *getSilenceAudioOutput();
|
||||
QAudioDevice getCurrentDeviceInfo();
|
||||
#else
|
||||
QAudioOutput *getSilenceAudioOutput();
|
||||
QAudioDeviceInfo getCurrentDeviceInfo();
|
||||
#endif
|
||||
QTreeWidgetItem *findItemByCoords(QPoint point);
|
||||
QTreeWidgetItem *findItem(QCPAbstractPlottable *plottable);
|
||||
void handleItemHighlight(QTreeWidgetItem *ti, bool scroll);
|
||||
|
@ -271,8 +289,8 @@ private:
|
|||
void fillAudioRateMenu();
|
||||
void cleanupMarkerStream();
|
||||
|
||||
qint64 saveAudioHeaderAU(QFile *save_file, int channels, unsigned audio_rate);
|
||||
qint64 saveAudioHeaderWAV(QFile *save_file, int channels, unsigned audio_rate, qint64 samples);
|
||||
qint64 saveAudioHeaderAU(QFile *save_file, quint32 channels, unsigned audio_rate);
|
||||
qint64 saveAudioHeaderWAV(QFile *save_file, quint32 channels, unsigned audio_rate, qint64 samples);
|
||||
bool writeAudioSilenceSamples(QFile *out_file, qint64 samples, int stream_count);
|
||||
bool writeAudioStreamsSamples(QFile *out_file, QVector<RtpAudioStream *> streams, bool swap_bytes);
|
||||
save_audio_t selectFileAudioFormatAndName(QString *file_path);
|
||||
|
|
Loading…
Reference in New Issue