Save Media frame info to the Media object

This commit is contained in:
Aaro Altonen 2020-09-16 11:31:35 +03:00
parent 7559482a84
commit 2d1c6bd79c
2 changed files with 50 additions and 34 deletions

View File

@ -1,6 +1,8 @@
#pragma once
#include <memory>
#include <unordered_map>
#include <unordered_set>
#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<uint16_t, uvg_rtp::frame::rtp_frame *> fragments;
} media_info_t;
typedef struct media_frame_info {
std::unordered_map<uint32_t, media_info> frames;
std::unordered_set<uint32_t> 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_;
};
};
};

View File

@ -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<uint16_t, uvg_rtp::frame::rtp_frame *> fragments;
};
static std::unordered_map<uint32_t, frame_info> 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;