rtcp: fix app packets hook to conform to current API

This commit is contained in:
Heikki Tampio 2023-02-27 10:33:19 +02:00
parent 41653397e2
commit 02f660a561
4 changed files with 27 additions and 33 deletions

View File

@ -78,14 +78,14 @@ namespace uvgrtp {
struct rtcp_app_packet {
rtcp_app_packet(const rtcp_app_packet& orig_packet) = delete;
rtcp_app_packet(const char* name, uint8_t subtype, uint32_t payload_len, const uint8_t* payload);
rtcp_app_packet(const char* name, uint8_t subtype, uint32_t payload_len, std::unique_ptr<uint8_t[]> payload);
~rtcp_app_packet();
const char* name;
uint8_t subtype;
uint32_t payload_len;
const uint8_t* payload;
std::unique_ptr<uint8_t[]> payload;
};
/// \endcond
@ -364,7 +364,7 @@ namespace uvgrtp {
* \retval RTP_OK on success
* \retval RTP_INVALID_VALUE If app_name is empty or longer that 4 characters or function pointer is empty
*/
rtp_error_t install_send_app_hook(std::string app_name, std::function<void(uint32_t& payload_len, uint8_t& subtype, std::vector<uint8_t>& payload)> app_sending_func);
rtp_error_t install_send_app_hook(std::string app_name, std::function<std::unique_ptr<uint8_t[]>(uint8_t& subtype, uint32_t& payload_len)> app_sending_func);
/**
* \brief Remove all installed hooks for RTCP
@ -595,7 +595,7 @@ namespace uvgrtp {
std::map<std::string, std::deque<rtcp_app_packet>> app_packets_; // sent one at a time per name
// APPs for hook
std::map<std::string, std::function <void(uint32_t& payload_len, uint8_t& subtype, std::vector<uint8_t>& payload)>> outgoing_app_hooks_;
std::multimap<std::string, std::function <std::unique_ptr<uint8_t[]>(uint8_t& subtype, uint32_t& payload_len)>> outgoing_app_hooks_;
bool hooked_app_;

View File

@ -133,23 +133,20 @@ void uvgrtp::rtcp::cleanup_participants()
initial_participants_.clear();
}
uvgrtp::rtcp_app_packet::rtcp_app_packet(const char* name, uint8_t subtype, uint32_t payload_len, const uint8_t* payload)
uvgrtp::rtcp_app_packet::rtcp_app_packet(const char* name, uint8_t subtype, uint32_t payload_len, std::unique_ptr<uint8_t[]> payload)
{
uint8_t* packet_payload = new uint8_t[payload_len];
memcpy(packet_payload, payload, payload_len);
char* packet_name = new char[APP_NAME_SIZE];
memcpy(packet_name, name, APP_NAME_SIZE);
this->name = packet_name;
this->payload = packet_payload;
this->payload = std::move(payload);
this->subtype = subtype;
this->payload_len = payload_len;
}
uvgrtp::rtcp_app_packet::~rtcp_app_packet() {
delete[] name;
delete[] payload;
}
void uvgrtp::rtcp::free_participant(std::unique_ptr<rtcp_participant> participant)
@ -678,19 +675,15 @@ rtp_error_t uvgrtp::rtcp::install_app_hook(std::function<void(std::shared_ptr<uv
return RTP_OK;
}
rtp_error_t uvgrtp::rtcp::install_send_app_hook(std::string app_name, std::function<void(uint32_t& payload_len, uint8_t& subtype, std::vector<uint8_t>& payload)> app_sending_func)
rtp_error_t uvgrtp::rtcp::install_send_app_hook(std::string app_name, std::function<std::unique_ptr<uint8_t[]>(uint8_t& subtype, uint32_t& payload_len)> app_sending_func)
{
if (!app_sending_func || app_name.empty() || app_name.size() > 4) {
return RTP_INVALID_VALUE;
}
if (outgoing_app_hooks_.find(app_name) != outgoing_app_hooks_.end()) {
UVG_LOG_WARN("Replacing existing outgoing APP hook");
}
hooked_app_ = true;
{
std::lock_guard<std::mutex> lock(send_app_mutex_);
outgoing_app_hooks_[app_name] = app_sending_func;
outgoing_app_hooks_.insert({ app_name, app_sending_func });
}
return RTP_OK;
}
@ -1702,11 +1695,10 @@ rtp_error_t uvgrtp::rtcp::generate_report()
for (auto& [name, hook] : outgoing_app_hooks_) {
uint32_t p_len = 0;
uint8_t subtype = 0;
std::vector<uint8_t> pload = {};
hook(p_len, subtype, pload);
if (p_len > 0 && !pload.empty()) {
std::shared_ptr<rtcp_app_packet> app_pkt = std::make_shared<rtcp_app_packet>(name.data(), subtype, p_len, pload.data());
std::unique_ptr<uint8_t[]> pload = hook(subtype, p_len);
if (p_len > 0 && sizeof(pload.get()) != 0) {
std::shared_ptr<rtcp_app_packet> app_pkt = std::make_shared<rtcp_app_packet>(name.data(), subtype, p_len, std::move(pload));
outgoing_apps_.push_back(app_pkt);
}
}
@ -1833,7 +1825,7 @@ rtp_error_t uvgrtp::rtcp::generate_report()
{
if (hooked_app_) {
for (auto& pkt : outgoing_apps_) {
if(!construct_app_block(frame, write_ptr, pkt->subtype & 0x1f, *ssrc_.get(), pkt->name, pkt->payload, pkt->payload_len))
if(!construct_app_block(frame, write_ptr, pkt->subtype & 0x1f, *ssrc_.get(), pkt->name, std::move(pkt->payload), pkt->payload_len))
{
UVG_LOG_ERROR("Failed to construct APP packet");
delete[] frame;
@ -1849,7 +1841,7 @@ rtp_error_t uvgrtp::rtcp::generate_report()
{
// take the oldest APP packet and send it
rtcp_app_packet& next_packet = app_name.second.front();
if (!construct_app_block(frame, write_ptr, next_packet.subtype & 0x1f, *ssrc_.get(), next_packet.name, next_packet.payload, next_packet.payload_len))
if (!construct_app_block(frame, write_ptr, next_packet.subtype & 0x1f, *ssrc_.get(), next_packet.name, std::move(next_packet.payload), next_packet.payload_len))
{
UVG_LOG_ERROR("Failed to construct APP packet");
delete[] frame;
@ -1917,15 +1909,17 @@ rtp_error_t uvgrtp::rtcp::send_bye_packet(std::vector<uint32_t> ssrcs)
}
rtp_error_t uvgrtp::rtcp::send_app_packet(const char* name, uint8_t subtype,
uint32_t payload_len, const uint8_t* payload)
uint32_t payload_len, const uint8_t *payload)
{
packet_mutex_.lock();
std::unique_ptr<uint8_t[]> pl = std::make_unique<uint8_t[]>(*payload);
if (!app_packets_[name].empty())
{
UVG_LOG_DEBUG("Adding a new APP packet for sending when %llu packets are waiting to be sent",
app_packets_[name].size());
}
app_packets_[name].emplace_back(name, subtype, payload_len, payload);
app_packets_[name].emplace_back(name, subtype, payload_len, std::move(pl));
packet_mutex_.unlock();
return RTP_OK;

View File

@ -3,7 +3,7 @@
#include "srtp/srtcp.hh"
#include "debug.hh"
#include <memory>
#define SET_NEXT_FIELD_32(a, p, v) do { *(uint32_t *)&(a)[p] = (v); p += 4; } while (0)
uint32_t uvgrtp::get_sr_packet_size(int rce_flags, uint16_t reports)
@ -115,10 +115,10 @@ bool uvgrtp::construct_report_block(uint8_t* frame, size_t& ptr, uint32_t ssrc,
}
bool uvgrtp::construct_app_packet(uint8_t* frame, size_t& ptr,
const char* name, const uint8_t* payload, size_t payload_len)
const char* name, std::unique_ptr<uint8_t[]> payload, size_t payload_len)
{
memcpy(&frame[ptr], name, APP_NAME_SIZE);
memcpy(&frame[ptr + APP_NAME_SIZE], payload, payload_len);
memcpy(&frame[ptr + APP_NAME_SIZE], payload.get(), payload_len);
ptr += APP_NAME_SIZE + payload_len;
return true;
@ -164,11 +164,11 @@ bool uvgrtp::construct_bye_packet(uint8_t* frame, size_t& ptr, const std::vector
return true;
}
bool uvgrtp::construct_app_block(uint8_t* frame, size_t& write_ptr, uint8_t sec_field, uint32_t ssrc, const char* name, const uint8_t* payload, size_t payload_len)
bool uvgrtp::construct_app_block(uint8_t* frame, size_t& write_ptr, uint8_t sec_field, uint32_t ssrc, const char* name, std::unique_ptr<uint8_t[]> payload, size_t payload_len)
{
uint32_t packet_size = get_app_packet_size(payload_len);
uint32_t packet_size = get_app_packet_size((uint32_t)payload_len);
return construct_rtcp_header(frame, write_ptr, packet_size, sec_field,
uvgrtp::frame::RTCP_FT_APP) &&
construct_ssrc(frame, write_ptr, ssrc) &&
construct_app_packet(frame, write_ptr, name, payload, payload_len);
construct_app_packet(frame, write_ptr, name, std::move(payload), payload_len);
}

View File

@ -3,7 +3,7 @@
#include "uvgrtp/frame.hh"
#include <vector>
#include <memory>
namespace uvgrtp
{
@ -40,12 +40,12 @@ namespace uvgrtp
// Add the name and payload to APP packet, remember to also add SSRC separately
bool construct_app_packet(uint8_t* frame, size_t& ptr,
const char* name, const uint8_t* payload, size_t payload_len);
const char* name, std::unique_ptr<uint8_t[]> payload, size_t payload_len);
// Add BYE ssrcs, should probably be removed
bool construct_bye_packet(uint8_t* frame, size_t& ptr, const std::vector<uint32_t>& ssrcs);
// APP block construction
bool construct_app_block(uint8_t* frame, size_t& write_ptr, uint8_t sec_field, uint32_t ssrc, const char* name, const uint8_t* payload, size_t payload_len);
bool construct_app_block(uint8_t* frame, size_t& write_ptr, uint8_t sec_field, uint32_t ssrc, const char* name, std::unique_ptr<uint8_t[]> payload, size_t payload_len);
}