[rtp_rtcp] rtcp::Sdes moved into own file

Cleaning/Parsing will be done in the https://codereview.webrtc.org/1439553003/

BUG=webrtc:5260
R=asapersson@webrtc.org, åsapersson

Review URL: https://codereview.webrtc.org/1592763002 .

Cr-Commit-Position: refs/heads/master@{#11274}
This commit is contained in:
Danil Chapovalov
2016-01-15 17:34:27 +01:00
parent 79a5a83e10
commit 1567d0bd98
11 changed files with 258 additions and 201 deletions

View File

@ -319,6 +319,7 @@
'rtp_rtcp/source/rtcp_packet/report_block_unittest.cc',
'rtp_rtcp/source/rtcp_packet/rpsi_unittest.cc',
'rtp_rtcp/source/rtcp_packet/rrtr_unittest.cc',
'rtp_rtcp/source/rtcp_packet/sdes_unittest.cc',
'rtp_rtcp/source/rtcp_packet/sli_unittest.cc',
'rtp_rtcp/source/rtcp_packet/tmmbn_unittest.cc',
'rtp_rtcp/source/rtcp_packet/tmmbr_unittest.cc',

View File

@ -78,6 +78,8 @@ source_set("rtp_rtcp") {
"source/rtcp_packet/rrtr.h",
"source/rtcp_packet/rtpfb.cc",
"source/rtcp_packet/rtpfb.h",
"source/rtcp_packet/sdes.cc",
"source/rtcp_packet/sdes.h",
"source/rtcp_packet/sli.cc",
"source/rtcp_packet/sli.h",
"source/rtcp_packet/tmmbn.cc",

View File

@ -73,6 +73,8 @@
'source/rtcp_packet/rrtr.h',
'source/rtcp_packet/rtpfb.cc',
'source/rtcp_packet/rtpfb.h',
'source/rtcp_packet/sdes.cc',
'source/rtcp_packet/sdes.h',
'source/rtcp_packet/sli.cc',
'source/rtcp_packet/sli.h',
'source/rtcp_packet/tmmbn.cc',

View File

@ -19,7 +19,6 @@
using webrtc::RTCPUtility::PT_APP;
using webrtc::RTCPUtility::PT_IJ;
using webrtc::RTCPUtility::PT_RTPFB;
using webrtc::RTCPUtility::PT_SDES;
using webrtc::RTCPUtility::PT_SR;
using webrtc::RTCPUtility::RTCPPacketAPP;
@ -98,48 +97,6 @@ void CreateReportBlocks(const std::vector<ReportBlock>& blocks,
*pos += ReportBlock::kLength;
}
}
// 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,
uint8_t* buffer,
size_t* 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;
}
}
} // namespace
void RtcpPacket::Append(RtcpPacket* packet) {
@ -262,49 +219,6 @@ bool SenderReport::WithReportBlock(const ReportBlock& block) {
return true;
}
bool Sdes::Create(uint8_t* packet,
size_t* index,
size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const {
assert(!chunks_.empty());
while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback))
return false;
}
CreateHeader(chunks_.size(), PT_SDES, HeaderLength(), packet, index);
CreateSdes(chunks_, packet, index);
return true;
}
bool Sdes::WithCName(uint32_t ssrc, const std::string& cname) {
assert(cname.length() <= 0xff);
if (chunks_.size() >= kMaxNumberOfChunks) {
LOG(LS_WARNING) << "Max SDES chunks reached.";
return false;
}
// 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);
return true;
}
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 (const Chunk& chunk : chunks_)
length += 6 + chunk.name.length() + chunk.null_octets;
assert(length % 4 == 0);
return length;
}
RawPacket::RawPacket(size_t buffer_length)
: buffer_length_(buffer_length), length_(0) {
buffer_.reset(new uint8_t[buffer_length]);

View File

@ -12,7 +12,6 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_
#include <string>
#include <vector>
#include "webrtc/base/scoped_ptr.h"
@ -194,62 +193,6 @@ class SenderReport : public RtcpPacket {
RTC_DISALLOW_COPY_AND_ASSIGN(SenderReport);
};
// 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() {}
bool WithCName(uint32_t ssrc, const std::string& cname);
struct Chunk {
uint32_t ssrc;
std::string name;
int null_octets;
};
protected:
bool Create(uint8_t* packet,
size_t* index,
size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override;
private:
static const int kMaxNumberOfChunks = 0x1f;
size_t BlockLength() const;
std::vector<Chunk> chunks_;
RTC_DISALLOW_COPY_AND_ASSIGN(Sdes);
};
// Class holding a RTCP packet.
//
// Takes a built rtcp packet.

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.h"
#include "webrtc/base/logging.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
using webrtc::RTCPUtility::PT_SDES;
namespace webrtc {
namespace rtcp {
namespace {
void AssignUWord8(uint8_t* buffer, size_t* offset, uint8_t value) {
buffer[(*offset)++] = value;
}
void AssignUWord32(uint8_t* buffer, size_t* offset, uint32_t value) {
ByteWriter<uint32_t>::WriteBigEndian(buffer + *offset, value);
*offset += 4;
}
// 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,
uint8_t* buffer,
size_t* 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;
}
}
} // namespace
bool Sdes::Create(uint8_t* packet,
size_t* index,
size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const {
assert(!chunks_.empty());
while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback))
return false;
}
CreateHeader(chunks_.size(), PT_SDES, HeaderLength(), packet, index);
CreateSdes(chunks_, packet, index);
return true;
}
bool Sdes::WithCName(uint32_t ssrc, const std::string& cname) {
assert(cname.length() <= 0xff);
if (chunks_.size() >= kMaxNumberOfChunks) {
LOG(LS_WARNING) << "Max SDES chunks reached.";
return false;
}
// 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);
return true;
}
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 (const Chunk& chunk : chunks_)
length += 6 + chunk.name.length() + chunk.null_octets;
assert(length % 4 == 0);
return length;
}
} // namespace rtcp
} // namespace webrtc

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*
*/
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_SDES_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_SDES_H_
#include <string>
#include <vector>
#include "webrtc/base/basictypes.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
namespace webrtc {
namespace rtcp {
// Source Description (SDES) (RFC 3550).
class Sdes : public RtcpPacket {
public:
Sdes() : RtcpPacket() {}
virtual ~Sdes() {}
bool WithCName(uint32_t ssrc, const std::string& cname);
struct Chunk {
uint32_t ssrc;
std::string name;
int null_octets;
};
protected:
bool Create(uint8_t* packet,
size_t* index,
size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override;
private:
static const int kMaxNumberOfChunks = 0x1f;
size_t BlockLength() const;
std::vector<Chunk> chunks_;
RTC_DISALLOW_COPY_AND_ASSIGN(Sdes);
};
} // namespace rtcp
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_SDES_H_

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/test/rtcp_packet_parser.h"
using webrtc::rtcp::RawPacket;
using webrtc::rtcp::Sdes;
using webrtc::test::RtcpPacketParser;
namespace webrtc {
const uint32_t kSenderSsrc = 0x12345678;
TEST(RtcpPacketSdesTest, WithOneChunk) {
Sdes sdes;
EXPECT_TRUE(sdes.WithCName(kSenderSsrc, "alice@host"));
rtc::scoped_ptr<RawPacket> packet(sdes.Build());
RtcpPacketParser parser;
parser.Parse(packet->Buffer(), packet->Length());
EXPECT_EQ(1, parser.sdes()->num_packets());
EXPECT_EQ(1, parser.sdes_chunk()->num_packets());
EXPECT_EQ(kSenderSsrc, parser.sdes_chunk()->Ssrc());
EXPECT_EQ("alice@host", parser.sdes_chunk()->Cname());
}
TEST(RtcpPacketSdesTest, WithMultipleChunks) {
Sdes sdes;
EXPECT_TRUE(sdes.WithCName(kSenderSsrc, "a"));
EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 1, "ab"));
EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 2, "abc"));
EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 3, "abcd"));
EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 4, "abcde"));
EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 5, "abcdef"));
rtc::scoped_ptr<RawPacket> packet(sdes.Build());
RtcpPacketParser parser;
parser.Parse(packet->Buffer(), packet->Length());
EXPECT_EQ(1, parser.sdes()->num_packets());
EXPECT_EQ(6, parser.sdes_chunk()->num_packets());
EXPECT_EQ(kSenderSsrc + 5, parser.sdes_chunk()->Ssrc());
EXPECT_EQ("abcdef", parser.sdes_chunk()->Cname());
}
TEST(RtcpPacketSdesTest, WithTooManyChunks) {
Sdes sdes;
const int kMaxChunks = (1 << 5) - 1;
for (int i = 0; i < kMaxChunks; ++i) {
uint32_t ssrc = kSenderSsrc + i;
std::ostringstream oss;
oss << "cname" << i;
EXPECT_TRUE(sdes.WithCName(ssrc, oss.str()));
}
EXPECT_FALSE(sdes.WithCName(kSenderSsrc + kMaxChunks, "foo"));
}
TEST(RtcpPacketSdesTest, CnameItemWithEmptyString) {
Sdes sdes;
EXPECT_TRUE(sdes.WithCName(kSenderSsrc, ""));
rtc::scoped_ptr<RawPacket> packet(sdes.Build());
RtcpPacketParser parser;
parser.Parse(packet->Buffer(), packet->Length());
EXPECT_EQ(1, parser.sdes()->num_packets());
EXPECT_EQ(1, parser.sdes_chunk()->num_packets());
EXPECT_EQ(kSenderSsrc, parser.sdes_chunk()->Ssrc());
EXPECT_EQ("", parser.sdes_chunk()->Cname());
}
} // namespace webrtc

