From e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 22:34:10 +0200 Subject: Adding upstream version 4.2.2. Signed-off-by: Daniel Baumann --- ui/qt/rtp_player_dialog.h | 314 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 ui/qt/rtp_player_dialog.h (limited to 'ui/qt/rtp_player_dialog.h') diff --git a/ui/qt/rtp_player_dialog.h b/ui/qt/rtp_player_dialog.h new file mode 100644 index 00000000..5fba67db --- /dev/null +++ b/ui/qt/rtp_player_dialog.h @@ -0,0 +1,314 @@ +/** @file + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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 +#include + +#include "ui/rtp_stream.h" + +#include "wireshark_dialog.h" +#include "rtp_audio_stream.h" + +#include +#include +#include +#include +#include +#include + +#ifdef QT_MULTIMEDIA_LIB +# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# include +# else +# include +# 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 stream_ids); + void addRtpStreams(QVector stream_ids); + void removeRtpStreams(QVector 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 stream_infos); + void rtpAnalysisDialogAddRtpStreams(QVector stream_infos); + void rtpAnalysisDialogRemoveRtpStreams(QVector 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 number_ticker_; + QSharedPointer datetime_ticker_; + bool stereo_available_; + QList 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 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 streams, bool swap_bytes); + save_audio_t selectFileAudioFormatAndName(QString *file_path); + save_payload_t selectFilePayloadFormatAndName(QString *file_path); + QVectorgetSelectedAudibleNonmutedAudioStreams(); + void saveAudio(save_mode_t save_mode); + void savePayload(); + void lockUI(); + void unlockUI(); + void selectInaudible(bool select); + QVectorgetSelectedRtpStreamIDs(); + void fillTappedColumns(); + +#else // QT_MULTIMEDIA_LIB +private: + Ui::RtpPlayerDialog *ui; +#endif // QT_MULTIMEDIA_LIB +}; + +#endif // RTP_PLAYER_DIALOG_H -- cgit v1.2.3