Wireshark  4.3.0
The Wireshark network protocol analyzer
rtp_player_dialog.h
Go to the documentation of this file.
1 
10 #ifndef RTP_PLAYER_DIALOG_H
11 #define RTP_PLAYER_DIALOG_H
12 
13 #include "config.h"
14 
15 #include <mutex>
16 
17 #include "ui/rtp_stream.h"
18 
19 #include "wireshark_dialog.h"
20 #include "rtp_audio_stream.h"
21 
22 #include <QWidget>
23 #include <QMap>
24 #include <QMultiHash>
25 #include <QTreeWidgetItem>
26 #include <QMetaType>
27 #include <ui/qt/widgets/qcustomplot.h>
28 
29 #ifdef QT_MULTIMEDIA_LIB
30 # if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
31 # include <QAudioDevice>
32 # else
33 # include <QAudioDeviceInfo>
34 # endif
35 #endif
36 
37 namespace Ui {
38 class RtpPlayerDialog;
39 }
40 
41 class QCPItemStraightLine;
42 class QDialogButtonBox;
43 class QMenu;
44 class RtpAudioStream;
45 class QCPAxisTicker;
46 class QCPAxisTickerDateTime;
47 
48 typedef enum {
49  save_audio_none,
50  save_audio_au,
51  save_audio_wav
52 } save_audio_t;
53 
54 typedef enum {
55  save_payload_none,
56  save_payload_data
57 } save_payload_t;
58 
59 typedef enum {
60  save_mode_from_cursor,
61  save_mode_sync_stream,
62  save_mode_sync_file
63 } save_mode_t;
64 
65 // Singleton by https://refactoring.guru/design-patterns/singleton/cpp/example#example-1
67 {
68  Q_OBJECT
69 #ifdef QT_MULTIMEDIA_LIB
70  Q_PROPERTY(QString currentOutputDeviceName READ currentOutputDeviceName)
71 #endif
72 
73 public:
77  static RtpPlayerDialog *openRtpPlayerDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list, bool capture_running);
78 
82  RtpPlayerDialog(RtpPlayerDialog &other) = delete;
83  void operator=(const RtpPlayerDialog &) = delete;
84 
90  static QToolButton *addPlayerButton(QDialogButtonBox *button_box, QDialog *dialog);
91 
92 #ifdef QT_MULTIMEDIA_LIB
93  void accept();
94  void reject();
95 
96  void setMarkers();
97 
105  void replaceRtpStreams(QVector<rtpstream_id_t *> stream_ids);
106  void addRtpStreams(QVector<rtpstream_id_t *> stream_ids);
107  void removeRtpStreams(QVector<rtpstream_id_t *> stream_ids);
108 
109 signals:
110  // Tells the packet list to redraw. An alternative might be to add a
111  // cf_packet_marked callback to file.[ch] but that's synchronous and
112  // might incur too much overhead.
113  void packetsMarked();
114  void updateFilter(QString filter, bool force = false);
115  void goToPacket(int packet_num);
116  void rtpAnalysisDialogReplaceRtpStreams(QVector<rtpstream_id_t *> stream_infos);
117  void rtpAnalysisDialogAddRtpStreams(QVector<rtpstream_id_t *> stream_infos);
118  void rtpAnalysisDialogRemoveRtpStreams(QVector<rtpstream_id_t *> stream_infos);
119 
120 public slots:
121  void rtpAnalysisReplace();
122  void rtpAnalysisAdd();
123  void rtpAnalysisRemove();
124 
125 #endif
126 protected:
127  explicit RtpPlayerDialog(QWidget &parent, CaptureFile &cf, bool capture_running);
128 #ifdef QT_MULTIMEDIA_LIB
129  ~RtpPlayerDialog();
130 
131  virtual void showEvent(QShowEvent *);
132  void contextMenuEvent(QContextMenuEvent *event);
133  bool eventFilter(QObject *obj, QEvent *event);
134 
135 private slots:
139  void retapPackets();
140  void captureEvent(CaptureEvent e);
143  void rescanPackets(bool rescale_axes = false);
144  void createPlot(bool rescale_axes = false);
145  void updateWidgets();
146  void itemEntered(QTreeWidgetItem *item, int column);
147  void mouseMovePlot(QMouseEvent *event);
148  void mouseMoveUpdate();
149  void showGraphContextMenu(const QPoint &pos);
150  void graphClicked(QMouseEvent *event);
151  void graphDoubleClicked(QMouseEvent *event);
152  void plotClicked(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event);
153  void updateHintLabel();
154  void resetXAxis();
155  void updateGraphs();
156  void playFinished(RtpAudioStream *stream, QAudio::Error error);
157 
158  void setPlayPosition(double secs);
159  void setPlaybackError(const QString playback_error);
160  void changeAudioRoutingOnItem(QTreeWidgetItem *ti, AudioRouting new_audio_routing);
161  void changeAudioRouting(AudioRouting new_audio_routing);
162  void invertAudioMutingOnItem(QTreeWidgetItem *ti);
163  void on_playButton_clicked();
164  void on_pauseButton_clicked();
165  void on_stopButton_clicked();
166  void on_actionReset_triggered();
167  void on_actionZoomIn_triggered();
168  void on_actionZoomOut_triggered();
169  void on_actionMoveLeft10_triggered();
170  void on_actionMoveRight10_triggered();
171  void on_actionMoveLeft1_triggered();
172  void on_actionMoveRight1_triggered();
173  void on_actionGoToPacket_triggered();
174  void on_actionGoToSetupPacketPlot_triggered();
175  void on_actionGoToSetupPacketTree_triggered();
176  void on_actionRemoveStream_triggered();
177  void on_actionAudioRoutingP_triggered();
178  void on_actionAudioRoutingL_triggered();
179  void on_actionAudioRoutingLR_triggered();
180  void on_actionAudioRoutingR_triggered();
181  void on_actionAudioRoutingMute_triggered();
182  void on_actionAudioRoutingUnmute_triggered();
183  void on_actionAudioRoutingMuteInvert_triggered();
184  void on_streamTreeWidget_itemSelectionChanged();
185  void on_streamTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, const int column);
186  void on_outputDeviceComboBox_currentTextChanged(const QString &);
187  void on_outputAudioRate_currentTextChanged(const QString &);
188  void on_jitterSpinBox_valueChanged(double);
189  void on_timingComboBox_currentIndexChanged(int);
190  void on_todCheckBox_toggled(bool checked);
191  void on_buttonBox_helpRequested();
192  void on_actionSelectAll_triggered();
193  void on_actionSelectInvert_triggered();
194  void on_actionSelectNone_triggered();
195  void outputNotify();
196  void on_actionPlay_triggered();
197  void on_actionStop_triggered();
198  void on_actionSaveAudioFromCursor_triggered();
199  void on_actionSaveAudioSyncStream_triggered();
200  void on_actionSaveAudioSyncFile_triggered();
201  void on_actionSavePayload_triggered();
202  void on_actionSelectInaudible_triggered();
203  void on_actionDeselectInaudible_triggered();
204  void on_actionPrepareFilter_triggered();
205  void on_actionReadCapture_triggered();
206 
207 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
208  void sinkStateChanged();
209 #endif
210 
211 #endif
212 private:
213  static RtpPlayerDialog *pinstance_;
214  static std::mutex init_mutex_;
215  static std::mutex run_mutex_;
216 
217 #ifdef QT_MULTIMEDIA_LIB
218  Ui::RtpPlayerDialog *ui;
219  QMenu *graph_ctx_menu_;
220  QMenu *list_ctx_menu_;
221  double first_stream_rel_start_time_; // Relative start time of first stream
222  double first_stream_abs_start_time_; // Absolute start time of first stream
223  double first_stream_rel_stop_time_; // Relative end time of first stream (ued for streams_length_ calculation
224  double streams_length_; // Difference between start of first stream and end of last stream
225  double start_marker_time_; // Always relative time to start of the capture
226  double start_marker_time_play_; // Copy when play started
227  QCPItemStraightLine *cur_play_pos_;
228  QCPItemStraightLine *start_marker_pos_;
229  QString playback_error_;
230  QSharedPointer<QCPAxisTicker> number_ticker_;
231  QSharedPointer<QCPAxisTickerDateTime> datetime_ticker_;
232  bool stereo_available_;
233  QList<RtpAudioStream *> playing_streams_;
234 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
235  QAudioSink *marker_stream_;
236  QTimer notify_timer_;
237  qint64 notify_timer_start_diff_; // Used to shift play cursor to correct place
238 #else
239  QAudioOutput *marker_stream_;
240 #endif
241  quint32 marker_stream_requested_out_rate_;
242  QTreeWidgetItem *last_ti_;
243  bool listener_removed_;
244  QPushButton *read_btn_;
245  QToolButton *inaudible_btn_;
246  QToolButton *analyze_btn_;
247  QPushButton *prepare_btn_;
248  QPushButton *export_btn_;
249  QMultiHash<unsigned, RtpAudioStream *> stream_hash_;
250  bool block_redraw_;
251  int lock_ui_;
252  bool read_capture_enabled_;
253  double silence_skipped_time_;
254  QTimer *mouse_update_timer_;
255  QPoint mouse_pos_;
256 
257 // const QString streamKey(const rtpstream_info_t *rtpstream);
258 // const QString streamKey(const packet_info *pinfo, const struct _rtp_info *rtpinfo);
259 
260  // Tap callbacks
261 // static void tapReset(void *tapinfo_ptr);
262  static tap_packet_status tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *rtpinfo_ptr, tap_flags_t flags);
263  static void tapDraw(void *tapinfo_ptr);
264 
265  void addPacket(packet_info *pinfo, const struct _rtp_info *rtpinfo);
266  void zoomXAxis(bool in);
267  void panXAxis(int x_pixels);
268  const QString getFormatedTime(double f_time);
269  const QString getFormatedHoveredTime();
270  int getHoveredPacket();
271  QString currentOutputDeviceName();
272  double getStartPlayMarker();
273  void drawStartPlayMarker();
274  void setStartPlayMarker(double new_time);
275  void updateStartStopTime(rtpstream_info_t *rtpstream, bool is_first);
276  void formatAudioRouting(QTreeWidgetItem *ti, AudioRouting audio_routing);
277  bool isStereoAvailable();
278 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
279  QAudioSink *getSilenceAudioOutput();
280  QAudioDevice getCurrentDeviceInfo();
281 #else
282  QAudioOutput *getSilenceAudioOutput();
283  QAudioDeviceInfo getCurrentDeviceInfo();
284 #endif
285  QTreeWidgetItem *findItemByCoords(QPoint point);
286  QTreeWidgetItem *findItem(QCPAbstractPlottable *plottable);
287  void handleItemHighlight(QTreeWidgetItem *ti, bool scroll);
288  void highlightItem(QTreeWidgetItem *ti, bool highlight);
289  void invertSelection();
290  void handleGoToSetupPacket(QTreeWidgetItem *ti);
291  void addSingleRtpStream(rtpstream_id_t *id);
292  void removeRow(QTreeWidgetItem *ti);
293  void fillAudioRateMenu();
294  void cleanupMarkerStream();
295 
296  qint64 saveAudioHeaderAU(QFile *save_file, quint32 channels, unsigned audio_rate);
297  qint64 saveAudioHeaderWAV(QFile *save_file, quint32 channels, unsigned audio_rate, qint64 samples);
298  bool writeAudioSilenceSamples(QFile *out_file, qint64 samples, int stream_count);
299  bool writeAudioStreamsSamples(QFile *out_file, QVector<RtpAudioStream *> streams, bool swap_bytes);
300  save_audio_t selectFileAudioFormatAndName(QString *file_path);
301  save_payload_t selectFilePayloadFormatAndName(QString *file_path);
302  QVector<RtpAudioStream *>getSelectedAudibleNonmutedAudioStreams();
303  void saveAudio(save_mode_t save_mode);
304  void savePayload();
305  void lockUI();
306  void unlockUI();
307  void selectInaudible(bool select);
308  QVector<rtpstream_id_t *>getSelectedRtpStreamIDs();
309  void fillTappedColumns();
310 
311 #else // QT_MULTIMEDIA_LIB
312 private:
313  Ui::RtpPlayerDialog *ui;
314 #endif // QT_MULTIMEDIA_LIB
315 };
316 
317 #endif // RTP_PLAYER_DIALOG_H
Definition: rtp_audio_routing.h:28
Definition: capture_event.h:21
Definition: capture_file.h:21
Definition: rtp_player_dialog.h:67
static RtpPlayerDialog * openRtpPlayerDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list, bool capture_running)
Definition: rtp_player_dialog.cpp:147
RtpPlayerDialog(RtpPlayerDialog &other)=delete
static QToolButton * addPlayerButton(QDialogButtonBox *button_box, QDialog *dialog)
Common routine to add a "Play call" button to a QDialogButtonBox.
Definition: rtp_player_dialog.cpp:360
Definition: wireshark_dialog.h:35
Definition: packet_info.h:44
Definition: packet-rtp.h:29
Definition: rtp_stream_id.h:33
Definition: rtp_stream.h:40
Definition: epan_dissect.h:28
Definition: stream.c:41
tap_packet_status
Definition: tap.h:25