summaryrefslogtreecommitdiffstats
path: root/ui/qt/rtp_player_dialog.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /ui/qt/rtp_player_dialog.h
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ui/qt/rtp_player_dialog.h')
-rw-r--r--ui/qt/rtp_player_dialog.h314
1 files changed, 314 insertions, 0 deletions
diff --git a/ui/qt/rtp_player_dialog.h b/ui/qt/rtp_player_dialog.h
new file mode 100644
index 0000000..5fba67d
--- /dev/null
+++ b/ui/qt/rtp_player_dialog.h
@@ -0,0 +1,314 @@
+/** @file
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef RTP_PLAYER_DIALOG_H
+#define RTP_PLAYER_DIALOG_H
+
+#include "config.h"
+
+#include <glib.h>
+#include <mutex>
+
+#include "ui/rtp_stream.h"
+
+#include "wireshark_dialog.h"
+#include "rtp_audio_stream.h"
+
+#include <QWidget>
+#include <QMap>
+#include <QMultiHash>
+#include <QTreeWidgetItem>
+#include <QMetaType>
+#include <ui/qt/widgets/qcustomplot.h>
+
+#ifdef QT_MULTIMEDIA_LIB
+# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+# include <QAudioDevice>
+# else
+# include <QAudioDeviceInfo>
+# endif
+#endif
+
+namespace Ui {
+class RtpPlayerDialog;
+}
+
+class QCPItemStraightLine;
+class QDialogButtonBox;
+class QMenu;
+class RtpAudioStream;
+class QCPAxisTicker;
+class QCPAxisTickerDateTime;
+
+typedef enum {
+ save_audio_none,
+ save_audio_au,
+ save_audio_wav
+} save_audio_t;
+
+typedef enum {
+ save_payload_none,
+ save_payload_data
+} save_payload_t;
+
+typedef enum {
+ save_mode_from_cursor,
+ save_mode_sync_stream,
+ save_mode_sync_file
+} save_mode_t;
+
+// Singleton by https://refactoring.guru/design-patterns/singleton/cpp/example#example-1
+class RtpPlayerDialog : public WiresharkDialog
+{
+ Q_OBJECT
+#ifdef QT_MULTIMEDIA_LIB
+ Q_PROPERTY(QString currentOutputDeviceName READ currentOutputDeviceName)
+#endif
+
+public:
+ /**
+ * Returns singleton
+ */
+ static RtpPlayerDialog *openRtpPlayerDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list, bool capture_running);
+
+ /**
+ * Should not be clonnable and assignable
+ */
+ RtpPlayerDialog(RtpPlayerDialog &other) = delete;
+ void operator=(const RtpPlayerDialog &) = delete;
+
+ /**
+ * @brief Common routine to add a "Play call" button to a QDialogButtonBox.
+ * @param button_box Caller's QDialogButtonBox.
+ * @return The new "Play call" button.
+ */
+ static QToolButton *addPlayerButton(QDialogButtonBox *button_box, QDialog *dialog);
+
+#ifdef QT_MULTIMEDIA_LIB
+ void accept();
+ void reject();
+
+ void setMarkers();
+
+ /** Replace/Add/Remove an RTP streams to play.
+ * Requires array of rtpstream_info_t.
+ * Each item must have filled items: src_addr, src_port, dest_addr,
+ * dest_port, ssrc, packet_count, setup_frame_number, and start_rel_time.
+ *
+ * @param stream_ids struct with rtpstream info
+ */
+ void replaceRtpStreams(QVector<rtpstream_id_t *> stream_ids);
+ void addRtpStreams(QVector<rtpstream_id_t *> stream_ids);
+ void removeRtpStreams(QVector<rtpstream_id_t *> stream_ids);
+
+signals:
+ // Tells the packet list to redraw. An alternative might be to add a
+ // cf_packet_marked callback to file.[ch] but that's synchronous and
+ // might incur too much overhead.
+ void packetsMarked();
+ void updateFilter(QString filter, bool force = false);
+ void goToPacket(int packet_num);
+ void rtpAnalysisDialogReplaceRtpStreams(QVector<rtpstream_id_t *> stream_infos);
+ void rtpAnalysisDialogAddRtpStreams(QVector<rtpstream_id_t *> stream_infos);
+ void rtpAnalysisDialogRemoveRtpStreams(QVector<rtpstream_id_t *> stream_infos);
+
+public slots:
+ void rtpAnalysisReplace();
+ void rtpAnalysisAdd();
+ void rtpAnalysisRemove();
+
+#endif
+protected:
+ explicit RtpPlayerDialog(QWidget &parent, CaptureFile &cf, bool capture_running);
+#ifdef QT_MULTIMEDIA_LIB
+ ~RtpPlayerDialog();
+
+ virtual void showEvent(QShowEvent *);
+ void contextMenuEvent(QContextMenuEvent *event);
+ bool eventFilter(QObject *obj, QEvent *event);
+
+private slots:
+ /** Retap the capture file, reading RTP packets that match the
+ * streams added using ::addRtpStream.
+ */
+ void retapPackets();
+ void captureEvent(CaptureEvent e);
+ /** Clear, decode, and redraw each stream.
+ */
+ void rescanPackets(bool rescale_axes = false);
+ void createPlot(bool rescale_axes = false);
+ void updateWidgets();
+ void itemEntered(QTreeWidgetItem *item, int column);
+ void mouseMovePlot(QMouseEvent *event);
+ void graphClicked(QMouseEvent *event);
+ void graphDoubleClicked(QMouseEvent *event);
+ void plotClicked(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event);
+ void updateHintLabel();
+ void resetXAxis();
+ void updateGraphs();
+ void playFinished(RtpAudioStream *stream, QAudio::Error error);
+
+ void setPlayPosition(double secs);
+ void setPlaybackError(const QString playback_error);
+ void changeAudioRoutingOnItem(QTreeWidgetItem *ti, AudioRouting new_audio_routing);
+ void changeAudioRouting(AudioRouting new_audio_routing);
+ void invertAudioMutingOnItem(QTreeWidgetItem *ti);
+ void on_playButton_clicked();
+ void on_pauseButton_clicked();
+ void on_stopButton_clicked();
+ void on_actionReset_triggered();
+ void on_actionZoomIn_triggered();
+ void on_actionZoomOut_triggered();
+ void on_actionMoveLeft10_triggered();
+ void on_actionMoveRight10_triggered();
+ void on_actionMoveLeft1_triggered();
+ void on_actionMoveRight1_triggered();
+ void on_actionGoToPacket_triggered();
+ void on_actionGoToSetupPacketPlot_triggered();
+ void on_actionGoToSetupPacketTree_triggered();
+ void on_actionRemoveStream_triggered();
+ void on_actionAudioRoutingP_triggered();
+ void on_actionAudioRoutingL_triggered();
+ void on_actionAudioRoutingLR_triggered();
+ void on_actionAudioRoutingR_triggered();
+ void on_actionAudioRoutingMute_triggered();
+ void on_actionAudioRoutingUnmute_triggered();
+ void on_actionAudioRoutingMuteInvert_triggered();
+ void on_streamTreeWidget_itemSelectionChanged();
+ void on_streamTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, const int column);
+ void on_outputDeviceComboBox_currentTextChanged(const QString &);
+ void on_outputAudioRate_currentTextChanged(const QString &);
+ void on_jitterSpinBox_valueChanged(double);
+ void on_timingComboBox_currentIndexChanged(int);
+ void on_todCheckBox_toggled(bool checked);
+ void on_buttonBox_helpRequested();
+ void on_actionSelectAll_triggered();
+ void on_actionSelectInvert_triggered();
+ void on_actionSelectNone_triggered();
+ void outputNotify();
+ void on_actionPlay_triggered();
+ void on_actionStop_triggered();
+ void on_actionSaveAudioFromCursor_triggered();
+ void on_actionSaveAudioSyncStream_triggered();
+ void on_actionSaveAudioSyncFile_triggered();
+ void on_actionSavePayload_triggered();
+ void on_actionSelectInaudible_triggered();
+ void on_actionDeselectInaudible_triggered();
+ void on_actionPrepareFilter_triggered();
+ void on_actionReadCapture_triggered();
+
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+ void sinkStateChanged();
+#endif
+
+#endif
+private:
+ static RtpPlayerDialog *pinstance_;
+ static std::mutex init_mutex_;
+ static std::mutex run_mutex_;
+
+#ifdef QT_MULTIMEDIA_LIB
+ Ui::RtpPlayerDialog *ui;
+ QMenu *graph_ctx_menu_;
+ QMenu *list_ctx_menu_;
+ double first_stream_rel_start_time_; // Relative start time of first stream
+ double first_stream_abs_start_time_; // Absolute start time of first stream
+ double first_stream_rel_stop_time_; // Relative end time of first stream (ued for streams_length_ calculation
+ double streams_length_; // Difference between start of first stream and end of last stream
+ double start_marker_time_; // Always relative time to start of the capture
+ double start_marker_time_play_; // Copy when play started
+ QCPItemStraightLine *cur_play_pos_;
+ QCPItemStraightLine *start_marker_pos_;
+ QString playback_error_;
+ QSharedPointer<QCPAxisTicker> number_ticker_;
+ QSharedPointer<QCPAxisTickerDateTime> datetime_ticker_;
+ bool stereo_available_;
+ QList<RtpAudioStream *> playing_streams_;
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+ QAudioSink *marker_stream_;
+ QTimer notify_timer_;
+ qint64 notify_timer_start_diff_; // Used to shift play cursor to correct place
+#else
+ QAudioOutput *marker_stream_;
+#endif
+ quint32 marker_stream_requested_out_rate_;
+ QTreeWidgetItem *last_ti_;
+ bool listener_removed_;
+ QPushButton *read_btn_;
+ QToolButton *inaudible_btn_;
+ QToolButton *analyze_btn_;
+ QPushButton *prepare_btn_;
+ QPushButton *export_btn_;
+ QMultiHash<guint, RtpAudioStream *> stream_hash_;
+ bool block_redraw_;
+ int lock_ui_;
+ bool read_capture_enabled_;
+ double silence_skipped_time_;
+
+// const QString streamKey(const rtpstream_info_t *rtpstream);
+// const QString streamKey(const packet_info *pinfo, const struct _rtp_info *rtpinfo);
+
+ // Tap callbacks
+// static void tapReset(void *tapinfo_ptr);
+ static tap_packet_status tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *rtpinfo_ptr, tap_flags_t flags);
+ static void tapDraw(void *tapinfo_ptr);
+
+ void addPacket(packet_info *pinfo, const struct _rtp_info *rtpinfo);
+ void zoomXAxis(bool in);
+ void panXAxis(int x_pixels);
+ const QString getFormatedTime(double f_time);
+ const QString getFormatedHoveredTime();
+ int getHoveredPacket();
+ QString currentOutputDeviceName();
+ double getStartPlayMarker();
+ void drawStartPlayMarker();
+ void setStartPlayMarker(double new_time);
+ void updateStartStopTime(rtpstream_info_t *rtpstream, bool is_first);
+ void formatAudioRouting(QTreeWidgetItem *ti, AudioRouting audio_routing);
+ bool isStereoAvailable();
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+ QAudioSink *getSilenceAudioOutput();
+ QAudioDevice getCurrentDeviceInfo();
+#else
+ QAudioOutput *getSilenceAudioOutput();
+ QAudioDeviceInfo getCurrentDeviceInfo();
+#endif
+ QTreeWidgetItem *findItemByCoords(QPoint point);
+ QTreeWidgetItem *findItem(QCPAbstractPlottable *plottable);
+ void handleItemHighlight(QTreeWidgetItem *ti, bool scroll);
+ void highlightItem(QTreeWidgetItem *ti, bool highlight);
+ void invertSelection();
+ void handleGoToSetupPacket(QTreeWidgetItem *ti);
+ void addSingleRtpStream(rtpstream_id_t *id);
+ void removeRow(QTreeWidgetItem *ti);
+ void fillAudioRateMenu();
+ void cleanupMarkerStream();
+
+ qint64 saveAudioHeaderAU(QFile *save_file, quint32 channels, unsigned audio_rate);
+ qint64 saveAudioHeaderWAV(QFile *save_file, quint32 channels, unsigned audio_rate, qint64 samples);
+ bool writeAudioSilenceSamples(QFile *out_file, qint64 samples, int stream_count);
+ bool writeAudioStreamsSamples(QFile *out_file, QVector<RtpAudioStream *> streams, bool swap_bytes);
+ save_audio_t selectFileAudioFormatAndName(QString *file_path);
+ save_payload_t selectFilePayloadFormatAndName(QString *file_path);
+ QVector<RtpAudioStream *>getSelectedAudibleNonmutedAudioStreams();
+ void saveAudio(save_mode_t save_mode);
+ void savePayload();
+ void lockUI();
+ void unlockUI();
+ void selectInaudible(bool select);
+ QVector<rtpstream_id_t *>getSelectedRtpStreamIDs();
+ void fillTappedColumns();
+
+#else // QT_MULTIMEDIA_LIB
+private:
+ Ui::RtpPlayerDialog *ui;
+#endif // QT_MULTIMEDIA_LIB
+};
+
+#endif // RTP_PLAYER_DIALOG_H