Add SDES, APP, IJ, SLI and PLI packet types to RTCP packet class.

BUG=2450
R=mflodman@webrtc.org, stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/19559004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@6449 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
asapersson@webrtc.org
2014-06-16 14:09:28 +00:00
parent 27626a6256
commit 4b12d40008
5 changed files with 1046 additions and 207 deletions

View File

@ -13,21 +13,39 @@
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
#include "webrtc/system_wrappers/interface/logging.h"
using webrtc::RTCPUtility::PT_APP;
using webrtc::RTCPUtility::PT_BYE;
using webrtc::RTCPUtility::PT_IJ;
using webrtc::RTCPUtility::PT_PSFB;
using webrtc::RTCPUtility::PT_RR;
using webrtc::RTCPUtility::PT_RTPFB;
using webrtc::RTCPUtility::PT_SDES;
using webrtc::RTCPUtility::PT_SR;
using webrtc::RTCPUtility::PT_XR;
using webrtc::RTCPUtility::RTCPPacketAPP;
using webrtc::RTCPUtility::RTCPPacketBYE;
using webrtc::RTCPUtility::RTCPPacketPSFBAPP;
using webrtc::RTCPUtility::RTCPPacketPSFBFIR;
using webrtc::RTCPUtility::RTCPPacketPSFBFIRItem;
using webrtc::RTCPUtility::RTCPPacketPSFBPLI;
using webrtc::RTCPUtility::RTCPPacketPSFBREMBItem;
using webrtc::RTCPUtility::RTCPPacketPSFBRPSI;
using webrtc::RTCPUtility::RTCPPacketPSFBSLI;
using webrtc::RTCPUtility::RTCPPacketPSFBSLIItem;
using webrtc::RTCPUtility::RTCPPacketReportBlockItem;
using webrtc::RTCPUtility::RTCPPacketRR;
using webrtc::RTCPUtility::RTCPPacketRTPFBNACK;
using webrtc::RTCPUtility::RTCPPacketRTPFBNACKItem;
using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBN;
using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBNItem;
using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBR;
using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBRItem;
using webrtc::RTCPUtility::RTCPPacketSR;
using webrtc::RTCPUtility::RTCPPacketXRDLRRReportBlockItem;
using webrtc::RTCPUtility::RTCPPacketXRReceiverReferenceTimeItem;
using webrtc::RTCPUtility::RTCPPacketXR;
using webrtc::RTCPUtility::RTCPPacketXRVOIPMetricItem;
namespace webrtc {
namespace rtcp {
@ -35,23 +53,23 @@ namespace {
// Unused SSRC of media source, set to 0.
const uint32_t kUnusedMediaSourceSsrc0 = 0;
void AssignUWord8(uint8_t* buffer, uint16_t* offset, uint8_t value) {
void AssignUWord8(uint8_t* buffer, size_t* offset, uint8_t value) {
buffer[(*offset)++] = value;
}
void AssignUWord16(uint8_t* buffer, uint16_t* offset, uint16_t value) {
void AssignUWord16(uint8_t* buffer, size_t* offset, uint16_t value) {
ModuleRTPUtility::AssignUWord16ToBuffer(buffer + *offset, value);
*offset += 2;
}
void AssignUWord24(uint8_t* buffer, uint16_t* offset, uint32_t value) {
void AssignUWord24(uint8_t* buffer, size_t* offset, uint32_t value) {
ModuleRTPUtility::AssignUWord24ToBuffer(buffer + *offset, value);
*offset += 3;
}
void AssignUWord32(uint8_t* buffer, uint16_t* offset, uint32_t value) {
void AssignUWord32(uint8_t* buffer, size_t* offset, uint32_t value) {
ModuleRTPUtility::AssignUWord32ToBuffer(buffer + *offset, value);
*offset += 4;
}
uint16_t BlockToHeaderLength(uint16_t length_in_bytes) {
size_t BlockToHeaderLength(size_t length_in_bytes) {
// Length in 32-bit words minus 1.
assert(length_in_bytes > 0);
assert(length_in_bytes % 4 == 0);
@ -69,9 +87,10 @@ uint16_t BlockToHeaderLength(uint16_t length_in_bytes) {
void CreateHeader(uint8_t count_or_format, // Depends on packet type.
uint8_t packet_type,
uint16_t length,
size_t length,
uint8_t* buffer,
uint16_t* pos) {
size_t* pos) {
assert(length <= 0xffff);
const uint8_t kVersion = 2;
AssignUWord8(buffer, pos, (kVersion << 6) + count_or_format);
AssignUWord8(buffer, pos, packet_type);
@ -98,9 +117,9 @@ void CreateHeader(uint8_t count_or_format, // Depends on packet type.
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
void CreateSenderReport(const RTCPPacketSR& sr,
uint16_t length,
size_t length,
uint8_t* buffer,
uint16_t* pos) {
size_t* pos) {
CreateHeader(sr.NumberOfReportBlocks, PT_SR, length, buffer, pos);
AssignUWord32(buffer, pos, sr.SenderSSRC);
AssignUWord32(buffer, pos, sr.NTPMostSignificant);
@ -120,9 +139,9 @@ void CreateSenderReport(const RTCPPacketSR& sr,
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
void CreateReceiverReport(const RTCPPacketRR& rr,
uint16_t length,
size_t length,
uint8_t* buffer,
uint16_t* pos) {
size_t* pos) {
CreateHeader(rr.NumberOfReportBlocks, PT_RR, length, buffer, pos);
AssignUWord32(buffer, pos, rr.SenderSSRC);
}
@ -144,16 +163,89 @@ void CreateReceiverReport(const RTCPPacketRR& rr,
// | delay since last SR (DLSR) |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
void CreateReportBlock(const RTCPPacketReportBlockItem& report_block,
uint8_t* buffer,
uint16_t* pos) {
AssignUWord32(buffer, pos, report_block.SSRC);
AssignUWord8(buffer, pos, report_block.FractionLost);
AssignUWord24(buffer, pos, report_block.CumulativeNumOfPacketsLost);
AssignUWord32(buffer, pos, report_block.ExtendedHighestSequenceNumber);
AssignUWord32(buffer, pos, report_block.Jitter);
AssignUWord32(buffer, pos, report_block.LastSR);
AssignUWord32(buffer, pos, report_block.DelayLastSR);
void CreateReportBlocks(const std::vector<RTCPPacketReportBlockItem>& blocks,
uint8_t* buffer,
size_t* pos) {
for (std::vector<RTCPPacketReportBlockItem>::const_iterator
it = blocks.begin(); it != blocks.end(); ++it) {
AssignUWord32(buffer, pos, (*it).SSRC);
AssignUWord8(buffer, pos, (*it).FractionLost);
AssignUWord24(buffer, pos, (*it).CumulativeNumOfPacketsLost);
AssignUWord32(buffer, pos, (*it).ExtendedHighestSequenceNumber);
AssignUWord32(buffer, pos, (*it).Jitter);
AssignUWord32(buffer, pos, (*it).LastSR);
AssignUWord32(buffer, pos, (*it).DelayLastSR);
}
}
// Transmission Time Offsets in RTP Streams (RFC 5450).
//
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// hdr |V=2|P| RC | PT=IJ=195 | length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | inter-arrival jitter |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// . .
// . .
// . .
// | inter-arrival jitter |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
void CreateIj(const std::vector<uint32_t>& ij_items,
uint8_t* buffer,
size_t* pos) {
size_t length = ij_items.size();
CreateHeader(length, PT_IJ, length, buffer, pos);
for (std::vector<uint32_t>::const_iterator it = ij_items.begin();
it != ij_items.end(); ++it) {
AssignUWord32(buffer, pos, *it);
}
}
// Source Description (SDES) (RFC 3550).
//
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// header |V=2|P| SC | PT=SDES=202 | length |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// chunk | SSRC/CSRC_1 |
// 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | SDES items |
// | ... |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// chunk | SSRC/CSRC_2 |
// 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | SDES items |
// | ... |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// Canonical End-Point Identifier SDES Item (CNAME)
//
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | CNAME=1 | length | user and domain name ...
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
void CreateSdes(const std::vector<Sdes::Chunk>& chunks,
size_t length,
uint8_t* buffer,
size_t* pos) {
CreateHeader(chunks.size(), PT_SDES, length, buffer, pos);
const uint8_t kSdesItemType = 1;
for (std::vector<Sdes::Chunk>::const_iterator it = chunks.begin();
it != chunks.end(); ++it) {
AssignUWord32(buffer, pos, (*it).ssrc);
AssignUWord8(buffer, pos, kSdesItemType);
AssignUWord8(buffer, pos, (*it).name.length());
memcpy(buffer + *pos, (*it).name.data(), (*it).name.length());
*pos += (*it).name.length();
memset(buffer + *pos, 0, (*it).null_octets);
*pos += (*it).null_octets;
}
}
// Bye packet (BYE) (RFC 3550).
@ -171,9 +263,9 @@ void CreateReportBlock(const RTCPPacketReportBlockItem& report_block,
void CreateBye(const RTCPPacketBYE& bye,
const std::vector<uint32_t>& csrcs,
uint16_t length,
size_t length,
uint8_t* buffer,
uint16_t* pos) {
size_t* pos) {
CreateHeader(length, PT_BYE, length, buffer, pos);
AssignUWord32(buffer, pos, bye.SenderSSRC);
for (std::vector<uint32_t>::const_iterator it = csrcs.begin();
@ -182,6 +274,32 @@ void CreateBye(const RTCPPacketBYE& bye,
}
}
// Application-Defined packet (APP) (RFC 3550).
//
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |V=2|P| subtype | PT=APP=204 | length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | SSRC/CSRC |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | name (ASCII) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | application-dependent data ...
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
void CreateApp(const RTCPPacketAPP& app,
uint32_t ssrc,
size_t length,
uint8_t* buffer,
size_t* pos) {
CreateHeader(app.SubType, PT_APP, length, buffer, pos);
AssignUWord32(buffer, pos, ssrc);
AssignUWord32(buffer, pos, app.Name);
memcpy(buffer + *pos, app.Data, app.Size);
*pos += app.Size;
}
// RFC 4585: Feedback format.
//
// Common packet format:
@ -199,6 +317,47 @@ void CreateBye(const RTCPPacketBYE& bye,
// :
//
// Picture loss indication (PLI) (RFC 4585).
//
// FCI: no feedback control information.
void CreatePli(const RTCPPacketPSFBPLI& pli,
size_t length,
uint8_t* buffer,
size_t* pos) {
const uint8_t kFmt = 1;
CreateHeader(kFmt, PT_PSFB, length, buffer, pos);
AssignUWord32(buffer, pos, pli.SenderSSRC);
AssignUWord32(buffer, pos, pli.MediaSSRC);
}
// Slice loss indication (SLI) (RFC 4585).
//
// FCI:
//
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | First | Number | PictureID |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
void CreateSli(const RTCPPacketPSFBSLI& sli,
const RTCPPacketPSFBSLIItem& sli_item,
size_t length,
uint8_t* buffer,
size_t* pos) {
const uint8_t kFmt = 2;
CreateHeader(kFmt, PT_PSFB, length, buffer, pos);
AssignUWord32(buffer, pos, sli.SenderSSRC);
AssignUWord32(buffer, pos, sli.MediaSSRC);
AssignUWord8(buffer, pos, sli_item.FirstMB >> 5);
AssignUWord8(buffer, pos, (sli_item.FirstMB << 3) +
((sli_item.NumberOfMB >> 10) & 0x07));
AssignUWord8(buffer, pos, sli_item.NumberOfMB >> 2);
AssignUWord8(buffer, pos, (sli_item.NumberOfMB << 6) + sli_item.PictureId);
}
// Generic NACK (RFC 4585).
//
// FCI:
@ -211,9 +370,9 @@ void CreateBye(const RTCPPacketBYE& bye,
void CreateNack(const RTCPPacketRTPFBNACK& nack,
const std::vector<RTCPPacketRTPFBNACKItem>& nack_fields,
uint16_t length,
size_t length,
uint8_t* buffer,
uint16_t* pos) {
size_t* pos) {
const uint8_t kFmt = 1;
CreateHeader(kFmt, PT_RTPFB, length, buffer, pos);
AssignUWord32(buffer, pos, nack.SenderSSRC);
@ -239,9 +398,9 @@ void CreateNack(const RTCPPacketRTPFBNACK& nack,
void CreateRpsi(const RTCPPacketPSFBRPSI& rpsi,
uint8_t padding_bytes,
uint16_t length,
size_t length,
uint8_t* buffer,
uint16_t* pos) {
size_t* pos) {
// Native bit string should be a multiple of 8 bits.
assert(rpsi.NumberOfValidBits % 8 == 0);
const uint8_t kFmt = 3;
@ -270,9 +429,9 @@ void CreateRpsi(const RTCPPacketPSFBRPSI& rpsi,
void CreateFir(const RTCPPacketPSFBFIR& fir,
const RTCPPacketPSFBFIRItem& fir_item,
uint16_t length,
size_t length,
uint8_t* buffer,
uint16_t* pos) {
size_t* pos) {
const uint8_t kFmt = 4;
CreateHeader(kFmt, PT_PSFB, length, buffer, pos);
AssignUWord32(buffer, pos, fir.SenderSSRC);
@ -281,16 +440,6 @@ void CreateFir(const RTCPPacketPSFBFIR& fir,
AssignUWord8(buffer, pos, fir_item.CommandSequenceNumber);
AssignUWord24(buffer, pos, 0);
}
template <typename T>
void AppendBlocks(const std::vector<T*>& blocks,
uint8_t* buffer,
uint16_t* pos) {
for (typename std::vector<T*>::const_iterator it = blocks.begin();
it != blocks.end(); ++it) {
(*it)->Create(buffer, pos);
}
}
} // namespace
void RtcpPacket::Append(RtcpPacket* packet) {
@ -299,39 +448,41 @@ void RtcpPacket::Append(RtcpPacket* packet) {
}
RawPacket RtcpPacket::Build() const {
uint16_t len = 0;
size_t length = 0;
uint8_t packet[IP_PACKET_SIZE];
CreateAndAddAppended(packet, &len, IP_PACKET_SIZE);
return RawPacket(packet, len);
CreateAndAddAppended(packet, &length, IP_PACKET_SIZE);
return RawPacket(packet, length);
}
void RtcpPacket::Build(uint8_t* packet, uint16_t* len, uint16_t max_len) const {
*len = 0;
CreateAndAddAppended(packet, len, max_len);
void RtcpPacket::Build(uint8_t* packet,
size_t* length,
size_t max_length) const {
*length = 0;
CreateAndAddAppended(packet, length, max_length);
}
void RtcpPacket::CreateAndAddAppended(uint8_t* packet,
uint16_t* len,
uint16_t max_len) const {
Create(packet, len, max_len);
size_t* length,
size_t max_length) const {
Create(packet, length, max_length);
for (std::vector<RtcpPacket*>::const_iterator it = appended_packets_.begin();
it != appended_packets_.end(); ++it) {
(*it)->CreateAndAddAppended(packet, len, max_len);
(*it)->CreateAndAddAppended(packet, length, max_length);
}
}
void Empty::Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const {
void Empty::Create(uint8_t* packet, size_t* length, size_t max_length) const {
}
void SenderReport::Create(uint8_t* packet,
uint16_t* len,
uint16_t max_len) const {
if (*len + Length() > max_len) {
size_t* length,
size_t max_length) const {
if (*length + BlockLength() > max_length) {
LOG(LS_WARNING) << "Max packet size reached.";
return;
}
CreateSenderReport(sr_, BlockToHeaderLength(Length()), packet, len);
AppendBlocks(report_blocks_, packet, len);
CreateSenderReport(sr_, BlockToHeaderLength(BlockLength()), packet, length);
CreateReportBlocks(report_blocks_, packet, length);
}
void SenderReport::WithReportBlock(ReportBlock* block) {
@ -340,19 +491,19 @@ void SenderReport::WithReportBlock(ReportBlock* block) {
LOG(LS_WARNING) << "Max report blocks reached.";
return;
}
report_blocks_.push_back(block);
report_blocks_.push_back(block->report_block_);
sr_.NumberOfReportBlocks = report_blocks_.size();
}
void ReceiverReport::Create(uint8_t* packet,
uint16_t* len,
uint16_t max_len) const {
if (*len + Length() > max_len) {
size_t* length,
size_t max_length) const {
if (*length + BlockLength() > max_length) {
LOG(LS_WARNING) << "Max packet size reached.";
return;
}
CreateReceiverReport(rr_, BlockToHeaderLength(Length()), packet, len);
AppendBlocks(report_blocks_, packet, len);
CreateReceiverReport(rr_, BlockToHeaderLength(BlockLength()), packet, length);
CreateReportBlocks(report_blocks_, packet, length);
}
void ReceiverReport::WithReportBlock(ReportBlock* block) {
@ -361,20 +512,71 @@ void ReceiverReport::WithReportBlock(ReportBlock* block) {
LOG(LS_WARNING) << "Max report blocks reached.";
return;
}
report_blocks_.push_back(block);
report_blocks_.push_back(block->report_block_);
rr_.NumberOfReportBlocks = report_blocks_.size();
}
void ReportBlock::Create(uint8_t* packet, uint16_t* len) const {
CreateReportBlock(report_block_, packet, len);
}
void Bye::Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const {
if (*len + Length() > max_len) {
void Ij::Create(uint8_t* packet, size_t* length, size_t max_length) const {
if (*length + BlockLength() > max_length) {
LOG(LS_WARNING) << "Max packet size reached.";
return;
}
CreateBye(bye_, csrcs_, BlockToHeaderLength(Length()), packet, len);
CreateIj(ij_items_, packet, length);
}
void Ij::WithJitterItem(uint32_t jitter) {
if (ij_items_.size() >= kMaxNumberOfIjItems) {
LOG(LS_WARNING) << "Max inter-arrival jitter items reached.";
return;
}
ij_items_.push_back(jitter);
}
void Sdes::Create(uint8_t* packet, size_t* length, size_t max_length) const {
assert(!chunks_.empty());
if (*length + BlockLength() > max_length) {
LOG(LS_WARNING) << "Max packet size reached.";
return;
}
CreateSdes(chunks_, BlockToHeaderLength(BlockLength()), packet, length);
}
void Sdes::WithCName(uint32_t ssrc, std::string cname) {
assert(cname.length() <= 0xff);
if (chunks_.size() >= kMaxNumberOfChunks) {
LOG(LS_WARNING) << "Max SDES chunks reached.";
return;
}
// In each chunk, the list of items must be terminated by one or more null
// octets. The next chunk must start on a 32-bit boundary.
// CNAME (1 byte) | length (1 byte) | name | padding.
int null_octets = 4 - ((2 + cname.length()) % 4);
Chunk chunk;
chunk.ssrc = ssrc;
chunk.name = cname;
chunk.null_octets = null_octets;
chunks_.push_back(chunk);
}
size_t Sdes::BlockLength() const {
// Header (4 bytes).
// Chunk:
// SSRC/CSRC (4 bytes) | CNAME (1 byte) | length (1 byte) | name | padding.
size_t length = kHeaderLength;
for (std::vector<Chunk>::const_iterator it = chunks_.begin();
it != chunks_.end(); ++it) {
length += 6 + (*it).name.length() + (*it).null_octets;
}
assert(length % 4 == 0);
return length;
}
void Bye::Create(uint8_t* packet, size_t* length, size_t max_length) const {
if (*length + BlockLength() > max_length) {
LOG(LS_WARNING) << "Max packet size reached.";
return;
}
CreateBye(bye_, csrcs_, BlockToHeaderLength(BlockLength()), packet, length);
}
void Bye::WithCsrc(uint32_t csrc) {
@ -385,13 +587,39 @@ void Bye::WithCsrc(uint32_t csrc) {
csrcs_.push_back(csrc);
}
void Nack::Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const {
assert(!nack_fields_.empty());
if (*len + Length() > max_len) {
void App::Create(uint8_t* packet, size_t* length, size_t max_length) const {
if (*length + BlockLength() > max_length) {
LOG(LS_WARNING) << "Max packet size reached.";
return;
}
CreateNack(nack_, nack_fields_, BlockToHeaderLength(Length()), packet, len);
CreateApp(app_, ssrc_, BlockToHeaderLength(BlockLength()), packet, length);
}
void Pli::Create(uint8_t* packet, size_t* length, size_t max_length) const {
if (*length + BlockLength() > max_length) {
LOG(LS_WARNING) << "Max packet size reached.";
return;
}
CreatePli(pli_, BlockToHeaderLength(BlockLength()), packet, length);
}
void Sli::Create(uint8_t* packet, size_t* length, size_t max_length) const {
if (*length + BlockLength() > max_length) {
LOG(LS_WARNING) << "Max packet size reached.";
return;
}
CreateSli(sli_, sli_item_, BlockToHeaderLength(BlockLength()), packet,
length);
}
void Nack::Create(uint8_t* packet, size_t* length, size_t max_length) const {
assert(!nack_fields_.empty());
if (*length + BlockLength() > max_length) {
LOG(LS_WARNING) << "Max packet size reached.";
return;
}
CreateNack(nack_, nack_fields_, BlockToHeaderLength(BlockLength()), packet,
length);
}
void Nack::WithList(const uint16_t* nack_list, int length) {
@ -418,13 +646,14 @@ void Nack::WithList(const uint16_t* nack_list, int length) {
}
}
void Rpsi::Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const {
void Rpsi::Create(uint8_t* packet, size_t* length, size_t max_length) const {
assert(rpsi_.NumberOfValidBits > 0);
if (*len + Length() > max_len) {
if (*length + BlockLength() > max_length) {
LOG(LS_WARNING) << "Max packet size reached.";
return;
}
CreateRpsi(rpsi_, padding_bytes_, BlockToHeaderLength(Length()), packet, len);
CreateRpsi(rpsi_, padding_bytes_, BlockToHeaderLength(BlockLength()), packet,
length);
}
void Rpsi::WithPictureId(uint64_t picture_id) {
@ -454,12 +683,13 @@ void Rpsi::WithPictureId(uint64_t picture_id) {
}
}
void Fir::Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const {
if (*len + Length() > max_len) {
void Fir::Create(uint8_t* packet, size_t* length, size_t max_length) const {
if (*length + BlockLength() > max_length) {
LOG(LS_WARNING) << "Max packet size reached.";
return;
}
CreateFir(fir_, fir_item_, BlockToHeaderLength(Length()), packet, len);
CreateFir(fir_, fir_item_, BlockToHeaderLength(BlockLength()), packet,
length);
}
} // namespace rtcp
} // namespace webrtc