Wireshark  4.3.0
The Wireshark network protocol analyzer
rtp_audio_stream.h
Go to the documentation of this file.
1 
10 #ifndef RTPAUDIOSTREAM_H
11 #define RTPAUDIOSTREAM_H
12 
13 #include "config.h"
14 
15 #ifdef QT_MULTIMEDIA_LIB
16 
17 #include <glib.h>
18 
19 #include <epan/address.h>
20 #include <ui/rtp_stream.h>
23 #include <ui/rtp_media.h>
24 
25 #include <QAudio>
26 #include <QColor>
27 #include <QMap>
28 #include <QObject>
29 #include <QSet>
30 #include <QVector>
31 #include <QIODevice>
32 #include <QAudioOutput>
33 
34 class QAudioFormat;
35 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
36 class QAudioSink;
37 #else
38 class QAudioOutput;
39 #endif
40 class QIODevice;
41 
42 
43 class RtpAudioStream : public QObject
44 {
45  Q_OBJECT
46 public:
47  enum TimingMode { JitterBuffer, RtpTimestamp, Uninterrupted };
48 
49  explicit RtpAudioStream(QObject *parent, rtpstream_id_t *id, bool stereo_required);
50  ~RtpAudioStream();
51  bool isMatch(const rtpstream_id_t *id) const;
52  bool isMatch(const struct _packet_info *pinfo, const struct _rtp_info *rtp_info) const;
53  void addRtpPacket(const struct _packet_info *pinfo, const struct _rtp_info *rtp_info);
54  void clearPackets();
55  void reset(double global_start_time);
56  AudioRouting getAudioRouting();
57  void setAudioRouting(AudioRouting audio_routing);
58 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
59  void decode(QAudioDevice out_device);
60 #else
61  void decode(QAudioDeviceInfo out_device);
62 #endif
63 
64  double startRelTime() const { return start_rel_time_; }
65  double stopRelTime() const { return stop_rel_time_; }
66  unsigned sampleRate() const { return first_sample_rate_; }
67  unsigned playRate() const { return audio_out_rate_; }
68  void setRequestedPlayRate(unsigned new_rate) { audio_requested_out_rate_ = new_rate; }
69  const QStringList payloadNames() const;
70 
75  const QVector<double> visualTimestamps(bool relative = true);
82  const QVector<double> visualSamples(int y_offset = 0);
83 
88  const QVector<double> outOfSequenceTimestamps(bool relative = true);
89  int outOfSequence() { return static_cast<int>(out_of_seq_timestamps_.size()); }
95  const QVector<double> outOfSequenceSamples(int y_offset = 0);
96 
101  const QVector<double> jitterDroppedTimestamps(bool relative = true);
102  int jitterDropped() { return static_cast<int>(jitter_drop_timestamps_.size()); }
108  const QVector<double> jitterDroppedSamples(int y_offset = 0);
109 
114  const QVector<double> wrongTimestampTimestamps(bool relative = true);
115  int wrongTimestamps() { return static_cast<int>(wrong_timestamp_timestamps_.size()); }
121  const QVector<double> wrongTimestampSamples(int y_offset = 0);
122 
127  const QVector<double> insertedSilenceTimestamps(bool relative = true);
128  int insertedSilences() { return static_cast<int>(silence_timestamps_.size()); }
134  const QVector<double> insertedSilenceSamples(int y_offset = 0);
135 
136  quint32 nearestPacket(double timestamp, bool is_relative = true);
137 
138  QRgb color() { return color_; }
139  void setColor(QRgb color) { color_ = color; }
140 
141  QAudio::State outputState() const;
142 
143  void setJitterBufferSize(int jitter_buffer_size) { jitter_buffer_size_ = jitter_buffer_size; }
144  void setTimingMode(TimingMode timing_mode) { timing_mode_ = timing_mode; }
145  void setStartPlayTime(double start_play_time) { start_play_time_ = start_play_time; }
146 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
147  bool prepareForPlay(QAudioDevice out_device);
148 #else
149  bool prepareForPlay(QAudioDeviceInfo out_device);
150 #endif
151  void startPlaying();
152  void pausePlaying();
153  void stopPlaying();
154  void seekPlaying(qint64 samples);
155  void setStereoRequired(bool stereo_required) { stereo_required_ = stereo_required; }
156  qint16 getMaxSampleValue() { return max_sample_val_; }
157  void setMaxSampleValue(gint16 max_sample_val) { max_sample_val_used_ = max_sample_val; }
158  void seekSample(qint64 samples);
159  qint64 readSample(SAMPLE *sample);
160  qint64 getLeadSilenceSamples() { return prepend_samples_; }
161  qint64 getTotalSamples() { return (audio_file_->getTotalSamples()); }
162  qint64 getEndOfSilenceSample() { return (audio_file_->getEndOfSilenceSample()); }
163  double getEndOfSilenceTime() { return (double)getEndOfSilenceSample() / (double)playRate(); }
164  qint64 convertTimeToSamples(double time) { return (qint64)(time * playRate()); }
165  bool savePayload(QIODevice *file);
166  guint getHash() { return rtpstream_id_to_hash(&(id_)); }
167  rtpstream_id_t *getID() { return &(id_); }
168  QString getIDAsQString();
169  rtpstream_info_t *getStreamInfo() { return &rtpstream_; }
170 
171 signals:
172  void processedSecs(double secs);
173  void playbackError(const QString error_msg);
174  void finishedPlaying(RtpAudioStream *stream, QAudio::Error error);
175 
176 private:
177  // Used to identify unique streams.
178  // The GTK+ UI also uses the call number + current channel.
179  rtpstream_id_t id_;
180  rtpstream_info_t rtpstream_;
181  bool first_packet_;
182 
183  QVector<struct _rtp_packet *>rtp_packets_;
184  RtpAudioFile *audio_file_; // Stores waveform samples in sparse file
185  QIODevice *temp_file_;
186  struct _GHashTable *decoders_hash_;
187  double global_start_rel_time_;
188  double start_abs_offset_;
189  double start_rel_time_;
190  double stop_rel_time_;
191  qint64 prepend_samples_; // Count of silence samples at begin of the stream to align with other streams
192  AudioRouting audio_routing_;
193  bool stereo_required_;
194  quint32 first_sample_rate_;
195  quint32 audio_out_rate_;
196  quint32 audio_requested_out_rate_;
197  QSet<QString> payload_names_;
198  struct SpeexResamplerState_ *visual_resampler_;
199  QMap<double, quint32> packet_timestamps_;
200  QVector<qint16> visual_samples_;
201  QVector<double> out_of_seq_timestamps_;
202  QVector<double> jitter_drop_timestamps_;
203  QVector<double> wrong_timestamp_timestamps_;
204  QVector<double> silence_timestamps_;
205  qint16 max_sample_val_;
206  qint16 max_sample_val_used_;
207  QRgb color_;
208 
209  int jitter_buffer_size_;
210  TimingMode timing_mode_;
211  double start_play_time_;
212 
213  const QString formatDescription(const QAudioFormat & format);
214  QString currentOutputDevice();
215 
216 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
217  QAudioSink *audio_output_;
218  void decodeAudio(QAudioDevice out_device);
219  quint32 calculateAudioOutRate(QAudioDevice out_device, unsigned int sample_rate, unsigned int requested_out_rate);
220 #else
221  QAudioOutput *audio_output_;
222  void decodeAudio(QAudioDeviceInfo out_device);
223  quint32 calculateAudioOutRate(QAudioDeviceInfo out_device, unsigned int sample_rate, unsigned int requested_out_rate);
224 #endif
225  void decodeVisual();
226  SAMPLE *resizeBufferIfNeeded(SAMPLE *buff, gint32 *buff_bytes, qint64 requested_size);
227 
228 private slots:
229  void outputStateChanged(QAudio::State new_state);
230  void delayedStopStream();
231 };
232 
233 #endif // QT_MULTIMEDIA_LIB
234 
235 #endif // RTPAUDIOSTREAM_H
Definition: rtp_audio_routing.h:28
Definition: rtp_audio_file.h:42
guint rtpstream_id_to_hash(const rtpstream_id_t *id)
Definition: rtp_stream_id.c:89
Definition: packet_info.h:44
Definition: packet-rtp.h:29
Definition: rtp_stream_id.h:33
Definition: rtp_stream.h:40
Definition: stream.c:41