/* rtp_audio_stream.h * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef RTPAUDIOSTREAM_H #define RTPAUDIOSTREAM_H #include "config.h" #ifdef QT_MULTIMEDIA_LIB #include #include #include #include #include #include #include #include #include class QAudioFormat; class QAudioOutput; class QTemporaryFile; struct _rtp_info; struct _rtp_sample; class RtpAudioStream : public QObject { Q_OBJECT public: enum TimingMode { JitterBuffer, RtpTimestamp, Uninterrupted }; explicit RtpAudioStream(QObject *parent, rtpstream_info_t *rtpstream); ~RtpAudioStream(); bool isMatch(const rtpstream_info_t *rtpstream) const; 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 decode(); double startRelTime() const { return start_rel_time_; } double stopRelTime() const { return stop_rel_time_; } unsigned sampleRate() const { return audio_out_rate_; } const QStringList payloadNames() const; /** * @brief Return a list of visual timestamps. * @return A set of timestamps suitable for passing to QCPGraph::setData. */ const QVector visualTimestamps(bool relative = true); /** * @brief Return a list of visual samples. There will be fewer visual samples * per second (1000) than the actual audio. * @param y_offset Y axis offset to be used for stacking graphs. * @return A set of values suitable for passing to QCPGraph::setData. */ const QVector visualSamples(int y_offset = 0); /** * @brief Return a list of out-of-sequence timestamps. * @return A set of timestamps suitable for passing to QCPGraph::setData. */ const QVector outOfSequenceTimestamps(bool relative = true); int outOfSequence() { return 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. * @return A set of values suitable for passing to QCPGraph::setData. */ const QVector outOfSequenceSamples(int y_offset = 0); /** * @brief Return a list of jitter dropped timestamps. * @return A set of timestamps suitable for passing to QCPGraph::setData. */ const QVector jitterDroppedTimestamps(bool relative = true); int jitterDropped() { return 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. * @return A set of values suitable for passing to QCPGraph::setData. */ const QVector jitterDroppedSamples(int y_offset = 0); /** * @brief Return a list of wrong timestamps. * @return A set of timestamps suitable for passing to QCPGraph::setData. */ const QVector wrongTimestampTimestamps(bool relative = true); int wrongTimestamps() { return 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. * @return A set of values suitable for passing to QCPGraph::setData. */ const QVector wrongTimestampSamples(int y_offset = 0); /** * @brief Return a list of inserted silence timestamps. * @return A set of timestamps suitable for passing to QCPGraph::setData. */ const QVector insertedSilenceTimestamps(bool relative = true); int insertedSilences() { return 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. * @return A set of values suitable for passing to QCPGraph::setData. */ const QVector insertedSilenceSamples(int y_offset = 0); quint32 nearestPacket(double timestamp, bool is_relative = true); QRgb color() { return color_; } void setColor(QRgb color) { color_ = color; } QAudio::State outputState() const; void setJitterBufferSize(int jitter_buffer_size) { jitter_buffer_size_ = jitter_buffer_size; } void setTimingMode(TimingMode timing_mode) { timing_mode_ = timing_mode; } signals: void startedPlaying(); void processedSecs(double secs); void playbackError(const QString error_msg); void finishedPlaying(); public slots: void startPlaying(); void stopPlaying(); private: // Used to identify unique streams. // The GTK+ UI also uses the call number + current channel. rtpstream_id_t id_; QVectorrtp_packets_; QTemporaryFile *tempfile_; struct _GHashTable *decoders_hash_; // TODO: It is not used //QListrtpstreams_; double global_start_rel_time_; double start_abs_offset_; double start_rel_time_; double stop_rel_time_; quint32 audio_out_rate_; QSet payload_names_; struct SpeexResamplerState_ *audio_resampler_; struct SpeexResamplerState_ *visual_resampler_; QAudioOutput *audio_output_; QMap packet_timestamps_; QVector visual_samples_; QVector out_of_seq_timestamps_; QVector jitter_drop_timestamps_; QVector wrong_timestamp_timestamps_; QVector silence_timestamps_; qint16 max_sample_val_; QRgb color_; int jitter_buffer_size_; TimingMode timing_mode_; void writeSilence(int samples); const QString formatDescription(const QAudioFormat & format); QString currentOutputDevice(); private slots: void outputStateChanged(QAudio::State new_state); void outputNotify(); }; #endif // QT_MULTIMEDIA_LIB #endif // RTPAUDIOSTREAM_H /* * Editor modelines * * Local Variables: * c-basic-offset: 4 * tab-width: 8 * indent-tabs-mode: nil * End: * * ex: set shiftwidth=4 tabstop=8 expandtab: * :indentSize=4:tabSize=8:noTabs=true: */