Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rtcp enhancements #914

Merged
merged 9 commits into from
Oct 4, 2022
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();
Comment on lines +205 to +207
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain in detail this math?

Copy link
Member Author

@jmillan jmillan Oct 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A Receiver Report packet is composed by:

  • RTCP common header (Packet::CommonHeaderSize).
  • SSRC of the packet sender. (4 bytes)
  • Up to 31 reports. (Each report size is ReceiverReport::HeaderSize )

This method returns the size needed to represent all it's content.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Why is (commonHeader size + 4) being multiplied by ((number of reports divided by max reports per packet) + 1)?

Copy link
Member Author

@jmillan jmillan Oct 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are calculating there how many receiver report packets (Common header + SSRC) we need, considering our packet instance packet can hold more than 31 receiver reports and the the maximum reports a serialized receiver report packet can contain is 31 (limit given by the 'count' header field in the RTCP common header).


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