Create new RTP Frame structure with separate header field
This commit is contained in:
parent
fa1c82fb0f
commit
839285b0dd
20
src/frame.cc
20
src/frame.cc
|
@ -5,6 +5,21 @@
|
|||
#include "send.hh"
|
||||
#include "util.hh"
|
||||
|
||||
kvz_rtp::frame::rtp_frame *kvz_rtp::frame::alloc_rtp_frame()
|
||||
{
|
||||
kvz_rtp::frame::rtp_frame *frame = new kvz_rtp::frame::rtp_frame;
|
||||
|
||||
if (!frame) {
|
||||
rtp_errno = RTP_MEMORY_ERROR;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::memset(&frame->header, 0, sizeof(kvz_rtp::frame::rtp_header));
|
||||
std::memset(frame, 0, sizeof(kvz_rtp::frame::rtp_frame));
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
kvz_rtp::frame::rtp_frame *kvz_rtp::frame::alloc_rtp_frame(size_t payload_len, rtp_type_t type)
|
||||
{
|
||||
if (payload_len == 0 || INVALID_FRAME_TYPE(type)) {
|
||||
|
@ -34,10 +49,8 @@ kvz_rtp::frame::rtp_frame *kvz_rtp::frame::alloc_rtp_frame(size_t payload_len, r
|
|||
break;
|
||||
}
|
||||
|
||||
if ((frame = new kvz_rtp::frame::rtp_frame) == nullptr) {
|
||||
rtp_errno = RTP_MEMORY_ERROR;
|
||||
if ((frame = kvz_rtp::frame::alloc_rtp_frame()) == nullptr)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ((frame->data = new uint8_t[payload_len + header_len]) == nullptr) {
|
||||
rtp_errno = RTP_MEMORY_ERROR;
|
||||
|
@ -45,7 +58,6 @@ kvz_rtp::frame::rtp_frame *kvz_rtp::frame::alloc_rtp_frame(size_t payload_len, r
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
frame->header_len = header_len;
|
||||
frame->payload_len = payload_len;
|
||||
frame->total_len = payload_len + header_len;
|
||||
frame->payload = frame->data + header_len;
|
||||
|
|
31
src/frame.hh
31
src/frame.hh
|
@ -29,20 +29,28 @@ namespace kvz_rtp {
|
|||
FRAME_TYPE_APP = 204 /* Application-specific message */
|
||||
} rtcp_type_t;
|
||||
|
||||
/* TODO: is this actually a useful struct? */
|
||||
struct rtp_frame {
|
||||
PACKED_STRUCT(rtp_header) {
|
||||
uint8_t version:2;
|
||||
uint8_t padding:1;
|
||||
uint8_t ext:1;
|
||||
uint8_t cc:4;
|
||||
uint8_t marker:1;
|
||||
uint8_t payload:7;
|
||||
uint16_t seq;
|
||||
uint32_t timestamp;
|
||||
uint32_t ssrc;
|
||||
uint16_t seq;
|
||||
uint8_t ptype;
|
||||
uint8_t marker;
|
||||
};
|
||||
|
||||
size_t total_len; /* total length of the frame (payload length + header length) */
|
||||
size_t header_len; /* length of header (varies based on the type of the frame) */
|
||||
size_t payload_len; /* length of the payload */
|
||||
struct rtp_frame {
|
||||
struct rtp_header header;
|
||||
uint32_t *csrc;
|
||||
|
||||
uint8_t *data; /* pointer to the start of the whole buffer */
|
||||
uint8_t *payload; /* pointer to actual payload */
|
||||
size_t total_len; /* total length of the frame (including padding) */
|
||||
size_t padding_len; /* non-zero if frame is padded */
|
||||
size_t payload_len; /* payload_len: total_len - header_len - padding length (if padded) */
|
||||
|
||||
uint8_t *data;
|
||||
uint8_t *payload;
|
||||
|
||||
rtp_format_t format;
|
||||
rtp_type_t type;
|
||||
|
@ -116,6 +124,7 @@ namespace kvz_rtp {
|
|||
uint8_t payload[0];
|
||||
};
|
||||
|
||||
rtp_frame *alloc_rtp_frame();
|
||||
rtp_frame *alloc_rtp_frame(size_t payload_len, rtp_type_t type);
|
||||
rtcp_app_frame *alloc_rtcp_app_frame(std::string name, uint8_t subtype, size_t payload_len);
|
||||
rtcp_sdes_frame *alloc_rtcp_sdes_frame(size_t ssrc_count, size_t total_len);
|
||||
|
@ -123,7 +132,7 @@ namespace kvz_rtp {
|
|||
rtcp_sender_frame *alloc_rtcp_sender_frame(size_t nblocks);
|
||||
rtcp_bye_frame *alloc_rtcp_bye_frame(size_t ssrc_count);
|
||||
|
||||
rtp_error_t dealloc_frame(rtp_frame *frame);
|
||||
rtp_error_t dealloc_frame(kvz_rtp::frame::rtp_frame *frame);
|
||||
|
||||
/* TODO: template??? */
|
||||
rtp_error_t dealloc_frame(rtcp_sender_frame *frame);
|
||||
|
|
33
src/rtcp.cc
33
src/rtcp.cc
|
@ -202,7 +202,7 @@ void kvz_rtp::rtcp::sender_update_stats(kvz_rtp::frame::rtp_frame *frame)
|
|||
|
||||
sender_stats.sent_pkts += 1;
|
||||
sender_stats.sent_bytes += frame->payload_len;
|
||||
sender_stats.max_seq = frame->seq;
|
||||
sender_stats.max_seq = frame->header.seq;
|
||||
}
|
||||
|
||||
void kvz_rtp::rtcp::receiver_inc_sent_bytes(uint32_t sender_ssrc, size_t n)
|
||||
|
@ -229,19 +229,19 @@ void kvz_rtp::rtcp::init_new_participant(kvz_rtp::frame::rtp_frame *frame)
|
|||
{
|
||||
assert(frame != nullptr);
|
||||
|
||||
kvz_rtp::rtcp::add_participant(frame->ssrc);
|
||||
kvz_rtp::rtcp::init_participant_seq(frame->ssrc, frame->seq);
|
||||
kvz_rtp::rtcp::add_participant(frame->header.ssrc);
|
||||
kvz_rtp::rtcp::init_participant_seq(frame->header.ssrc, frame->header.seq);
|
||||
|
||||
/* Set the probation to MIN_SEQUENTIAL (2)
|
||||
*
|
||||
* What this means is that we must receive at least two packets from SSRC
|
||||
* with sequential RTP sequence numbers for this peer to be considered valid */
|
||||
participants_[frame->ssrc]->probation = MIN_SEQUENTIAL;
|
||||
participants_[frame->header.ssrc]->probation = MIN_SEQUENTIAL;
|
||||
|
||||
/* This is the first RTP frame from remote to frame->timestamp represents t = 0
|
||||
/* This is the first RTP frame from remote to frame->header.timestamp represents t = 0
|
||||
* Save the timestamp and current NTP timestamp so we can do jitter calculations later on */
|
||||
participants_[frame->ssrc]->stats.initial_rtp = frame->timestamp;
|
||||
participants_[frame->ssrc]->stats.initial_ntp = kvz_rtp::clock::now_ntp();
|
||||
participants_[frame->header.ssrc]->stats.initial_rtp = frame->header.timestamp;
|
||||
participants_[frame->header.ssrc]->stats.initial_ntp = kvz_rtp::clock::now_ntp();
|
||||
|
||||
senders_++;
|
||||
}
|
||||
|
@ -311,17 +311,17 @@ void kvz_rtp::rtcp::receiver_update_stats(kvz_rtp::frame::rtp_frame *frame)
|
|||
if (!frame)
|
||||
return;
|
||||
|
||||
if (!is_participant(frame->ssrc)) {
|
||||
LOG_WARN("Got RTP packet from unknown source: 0x%x", frame->ssrc);
|
||||
if (!is_participant(frame->header.ssrc)) {
|
||||
LOG_WARN("Got RTP packet from unknown source: 0x%x", frame->header.ssrc);
|
||||
init_new_participant(frame);
|
||||
}
|
||||
|
||||
if (kvz_rtp::rtcp::update_participant_seq(frame->ssrc, frame->seq) != RTP_OK) {
|
||||
if (kvz_rtp::rtcp::update_participant_seq(frame->header.ssrc, frame->header.seq) != RTP_OK) {
|
||||
LOG_DEBUG("Invalid packet received from remote!");
|
||||
return;
|
||||
}
|
||||
|
||||
auto p = participants_[frame->ssrc];
|
||||
auto p = participants_[frame->header.ssrc];
|
||||
|
||||
p->stats.received_pkts += 1;
|
||||
p->stats.received_bytes += frame->payload_len;
|
||||
|
@ -339,7 +339,7 @@ void kvz_rtp::rtcp::receiver_update_stats(kvz_rtp::frame::rtp_frame *frame)
|
|||
/ 1000);
|
||||
|
||||
/* calculate interarrival jitter */
|
||||
int transit = arrival - frame->timestamp;
|
||||
int transit = arrival - frame->header.timestamp;
|
||||
int d = std::abs((int)(transit - p->stats.transit));
|
||||
|
||||
p->stats.transit = transit;
|
||||
|
@ -672,6 +672,15 @@ rtp_error_t kvz_rtp::rtcp::handle_receiver_report_packet(kvz_rtp::frame::rtcp_re
|
|||
return RTP_INVALID_VALUE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < frame->header.count; ++i) {
|
||||
fprintf(stderr, "-------\n");
|
||||
fprintf(stderr, "lost: %d\n", frame->blocks[i].lost); /* TODO: */
|
||||
fprintf(stderr, "last_seq: %u\n", ntohl(frame->blocks[i].last_seq));
|
||||
fprintf(stderr, "last sr: %u\n", ntohl(frame->blocks[i].lsr));
|
||||
fprintf(stderr, "dlsr: %u\n", ntohl(frame->blocks[i].dlsr));
|
||||
fprintf(stderr, "-------\n");
|
||||
}
|
||||
|
||||
/* TODO: 6.4.4 Analyzing Sender and Receiver Reports */
|
||||
|
||||
return RTP_OK;
|
||||
|
|
|
@ -207,10 +207,17 @@ kvz_rtp::frame::rtp_frame *kvz_rtp::hevc::process_hevc_frame(
|
|||
}
|
||||
|
||||
if (!fu.second.empty()) {
|
||||
if (frame->timestamp != fu.second.at(0)->timestamp) {
|
||||
if (frame->header.timestamp != fu.second.at(0)->header.timestamp) {
|
||||
LOG_ERROR("Timestamp mismatch for fragmentation units!");
|
||||
|
||||
/* TODO: update rtcp stats for dropped packets */
|
||||
if (frame->header.timestamp > fu.second.at(0)->header.timestamp) {
|
||||
LOG_ERROR("packet was dropped: %u %u | %u %u", frame->header.timestamp, fu.second.at(0)->header.timestamp,
|
||||
frame->header.seq, fu.second.at(fu.second.size() - 1)->header.seq);
|
||||
} else {
|
||||
LOG_ERROR("packet came in late: %u %u", frame->header.timestamp, fu.second.at(0)->header.timestamp);
|
||||
}
|
||||
|
||||
LOG_WARN("removing %u frames", fu.second.size());
|
||||
|
||||
/* push the frame to fu vector so deallocation is cleaner */
|
||||
fu.second.push_back(frame);
|
||||
|
@ -273,7 +280,7 @@ kvz_rtp::frame::rtp_frame *kvz_rtp::hevc::process_hevc_frame(
|
|||
while (fu.second.size() != 0) {
|
||||
auto tmp = fu.second.back();
|
||||
fu.second.pop_back();
|
||||
kvz_rtp::frame::dealloc_frame(tmp);
|
||||
(void)kvz_rtp::frame::dealloc_frame(tmp);
|
||||
}
|
||||
|
||||
/* reset the total size of fragmentation units */
|
||||
|
@ -286,7 +293,7 @@ error:
|
|||
while (fu.second.size() != 0) {
|
||||
auto tmp = fu.second.back();
|
||||
fu.second.pop_back();
|
||||
kvz_rtp::frame::dealloc_frame(tmp);
|
||||
(void)kvz_rtp::frame::dealloc_frame(tmp);
|
||||
}
|
||||
|
||||
/* reset the total size of fragmentation units */
|
||||
|
|
Loading…
Reference in New Issue