diff --git a/include/formats/media.hh b/include/formats/media.hh index 2a8582e..5e7abe0 100644 --- a/include/formats/media.hh +++ b/include/formats/media.hh @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include "../rtp.hh" #include "../socket.hh" @@ -11,6 +13,19 @@ namespace uvg_rtp { namespace formats { + typedef struct media_info { + uint32_t s_seq; + uint32_t e_seq; + size_t npkts; + size_t size; + std::map fragments; + } media_info_t; + + typedef struct media_frame_info { + std::unordered_map frames; + std::unordered_set dropped; + } media_frame_info_t; + class media { public: media(uvg_rtp::socket *socket, uvg_rtp::rtp *rtp_ctx, int flags); @@ -36,6 +51,9 @@ namespace uvg_rtp { * Return RTP_GENERIC_ERROR if the packet was corrupted in some way */ static rtp_error_t packet_handler(void *arg, int flags, frame::rtp_frame **frame); + /* Return pointer to the internal frame info structure which is relayed to packet handler */ + media_frame_info_t *get_hevc_frame_info(); + protected: virtual rtp_error_t __push_frame(uint8_t *data, size_t data_len, int flags); @@ -43,6 +61,9 @@ namespace uvg_rtp { uvg_rtp::rtp *rtp_ctx_; int flags_; uvg_rtp::frame_queue *fqueue_; + + private: + media_frame_info_t minfo_; }; }; }; diff --git a/src/formats/media.cc b/src/formats/media.cc index 1131658..14fa1e2 100644 --- a/src/formats/media.cc +++ b/src/formats/media.cc @@ -11,7 +11,7 @@ #define INVALID_SEQ 0xffffffff uvg_rtp::formats::media::media(uvg_rtp::socket *socket, uvg_rtp::rtp *rtp_ctx, int flags): - socket_(socket), rtp_ctx_(rtp_ctx), flags_(flags) + socket_(socket), rtp_ctx_(rtp_ctx), flags_(flags), minfo_{} { fqueue_ = new uvg_rtp::frame_queue(socket, rtp_ctx, flags); } @@ -122,51 +122,46 @@ rtp_error_t uvg_rtp::formats::media::__push_frame(uint8_t *data, size_t data_len #endif } +uvg_rtp::formats::media_frame_info_t *uvg_rtp::formats::media::get_hevc_frame_info() +{ + return &minfo_; +} + 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; - size_t npkts; - size_t size; - std::map fragments; - }; - static std::unordered_map frames; - - auto frame = *out; - uint32_t ts = frame->header.timestamp; - uint32_t seq = frame->header.seq; - size_t recv = 0; + auto minfo = (uvg_rtp::formats::media_frame_info_t *)arg; + auto frame = *out; + uint32_t ts = frame->header.timestamp; + uint32_t seq = frame->header.seq; + size_t recv = 0; /* If fragmentation of generic frame has not been enabled, we can just return the frame * in "out" because RTP packet handler has done all the necessasry stuff for small RTP packets */ if (!(flags & RCE_FRAGMENT_GENERIC)) return RTP_PKT_READY; - if (frames.find(ts) != frames.end()) { - frames[ts].npkts++; - frames[ts].fragments[seq] = frame; - frames[ts].size += frame->payload_len; + if (minfo->frames.find(ts) != minfo->frames.end()) { + minfo->frames[ts].npkts++; + minfo->frames[ts].fragments[seq] = frame; + minfo->frames[ts].size += frame->payload_len; *out = nullptr; if (frame->header.marker) - frames[ts].e_seq = seq; + minfo->frames[ts].e_seq = seq; - if (frames[ts].e_seq != INVALID_SEQ && frames[ts].s_seq != INVALID_SEQ) { - if (frames[ts].s_seq > frames[ts].e_seq) - recv = 0xffff - frames[ts].s_seq + frames[ts].e_seq + 2; + if (minfo->frames[ts].e_seq != INVALID_SEQ && minfo->frames[ts].s_seq != INVALID_SEQ) { + if (minfo->frames[ts].s_seq > minfo->frames[ts].e_seq) + recv = 0xffff - minfo->frames[ts].s_seq + minfo->frames[ts].e_seq + 2; else - recv = frames[ts].e_seq - frames[ts].s_seq + 1; + recv = minfo->frames[ts].e_seq - minfo->frames[ts].s_seq + 1; - if (recv == frames[ts].npkts) { - auto retframe = uvg_rtp::frame::alloc_rtp_frame(frames[ts].size); + if (recv == minfo->frames[ts].npkts) { + auto retframe = uvg_rtp::frame::alloc_rtp_frame(minfo->frames[ts].size); size_t ptr = 0; std::memcpy(&retframe->header, &frame->header, sizeof(frame->header)); - for (auto& frag : frames[ts].fragments) { + for (auto& frag : minfo->frames[ts].fragments) { std::memcpy( retframe->payload + ptr, frag.second->payload, @@ -176,7 +171,7 @@ rtp_error_t uvg_rtp::formats::media::packet_handler(void *arg, int flags, uvg_rt (void)uvg_rtp::frame::dealloc_frame(frag.second); } - frames.erase(ts); + minfo->frames.erase(ts); (void)uvg_rtp::frame::dealloc_frame(*out); *out = retframe; return RTP_PKT_READY; @@ -184,11 +179,11 @@ rtp_error_t uvg_rtp::formats::media::packet_handler(void *arg, int flags, uvg_rt } } else { if (frame->header.marker) { - frames[ts].npkts = 1; - frames[ts].s_seq = seq; - frames[ts].e_seq = INVALID_SEQ; - frames[ts].fragments[seq] = frame; - frames[ts].size = frame->payload_len; + minfo->frames[ts].npkts = 1; + minfo->frames[ts].s_seq = seq; + minfo->frames[ts].e_seq = INVALID_SEQ; + minfo->frames[ts].fragments[seq] = frame; + minfo->frames[ts].size = frame->payload_len; *out = nullptr; } else { return RTP_PKT_READY;