| Wireshark 4.7.0 The Wireshark network protocol analyzer

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