Skip to content

Commit

Permalink
Rtcp enhancements (#914)
Browse files Browse the repository at this point in the history
* RTCP: ReceiverReportPacket, fix serization when report number > 31

Each RR packet can hold up to 31 reports. Do serialize multiple packets
if the number of reports exceed 31.

* RTCP: SdesPacket, fix serization when chunk number > 31

Each Sdes packet can hold up to 31 chunks. Do serialize multiple packets
    if the number of reports exceed 31.

* RTCP: SenderReportPacket, serialize multiple SR packets at once

So a single serialized packet can be sent out instead of sending multiple
smaller packets.

* Consumer: GetRtcp() do not indicate a specific RtpStream

The method gathers all needed RTCP itself.

* RTCP: CompoundPacket, fill it up to the MTU before sending

Make sure CompoundPacket is filled before sending it.

* Reduces memory allocations for new CompoundPacket instances.
* Reduces the CPU and network overhead compared to sending smaller
  packets.

* RTCP: CompoundPacket, serialize it in the corresponding sending method

* Transport: enhance RTCP send interval

Set the interval to 1 second with a variation of [1..1.5].

Previously the interval was smaller as the send bandwidth increased
getting too small values for large meetings.

* RTCP: CompoundPacket, avoid creating unneeded std::vector instances

* RTCP: Sdes, fix typo
  • Loading branch information
jmillan authored Oct 4, 2022
1 parent 5fe51e4 commit ab9cfb9
Show file tree
Hide file tree
Showing 28 changed files with 642 additions and 210 deletions.
5 changes: 2 additions & 3 deletions worker/include/RTC/Consumer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,8 @@ namespace RTC
virtual void ApplyLayers() = 0;
virtual uint32_t GetDesiredBitrate() const = 0;
virtual void SendRtpPacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket) = 0;
virtual const std::vector<RTC::RtpStreamSend*>& GetRtpStreams() const = 0;
virtual void GetRtcp(
RTC::RTCP::CompoundPacket* packet, RTC::RtpStreamSend* rtpStream, uint64_t nowMs) = 0;
virtual bool GetRtcp(RTC::RTCP::CompoundPacket* packet, uint64_t nowMs) = 0;
virtual const std::vector<RTC::RtpStreamSend*>& GetRtpStreams() const = 0;
virtual void NeedWorstRemoteFractionLost(uint32_t mappedSsrc, uint8_t& worstRemoteFractionLost) = 0;
virtual void ReceiveNack(RTC::RTCP::FeedbackRtpNackPacket* nackPacket) = 0;
virtual void ReceiveKeyFrameRequest(
Expand Down
2 changes: 1 addition & 1 deletion worker/include/RTC/PipeConsumer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace RTC
void ApplyLayers() override;
uint32_t GetDesiredBitrate() const override;
void SendRtpPacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket) override;
void GetRtcp(RTC::RTCP::CompoundPacket* packet, RTC::RtpStreamSend* rtpStream, uint64_t nowMs) override;
bool GetRtcp(RTC::RTCP::CompoundPacket* packet, uint64_t nowMs) override;
const std::vector<RTC::RtpStreamSend*>& GetRtpStreams() const override
{
return this->rtpStreams;
Expand Down
2 changes: 1 addition & 1 deletion worker/include/RTC/Producer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ namespace RTC
ReceiveRtpPacketResult ReceiveRtpPacket(RTC::RtpPacket* packet);
void ReceiveRtcpSenderReport(RTC::RTCP::SenderReport* report);
void ReceiveRtcpXrDelaySinceLastRr(RTC::RTCP::DelaySinceLastRr::SsrcInfo* ssrcInfo);
void GetRtcp(RTC::RTCP::CompoundPacket* packet, uint64_t nowMs);
bool GetRtcp(RTC::RTCP::CompoundPacket* packet, uint64_t nowMs);
void RequestKeyFrame(uint32_t mappedSsrc);

/* Methods inherited from Channel::ChannelSocket::RequestHandler. */
Expand Down
30 changes: 25 additions & 5 deletions worker/include/RTC/RTCP/CompoundPacket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "RTC/RTCP/SenderReport.hpp"
#include "RTC/RTCP/XrDelaySinceLastRr.hpp"
#include "RTC/RTCP/XrReceiverReferenceTime.hpp"
#include "RTC/RtpPacket.hpp" // MtuSize.
#include <vector>

namespace RTC
Expand All @@ -15,6 +16,13 @@ namespace RTC
{
class CompoundPacket
{
public:
// Maximum size for a CompundPacket, leaving free space for encryption.
// 144 is the maximum number of octects that will be added to an RTP packet
// by srtp_protect().
// srtp.h: SRTP_MAX_TRAILER_LEN (SRTP_MAX_TAG_LEN + SRTP_MAX_MKI_LEN)
constexpr static size_t MaxSize{ RTC::MtuSize - 144u };

public:
CompoundPacket() = default;

Expand All @@ -23,10 +31,7 @@ namespace RTC
{
return this->header;
}
size_t GetSize() const
{
return this->size;
}
size_t GetSize();
size_t GetSenderReportCount() const
{
return this->senderReportPacket.GetCount();
Expand All @@ -36,6 +41,22 @@ namespace RTC
return this->receiverReportPacket.GetCount();
}
void Dump();
// RTCP additions per Consumer (non pipe).
// Adds the given data and returns true if there is enough space to hold it,
// false otherwise.
bool Add(
SenderReport* senderReport, SdesChunk* sdesChunk, DelaySinceLastRr* delaySinceLastRrReport);
// RTCP additions per Consumer (pipe).
// Adds the given data and returns true if there is enough space to hold it,
// false otherwise.
bool Add(
std::vector<SenderReport*>& senderReports,
std::vector<SdesChunk*>& sdesChunks,
std::vector<DelaySinceLastRr*>& delaySinceLastRrReports);
// RTCP additions per Producer.
// Adds the given data and returns true if there is enough space to hold it,
// false otherwise.
bool Add(std::vector<ReceiverReport*>&, ReceiverReferenceTime*);
void AddSenderReport(SenderReport* report);
void AddReceiverReport(ReceiverReport* report);
void AddSdesChunk(SdesChunk* chunk);
Expand All @@ -57,7 +78,6 @@ namespace RTC

private:
uint8_t* header{ nullptr };
size_t size{ 0 };
SenderReportPacket senderReportPacket;
ReceiverReportPacket receiverReportPacket;
SdesPacket sdesPacket;
Expand Down
21 changes: 15 additions & 6 deletions worker/include/RTC/RTCP/ReceiverReport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ namespace RTC
class ReceiverReportPacket : public Packet
{
public:
static size_t MaxReportsPerPacket;

using Iterator = std::vector<ReceiverReport*>::iterator;

public:
Expand Down Expand Up @@ -163,6 +165,13 @@ namespace RTC
{
this->reports.push_back(report);
}
void RemoveReport(ReceiverReport* report)
{
auto it = std::find(this->reports.begin(), this->reports.end(), report);

if (it != this->reports.end())
this->reports.erase(it);
}
Iterator Begin()
{
return this->reports.begin();
Expand Down Expand Up @@ -190,12 +199,12 @@ namespace RTC
}
size_t GetSize() const override
{
size_t size = Packet::CommonHeaderSize + 4u /* this->ssrc */;

for (auto* report : reports)
{
size += report->GetSize();
}
// A serialized packet can contain a maximum of 31 reports.
// If number of reports exceeds 31 then the required number of packets
// will be serialized which will take the size calculated below.
size_t size = (Packet::CommonHeaderSize + 4u /* this->ssrc */) *
((this->GetCount() / MaxReportsPerPacket) + 1);
size += ReceiverReport::HeaderSize * this->GetCount();

return size;
}
Expand Down
14 changes: 13 additions & 1 deletion worker/include/RTC/RTCP/Sdes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ namespace RTC
class SdesPacket : public Packet
{
public:
static size_t MaxChunksPerPacket;

using Iterator = std::vector<SdesChunk*>::iterator;

public:
Expand All @@ -178,6 +180,13 @@ namespace RTC
{
this->chunks.push_back(chunk);
}
void RemoveChunk(SdesChunk* chunk)
{
auto it = std::find(this->chunks.begin(), this->chunks.end(), chunk);

if (it != this->chunks.end())
this->chunks.erase(it);
}
Iterator Begin()
{
return this->chunks.begin();
Expand All @@ -197,7 +206,10 @@ namespace RTC
}
size_t GetSize() const override
{
size_t size = Packet::CommonHeaderSize;
// A serialized packet can contain a maximum of 31 chunks.
// If number of chunks exceeds 31 then the required number of packets
// will be serialized which will take the size calculated below.
size_t size = Packet::CommonHeaderSize * ((this->GetCount() / MaxChunksPerPacket) + 1);

for (auto* chunk : this->chunks)
{
Expand Down
14 changes: 12 additions & 2 deletions worker/include/RTC/RTCP/SenderReport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ namespace RTC
{
this->reports.push_back(report);
}
void RemoveReport(SenderReport* report)
{
auto it = std::find(this->reports.begin(), this->reports.end(), report);

if (it != this->reports.end())
this->reports.erase(it);
}
Iterator Begin()
{
return this->reports.begin();
Expand All @@ -143,14 +150,17 @@ namespace RTC
size_t Serialize(uint8_t* buffer) override;
size_t GetCount() const override
{
return 0;
return this->reports.size();
}
size_t GetSize() const override
{
size_t size = Packet::CommonHeaderSize;
// A serialized packet consists of a series of SR packets with
// one SR report each.
size_t size{ 0 };

for (auto* report : this->reports)
{
size += Packet::CommonHeaderSize;
size += report->GetSize();
}

Expand Down
7 changes: 7 additions & 0 deletions worker/include/RTC/RTCP/XR.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ namespace RTC
{
this->reports.push_back(report);
}
void RemoveReport(ExtendedReportBlock* report)
{
auto it = std::find(this->reports.begin(), this->reports.end(), report);

if (it != this->reports.end())
this->reports.erase(it);
}
uint32_t GetSsrc() const
{
return this->ssrc;
Expand Down
2 changes: 1 addition & 1 deletion worker/include/RTC/SimpleConsumer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace RTC
{
return this->rtpStreams;
}
void GetRtcp(RTC::RTCP::CompoundPacket* packet, RTC::RtpStreamSend* rtpStream, uint64_t nowMs) override;
bool GetRtcp(RTC::RTCP::CompoundPacket* packet, uint64_t nowMs) override;
void NeedWorstRemoteFractionLost(uint32_t mappedSsrc, uint8_t& worstRemoteFractionLost) override;
void ReceiveNack(RTC::RTCP::FeedbackRtpNackPacket* nackPacket) override;
void ReceiveKeyFrameRequest(RTC::RTCP::FeedbackPs::MessageType messageType, uint32_t ssrc) override;
Expand Down
2 changes: 1 addition & 1 deletion worker/include/RTC/SimulcastConsumer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace RTC
void ApplyLayers() override;
uint32_t GetDesiredBitrate() const override;
void SendRtpPacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket) override;
void GetRtcp(RTC::RTCP::CompoundPacket* packet, RTC::RtpStreamSend* rtpStream, uint64_t nowMs) override;
bool GetRtcp(RTC::RTCP::CompoundPacket* packet, uint64_t nowMs) override;
const std::vector<RTC::RtpStreamSend*>& GetRtpStreams() const override
{
return this->rtpStreams;
Expand Down
2 changes: 1 addition & 1 deletion worker/include/RTC/SvcConsumer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ namespace RTC
void ApplyLayers() override;
uint32_t GetDesiredBitrate() const override;
void SendRtpPacket(RTC::RtpPacket* packet, std::shared_ptr<RTC::RtpPacket>& sharedPacket) override;
void GetRtcp(RTC::RTCP::CompoundPacket* packet, RTC::RtpStreamSend* rtpStream, uint64_t nowMs) override;
bool GetRtcp(RTC::RTCP::CompoundPacket* packet, uint64_t nowMs) override;
const std::vector<RTC::RtpStreamSend*>& GetRtpStreams() const override
{
return this->rtpStreams;
Expand Down
2 changes: 2 additions & 0 deletions worker/src/RTC/DirectTransport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ namespace RTC
{
MS_TRACE();

packet->Serialize(RTC::RTCP::Buffer);

const uint8_t* data = packet->GetData();
size_t len = packet->GetSize();

Expand Down
47 changes: 27 additions & 20 deletions worker/src/RTC/PipeConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,15 +289,10 @@ namespace RTC
packet->SetSequenceNumber(origSeq);
}

void PipeConsumer::GetRtcp(
RTC::RTCP::CompoundPacket* packet, RTC::RtpStreamSend* rtpStream, uint64_t nowMs)
bool PipeConsumer::GetRtcp(RTC::RTCP::CompoundPacket* packet, uint64_t nowMs)
{
MS_TRACE();

MS_ASSERT(
std::find(this->rtpStreams.begin(), this->rtpStreams.end(), rtpStream) != this->rtpStreams.end(),
"RTP stream does exist");

// Special condition for PipeConsumer since this method will be called in a loop for
// each stream in this PipeConsumer.
// clang-format off
Expand All @@ -307,32 +302,44 @@ namespace RTC
)
// clang-format on
{
return;
return true;
}

auto* report = rtpStream->GetRtcpSenderReport(nowMs);
std::vector<RTCP::SenderReport*> senderReports;
std::vector<RTCP::SdesChunk*> sdesChunks;
std::vector<RTCP::DelaySinceLastRr*> xrReports;

if (!report)
return;
for (auto* rtpStream : this->rtpStreams)
{
auto* report = rtpStream->GetRtcpSenderReport(nowMs);

packet->AddSenderReport(report);
if (!report)
continue;

// Build SDES chunk for this sender.
auto* sdesChunk = rtpStream->GetRtcpSdesChunk();
senderReports.push_back(report);

packet->AddSdesChunk(sdesChunk);
// Build SDES chunk for this sender.
auto* sdesChunk = rtpStream->GetRtcpSdesChunk();
sdesChunks.push_back(sdesChunk);

auto* dlrr = rtpStream->GetRtcpXrDelaySinceLastRr(nowMs);
auto* dlrr = rtpStream->GetRtcpXrDelaySinceLastRr(nowMs);

if (dlrr)
{
auto* report = new RTC::RTCP::DelaySinceLastRr();
if (dlrr)
{
auto* report = new RTC::RTCP::DelaySinceLastRr();
report->AddSsrcInfo(dlrr);

report->AddSsrcInfo(dlrr);
packet->AddDelaySinceLastRr(report);
xrReports.push_back(report);
}
}

// RTCP Compound packet buffer cannot hold the data.
if (!packet->Add(senderReports, sdesChunks, xrReports))
return false;

this->lastRtcpSentTime = nowMs;

return true;
}

void PipeConsumer::NeedWorstRemoteFractionLost(uint32_t /*mappedSsrc*/, uint8_t& worstRemoteFractionLost)
Expand Down
2 changes: 2 additions & 0 deletions worker/src/RTC/PipeTransport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,8 @@ namespace RTC
if (!IsConnected())
return;

packet->Serialize(RTC::RTCP::Buffer);

const uint8_t* data = packet->GetData();
auto intLen = static_cast<int>(packet->GetSize());

Expand Down
2 changes: 2 additions & 0 deletions worker/src/RTC/PlainTransport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,8 @@ namespace RTC
if (!IsConnected())
return;

packet->Serialize(RTC::RTCP::Buffer);

const uint8_t* data = packet->GetData();
auto intLen = static_cast<int>(packet->GetSize());

Expand Down
Loading

0 comments on commit ab9cfb9

Please sign in to comment.