rtcp::App moved into own file and got Parse function

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

Cr-Commit-Position: refs/heads/master@{#10688}
This commit is contained in:
danilchap 2015-11-18 05:56:53 -08:00 committed by Commit bot
parent 2aff615bd7
commit 0219c9b4bf
11 changed files with 234 additions and 96 deletions

View File

@ -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',

View File

@ -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",

View File

@ -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',

View File

@ -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,

View File

@ -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:

View File

@ -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<uint32_t>::ReadBigEndian(&payload[0]);
name_ = ByteReader<uint32_t>::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<uint32_t>::WriteBigEndian(&packet[*index + 0], ssrc_);
ByteWriter<uint32_t>::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

View File

@ -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_

View File

@ -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 <limits>
#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<RawPacket> 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

View File

@ -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;

View File

@ -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"

View File

@ -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"