Add optional argument for auxiliary packet handlers
Some packet handlers (such as RTCP) may need access to the parent object or they may require some additional data from outside the packet handler that is required when processing the packet.
This commit is contained in:
parent
8d48cbfe7e
commit
d32b2b82b9
|
@ -33,7 +33,7 @@ namespace uvg_rtp {
|
|||
* Return RTP_PKT_NOT_HANDLED if the packet is not handled by this handler
|
||||
* Return RTP_PKT_MODIFIED if the packet was modified but should be forwarded to other handlers
|
||||
* Return RTP_GENERIC_ERROR if the packet was corrupted in some way */
|
||||
static rtp_error_t packet_handler(int flags, frame::rtp_frame **frame);
|
||||
static rtp_error_t packet_handler(void *arg, int flags, frame::rtp_frame **frame);
|
||||
|
||||
protected:
|
||||
rtp_error_t __push_frame(uint8_t *data, size_t data_len, int flags);
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace uvg_rtp {
|
|||
* Return RTP_PKT_NOT_HANDLED if the packet is not handled by this handler
|
||||
* Return RTP_PKT_MODIFIED if the packet was modified but should be forwarded to other handlers
|
||||
* Return RTP_GENERIC_ERROR if the packet was corrupted in some way */
|
||||
static rtp_error_t packet_handler(int flags, frame::rtp_frame **frame);
|
||||
static rtp_error_t packet_handler(void *arg, int flags, frame::rtp_frame **frame);
|
||||
|
||||
protected:
|
||||
virtual rtp_error_t __push_frame(uint8_t *data, size_t data_len, int flags);
|
||||
|
|
|
@ -11,11 +11,16 @@
|
|||
namespace uvg_rtp {
|
||||
|
||||
typedef rtp_error_t (*packet_handler)(ssize_t, void *, int, uvg_rtp::frame::rtp_frame **);
|
||||
typedef rtp_error_t (*packet_handler_aux)(int, uvg_rtp::frame::rtp_frame **);
|
||||
typedef rtp_error_t (*packet_handler_aux)(void *, int, uvg_rtp::frame::rtp_frame **);
|
||||
|
||||
struct auxiliary_handler {
|
||||
void *arg;
|
||||
packet_handler_aux handler;
|
||||
};
|
||||
|
||||
struct packet_handlers {
|
||||
packet_handler primary;
|
||||
std::vector<packet_handler_aux> auxiliary;
|
||||
std::vector<auxiliary_handler> auxiliary;
|
||||
};
|
||||
|
||||
class pkt_dispatcher : public runner {
|
||||
|
@ -44,9 +49,12 @@ namespace uvg_rtp {
|
|||
* "key" is used to specify for which primary handlers for "handler"
|
||||
* An auxiliary handler can be installed to multiple primary handlers
|
||||
*
|
||||
* "arg" is an optional argument that is passed to the handler when it's called
|
||||
* It can be null if the handler does not require additional data
|
||||
*
|
||||
* Return RTP_OK on success
|
||||
* Return RTP_INVALID_VALUE if "handler" is nullptr or if "key" is not valid */
|
||||
rtp_error_t install_aux_handler(uint32_t key, packet_handler_aux handler);
|
||||
rtp_error_t install_aux_handler(uint32_t key, void *arg, packet_handler_aux handler);
|
||||
|
||||
/* Install receive hook for the RTP packet dispatcher
|
||||
*
|
||||
|
|
|
@ -141,7 +141,7 @@ namespace uvg_rtp {
|
|||
rtp_error_t install_app_hook(void (*hook)(uvg_rtp::frame::rtcp_app_frame *));
|
||||
|
||||
/* Update RTCP-related session statistics */
|
||||
static rtp_error_t packet_handler(int flags, frame::rtp_frame **out);
|
||||
static rtp_error_t packet_handler(void *arg, int flags, frame::rtp_frame **out);
|
||||
|
||||
private:
|
||||
static void rtcp_runner(rtcp *rtcp);
|
||||
|
|
|
@ -102,8 +102,10 @@ static void __drop_frame(frame_info_t& finfo, uint32_t ts)
|
|||
finfo.erase(ts);
|
||||
}
|
||||
|
||||
rtp_error_t uvg_rtp::formats::hevc::packet_handler(int flags, uvg_rtp::frame::rtp_frame **out)
|
||||
rtp_error_t uvg_rtp::formats::hevc::packet_handler(void *arg, int flags, uvg_rtp::frame::rtp_frame **out)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
static frame_info_t finfo;
|
||||
static std::unordered_set<uint32_t> dropped;
|
||||
|
||||
|
|
|
@ -92,8 +92,10 @@ rtp_error_t uvg_rtp::formats::media::__push_frame(uint8_t *data, size_t data_len
|
|||
return socket_->sendto(buffers, 0);
|
||||
}
|
||||
|
||||
rtp_error_t uvg_rtp::formats::media::packet_handler(int flags, uvg_rtp::frame::rtp_frame **out)
|
||||
rtp_error_t uvg_rtp::formats::media::packet_handler(void *arg, int flags, uvg_rtp::frame::rtp_frame **out)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
struct frame_info {
|
||||
uint32_t s_seq;
|
||||
uint32_t e_seq;
|
||||
|
|
|
@ -117,13 +117,14 @@ rtp_error_t uvg_rtp::media_stream::init()
|
|||
}
|
||||
|
||||
rtp_handler_key_ = pkt_dispatcher_->install_handler(rtp_->packet_handler);
|
||||
pkt_dispatcher_->install_aux_handler(rtp_handler_key_, rtcp_->packet_handler);
|
||||
pkt_dispatcher_->install_aux_handler(rtp_handler_key_, rtcp_, rtcp_->packet_handler);
|
||||
|
||||
switch (fmt_) {
|
||||
case RTP_FORMAT_HEVC:
|
||||
media_ = new uvg_rtp::formats::hevc(&socket_, rtp_, ctx_config_.flags);
|
||||
pkt_dispatcher_->install_aux_handler(
|
||||
rtp_handler_key_,
|
||||
nullptr,
|
||||
dynamic_cast<uvg_rtp::formats::hevc *>(media_)->packet_handler
|
||||
);
|
||||
break;
|
||||
|
@ -131,7 +132,7 @@ rtp_error_t uvg_rtp::media_stream::init()
|
|||
case RTP_FORMAT_OPUS:
|
||||
case RTP_FORMAT_GENERIC:
|
||||
media_ = new uvg_rtp::formats::media(&socket_, rtp_, ctx_config_.flags);
|
||||
pkt_dispatcher_->install_aux_handler(rtp_handler_key_, media_->packet_handler);
|
||||
pkt_dispatcher_->install_aux_handler(rtp_handler_key_, nullptr, media_->packet_handler);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -104,7 +104,11 @@ uint32_t uvg_rtp::pkt_dispatcher::install_handler(uvg_rtp::packet_handler handle
|
|||
return key;
|
||||
}
|
||||
|
||||
rtp_error_t uvg_rtp::pkt_dispatcher::install_aux_handler(uint32_t key, uvg_rtp::packet_handler_aux handler)
|
||||
rtp_error_t uvg_rtp::pkt_dispatcher::install_aux_handler(
|
||||
uint32_t key,
|
||||
void *arg,
|
||||
uvg_rtp::packet_handler_aux handler
|
||||
)
|
||||
{
|
||||
if (!handler)
|
||||
return RTP_INVALID_VALUE;
|
||||
|
@ -112,7 +116,7 @@ rtp_error_t uvg_rtp::pkt_dispatcher::install_aux_handler(uint32_t key, uvg_rtp::
|
|||
if (packet_handlers_.find(key) == packet_handlers_.end())
|
||||
return RTP_INVALID_VALUE;
|
||||
|
||||
packet_handlers_[key].auxiliary.push_back(handler);
|
||||
packet_handlers_[key].auxiliary.push_back({ arg, handler });
|
||||
return RTP_OK;
|
||||
}
|
||||
|
||||
|
@ -136,8 +140,8 @@ void uvg_rtp::pkt_dispatcher::call_aux_handlers(uint32_t key, int flags, uvg_rtp
|
|||
{
|
||||
rtp_error_t ret;
|
||||
|
||||
for (auto& handler : packet_handlers_[key].auxiliary) {
|
||||
switch ((ret = (*handler)(flags, frame))) {
|
||||
for (auto& aux : packet_handlers_[key].auxiliary) {
|
||||
switch ((ret = (*aux.handler)(aux.arg, flags, frame))) {
|
||||
/* packet was handled successfully */
|
||||
case RTP_OK:
|
||||
break;
|
||||
|
|
12
src/rtcp.cc
12
src/rtcp.cc
|
@ -605,7 +605,17 @@ void uvg_rtp::rtcp::rtcp_runner(uvg_rtp::rtcp *rtcp)
|
|||
}
|
||||
}
|
||||
|
||||
rtp_error_t uvg_rtp::rtcp::packet_handler(int flags, frame::rtp_frame **out)
|
||||
/* RTCP packet handler is responsible for doing two things:
|
||||
*
|
||||
* - it checks whether the packet is coming from an existing user and if so,
|
||||
* updates that user's session statistics. If the packet is coming from a user,
|
||||
* the user is put on probation where they will stay until enough valid packets
|
||||
* have been received.
|
||||
* - it keeps track of participants' SSRCs and if a collision
|
||||
* is detected, the RTP context is updated */
|
||||
rtp_error_t uvg_rtp::rtcp::packet_handler(void *arg, int flags, frame::rtp_frame **out)
|
||||
{
|
||||
(void)arg, (void)flags, (void)out;
|
||||
|
||||
return RTP_PKT_NOT_HANDLED;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue