common: Remove memory leaks shown by Valgrind with tests
This commit is contained in:
parent
fef90f154c
commit
1e751e051f
|
@ -117,7 +117,7 @@ namespace uvgrtp {
|
|||
struct rtcp_sdes_item {
|
||||
uint8_t type = 0;
|
||||
uint8_t length = 0;
|
||||
void *data = nullptr;
|
||||
uint8_t *data = nullptr;
|
||||
};
|
||||
|
||||
struct rtcp_sdes_chunk {
|
||||
|
|
|
@ -176,7 +176,7 @@ namespace uvgrtp {
|
|||
uvgrtp::frame::rtcp_app_packet *get_app_packet(uint32_t ssrc);
|
||||
|
||||
/* Return a reference to vector that contains the sockets of all participants */
|
||||
std::vector<uvgrtp::socket>& get_sockets();
|
||||
std::vector<std::shared_ptr<uvgrtp::socket>>& get_sockets();
|
||||
|
||||
/* Somebody joined the multicast group the owner of this RTCP instance is part of
|
||||
* Add it to RTCP participant list so we can start listening for reports
|
||||
|
@ -388,7 +388,9 @@ namespace uvgrtp {
|
|||
/* Takes ownership of the frame */
|
||||
rtp_error_t send_rtcp_packet_to_participants(uint8_t* frame, uint32_t frame_size, bool encrypt);
|
||||
|
||||
void free_participant(rtcp_participant* participant);
|
||||
void free_participant(std::unique_ptr<rtcp_participant> participant);
|
||||
|
||||
void cleanup_participants();
|
||||
|
||||
/* Secure RTCP context */
|
||||
std::shared_ptr<uvgrtp::srtcp> srtcp_;
|
||||
|
@ -451,7 +453,7 @@ namespace uvgrtp {
|
|||
/* The first value of RTP timestamp (aka t = 0) */
|
||||
uint32_t rtp_ts_start_;
|
||||
|
||||
std::map<uint32_t, rtcp_participant *> participants_;
|
||||
std::map<uint32_t, std::unique_ptr<rtcp_participant>> participants_;
|
||||
uint8_t num_receivers_; // maximum is 32 at the moment (5 bits)
|
||||
|
||||
/* statistics for RTCP Sender and Receiver Reports */
|
||||
|
@ -459,13 +461,13 @@ namespace uvgrtp {
|
|||
|
||||
/* If we expect frames from remote but haven't received anything from remote yet,
|
||||
* the participant resides in this vector until he's moved to participants_ */
|
||||
std::vector<rtcp_participant *> initial_participants_;
|
||||
std::vector<std::unique_ptr<rtcp_participant>> initial_participants_;
|
||||
|
||||
/* Vector of sockets the RTCP runner is listening to
|
||||
*
|
||||
* The socket are also stored here (in addition to participants_ map) so they're easier
|
||||
* to pass to poll when RTCP runner is listening to incoming packets */
|
||||
std::vector<uvgrtp::socket> sockets_;
|
||||
std::vector<std::shared_ptr<uvgrtp::socket>> sockets_;
|
||||
|
||||
void (*sender_hook_)(uvgrtp::frame::rtcp_sender_report *);
|
||||
void (*receiver_hook_)(uvgrtp::frame::rtcp_receiver_report *);
|
||||
|
|
|
@ -104,10 +104,20 @@ uvgrtp::formats::h26x::~h26x()
|
|||
{
|
||||
for (auto& frame : queued_)
|
||||
{
|
||||
delete[] frame;
|
||||
(void)uvgrtp::frame::dealloc_frame(frame);
|
||||
}
|
||||
|
||||
queued_.clear();
|
||||
|
||||
for (auto& fragment : fragments_)
|
||||
{
|
||||
if (fragment != nullptr)
|
||||
{
|
||||
(void)uvgrtp::frame::dealloc_frame(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
fragments_.clear();
|
||||
}
|
||||
|
||||
/* NOTE: the area 0 - len (ie data[0] - data[len - 1]) must be addressable
|
||||
|
@ -613,12 +623,14 @@ rtp_error_t uvgrtp::formats::h26x::packet_handler(int rce_flags, uvgrtp::frame::
|
|||
if (dropped_ts_.find(frame->header.timestamp) != dropped_ts_.end()) {
|
||||
UVG_LOG_DEBUG("Received an RTP packet belonging to a dropped frame! Timestamp: %lu, seq: %u",
|
||||
frame->header.timestamp, frame->header.seq);
|
||||
(void)uvgrtp::frame::dealloc_frame(frame); // free fragment memory
|
||||
return RTP_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
if (completed_ts_.find(frame->header.timestamp) != completed_ts_.end()) {
|
||||
UVG_LOG_DEBUG("Received an RTP packet belonging to a completed frame! Timestamp: %lu, seq: %u",
|
||||
frame->header.timestamp, frame->header.seq);
|
||||
(void)uvgrtp::frame::dealloc_frame(frame); // free fragment memory
|
||||
return RTP_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
|
@ -676,6 +688,7 @@ rtp_error_t uvgrtp::formats::h26x::packet_handler(int rce_flags, uvgrtp::frame::
|
|||
if (frames_[fragment_ts].nal_type != nal_type)
|
||||
{
|
||||
UVG_LOG_ERROR("The fragment has different NAL type fragments before!");
|
||||
(void)uvgrtp::frame::dealloc_frame(frame); // free fragment memory
|
||||
return RTP_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -210,7 +210,10 @@ rtp_error_t uvgrtp::frame_queue::enqueue_message(uint8_t *message, size_t messag
|
|||
/* If SRTP with proper encryption has been enabled but
|
||||
* RCE_SRTP_INPLACE_ENCRYPTION has **not** been enabled, make a copy of the memory block*/
|
||||
if ((rce_flags_ & (RCE_SRTP | RCE_SRTP_INPLACE_ENCRYPTION | RCE_SRTP_NULL_CIPHER)) == RCE_SRTP)
|
||||
message = (uint8_t *)memdup(message, message_len);
|
||||
{
|
||||
// TODO: This memory is never deleted
|
||||
message = (uint8_t*)memdup(message, message_len);
|
||||
}
|
||||
|
||||
tmp.push_back({ message_len, message });
|
||||
|
||||
|
|
10
src/poll.cc
10
src/poll.cc
|
@ -53,7 +53,7 @@ rtp_error_t uvgrtp::poll::blocked_recv(std::shared_ptr<uvgrtp::socket> socket, u
|
|||
return rtp_ret;
|
||||
}
|
||||
|
||||
rtp_error_t uvgrtp::poll::poll(std::vector<uvgrtp::socket>& sockets, uint8_t *buf, size_t buf_len, int timeout, int *bytes_read)
|
||||
rtp_error_t uvgrtp::poll::poll(std::vector<std::shared_ptr<uvgrtp::socket>>& sockets, uint8_t *buf, size_t buf_len, int timeout, int *bytes_read)
|
||||
{
|
||||
if (buf == nullptr || buf_len == 0)
|
||||
return RTP_INVALID_VALUE;
|
||||
|
@ -68,7 +68,7 @@ rtp_error_t uvgrtp::poll::poll(std::vector<uvgrtp::socket>& sockets, uint8_t *bu
|
|||
int ret;
|
||||
|
||||
for (size_t i = 0; i < sockets.size(); ++i) {
|
||||
fds[i].fd = sockets.at(i).get_raw_socket();
|
||||
fds[i].fd = sockets.at(i)->get_raw_socket();
|
||||
fds[i].events = POLLIN | POLLERR;
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ rtp_error_t uvgrtp::poll::poll(std::vector<uvgrtp::socket>& sockets, uint8_t *bu
|
|||
|
||||
for (size_t i = 0; i < sockets.size(); ++i) {
|
||||
if (fds[i].revents & POLLIN) {
|
||||
auto rtp_ret = sockets.at(i).recv(buf, buf_len, 0, bytes_read);
|
||||
auto rtp_ret = sockets.at(i)->recv(buf, buf_len, 0, bytes_read);
|
||||
|
||||
if (rtp_ret != RTP_OK) {
|
||||
UVG_LOG_ERROR("recv() for socket %d failed: %s", fds[i].fd, strerror(errno));
|
||||
|
@ -107,7 +107,7 @@ rtp_error_t uvgrtp::poll::poll(std::vector<uvgrtp::socket>& sockets, uint8_t *bu
|
|||
FD_ZERO(&read_fds);
|
||||
|
||||
for (size_t i = 0; i < sockets.size(); ++i) {
|
||||
auto fd = sockets.at(i).get_raw_socket();
|
||||
auto fd = sockets.at(i)->get_raw_socket();
|
||||
FD_SET(fd, &read_fds);
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ rtp_error_t uvgrtp::poll::poll(std::vector<uvgrtp::socket>& sockets, uint8_t *bu
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < sockets.size(); ++i) {
|
||||
auto rtp_ret = sockets.at(i).recv((uint8_t *)buf, (int)buf_len, 0, bytes_read);
|
||||
auto rtp_ret = sockets.at(i)->recv((uint8_t *)buf, (int)buf_len, 0, bytes_read);
|
||||
|
||||
if (rtp_ret != RTP_OK) {
|
||||
if (WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace uvgrtp {
|
|||
*
|
||||
* If some actions happens with the socket, return status
|
||||
* If the timeout is exceeded, return RTP_INTERRUPTED */
|
||||
rtp_error_t poll(std::vector<uvgrtp::socket>& sockets, uint8_t *buf, size_t buf_len, int timeout, int *bytes_read);
|
||||
rtp_error_t poll(std::vector<std::shared_ptr<uvgrtp::socket>>& sockets, uint8_t *buf, size_t buf_len, int timeout, int *bytes_read);
|
||||
|
||||
/* TODO: */
|
||||
rtp_error_t blocked_recv(std::shared_ptr<uvgrtp::socket> socket, uint8_t *buf, size_t buf_len, int timeout, int *bytes_read);
|
||||
|
|
|
@ -48,7 +48,7 @@ void uvgrtp::reception_flow::clear_frames()
|
|||
frames_mtx_.lock();
|
||||
for (auto& frame : frames_)
|
||||
{
|
||||
delete[] frame;
|
||||
(void)uvgrtp::frame::dealloc_frame(frame);
|
||||
}
|
||||
|
||||
frames_.clear();
|
||||
|
@ -256,12 +256,12 @@ void uvgrtp::reception_flow::call_aux_handlers(uint32_t key, int rce_flags, uvgr
|
|||
case RTP_MULTIPLE_PKTS_READY:
|
||||
{
|
||||
while ((*aux.getter)(aux.arg, frame) == RTP_PKT_READY)
|
||||
this->return_frame(*frame);
|
||||
return_frame(*frame);
|
||||
}
|
||||
break;
|
||||
|
||||
case RTP_PKT_READY:
|
||||
this->return_frame(*frame);
|
||||
return_frame(*frame);
|
||||
break;
|
||||
|
||||
/* packet was not handled or only partially handled by the handler
|
||||
|
@ -291,13 +291,13 @@ void uvgrtp::reception_flow::call_aux_handlers(uint32_t key, int rce_flags, uvgr
|
|||
case RTP_MULTIPLE_PKTS_READY:
|
||||
{
|
||||
while (aux.getter(frame) == RTP_PKT_READY)
|
||||
this->return_frame(*frame);
|
||||
return_frame(*frame);
|
||||
|
||||
break;
|
||||
}
|
||||
case RTP_PKT_READY:
|
||||
{
|
||||
this->return_frame(*frame);
|
||||
return_frame(*frame);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -461,7 +461,7 @@ void uvgrtp::reception_flow::process_packet(int rce_flags)
|
|||
}
|
||||
case RTP_PKT_MODIFIED:
|
||||
{
|
||||
this->call_aux_handlers(handler.first, rce_flags, &frame);
|
||||
call_aux_handlers(handler.first, rce_flags, &frame);
|
||||
break;
|
||||
}
|
||||
case RTP_GENERIC_ERROR:
|
||||
|
|
163
src/rtcp.cc
163
src/rtcp.cc
|
@ -81,7 +81,7 @@ uvgrtp::rtcp::rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::string cname, int rce_
|
|||
memcpy(cname_, c, cname.length());
|
||||
uint8_t length = (uint8_t)cname.length();
|
||||
|
||||
cnameItem_ = { 1, length, (void*)cname_ };
|
||||
cnameItem_ = { 1, length, (uint8_t*)cname_ };
|
||||
ourItems_.push_back(cnameItem_);
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,28 @@ uvgrtp::rtcp::~rtcp()
|
|||
stop();
|
||||
}
|
||||
|
||||
cleanup_participants();
|
||||
|
||||
ourItems_.clear();
|
||||
sockets_.clear();
|
||||
}
|
||||
|
||||
void uvgrtp::rtcp::cleanup_participants()
|
||||
{
|
||||
UVG_LOG_DEBUG("Removing all participants");
|
||||
|
||||
/* free all receiver statistic structs */
|
||||
for (auto& participant : participants_)
|
||||
{
|
||||
free_participant(std::move(participant.second));
|
||||
}
|
||||
participants_.clear();
|
||||
|
||||
for (auto& participant : initial_participants_)
|
||||
{
|
||||
free_participant(std::move(participant));
|
||||
}
|
||||
initial_participants_.clear();
|
||||
}
|
||||
|
||||
uvgrtp::rtcp_app_packet::rtcp_app_packet(const char* name, uint8_t subtype, uint32_t payload_len, const uint8_t* payload)
|
||||
|
@ -122,7 +143,7 @@ uvgrtp::rtcp_app_packet::~rtcp_app_packet() {
|
|||
delete[] payload;
|
||||
}
|
||||
|
||||
void uvgrtp::rtcp::free_participant(rtcp_participant* participant)
|
||||
void uvgrtp::rtcp::free_participant(std::unique_ptr<rtcp_participant> participant)
|
||||
{
|
||||
participant->socket = nullptr;
|
||||
|
||||
|
@ -136,14 +157,27 @@ void uvgrtp::rtcp::free_participant(rtcp_participant* participant)
|
|||
}
|
||||
if (participant->sdes_frame)
|
||||
{
|
||||
for (auto& chunk : participant->sdes_frame->chunks)
|
||||
{
|
||||
for (auto& item : chunk.items)
|
||||
{
|
||||
if (item.data != nullptr)
|
||||
{
|
||||
delete[] item.data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete participant->sdes_frame;
|
||||
}
|
||||
if (participant->app_frame)
|
||||
{
|
||||
if (participant->app_frame->payload != nullptr)
|
||||
{
|
||||
delete[] participant->app_frame->payload;
|
||||
}
|
||||
delete participant->app_frame;
|
||||
}
|
||||
|
||||
delete participant;
|
||||
}
|
||||
|
||||
rtp_error_t uvgrtp::rtcp::start()
|
||||
|
@ -163,23 +197,11 @@ rtp_error_t uvgrtp::rtcp::start()
|
|||
rtp_error_t uvgrtp::rtcp::stop()
|
||||
{
|
||||
UVG_LOG_DEBUG("Stopping RTCP");
|
||||
|
||||
// TODO: Make thread safe. I think this kind of works, but not in a flexible way
|
||||
if (!active_)
|
||||
{
|
||||
UVG_LOG_DEBUG("Removing all participants");
|
||||
/* free all receiver statistic structs */
|
||||
for (auto& participant : participants_)
|
||||
{
|
||||
free_participant(participant.second);
|
||||
}
|
||||
participants_.clear();
|
||||
|
||||
for (auto& participant : initial_participants_)
|
||||
{
|
||||
free_participant(participant);
|
||||
}
|
||||
initial_participants_.clear();
|
||||
|
||||
cleanup_participants();
|
||||
return RTP_OK;
|
||||
}
|
||||
|
||||
|
@ -320,7 +342,7 @@ rtp_error_t uvgrtp::rtcp::add_participant(std::string dst_addr, uint16_t dst_por
|
|||
}
|
||||
|
||||
rtp_error_t ret;
|
||||
rtcp_participant *p = new rtcp_participant();
|
||||
std::unique_ptr<rtcp_participant> p = std::unique_ptr<rtcp_participant>(new rtcp_participant());
|
||||
|
||||
zero_stats(&p->stats);
|
||||
|
||||
|
@ -328,7 +350,7 @@ rtp_error_t uvgrtp::rtcp::add_participant(std::string dst_addr, uint16_t dst_por
|
|||
|
||||
if ((ret = p->socket->init(AF_INET, SOCK_DGRAM, 0)) != RTP_OK)
|
||||
{
|
||||
delete p;
|
||||
free_participant(std::move(p));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -336,7 +358,7 @@ rtp_error_t uvgrtp::rtcp::add_participant(std::string dst_addr, uint16_t dst_por
|
|||
|
||||
if ((ret = p->socket->setsockopt(SOL_SOCKET, SO_REUSEADDR, (const char *)&enable, sizeof(int))) != RTP_OK)
|
||||
{
|
||||
delete p;
|
||||
free_participant(std::move(p));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -360,7 +382,7 @@ rtp_error_t uvgrtp::rtcp::add_participant(std::string dst_addr, uint16_t dst_por
|
|||
|
||||
if ((ret = p->socket->setsockopt(SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))) != RTP_OK)
|
||||
{
|
||||
delete p;
|
||||
free_participant(std::move(p));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -368,7 +390,7 @@ rtp_error_t uvgrtp::rtcp::add_participant(std::string dst_addr, uint16_t dst_por
|
|||
|
||||
if ((ret = p->socket->bind(AF_INET, INADDR_ANY, src_port)) != RTP_OK)
|
||||
{
|
||||
delete p;
|
||||
free_participant(std::move(p));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -376,8 +398,8 @@ rtp_error_t uvgrtp::rtcp::add_participant(std::string dst_addr, uint16_t dst_por
|
|||
p->address = p->socket->create_sockaddr(AF_INET, dst_addr, dst_port);
|
||||
p->stats.clock_rate = clock_rate;
|
||||
|
||||
initial_participants_.push_back(p);
|
||||
sockets_.push_back(*p->socket);
|
||||
sockets_.push_back(p->socket);
|
||||
initial_participants_.push_back(std::move(p));
|
||||
|
||||
return RTP_OK;
|
||||
}
|
||||
|
@ -395,10 +417,10 @@ rtp_error_t uvgrtp::rtcp::add_participant(uint32_t ssrc)
|
|||
* create a "fake" participant that is only used for storing statistics information */
|
||||
if (initial_participants_.empty())
|
||||
{
|
||||
participants_[ssrc] = new rtcp_participant();
|
||||
participants_[ssrc] = std::unique_ptr<rtcp_participant> (new rtcp_participant());
|
||||
zero_stats(&participants_[ssrc]->stats);
|
||||
} else {
|
||||
participants_[ssrc] = initial_participants_.back();
|
||||
participants_[ssrc] = std::move(initial_participants_.back());
|
||||
initial_participants_.pop_back();
|
||||
}
|
||||
num_receivers_++;
|
||||
|
@ -691,7 +713,7 @@ uvgrtp::frame::rtcp_app_packet* uvgrtp::rtcp::get_app_packet(uint32_t ssrc)
|
|||
return frame;
|
||||
}
|
||||
|
||||
std::vector<uvgrtp::socket>& uvgrtp::rtcp::get_sockets()
|
||||
std::vector<std::shared_ptr<uvgrtp::socket>>& uvgrtp::rtcp::get_sockets()
|
||||
{
|
||||
return sockets_;
|
||||
}
|
||||
|
@ -847,48 +869,47 @@ rtp_error_t uvgrtp::rtcp::update_participant_seq(uint32_t ssrc, uint16_t seq)
|
|||
return RTP_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
auto p = participants_[ssrc];
|
||||
uint16_t udelta = seq - p->stats.max_seq;
|
||||
uint16_t udelta = seq - participants_[ssrc]->stats.max_seq;
|
||||
|
||||
/* Source is not valid until MIN_SEQUENTIAL packets with
|
||||
* sequential sequence numbers have been received. */
|
||||
if (p->probation)
|
||||
if (participants_[ssrc]->probation)
|
||||
{
|
||||
/* packet is in sequence */
|
||||
if (seq == p->stats.max_seq + 1)
|
||||
if (seq == participants_[ssrc]->stats.max_seq + 1)
|
||||
{
|
||||
p->probation--;
|
||||
p->stats.max_seq = seq;
|
||||
if (!p->probation)
|
||||
participants_[ssrc]->probation--;
|
||||
participants_[ssrc]->stats.max_seq = seq;
|
||||
if (!participants_[ssrc]->probation)
|
||||
{
|
||||
uvgrtp::rtcp::init_participant_seq(ssrc, seq);
|
||||
return RTP_OK;
|
||||
}
|
||||
} else {
|
||||
p->probation = MIN_SEQUENTIAL - 1;
|
||||
p->stats.max_seq = seq;
|
||||
participants_[ssrc]->probation = MIN_SEQUENTIAL - 1;
|
||||
participants_[ssrc]->stats.max_seq = seq;
|
||||
}
|
||||
|
||||
return RTP_NOT_READY;
|
||||
} else if (udelta < MAX_DROPOUT) {
|
||||
/* in order, with permissible gap */
|
||||
if (seq < p->stats.max_seq)
|
||||
if (seq < participants_[ssrc]->stats.max_seq)
|
||||
{
|
||||
/* Sequence number wrapped - count another 64K cycle. */
|
||||
p->stats.cycles += 1;
|
||||
participants_[ssrc]->stats.cycles += 1;
|
||||
}
|
||||
p->stats.max_seq = seq;
|
||||
participants_[ssrc]->stats.max_seq = seq;
|
||||
} else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) {
|
||||
/* the sequence number made a very large jump */
|
||||
if (seq == p->stats.bad_seq)
|
||||
if (seq == participants_[ssrc]->stats.bad_seq)
|
||||
{
|
||||
/* Two sequential packets -- assume that the other side
|
||||
* restarted without telling us so just re-sync
|
||||
* (i.e., pretend this was the first packet). */
|
||||
uvgrtp::rtcp::init_participant_seq(ssrc, seq);
|
||||
} else {
|
||||
p->stats.bad_seq = (seq + 1) & (RTP_SEQ_MOD - 1);
|
||||
UVG_LOG_ERROR("Invalid sequence number. Seq jump: %u -> %u", p->stats.max_seq, seq);
|
||||
participants_[ssrc]->stats.bad_seq = (seq + 1) & (RTP_SEQ_MOD - 1);
|
||||
UVG_LOG_ERROR("Invalid sequence number. Seq jump: %u -> %u", participants_[ssrc]->stats.max_seq, seq);
|
||||
return RTP_GENERIC_ERROR;
|
||||
}
|
||||
} else {
|
||||
|
@ -917,10 +938,8 @@ bool uvgrtp::rtcp::collision_detected(uint32_t ssrc, const sockaddr_in& src_addr
|
|||
return false;
|
||||
}
|
||||
|
||||
auto sender = participants_.at(ssrc);
|
||||
|
||||
if (src_addr.sin_port != sender->address.sin_port &&
|
||||
src_addr.sin_addr.s_addr != sender->address.sin_addr.s_addr)
|
||||
if (src_addr.sin_port != participants_.at(ssrc)->address.sin_port &&
|
||||
src_addr.sin_addr.s_addr != participants_.at(ssrc)->address.sin_addr.s_addr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -930,31 +949,32 @@ bool uvgrtp::rtcp::collision_detected(uint32_t ssrc, const sockaddr_in& src_addr
|
|||
|
||||
void uvgrtp::rtcp::update_session_statistics(const uvgrtp::frame::rtp_frame *frame)
|
||||
{
|
||||
auto p = participants_[frame->header.ssrc];
|
||||
participants_[frame->header.ssrc]->stats.received_rtp_packet = true;
|
||||
|
||||
p->stats.received_rtp_packet = true;
|
||||
|
||||
p->stats.received_pkts += 1;
|
||||
p->stats.received_bytes += (uint32_t)frame->payload_len;
|
||||
participants_[frame->header.ssrc]->stats.received_pkts += 1;
|
||||
participants_[frame->header.ssrc]->stats.received_bytes += (uint32_t)frame->payload_len;
|
||||
|
||||
/* calculate number of dropped packets */
|
||||
int extended_max = (static_cast<int>(p->stats.cycles) << 16) + p->stats.max_seq;
|
||||
int expected = extended_max - p->stats.base_seq + 1;
|
||||
int extended_max = (static_cast<int>(participants_[frame->header.ssrc]->stats.cycles) << 16) +
|
||||
participants_[frame->header.ssrc]->stats.max_seq;
|
||||
int expected = extended_max - participants_[frame->header.ssrc]->stats.base_seq + 1;
|
||||
|
||||
int dropped = expected - p->stats.received_pkts;
|
||||
p->stats.dropped_pkts = dropped >= 0 ? dropped : 0;
|
||||
int dropped = expected - participants_[frame->header.ssrc]->stats.received_pkts;
|
||||
participants_[frame->header.ssrc]->stats.dropped_pkts = dropped >= 0 ? dropped : 0;
|
||||
|
||||
// the arrival time expressed as an RTP timestamp
|
||||
uint32_t arrival = p->stats.initial_rtp +
|
||||
(uint32_t)uvgrtp::clock::ntp::diff_now(p->stats.initial_ntp)*(p->stats.clock_rate / 1000);
|
||||
uint32_t arrival = participants_[frame->header.ssrc]->stats.initial_rtp +
|
||||
(uint32_t)uvgrtp::clock::ntp::diff_now(participants_[frame->header.ssrc]->stats.initial_ntp)*
|
||||
(participants_[frame->header.ssrc]->stats.clock_rate / 1000);
|
||||
|
||||
// calculate interarrival jitter. See RFC 3550 A.8
|
||||
uint32_t transit = arrival - frame->header.timestamp; // A.8: int transit = arrival - r->ts
|
||||
uint32_t trans_difference = std::abs((int)(transit - p->stats.transit));
|
||||
uint32_t trans_difference = std::abs((int)(transit - participants_[frame->header.ssrc]->stats.transit));
|
||||
|
||||
// update statistics
|
||||
p->stats.transit = transit;
|
||||
p->stats.jitter += (1.f / 16.f) * ((double)trans_difference - p->stats.jitter);
|
||||
participants_[frame->header.ssrc]->stats.transit = transit;
|
||||
participants_[frame->header.ssrc]->stats.jitter += (1.f / 16.f) *
|
||||
((double)trans_difference - participants_[frame->header.ssrc]->stats.jitter);
|
||||
}
|
||||
|
||||
/* RTCP packet handler is responsible for doing two things:
|
||||
|
@ -1330,8 +1350,6 @@ rtp_error_t uvgrtp::rtcp::handle_sdes_packet(uint8_t* packet, size_t& read_ptr,
|
|||
auto frame = new uvgrtp::frame::rtcp_sdes_packet;
|
||||
frame->header = header;
|
||||
|
||||
// TODO: The SDES parsing is incorrect at the moment
|
||||
|
||||
// Read SDES chunks
|
||||
while (read_ptr + SSRC_CSRC_SIZE <= packet_end)
|
||||
{
|
||||
|
@ -1348,7 +1366,7 @@ rtp_error_t uvgrtp::rtcp::handle_sdes_packet(uint8_t* packet, size_t& read_ptr,
|
|||
|
||||
if (read_ptr + item.length <= packet_end)
|
||||
{
|
||||
item.data = (void*)new uint8_t[item.length];
|
||||
item.data = new uint8_t[item.length];
|
||||
|
||||
memcpy(item.data, &packet[read_ptr], item.length);
|
||||
read_ptr += item.length;
|
||||
|
@ -1363,7 +1381,6 @@ rtp_error_t uvgrtp::rtcp::handle_sdes_packet(uint8_t* packet, size_t& read_ptr,
|
|||
}
|
||||
|
||||
frame->chunks.push_back(chunk);
|
||||
|
||||
}
|
||||
|
||||
sdes_mutex_.lock();
|
||||
|
@ -1415,8 +1432,7 @@ rtp_error_t uvgrtp::rtcp::handle_bye_packet(uint8_t* packet, size_t& read_ptr,
|
|||
}
|
||||
|
||||
UVG_LOG_DEBUG("Destroying participant with BYE");
|
||||
participants_[ssrc]->socket = nullptr;
|
||||
delete participants_[ssrc];
|
||||
free_participant(std::move(participants_[ssrc]));
|
||||
participants_.erase(ssrc);
|
||||
}
|
||||
|
||||
|
@ -1445,9 +1461,16 @@ rtp_error_t uvgrtp::rtcp::handle_app_packet(uint8_t* packet, size_t& read_ptr,
|
|||
|
||||
size_t application_data_size = packet_end - read_ptr;
|
||||
|
||||
// application data is saved to payload
|
||||
frame->payload = new uint8_t[application_data_size];
|
||||
memcpy(frame->payload, &packet[read_ptr], application_data_size);
|
||||
if (application_data_size > 0)
|
||||
{
|
||||
// application data is saved to payload
|
||||
frame->payload = new uint8_t[application_data_size];
|
||||
memcpy(frame->payload, &packet[read_ptr], application_data_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
frame->payload = nullptr;
|
||||
}
|
||||
|
||||
app_mutex_.lock();
|
||||
if (app_hook_) {
|
||||
|
|
|
@ -170,6 +170,8 @@ std::string uvgrtp::socket::sockaddr_to_string(const sockaddr_in& addr) const
|
|||
|
||||
std::string string(c_string);
|
||||
string.append(":" + std::to_string(ntohs(addr.sin_port)));
|
||||
|
||||
delete[] c_string;
|
||||
return string;
|
||||
}
|
||||
|
||||
|
|
|
@ -646,7 +646,7 @@ rtp_error_t uvgrtp::zrtp::init(uint32_t ssrc, std::shared_ptr<uvgrtp::socket> so
|
|||
"to select which streams should not perform DH");
|
||||
}
|
||||
|
||||
// perform Diffie-Helmann (DH)
|
||||
// perform Diffie-Hellman (DH)
|
||||
ret = init_dhm(ssrc, socket, addr);
|
||||
zrtp_mtx_.unlock();
|
||||
}
|
||||
|
|
|
@ -244,6 +244,17 @@ void sdes_hook(uvgrtp::frame::rtcp_sdes_packet* frame)
|
|||
{
|
||||
std::cout << "Got SDES frame with " << frame->chunks.size() << " chunk" << std::endl;
|
||||
|
||||
for (auto& chunk : frame->chunks)
|
||||
{
|
||||
for (auto& item : chunk.items)
|
||||
{
|
||||
if (item.data != nullptr)
|
||||
{
|
||||
delete[] item.data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* RTCP frames can be deallocated using delete */
|
||||
delete frame;
|
||||
}
|
||||
|
@ -258,6 +269,10 @@ void app_hook(uvgrtp::frame::rtcp_app_packet* frame)
|
|||
std::cout << "ssrc: " << frame->ssrc << std::endl;
|
||||
std::cout << "Name: " << name << std::endl;
|
||||
std::cout << "Payload length " << payload_len << " and content: " << payload << std::endl;
|
||||
if (payload_len > 0)
|
||||
{
|
||||
delete[] frame->payload;
|
||||
}
|
||||
delete frame;
|
||||
}
|
||||
|
||||
|
|
|
@ -188,6 +188,9 @@ TEST(EncryptionTests, zrtp)
|
|||
{
|
||||
receiver_thread->join();
|
||||
}
|
||||
|
||||
cleanup_sess(ctx, sender_session);
|
||||
cleanup_sess(ctx, receiver_session);
|
||||
}
|
||||
|
||||
TEST(EncryptionTests, zrtp_multistream)
|
||||
|
|
Loading…
Reference in New Issue