[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}
diff --git a/webrtc/call/rtc_event_log_unittest.cc b/webrtc/call/rtc_event_log_unittest.cc
index f590f66..0998071 100644
--- a/webrtc/call/rtc_event_log_unittest.cc
+++ b/webrtc/call/rtc_event_log_unittest.cc
@@ -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 @@
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);
diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp
index 37d4304..9c50d26 100644
--- a/webrtc/modules/modules.gyp
+++ b/webrtc/modules/modules.gyp
@@ -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',
diff --git a/webrtc/modules/rtp_rtcp/BUILD.gn b/webrtc/modules/rtp_rtcp/BUILD.gn
index 42de871..f423d08 100644
--- a/webrtc/modules/rtp_rtcp/BUILD.gn
+++ b/webrtc/modules/rtp_rtcp/BUILD.gn
@@ -80,6 +80,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",
diff --git a/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi b/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi
index 1db0441..a927e4e 100644
--- a/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi
+++ b/webrtc/modules/rtp_rtcp/rtp_rtcp.gypi
@@ -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',
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc
index ec87ed6..eaaa78c 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc
@@ -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 @@
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 @@
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]);
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h
index 2cf9005..965a667 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h
@@ -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 rtcp {
static const int kCommonFbFmtLength = 12;
-static const int kReportBlockLength = 24;
class RawPacket;
@@ -120,79 +117,6 @@
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.
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet_unittest.cc
index b38b69c..0378566 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet_unittest.cc
@@ -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;
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.cc
new file mode 100644
index 0000000..ab1863e
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.cc
@@ -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
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.h
new file mode 100644
index 0000000..e26911a
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.h
@@ -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_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report_unittest.cc
new file mode 100644
index 0000000..548c130
--- /dev/null
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report_unittest.cc
@@ -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
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc
index 6b4ef90..1b5d4f3 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet_unittest.cc
@@ -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;
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
index f36c04e..d239d85 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
@@ -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"
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
index 64331a5..4b0914d 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -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 @@
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);
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
index dd3aec4..3cc8f4a 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
@@ -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"