From 5e29a0bf3235ea06304ed43d9e74419006947cd5 Mon Sep 17 00:00:00 2001 From: Heikki Tampio Date: Tue, 27 Jun 2023 08:30:38 +0300 Subject: [PATCH] multiplex: Revive sending user packets functionality that was disabled --- include/uvgrtp/media_stream.hh | 41 ++++++++++++++++++++++++++++++---- src/media_stream.cc | 10 ++++----- src/reception_flow.cc | 15 ++++++------- src/reception_flow.hh | 14 +++++------- 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/include/uvgrtp/media_stream.hh b/include/uvgrtp/media_stream.hh index 8e7622b..85063a3 100644 --- a/include/uvgrtp/media_stream.hh +++ b/include/uvgrtp/media_stream.hh @@ -273,11 +273,44 @@ namespace uvgrtp { */ rtp_error_t push_frame(std::unique_ptr data, size_t data_len, uint32_t ts, uint64_t ntp_ts, int rtp_flags); - /* ----------- User packets not yet supported ----------- - rtp_error_t push_user_frame(uint8_t* data, uint32_t payload_size, + /** + * \brief Send a custom UDP packet to the specified address + * + * \details -----------something about mtu size? --------------- + * + * \param data Pointer to data the that should be sent + * \param len Length of data + * \param Remote_address IPv4 or IPv6 address of the remote participant + * \param port Port number of the remote participant + * + * \return RTP error code + * + * \retval RTP_OK On success + * \retval RTP_SEND_ERROR If uvgRTP failed to send the data to remote + * \retval RTP_GENERIC_ERROR If an unspecified error occurred + */ + rtp_error_t push_user_frame(uint8_t* data, uint32_t len, std::string remote_address, uint16_t port); - rtp_error_t install_user_hook(void* arg, void (*hook)(void*, uint8_t* payload)); - */ + + /** + * \brief Asynchronous way of getting frames + * + * \details When a user hook is installed, uvgRTP will notify + * the application when user frames are received. + * + * The hook should not be used for frame processing as it will block the receiver from + * reading more frames. Instead, it should only be used as an interface between uvgRTP and + * the calling application where the frame hand-off happens. + * + * \param arg Optional argument that is passed to the hook when it is called, can be set to nullptr + * \param hook Function pointer to the receive hook that uvgRTP should call + * + * \return RTP error code + * + * \retval RTP_OK On success + * \retval RTP_INVALID_VALUE If hook is nullptr */ + rtp_error_t install_user_hook(void* arg, void (*hook)(void*, uint8_t* data, uint32_t len)); + /** * \brief Poll a frame indefinitely from the media stream object diff --git a/src/media_stream.cc b/src/media_stream.cc index 1b6f1b3..1f34803 100644 --- a/src/media_stream.cc +++ b/src/media_stream.cc @@ -647,8 +647,8 @@ rtp_error_t uvgrtp::media_stream::push_frame(std::unique_ptr data, si return ret; } -/* ----------- User packets not yet supported ----------- -rtp_error_t uvgrtp::media_stream::push_user_frame(uint8_t* data, uint32_t payload_size, + +rtp_error_t uvgrtp::media_stream::push_user_frame(uint8_t* data, uint32_t len, std::string remote_address, uint16_t port) { sockaddr_in6 addr6; @@ -660,10 +660,10 @@ rtp_error_t uvgrtp::media_stream::push_user_frame(uint8_t* data, uint32_t payloa addr = uvgrtp::socket::create_sockaddr(AF_INET, remote_address, port); } UVG_LOG_DEBUG("Sending user packet"); - return socket_->sendto(addr, addr6, data, payload_size, 0); + return socket_->sendto(addr, addr6, data, len, 0); } -rtp_error_t uvgrtp::media_stream::install_user_hook(void* arg, void (*hook)(void*, uint8_t* payload)) +rtp_error_t uvgrtp::media_stream::install_user_hook(void* arg, void (*hook)(void*, uint8_t* payload, uint32_t len)) { if (!initialized_) { UVG_LOG_ERROR("RTP context has not been initialized fully, cannot continue!"); @@ -675,7 +675,7 @@ rtp_error_t uvgrtp::media_stream::install_user_hook(void* arg, void (*hook)(void return reception_flow_->install_user_hook(arg, hook);; -}*/ +} uvgrtp::frame::rtp_frame *uvgrtp::media_stream::pull_frame() { diff --git a/src/reception_flow.cc b/src/reception_flow.cc index b275b92..09c7957 100644 --- a/src/reception_flow.cc +++ b/src/reception_flow.cc @@ -35,8 +35,8 @@ uvgrtp::reception_flow::reception_flow(bool ipv6) : hooks_({}), should_stop_(true), receiver_(nullptr), - //user_hook_arg_(nullptr), - //user_hook_(nullptr), + user_hook_arg_(nullptr), + user_hook_(nullptr), packet_handlers_({}), ring_buffer_(), ring_read_index_(-1), // invalid first index that will increase to a valid one @@ -374,8 +374,7 @@ void uvgrtp::reception_flow::return_frame(uvgrtp::frame::rtp_frame *frame) frames_mtx_.unlock(); } } -/* ----------- User packets not yet supported ----------- -rtp_error_t uvgrtp::reception_flow::install_user_hook(void* arg, void (*hook)(void*, uint8_t* payload)) +rtp_error_t uvgrtp::reception_flow::install_user_hook(void* arg, void (*hook)(void*, uint8_t* data, uint32_t len)) { if (!hook) return RTP_INVALID_VALUE; @@ -386,7 +385,7 @@ rtp_error_t uvgrtp::reception_flow::install_user_hook(void* arg, void (*hook)(vo return RTP_OK; } -void uvgrtp::reception_flow::return_user_pkt(uint8_t* pkt) +void uvgrtp::reception_flow::return_user_pkt(uint8_t* pkt, uint32_t len) { UVG_LOG_DEBUG("Received user packet"); if (!pkt) { @@ -394,12 +393,12 @@ void uvgrtp::reception_flow::return_user_pkt(uint8_t* pkt) return; } if (user_hook_) { - user_hook_(user_hook_arg_, pkt); + user_hook_(user_hook_arg_, pkt, len); } else { UVG_LOG_DEBUG("No user hook installed"); } -}*/ +} void uvgrtp::reception_flow::receiver(std::shared_ptr socket) { @@ -566,7 +565,7 @@ void uvgrtp::reception_flow::process_packet(int rce_flags) /* If after looping through all the handlers there is no handler found, we assume this to be a user packet */ if (i == packet_handlers_.size()) { - UVG_LOG_DEBUG("User packet"); + user_hook_(user_hook_arg_, &ptr[0], size); } continue; } diff --git a/src/reception_flow.hh b/src/reception_flow.hh index 5058a47..5dc2be6 100644 --- a/src/reception_flow.hh +++ b/src/reception_flow.hh @@ -31,8 +31,7 @@ namespace uvgrtp { typedef void (*recv_hook)(void* arg, uvgrtp::frame::rtp_frame* frame); - // Not yet supported - //typedef void (*user_hook)(void* arg, uint8_t* payload, uint32_t payload_size); + typedef void (*user_hook)(void* arg, uint8_t* data, uint32_t len); struct receive_pkt_hook { void* arg = nullptr; @@ -150,8 +149,7 @@ namespace uvgrtp { ssize_t get_buffer_size() const; void set_payload_size(const size_t& value); - // Not yet supported - //rtp_error_t install_user_hook(void* arg, void (*hook)(void*, uint8_t* payload)); + rtp_error_t install_user_hook(void* arg, void (*hook)(void*, uint8_t* data, uint32_t len)); /// \endcond private: @@ -164,8 +162,7 @@ namespace uvgrtp { /* Return a processed RTP frame to user either through frame queue or receive hook */ void return_frame(uvgrtp::frame::rtp_frame *frame); - // Not yet supported - //void return_user_pkt(uint8_t* pkt); + void return_user_pkt(uint8_t* pkt, uint32_t len); inline void increase_buffer_size(ssize_t next_write_index); @@ -201,9 +198,8 @@ namespace uvgrtp { sockaddr_in from; }; - // Not yet supported - //void* user_hook_arg_; - //void (*user_hook_)(void* arg, uint8_t* payload); + void* user_hook_arg_; + void (*user_hook_)(void* arg, uint8_t* data, uint32_t len); // Map different types of handlers by remote SSRC std::map>, handler> packet_handlers_;