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

@ -12,6 +12,8 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_
#define WEBRTC_MODULES_RTP_RTCP_RTCP_PACKET_H_
#include <map>
#include <string>
#include <vector>
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
@ -21,8 +23,10 @@
namespace webrtc {
namespace rtcp {
enum { kCommonFbFmtLength = 12 };
enum { kReportBlockLength = 24 };
class RawPacket;
class ReportBlock;
// Class for building RTCP packets.
//
@ -40,9 +44,9 @@ class ReportBlock;
// fir.To(234)
// fir.WithCommandSeqNum(123);
//
// uint16_t len = 0; // Builds an intra frame request
// size_t length = 0; // Builds an intra frame request
// uint8_t packet[kPacketSize]; // with sequence number 123.
// fir.Build(packet, &len, kPacketSize);
// fir.Build(packet, &length, kPacketSize);
//
// RawPacket packet = fir.Build(); // Returns a RawPacket holding
// // the built rtcp packet.
@ -59,18 +63,20 @@ class RtcpPacket {
RawPacket Build() const;
void Build(uint8_t* packet, uint16_t* len, uint16_t max_len) const;
void Build(uint8_t* packet, size_t* length, size_t max_length) const;
protected:
RtcpPacket() {}
RtcpPacket() : kHeaderLength(4) {}
virtual void Create(
uint8_t* packet, uint16_t* len, uint16_t max_len) const = 0;
uint8_t* packet, size_t* length, size_t max_length) const = 0;
void CreateAndAddAppended(
uint8_t* packet, uint16_t* len, uint16_t max_len) const;
const size_t kHeaderLength;
private:
void CreateAndAddAppended(
uint8_t* packet, size_t* length, size_t max_length) const;
std::vector<RtcpPacket*> appended_packets_;
};
@ -81,11 +87,66 @@ class Empty : public RtcpPacket {
virtual ~Empty() {}
protected:
virtual void Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const;
virtual void Create(uint8_t* packet, size_t* length, size_t max_length) const;
};
//// From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
// From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
//
// RTCP report block (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
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// | SSRC_1 (SSRC of first source) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | fraction lost | cumulative number of packets lost |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | extended highest sequence number received |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | interarrival jitter |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | last SR (LSR) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | delay since last SR (DLSR) |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
class ReportBlock {
public:
ReportBlock() {
// TODO(asapersson): Consider adding a constructor to struct.
memset(&report_block_, 0, sizeof(report_block_));
}
~ReportBlock() {}
void To(uint32_t ssrc) {
report_block_.SSRC = ssrc;
}
void WithFractionLost(uint8_t fraction_lost) {
report_block_.FractionLost = fraction_lost;
}
void WithCumulativeLost(uint32_t cumulative_lost) {
report_block_.CumulativeNumOfPacketsLost = cumulative_lost;
}
void WithExtHighestSeqNum(uint32_t ext_highest_seq_num) {
report_block_.ExtendedHighestSequenceNumber = ext_highest_seq_num;
}
void WithJitter(uint32_t jitter) {
report_block_.Jitter = jitter;
}
void WithLastSr(uint32_t last_sr) {
report_block_.LastSR = last_sr;
}
void WithDelayLastSr(uint32_t delay_last_sr) {
report_block_.DelayLastSR = delay_last_sr;
}
private:
friend class SenderReport;
friend class ReceiverReport;
RTCPUtility::RTCPPacketReportBlockItem report_block_;
};
// RTCP sender report (RFC 3550).
//
// 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
@ -109,8 +170,7 @@ class Empty : public RtcpPacket {
class SenderReport : public RtcpPacket {
public:
SenderReport()
: RtcpPacket() {
SenderReport() : RtcpPacket() {
memset(&sr_, 0, sizeof(sr_));
}
@ -136,20 +196,22 @@ class SenderReport : public RtcpPacket {
}
void WithReportBlock(ReportBlock* block);
enum { kMaxNumberOfReportBlocks = 0x1f };
protected:
virtual void Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const;
virtual void Create(
uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
private:
uint16_t Length() const {
const uint16_t kSrBlockLen = 28;
const uint16_t kReportBlockLen = 24;
return kSrBlockLen + report_blocks_.size() * kReportBlockLen;
enum { kMaxNumberOfReportBlocks = 0x1f };
size_t BlockLength() const {
const size_t kSrHeaderLength = 8;
const size_t kSenderInfoLength = 20;
return kSrHeaderLength + kSenderInfoLength +
report_blocks_.size() * kReportBlockLength;
}
RTCPUtility::RTCPPacketSR sr_;
std::vector<ReportBlock*> report_blocks_;
std::vector<RTCPUtility::RTCPPacketReportBlockItem> report_blocks_;
};
//
@ -167,8 +229,7 @@ class SenderReport : public RtcpPacket {
class ReceiverReport : public RtcpPacket {
public:
ReceiverReport()
: RtcpPacket() {
ReceiverReport() : RtcpPacket() {
memset(&rr_, 0, sizeof(rr_));
}
@ -179,75 +240,117 @@ class ReceiverReport : public RtcpPacket {
}
void WithReportBlock(ReportBlock* block);
enum { kMaxNumberOfReportBlocks = 0x1f };
protected:
virtual void Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const;
virtual void Create(
uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
private:
uint16_t Length() const {
const uint16_t kRrBlockLen = 8;
const uint16_t kReportBlockLen = 24;
return kRrBlockLen + report_blocks_.size() * kReportBlockLen;
enum { kMaxNumberOfReportBlocks = 0x1f };
size_t BlockLength() const {
const size_t kRrHeaderLength = 8;
return kRrHeaderLength + report_blocks_.size() * kReportBlockLength;
}
RTCPUtility::RTCPPacketRR rr_;
std::vector<ReportBlock*> report_blocks_;
std::vector<RTCPUtility::RTCPPacketReportBlockItem> report_blocks_;
};
// Transmission Time Offsets in RTP Streams (RFC 5450).
//
// RTCP report block (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
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// hdr |V=2|P| RC | PT=IJ=195 | length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | inter-arrival jitter |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// . .
// . .
// . .
// | inter-arrival jitter |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// 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
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// | SSRC_1 (SSRC of first source) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | fraction lost | cumulative number of packets lost |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | extended highest sequence number received |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | interarrival jitter |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | last SR (LSR) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | delay since last SR (DLSR) |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// If present, this RTCP packet must be placed after a receiver report
// (inside a compound RTCP packet), and MUST have the same value for RC
// (reception report count) as the receiver report.
class ReportBlock {
class Ij : public RtcpPacket {
public:
ReportBlock() {
memset(&report_block_, 0, sizeof(report_block_));
}
Ij() : RtcpPacket() {}
~ReportBlock() {}
virtual ~Ij() {}
void To(uint32_t ssrc) {
report_block_.SSRC = ssrc;
}
void WithFractionLost(uint8_t fraction_lost) {
report_block_.FractionLost = fraction_lost;
}
void WithCumPacketsLost(uint32_t cum_packets_lost) {
report_block_.CumulativeNumOfPacketsLost = cum_packets_lost;
}
void WithExtHighestSeqNum(uint32_t ext_highest_seq_num) {
report_block_.ExtendedHighestSequenceNumber = ext_highest_seq_num;
}
void WithJitter(uint32_t jitter) {
report_block_.Jitter = jitter;
}
void WithLastSr(uint32_t last_sr) {
report_block_.LastSR = last_sr;
}
void WithDelayLastSr(uint32_t delay_last_sr) {
report_block_.DelayLastSR = delay_last_sr;
}
void WithJitterItem(uint32_t jitter);
void Create(uint8_t* packet, uint16_t* len) const;
protected:
virtual void Create(
uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
private:
RTCPUtility::RTCPPacketReportBlockItem report_block_;
enum { kMaxNumberOfIjItems = 0x1f };
size_t BlockLength() const {
return kHeaderLength + 4 * ij_items_.size();
}
std::vector<uint32_t> ij_items_;
DISALLOW_COPY_AND_ASSIGN(Ij);
};
// 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 ...
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
class Sdes : public RtcpPacket {
public:
Sdes() : RtcpPacket() {}
virtual ~Sdes() {}
void WithCName(uint32_t ssrc, std::string cname);
struct Chunk {
uint32_t ssrc;
std::string name;
int null_octets;
};
protected:
virtual void Create(
uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
private:
enum { kMaxNumberOfChunks = 0x1f };
size_t BlockLength() const;
std::vector<Chunk> chunks_;
DISALLOW_COPY_AND_ASSIGN(Sdes);
};
//
@ -266,8 +369,7 @@ class ReportBlock {
class Bye : public RtcpPacket {
public:
Bye()
: RtcpPacket() {
Bye() : RtcpPacket() {
memset(&bye_, 0, sizeof(bye_));
}
@ -278,21 +380,79 @@ class Bye : public RtcpPacket {
}
void WithCsrc(uint32_t csrc);
enum { kMaxNumberOfCsrcs = 0x1f - 1 };
protected:
virtual void Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const;
virtual void Create(
uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
private:
uint16_t Length() const {
const uint16_t kByeBlockLen = 8 + 4 * csrcs_.size();
return kByeBlockLen;
enum { kMaxNumberOfCsrcs = 0x1f - 1 };
size_t BlockLength() const {
size_t source_count = 1 + csrcs_.size();
return kHeaderLength + 4 * source_count;
}
RTCPUtility::RTCPPacketBYE bye_;
std::vector<uint32_t> csrcs_;
};
// 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 ...
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
class App : public RtcpPacket {
public:
App()
: RtcpPacket(),
ssrc_(0) {
memset(&app_, 0, sizeof(app_));
}
virtual ~App() {}
void From(uint32_t ssrc) {
ssrc_ = ssrc;
}
void WithSubType(uint8_t subtype) {
assert(subtype <= 0x1f);
app_.SubType = subtype;
}
void WithName(uint32_t name) {
app_.Name = name;
}
void WithData(const uint8_t* data, uint16_t data_length) {
assert(data);
assert(data_length <= kRtcpAppCode_DATA_SIZE);
assert(data_length % 4 == 0);
memcpy(app_.Data, data, data_length);
app_.Size = data_length;
}
protected:
virtual void Create(
uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
private:
size_t BlockLength() const {
return 12 + app_.Size;
}
uint32_t ssrc_;
RTCPUtility::RTCPPacketAPP app_;
DISALLOW_COPY_AND_ASSIGN(App);
};
// RFC 4585: Feedback format.
//
// Common packet format:
@ -309,6 +469,92 @@ class Bye : public RtcpPacket {
// : Feedback Control Information (FCI) :
// :
// Picture loss indication (PLI) (RFC 4585).
//
// FCI: no feedback control information.
class Pli : public RtcpPacket {
public:
Pli() : RtcpPacket() {
memset(&pli_, 0, sizeof(pli_));
}
virtual ~Pli() {}
void From(uint32_t ssrc) {
pli_.SenderSSRC = ssrc;
}
void To(uint32_t ssrc) {
pli_.MediaSSRC = ssrc;
}
protected:
virtual void Create(
uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
private:
size_t BlockLength() const {
return kCommonFbFmtLength;
}
RTCPUtility::RTCPPacketPSFBPLI pli_;
DISALLOW_COPY_AND_ASSIGN(Pli);
};
// 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 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
class Sli : public RtcpPacket {
public:
Sli() : RtcpPacket() {
memset(&sli_, 0, sizeof(sli_));
memset(&sli_item_, 0, sizeof(sli_item_));
}
virtual ~Sli() {}
void From(uint32_t ssrc) {
sli_.SenderSSRC = ssrc;
}
void To(uint32_t ssrc) {
sli_.MediaSSRC = ssrc;
}
void WithFirstMb(uint16_t first_mb) {
assert(first_mb <= 0x1fff);
sli_item_.FirstMB = first_mb;
}
void WithNumberOfMb(uint16_t number_mb) {
assert(number_mb <= 0x1fff);
sli_item_.NumberOfMB = number_mb;
}
void WithPictureId(uint8_t picture_id) {
assert(picture_id <= 0x3f);
sli_item_.PictureId = picture_id;
}
protected:
virtual void Create(
uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
private:
size_t BlockLength() const {
const size_t kFciLength = 4;
return kCommonFbFmtLength + kFciLength;
}
RTCPUtility::RTCPPacketPSFBSLI sli_;
RTCPUtility::RTCPPacketPSFBSLIItem sli_item_;
DISALLOW_COPY_AND_ASSIGN(Sli);
};
// Generic NACK (RFC 4585).
//
// FCI:
@ -320,8 +566,7 @@ class Bye : public RtcpPacket {
class Nack : public RtcpPacket {
public:
Nack()
: RtcpPacket() {
Nack() : RtcpPacket() {
memset(&nack_, 0, sizeof(nack_));
}
@ -336,13 +581,13 @@ class Nack : public RtcpPacket {
void WithList(const uint16_t* nack_list, int length);
protected:
virtual void Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const
OVERRIDE;
virtual void Create(
uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
private:
uint16_t Length() const {
const uint16_t kNackBlockLen = 4 * (3 + nack_fields_.size());
return kNackBlockLen;
size_t BlockLength() const {
size_t fci_length = 4 * nack_fields_.size();
return kCommonFbFmtLength + fci_length;
}
RTCPUtility::RTCPPacketRTPFBNACK nack_;
@ -366,8 +611,8 @@ class Nack : public RtcpPacket {
class Rpsi : public RtcpPacket {
public:
Rpsi()
: RtcpPacket(),
padding_bytes_(0) {
: RtcpPacket(),
padding_bytes_(0) {
memset(&rpsi_, 0, sizeof(rpsi_));
}
@ -386,14 +631,13 @@ class Rpsi : public RtcpPacket {
void WithPictureId(uint64_t picture_id);
protected:
virtual void Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const
OVERRIDE;
virtual void Create(
uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
private:
uint16_t Length() const {
const uint16_t kRpsiBlockLen =
12 + 2 + (rpsi_.NumberOfValidBits / 8) + padding_bytes_;
return kRpsiBlockLen;
size_t BlockLength() const {
size_t fci_length = 2 + (rpsi_.NumberOfValidBits / 8) + padding_bytes_;
return kCommonFbFmtLength + fci_length;
}
uint8_t padding_bytes_;
@ -417,7 +661,7 @@ class Rpsi : public RtcpPacket {
class Fir : public RtcpPacket {
public:
Fir()
: RtcpPacket() {
: RtcpPacket() {
memset(&fir_, 0, sizeof(fir_));
memset(&fir_item_, 0, sizeof(fir_item_));
}
@ -435,12 +679,13 @@ class Fir : public RtcpPacket {
}
protected:
virtual void Create(uint8_t* packet, uint16_t* len, uint16_t max_len) const;
virtual void Create(
uint8_t* packet, size_t* length, size_t max_length) const OVERRIDE;
private:
uint16_t Length() const {
const uint16_t kFirBlockLen = 20;
return kFirBlockLen;
size_t BlockLength() const {
const size_t kFciLength = 8;
return kCommonFbFmtLength + kFciLength;
}
RTCPUtility::RTCPPacketPSFBFIR fir_;
@ -450,7 +695,7 @@ class Fir : public RtcpPacket {
// Class holding a RTCP packet.
//
// Takes a built rtcp packet.
// RawPacket raw_packet(buffer, len);
// RawPacket raw_packet(buffer, length);
//
// To access the raw packet:
// raw_packet.buffer(); - pointer to the raw packet
@ -458,22 +703,22 @@ class Fir : public RtcpPacket {
class RawPacket {
public:
RawPacket(const uint8_t* buffer, uint16_t len) {
assert(len <= IP_PACKET_SIZE);
memcpy(packet_, buffer, len);
packet_length_ = len;
RawPacket(const uint8_t* packet, size_t length) {
assert(length <= IP_PACKET_SIZE);
memcpy(buffer_, packet, length);
buffer_length_ = length;
}
const uint8_t* buffer() {
return packet_;
return buffer_;
}
uint16_t buffer_length() const {
return packet_length_;
size_t buffer_length() const {
return buffer_length_;
}
private:
uint16_t packet_length_;
uint8_t packet_[IP_PACKET_SIZE];
size_t buffer_length_;
uint8_t buffer_[IP_PACKET_SIZE];
};
} // namespace rtcp