Save Media frame info to the Media object
This commit is contained in:
parent
7559482a84
commit
2d1c6bd79c
|
@ -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_;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue