From 0219c9b4bfcbb778137756210eb95f40d936cc66 Mon Sep 17 00:00:00 2001 From: danilchap Date: Wed, 18 Nov 2015 05:56:53 -0800 Subject: [PATCH] rtcp::App moved into own file and got Parse function Review URL: https://codereview.webrtc.org/1437353003 Cr-Commit-Position: refs/heads/master@{#10688} --- webrtc/modules/modules.gyp | 1 + webrtc/modules/rtp_rtcp/BUILD.gn | 2 + webrtc/modules/rtp_rtcp/rtp_rtcp.gypi | 2 + webrtc/modules/rtp_rtcp/source/rtcp_packet.cc | 37 --------- webrtc/modules/rtp_rtcp/source/rtcp_packet.h | 59 -------------- .../rtp_rtcp/source/rtcp_packet/app.cc | 79 ++++++++++++++++++ .../modules/rtp_rtcp/source/rtcp_packet/app.h | 66 +++++++++++++++ .../source/rtcp_packet/app_unittest.cc | 81 +++++++++++++++++++ .../rtp_rtcp/source/rtcp_packet_unittest.cc | 1 + .../rtp_rtcp/source/rtcp_receiver_unittest.cc | 1 + webrtc/modules/rtp_rtcp/source/rtcp_sender.cc | 1 + 11 files changed, 234 insertions(+), 96 deletions(-) create mode 100644 webrtc/modules/rtp_rtcp/source/rtcp_packet/app.cc create mode 100644 webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h create mode 100644 webrtc/modules/rtp_rtcp/source/rtcp_packet/app_unittest.cc diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp index 7cac61971d..cf78b12710 100644 --- a/webrtc/modules/modules.gyp +++ b/webrtc/modules/modules.gyp @@ -246,6 +246,7 @@ 'rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc', 'rtp_rtcp/source/rtcp_format_remb_unittest.cc', 'rtp_rtcp/source/rtcp_packet_unittest.cc', + 'rtp_rtcp/source/rtcp_packet/app_unittest.cc', 'rtp_rtcp/source/rtcp_packet/extended_jitter_report_unittest.cc', 'rtp_rtcp/source/rtcp_packet/report_block_unittest.cc', 'rtp_rtcp/source/rtcp_packet/transport_feedback_unittest.cc', diff --git a/webrtc/modules/rtp_rtcp/BUILD.gn b/webrtc/modules/rtp_rtcp/BUILD.gn index fd81586b85..f7d887d14c 100644 --- a/webrtc/modules/rtp_rtcp/BUILD.gn +++ b/webrtc/modules/rtp_rtcp/BUILD.gn @@ -46,6 +46,8 @@ source_set("rtp_rtcp") { "source/remote_ntp_time_estimator.cc", "source/rtcp_packet.cc", "source/rtcp_packet.h", + "source/rtcp_packet/app.cc", + "source/rtcp_packet/app.h", "source/rtcp_packet/extended_jitter_report.cc", "source/rtcp_packet/extended_jitter_report.h", "source/rtcp_packet/report_block.cc", diff --git a/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi b/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi index 5eb3c5f79c..71e2ce7d69 100644 --- a/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi +++ b/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi @@ -41,6 +41,8 @@ 'source/rtp_rtcp_impl.h', 'source/rtcp_packet.cc', 'source/rtcp_packet.h', + 'source/rtcp_packet/app.cc', + 'source/rtcp_packet/app.h', 'source/rtcp_packet/extended_jitter_report.cc', 'source/rtcp_packet/extended_jitter_report.h', 'source/rtcp_packet/report_block.cc', diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc index 7c0650c488..be03d9b41a 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc @@ -227,30 +227,6 @@ void CreateBye(const RTCPPacketBYE& bye, AssignUWord32(buffer, pos, csrc); } -// 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, - uint8_t* buffer, - size_t* 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: @@ -848,19 +824,6 @@ bool Bye::WithCsrc(uint32_t csrc) { return true; } -bool App::Create(uint8_t* packet, - size_t* index, - size_t max_length, - RtcpPacket::PacketReadyCallback* callback) const { - while (*index + BlockLength() > max_length) { - if (!OnBufferFull(packet, index, callback)) - return false; - } - CreateHeader(app_.SubType, PT_APP, HeaderLength(), packet, index); - CreateApp(app_, ssrc_, packet, index); - return true; -} - bool Pli::Create(uint8_t* packet, size_t* index, size_t max_length, diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h index d27a9878ee..bea83070cb 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h @@ -369,65 +369,6 @@ class Bye : public RtcpPacket { RTC_DISALLOW_COPY_AND_ASSIGN(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 ... -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - -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: - bool Create(uint8_t* packet, - size_t* index, - size_t max_length, - RtcpPacket::PacketReadyCallback* callback) const override; - - private: - size_t BlockLength() const { - return 12 + app_.Size; - } - - uint32_t ssrc_; - RTCPUtility::RTCPPacketAPP app_; - - RTC_DISALLOW_COPY_AND_ASSIGN(App); -}; - // RFC 4585: Feedback format. // // Common packet format: diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/app.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/app.cc new file mode 100644 index 0000000000..a1ad8d6427 --- /dev/null +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/app.cc @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015 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/app.h" + +#include "webrtc/base/checks.h" +#include "webrtc/base/logging.h" +#include "webrtc/modules/rtp_rtcp/source/byte_io.h" + +using webrtc::RTCPUtility::RtcpCommonHeader; + +namespace webrtc { +namespace rtcp { + +// 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 | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// 0 | SSRC/CSRC | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// 4 | name (ASCII) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// 8 | application-dependent data ... +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +bool App::Parse(const RtcpCommonHeader& header, const uint8_t* payload) { + RTC_DCHECK(header.packet_type == kPacketType); + + sub_type_ = header.count_or_format; + ssrc_ = ByteReader::ReadBigEndian(&payload[0]); + name_ = ByteReader::ReadBigEndian(&payload[4]); + data_.SetData(&payload[8], header.payload_size_bytes - 8); + return true; +} + +void App::WithSubType(uint8_t subtype) { + RTC_DCHECK_LE(subtype, 0x1f); + sub_type_ = subtype; +} + +void App::WithData(const uint8_t* data, size_t data_length) { + RTC_DCHECK(data); + RTC_DCHECK_EQ(0u, data_length % 4) << "Data must be 32 bits aligned."; + RTC_DCHECK(data_length <= kMaxDataSize) << "App data size << " << data_length + << "exceed maximum of " + << kMaxDataSize << " bytes."; + data_.SetData(data, data_length); +} + +bool App::Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const { + while (*index + BlockLength() > max_length) { + if (!OnBufferFull(packet, index, callback)) + return false; + } + const size_t index_end = *index + BlockLength(); + CreateHeader(sub_type_, kPacketType, HeaderLength(), packet, index); + + ByteWriter::WriteBigEndian(&packet[*index + 0], ssrc_); + ByteWriter::WriteBigEndian(&packet[*index + 4], name_); + memcpy(&packet[*index + 8], data_.data(), data_.size()); + *index += (8 + data_.size()); + RTC_DCHECK_EQ(index_end, *index); + return true; +} + +} // namespace rtcp +} // namespace webrtc diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h new file mode 100644 index 0000000000..16bd3fc2a2 --- /dev/null +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2015 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_APP_H_ +#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_APP_H_ + +#include "webrtc/base/buffer.h" +#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h" +#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" + +namespace webrtc { +namespace rtcp { + +class App : public RtcpPacket { + public: + static const uint8_t kPacketType = 204; + // 28 bytes for UDP header + // 12 bytes for RTCP app header + static const size_t kMaxDataSize = IP_PACKET_SIZE - 12 - 28; + App() : sub_type_(0), ssrc_(0), name_(0) {} + + virtual ~App() {} + + // Parse assumes header is already parsed and validated. + bool Parse(const RTCPUtility::RtcpCommonHeader& header, + const uint8_t* payload); // Size of the payload is in the header. + + void From(uint32_t ssrc) { ssrc_ = ssrc; } + void WithSubType(uint8_t subtype); + void WithName(uint32_t name) { name_ = name; } + void WithData(const uint8_t* data, size_t data_length); + + uint8_t sub_type() const { return sub_type_; } + uint32_t ssrc() const { return ssrc_; } + uint32_t name() const { return name_; } + size_t data_size() const { return data_.size(); } + const uint8_t* data() const { return data_.data(); } + + protected: + bool Create(uint8_t* packet, + size_t* index, + size_t max_length, + RtcpPacket::PacketReadyCallback* callback) const override; + + private: + size_t BlockLength() const override { return 12 + data_.size(); } + + uint8_t sub_type_; + uint32_t ssrc_; + uint32_t name_; + rtc::Buffer data_; + + RTC_DISALLOW_COPY_AND_ASSIGN(App); +}; + +} // namespace rtcp +} // namespace webrtc +#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_APP_H_ diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/app_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/app_unittest.cc new file mode 100644 index 0000000000..01ded72d99 --- /dev/null +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/app_unittest.cc @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2015 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/app.h" + +#include + +#include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" + +using webrtc::rtcp::App; +using webrtc::rtcp::RawPacket; +using webrtc::RTCPUtility::RtcpCommonHeader; +using webrtc::RTCPUtility::RtcpParseCommonHeader; + +namespace webrtc { +namespace { + +const uint32_t kName = ((uint32_t)'n' << 24) | ((uint32_t)'a' << 16) | + ((uint32_t)'m' << 8) | (uint32_t)'e'; +const uint32_t kSenderSsrc = 0x12345678; + +class RtcpPacketAppTest : public ::testing::Test { + protected: + void BuildPacket() { packet = app.Build().Pass(); } + void ParsePacket() { + RtcpCommonHeader header; + EXPECT_TRUE( + RtcpParseCommonHeader(packet->Buffer(), packet->Length(), &header)); + // Check there is exactly one RTCP packet in the buffer. + EXPECT_EQ(header.BlockSize(), packet->Length()); + EXPECT_TRUE(parsed_.Parse( + header, packet->Buffer() + RtcpCommonHeader::kHeaderSizeBytes)); + } + + App app; + rtc::scoped_ptr packet; + const App& parsed() { return parsed_; } + + private: + App parsed_; +}; + +TEST_F(RtcpPacketAppTest, WithNoData) { + app.WithSubType(30); + app.WithName(kName); + + BuildPacket(); + ParsePacket(); + + EXPECT_EQ(30U, parsed().sub_type()); + EXPECT_EQ(kName, parsed().name()); + EXPECT_EQ(0u, parsed().data_size()); +} + +TEST_F(RtcpPacketAppTest, WithData) { + app.From(kSenderSsrc); + app.WithSubType(30); + app.WithName(kName); + const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'}; + const size_t kDataLength = sizeof(kData) / sizeof(kData[0]); + app.WithData(kData, kDataLength); + + BuildPacket(); + ParsePacket(); + + EXPECT_EQ(30U, parsed().sub_type()); + EXPECT_EQ(kName, parsed().name()); + EXPECT_EQ(kDataLength, parsed().data_size()); + EXPECT_EQ(0, memcmp(kData, parsed().data(), kDataLength)); +} + +} // namespace +} // 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 ac84356c0f..4c1d55e049 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc @@ -14,6 +14,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h" +#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h" #include "webrtc/test/rtcp_packet_parser.h" using ::testing::ElementsAre; diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc index 45e803e372..53c31776ae 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc @@ -25,6 +25,7 @@ #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h" #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" +#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h" #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.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 1b8c62faaf..ffab90ebe7 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc @@ -22,6 +22,7 @@ #include "webrtc/base/trace_event.h" #include "webrtc/common_types.h" #include "webrtc/modules/rtp_rtcp/source/byte_io.h" +#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h" #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" #include "webrtc/system_wrappers/include/critical_section_wrapper.h"