diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp index 9ca0587fe3..37d43042a2 100644 --- a/webrtc/modules/modules.gyp +++ b/webrtc/modules/modules.gyp @@ -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', diff --git a/webrtc/modules/rtp_rtcp/BUILD.gn b/webrtc/modules/rtp_rtcp/BUILD.gn index 0e8f07e6b2..42de871f4a 100644 --- a/webrtc/modules/rtp_rtcp/BUILD.gn +++ b/webrtc/modules/rtp_rtcp/BUILD.gn @@ -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", diff --git a/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi b/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi index 0e9071be76..1db044143f 100644 --- a/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi +++ b/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi @@ -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', diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc index aa7a28669a..ec87ed6bdb 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc @@ -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& 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& chunks, - uint8_t* buffer, - size_t* pos) { - const uint8_t kSdesItemType = 1; - for (std::vector::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]); diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h index 9184ba88e2..2cf90055e8 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h @@ -12,7 +12,6 @@ #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_ -#include #include #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 chunks_; - - RTC_DISALLOW_COPY_AND_ASSIGN(Sdes); -}; - // Class holding a RTCP packet. // // Takes a built rtcp packet. diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.cc new file mode 100644 index 0000000000..38c4ef341f --- /dev/null +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.cc @@ -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::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& chunks, + uint8_t* buffer, + size_t* pos) { + const uint8_t kSdesItemType = 1; + for (std::vector::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 diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.h new file mode 100644 index 0000000000..5520e3486a --- /dev/null +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.h @@ -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 +#include + +#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 chunks_; + + RTC_DISALLOW_COPY_AND_ASSIGN(Sdes); +}; +} // namespace rtcp +} // namespace webrtc +#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_SDES_H_ diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes_unittest.cc new file mode 100644 index 0000000000..65f8096096 --- /dev/null +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes_unittest.cc @@ -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 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 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 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 diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc index 7b942871e9..6b4ef902a1 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc @@ -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 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 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 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; diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc index d9702f48d9..f36c04eb08 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc @@ -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" diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc index bf7d24f320..64331a5e52 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc @@ -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"