[rtp_rtcp] rtcp::SenderReport moved into own file and got Parse function

BUG=webrtc:5260
R=åsapersson

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

Cr-Commit-Position: refs/heads/master@{#11288}
This commit is contained in:
danilchap 2016-01-18 02:43:32 -08:00 committed by Commit bot
parent 8b1e431231
commit 34ed2b95a5
14 changed files with 334 additions and 305 deletions

View File

@ -23,6 +23,7 @@
#include "webrtc/call.h"
#include "webrtc/call/rtc_event_log.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_sender.h"
#include "webrtc/system_wrappers/include/clock.h"
#include "webrtc/test/test_suite.h"
@ -355,8 +356,8 @@ rtc::scoped_ptr<rtcp::RawPacket> GenerateRtcpPacket(Random* prng) {
rtcp::SenderReport sender_report;
sender_report.From(prng->Rand<uint32_t>()); // Sender SSRC.
sender_report.WithNtpSec(prng->Rand<uint32_t>());
sender_report.WithNtpFrac(prng->Rand<uint32_t>());
sender_report.WithNtp(
NtpTime(prng->Rand<uint32_t>(), prng->Rand<uint32_t>()));
sender_report.WithPacketCount(prng->Rand<uint32_t>());
sender_report.WithReportBlock(report_block);

View File

@ -320,6 +320,7 @@
'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/sender_report_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

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

View File

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

View File

@ -10,23 +10,10 @@
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
#include <algorithm>
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
using webrtc::RTCPUtility::PT_APP;
using webrtc::RTCPUtility::PT_IJ;
using webrtc::RTCPUtility::PT_RTPFB;
using webrtc::RTCPUtility::PT_SR;
using webrtc::RTCPUtility::RTCPPacketAPP;
using webrtc::RTCPUtility::RTCPPacketReportBlockItem;
using webrtc::RTCPUtility::RTCPPacketRTPFBNACK;
using webrtc::RTCPUtility::RTCPPacketRTPFBNACKItem;
using webrtc::RTCPUtility::RTCPPacketSR;
namespace webrtc {
namespace rtcp {
namespace {
@ -37,66 +24,6 @@ void AssignUWord16(uint8_t* buffer, size_t* offset, uint16_t value) {
ByteWriter<uint16_t>::WriteBigEndian(buffer + *offset, value);
*offset += 2;
}
void AssignUWord32(uint8_t* buffer, size_t* offset, uint32_t value) {
ByteWriter<uint32_t>::WriteBigEndian(buffer + *offset, value);
*offset += 4;
}
// Sender report (SR) (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| RC | PT=SR=200 | length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | SSRC of sender |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// | NTP timestamp, most significant word |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | NTP timestamp, least significant word |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | RTP timestamp |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | sender's packet count |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | sender's octet count |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
void CreateSenderReport(const RTCPPacketSR& sr,
uint8_t* buffer,
size_t* pos) {
AssignUWord32(buffer, pos, sr.SenderSSRC);
AssignUWord32(buffer, pos, sr.NTPMostSignificant);
AssignUWord32(buffer, pos, sr.NTPLeastSignificant);
AssignUWord32(buffer, pos, sr.RTPTimestamp);
AssignUWord32(buffer, pos, sr.SenderPacketCount);
AssignUWord32(buffer, pos, sr.SenderOctetCount);
}
// Report block (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
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// | 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) |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
void CreateReportBlocks(const std::vector<ReportBlock>& blocks,
uint8_t* buffer,
size_t* pos) {
for (const ReportBlock& block : blocks) {
block.Create(buffer + *pos);
*pos += ReportBlock::kLength;
}
}
} // namespace
void RtcpPacket::Append(RtcpPacket* packet) {
@ -195,30 +122,6 @@ void RtcpPacket::CreateHeader(
AssignUWord16(buffer, pos, length);
}
bool SenderReport::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(sr_.NumberOfReportBlocks, PT_SR, HeaderLength(), packet, index);
CreateSenderReport(sr_, packet, index);
CreateReportBlocks(report_blocks_, packet, index);
return true;
}
bool SenderReport::WithReportBlock(const ReportBlock& block) {
if (report_blocks_.size() >= kMaxNumberOfReportBlocks) {
LOG(LS_WARNING) << "Max report blocks reached.";
return false;
}
report_blocks_.push_back(block);
sr_.NumberOfReportBlocks = report_blocks_.size();
return true;
}
RawPacket::RawPacket(size_t buffer_length)
: buffer_length_(buffer_length), length_(0) {
buffer_.reset(new uint8_t[buffer_length]);

View File

@ -15,8 +15,6 @@
#include <vector>
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
#include "webrtc/typedefs.h"
@ -24,7 +22,6 @@ namespace webrtc {
namespace rtcp {
static const int kCommonFbFmtLength = 12;
static const int kReportBlockLength = 24;
class RawPacket;
@ -120,79 +117,6 @@ class RtcpPacket {
PacketReadyCallback* callback) const;
};
// TODO(sprang): Move RtcpPacket subclasses out to separate files.
// 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
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |V=2|P| RC | PT=SR=200 | length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | SSRC of sender |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// | NTP timestamp, most significant word |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | NTP timestamp, least significant word |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | RTP timestamp |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | sender's packet count |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | sender's octet count |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// | report block(s) |
// | .... |
class SenderReport : public RtcpPacket {
public:
SenderReport() : RtcpPacket() {
memset(&sr_, 0, sizeof(sr_));
}
virtual ~SenderReport() {}
void From(uint32_t ssrc) {
sr_.SenderSSRC = ssrc;
}
void WithNtpSec(uint32_t sec) {
sr_.NTPMostSignificant = sec;
}
void WithNtpFrac(uint32_t frac) {
sr_.NTPLeastSignificant = frac;
}
void WithRtpTimestamp(uint32_t rtp_timestamp) {
sr_.RTPTimestamp = rtp_timestamp;
}
void WithPacketCount(uint32_t packet_count) {
sr_.SenderPacketCount = packet_count;
}
void WithOctetCount(uint32_t octet_count) {
sr_.SenderOctetCount = octet_count;
}
bool WithReportBlock(const ReportBlock& block);
protected:
bool Create(uint8_t* packet,
size_t* index,
size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override;
private:
static const int 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_;
RTC_DISALLOW_COPY_AND_ASSIGN(SenderReport);
};
// Class holding a RTCP packet.
//
// Takes a built rtcp packet.

View File

@ -15,6 +15,7 @@
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/fir.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
#include "webrtc/test/rtcp_packet_parser.h"
using webrtc::rtcp::Bye;

View File

@ -0,0 +1,118 @@
/*
* 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/sender_report.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 {
// Sender report (SR) (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| RC | PT=SR=200 | length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 0 | SSRC of sender |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// 4 | NTP timestamp, most significant word |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 8 | NTP timestamp, least significant word |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 12 | RTP timestamp |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 16 | sender's packet count |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// 20 | sender's octet count |
// 24 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
SenderReport::SenderReport()
: sender_ssrc_(0),
rtp_timestamp_(0),
sender_packet_count_(0),
sender_octet_count_(0) {}
bool SenderReport::Parse(const RtcpCommonHeader& header,
const uint8_t* payload) {
RTC_DCHECK(header.packet_type == kPacketType);
const uint8_t report_block_count = header.count_or_format;
if (header.payload_size_bytes <
kSenderBaseLength + report_block_count * ReportBlock::kLength) {
LOG(LS_WARNING) << "Packet is too small to contain all the data.";
return false;
}
// Read SenderReport header.
sender_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&payload[0]);
uint32_t secs = ByteReader<uint32_t>::ReadBigEndian(&payload[4]);
uint32_t frac = ByteReader<uint32_t>::ReadBigEndian(&payload[8]);
ntp_.Set(secs, frac);
rtp_timestamp_ = ByteReader<uint32_t>::ReadBigEndian(&payload[12]);
sender_packet_count_ = ByteReader<uint32_t>::ReadBigEndian(&payload[16]);
sender_octet_count_ = ByteReader<uint32_t>::ReadBigEndian(&payload[20]);
report_blocks_.resize(report_block_count);
const uint8_t* next_block = payload + kSenderBaseLength;
for (ReportBlock& block : report_blocks_) {
bool block_parsed = block.Parse(next_block, ReportBlock::kLength);
RTC_DCHECK(block_parsed);
next_block += ReportBlock::kLength;
}
// Double check we didn't read beyond provided buffer.
RTC_DCHECK_LE(next_block, payload + header.payload_size_bytes);
return true;
}
bool SenderReport::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(report_blocks_.size(), kPacketType, HeaderLength(), packet,
index);
// Write SenderReport header.
ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 0], sender_ssrc_);
ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 4], ntp_.seconds());
ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 8], ntp_.fractions());
ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 12], rtp_timestamp_);
ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 16],
sender_packet_count_);
ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 20],
sender_octet_count_);
*index += kSenderBaseLength;
// Write report blocks.
for (const ReportBlock& block : report_blocks_) {
block.Create(packet + *index);
*index += ReportBlock::kLength;
}
// Ensure bytes written match expected.
RTC_DCHECK_EQ(*index, index_end);
return true;
}
bool SenderReport::WithReportBlock(const ReportBlock& block) {
if (report_blocks_.size() >= kMaxNumberOfReportBlocks) {
LOG(LS_WARNING) << "Max report blocks reached.";
return false;
}
report_blocks_.push_back(block);
return true;
}
} // namespace rtcp
} // namespace webrtc

View File

@ -0,0 +1,86 @@
/*
* 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_SENDER_REPORT_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_SENDER_REPORT_H_
#include <vector>
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
#include "webrtc/system_wrappers/include/ntp_time.h"
namespace webrtc {
namespace rtcp {
class SenderReport : public RtcpPacket {
public:
static const uint8_t kPacketType = 200;
SenderReport();
virtual ~SenderReport() {}
// 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) { sender_ssrc_ = ssrc; }
void WithNtp(NtpTime ntp) { ntp_ = ntp; }
void WithRtpTimestamp(uint32_t rtp_timestamp) {
rtp_timestamp_ = rtp_timestamp;
}
void WithPacketCount(uint32_t packet_count) {
sender_packet_count_ = packet_count;
}
void WithOctetCount(uint32_t octet_count) {
sender_octet_count_ = octet_count;
}
bool WithReportBlock(const ReportBlock& block);
void ClearReportBlocks() { report_blocks_.clear(); }
uint32_t sender_ssrc() const { return sender_ssrc_; }
NtpTime ntp() const { return ntp_; }
uint32_t rtp_timestamp() const { return rtp_timestamp_; }
uint32_t sender_packet_count() const { return sender_packet_count_; }
uint32_t sender_octet_count() const { return sender_octet_count_; }
const std::vector<ReportBlock>& report_blocks() const {
return report_blocks_;
}
protected:
bool Create(uint8_t* packet,
size_t* index,
size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override;
private:
static const size_t kMaxNumberOfReportBlocks = 0x1f;
const size_t kSenderBaseLength = 24;
size_t BlockLength() const override {
return kHeaderLength + kSenderBaseLength +
report_blocks_.size() * ReportBlock::kLength;
}
uint32_t sender_ssrc_;
NtpTime ntp_;
uint32_t rtp_timestamp_;
uint32_t sender_packet_count_;
uint32_t sender_octet_count_;
std::vector<ReportBlock> report_blocks_;
RTC_DISALLOW_COPY_AND_ASSIGN(SenderReport);
};
} // namespace rtcp
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_SENDER_REPORT_H_

View File

@ -0,0 +1,117 @@
/*
* 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/sender_report.h"
#include "testing/gtest/include/gtest/gtest.h"
using webrtc::rtcp::RawPacket;
using webrtc::rtcp::ReportBlock;
using webrtc::rtcp::SenderReport;
using webrtc::RTCPUtility::RtcpCommonHeader;
using webrtc::RTCPUtility::RtcpParseCommonHeader;
namespace webrtc {
class RtcpPacketSenderReportTest : public ::testing::Test {
protected:
const uint32_t kSenderSsrc = 0x12345678;
const uint32_t kRemoteSsrc = 0x23456789;
void ParsePacket(const RawPacket& packet) {
RtcpCommonHeader header;
EXPECT_TRUE(
RtcpParseCommonHeader(packet.Buffer(), packet.Length(), &header));
EXPECT_EQ(packet.Length(), header.BlockSize());
EXPECT_TRUE(parsed_.Parse(
header, packet.Buffer() + RtcpCommonHeader::kHeaderSizeBytes));
}
// Only ParsePacket can change parsed, tests should use it in readonly mode.
const SenderReport& parsed() { return parsed_; }
private:
SenderReport parsed_;
};
TEST_F(RtcpPacketSenderReportTest, WithoutReportBlocks) {
const NtpTime kNtp(0x11121418, 0x22242628);
const uint32_t kRtpTimestamp = 0x33343536;
const uint32_t kPacketCount = 0x44454647;
const uint32_t kOctetCount = 0x55565758;
SenderReport sr;
sr.From(kSenderSsrc);
sr.WithNtp(kNtp);
sr.WithRtpTimestamp(kRtpTimestamp);
sr.WithPacketCount(kPacketCount);
sr.WithOctetCount(kOctetCount);
rtc::scoped_ptr<RawPacket> packet = sr.Build();
ParsePacket(*packet);
EXPECT_EQ(kSenderSsrc, parsed().sender_ssrc());
EXPECT_EQ(kNtp, parsed().ntp());
EXPECT_EQ(kRtpTimestamp, parsed().rtp_timestamp());
EXPECT_EQ(kPacketCount, parsed().sender_packet_count());
EXPECT_EQ(kOctetCount, parsed().sender_octet_count());
EXPECT_TRUE(parsed().report_blocks().empty());
}
TEST_F(RtcpPacketSenderReportTest, WithOneReportBlock) {
ReportBlock rb;
rb.To(kRemoteSsrc);
SenderReport sr;
sr.From(kSenderSsrc);
EXPECT_TRUE(sr.WithReportBlock(rb));
rtc::scoped_ptr<RawPacket> packet = sr.Build();
ParsePacket(*packet);
EXPECT_EQ(kSenderSsrc, parsed().sender_ssrc());
EXPECT_EQ(1u, parsed().report_blocks().size());
EXPECT_EQ(kRemoteSsrc, parsed().report_blocks()[0].source_ssrc());
}
TEST_F(RtcpPacketSenderReportTest, WithTwoReportBlocks) {
ReportBlock rb1;
rb1.To(kRemoteSsrc);
ReportBlock rb2;
rb2.To(kRemoteSsrc + 1);
SenderReport sr;
sr.From(kSenderSsrc);
EXPECT_TRUE(sr.WithReportBlock(rb1));
EXPECT_TRUE(sr.WithReportBlock(rb2));
rtc::scoped_ptr<RawPacket> packet = sr.Build();
ParsePacket(*packet);
EXPECT_EQ(kSenderSsrc, parsed().sender_ssrc());
EXPECT_EQ(2u, parsed().report_blocks().size());
EXPECT_EQ(kRemoteSsrc, parsed().report_blocks()[0].source_ssrc());
EXPECT_EQ(kRemoteSsrc + 1, parsed().report_blocks()[1].source_ssrc());
}
TEST_F(RtcpPacketSenderReportTest, WithTooManyReportBlocks) {
SenderReport sr;
sr.From(kSenderSsrc);
const size_t kMaxReportBlocks = (1 << 5) - 1;
ReportBlock rb;
for (size_t i = 0; i < kMaxReportBlocks; ++i) {
rb.To(kRemoteSsrc + i);
EXPECT_TRUE(sr.WithReportBlock(rb));
}
rb.To(kRemoteSsrc + kMaxReportBlocks);
EXPECT_FALSE(sr.WithReportBlock(rb));
}
} // namespace webrtc

View File

@ -14,142 +14,14 @@
#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/modules/rtp_rtcp/source/rtcp_packet/bye.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
#include "webrtc/test/rtcp_packet_parser.h"
using ::testing::ElementsAre;
using webrtc::rtcp::App;
using webrtc::rtcp::Bye;
using webrtc::rtcp::RawPacket;
using webrtc::rtcp::ReceiverReport;
using webrtc::rtcp::ReportBlock;
using webrtc::rtcp::SenderReport;
using webrtc::test::RtcpPacketParser;
namespace webrtc {
const uint32_t kSenderSsrc = 0x12345678;
const uint32_t kRemoteSsrc = 0x23456789;
TEST(RtcpPacketTest, Sr) {
SenderReport sr;
sr.From(kSenderSsrc);
sr.WithNtpSec(0x11111111);
sr.WithNtpFrac(0x22222222);
sr.WithRtpTimestamp(0x33333333);
sr.WithPacketCount(0x44444444);
sr.WithOctetCount(0x55555555);
rtc::scoped_ptr<RawPacket> packet(sr.Build());
RtcpPacketParser parser;
parser.Parse(packet->Buffer(), packet->Length());
EXPECT_EQ(1, parser.sender_report()->num_packets());
EXPECT_EQ(kSenderSsrc, parser.sender_report()->Ssrc());
EXPECT_EQ(0x11111111U, parser.sender_report()->NtpSec());
EXPECT_EQ(0x22222222U, parser.sender_report()->NtpFrac());
EXPECT_EQ(0x33333333U, parser.sender_report()->RtpTimestamp());
EXPECT_EQ(0x44444444U, parser.sender_report()->PacketCount());
EXPECT_EQ(0x55555555U, parser.sender_report()->OctetCount());
EXPECT_EQ(0, parser.report_block()->num_packets());
}
TEST(RtcpPacketTest, SrWithOneReportBlock) {
ReportBlock rb;
rb.To(kRemoteSsrc);
SenderReport sr;
sr.From(kSenderSsrc);
EXPECT_TRUE(sr.WithReportBlock(rb));
rtc::scoped_ptr<RawPacket> packet(sr.Build());
RtcpPacketParser parser;
parser.Parse(packet->Buffer(), packet->Length());
EXPECT_EQ(1, parser.sender_report()->num_packets());
EXPECT_EQ(kSenderSsrc, parser.sender_report()->Ssrc());
EXPECT_EQ(1, parser.report_block()->num_packets());
EXPECT_EQ(kRemoteSsrc, parser.report_block()->Ssrc());
}
TEST(RtcpPacketTest, SrWithTwoReportBlocks) {
ReportBlock rb1;
rb1.To(kRemoteSsrc);
ReportBlock rb2;
rb2.To(kRemoteSsrc + 1);
SenderReport sr;
sr.From(kSenderSsrc);
EXPECT_TRUE(sr.WithReportBlock(rb1));
EXPECT_TRUE(sr.WithReportBlock(rb2));
rtc::scoped_ptr<RawPacket> packet(sr.Build());
RtcpPacketParser parser;
parser.Parse(packet->Buffer(), packet->Length());
EXPECT_EQ(1, parser.sender_report()->num_packets());
EXPECT_EQ(kSenderSsrc, parser.sender_report()->Ssrc());
EXPECT_EQ(2, parser.report_block()->num_packets());
EXPECT_EQ(1, parser.report_blocks_per_ssrc(kRemoteSsrc));
EXPECT_EQ(1, parser.report_blocks_per_ssrc(kRemoteSsrc + 1));
}
TEST(RtcpPacketTest, SrWithTooManyReportBlocks) {
SenderReport sr;
sr.From(kSenderSsrc);
const int kMaxReportBlocks = (1 << 5) - 1;
ReportBlock rb;
for (int i = 0; i < kMaxReportBlocks; ++i) {
rb.To(kRemoteSsrc + i);
EXPECT_TRUE(sr.WithReportBlock(rb));
}
rb.To(kRemoteSsrc + kMaxReportBlocks);
EXPECT_FALSE(sr.WithReportBlock(rb));
}
TEST(RtcpPacketTest, AppWithNoData) {
App app;
app.WithSubType(30);
uint32_t name = 'n' << 24;
name += 'a' << 16;
name += 'm' << 8;
name += 'e';
app.WithName(name);
rtc::scoped_ptr<RawPacket> packet(app.Build());
RtcpPacketParser parser;
parser.Parse(packet->Buffer(), packet->Length());
EXPECT_EQ(1, parser.app()->num_packets());
EXPECT_EQ(30U, parser.app()->SubType());
EXPECT_EQ(name, parser.app()->Name());
EXPECT_EQ(0, parser.app_item()->num_packets());
}
TEST(RtcpPacketTest, App) {
App app;
app.From(kSenderSsrc);
app.WithSubType(30);
uint32_t name = 'n' << 24;
name += 'a' << 16;
name += 'm' << 8;
name += 'e';
app.WithName(name);
const char kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
const size_t kDataLength = sizeof(kData) / sizeof(kData[0]);
app.WithData((const uint8_t*)kData, kDataLength);
rtc::scoped_ptr<RawPacket> packet(app.Build());
RtcpPacketParser parser;
parser.Parse(packet->Buffer(), packet->Length());
EXPECT_EQ(1, parser.app()->num_packets());
EXPECT_EQ(30U, parser.app()->SubType());
EXPECT_EQ(name, parser.app()->Name());
EXPECT_EQ(1, parser.app_item()->num_packets());
EXPECT_EQ(kDataLength, parser.app_item()->DataLength());
EXPECT_EQ(0, strncmp(kData, (const char*)parser.app_item()->Data(),
parser.app_item()->DataLength()));
}
TEST(RtcpPacketTest, BuildWithTooSmallBuffer) {
ReportBlock rb;

View File

@ -29,6 +29,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/sdes.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.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

@ -33,6 +33,7 @@
#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/sender_report.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"
@ -483,8 +484,7 @@ rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildSR(const RtcpContext& ctx) {
rtcp::SenderReport* report = new rtcp::SenderReport();
report->From(ssrc_);
report->WithNtpSec(ctx.ntp_sec_);
report->WithNtpFrac(ctx.ntp_frac_);
report->WithNtp(NtpTime(ctx.ntp_sec_, ctx.ntp_frac_));
report->WithRtpTimestamp(rtp_timestamp);
report->WithPacketCount(ctx.feedback_state_.packets_sent);
report->WithOctetCount(ctx.feedback_state_.media_bytes_sent);

View File

@ -25,6 +25,7 @@
#include "webrtc/modules/rtp_rtcp/include/receive_statistics.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_packet/report_block.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
#include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h"