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