View File

@ -26,7 +26,6 @@ using webrtc::rtcp::Bye;
using webrtc::rtcp::RawPacket;
using webrtc::rtcp::ReceiverReport;
using webrtc::rtcp::ReportBlock;
using webrtc::rtcp::Sdes;
using webrtc::rtcp::SenderReport;
using webrtc::test::RtcpPacketParser;
@ -152,63 +151,6 @@ TEST(RtcpPacketTest, App) {
parser.app_item()->DataLength()));
}
TEST(RtcpPacketTest, SdesWithOneChunk) {
Sdes sdes;
EXPECT_TRUE(sdes.WithCName(kSenderSsrc, "alice@host"));
rtc::scoped_ptr<RawPacket> packet(sdes.Build());
RtcpPacketParser parser;
parser.Parse(packet->Buffer(), packet->Length());
EXPECT_EQ(1, parser.sdes()->num_packets());
EXPECT_EQ(1, parser.sdes_chunk()->num_packets());
EXPECT_EQ(kSenderSsrc, parser.sdes_chunk()->Ssrc());
EXPECT_EQ("alice@host", parser.sdes_chunk()->Cname());
}
TEST(RtcpPacketTest, SdesWithMultipleChunks) {
Sdes sdes;
EXPECT_TRUE(sdes.WithCName(kSenderSsrc, "a"));
EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 1, "ab"));
EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 2, "abc"));
EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 3, "abcd"));
EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 4, "abcde"));
EXPECT_TRUE(sdes.WithCName(kSenderSsrc + 5, "abcdef"));
rtc::scoped_ptr<RawPacket> packet(sdes.Build());
RtcpPacketParser parser;
parser.Parse(packet->Buffer(), packet->Length());
EXPECT_EQ(1, parser.sdes()->num_packets());
EXPECT_EQ(6, parser.sdes_chunk()->num_packets());
EXPECT_EQ(kSenderSsrc + 5, parser.sdes_chunk()->Ssrc());
EXPECT_EQ("abcdef", parser.sdes_chunk()->Cname());
}
TEST(RtcpPacketTest, SdesWithTooManyChunks) {
Sdes sdes;
const int kMaxChunks = (1 << 5) - 1;
for (int i = 0; i < kMaxChunks; ++i) {
uint32_t ssrc = kSenderSsrc + i;
std::ostringstream oss;
oss << "cname" << i;
EXPECT_TRUE(sdes.WithCName(ssrc, oss.str()));
}
EXPECT_FALSE(sdes.WithCName(kSenderSsrc + kMaxChunks, "foo"));
}
TEST(RtcpPacketTest, CnameItemWithEmptyString) {
Sdes sdes;
EXPECT_TRUE(sdes.WithCName(kSenderSsrc, ""));
rtc::scoped_ptr<RawPacket> packet(sdes.Build());
RtcpPacketParser parser;
parser.Parse(packet->Buffer(), packet->Length());
EXPECT_EQ(1, parser.sdes()->num_packets());
EXPECT_EQ(1, parser.sdes_chunk()->num_packets());
EXPECT_EQ(kSenderSsrc, parser.sdes_chunk()->Ssrc());
EXPECT_EQ("", parser.sdes_chunk()->Cname());
}
TEST(RtcpPacketTest, BuildWithTooSmallBuffer) {
ReportBlock rb;
ReceiverReport rr;

View File

@ -28,6 +28,7 @@
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/remb.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"

View File

@ -32,6 +32,7 @@
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/remb.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/rpsi.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"