Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(376)

Unified Diff: webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc

Issue 1557593002: [rtp_rtcp] rtcp::ExtenededReports packet got Parse function (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc
index a78ad464b72174d4106020dd90c6ab32a8473a9a..980267017c076ab88d95ae391b4b5e6404cb97ec 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc
@@ -14,16 +14,10 @@
#include "webrtc/base/logging.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
-using webrtc::RTCPUtility::PT_XR;
-using webrtc::RTCPUtility::RTCPPacketXR;
+using webrtc::RTCPUtility::RtcpCommonHeader;
namespace webrtc {
namespace rtcp {
-namespace {
-void AssignUWord32(uint8_t* buffer, size_t* offset, uint32_t value) {
- ByteWriter<uint32_t>::WriteBigEndian(buffer + *offset, value);
- *offset += 4;
-}
// From RFC 3611: RTP Control Protocol Extended Reports (RTCP XR).
//
// Format for XR packets:
@@ -37,65 +31,114 @@ void AssignUWord32(uint8_t* buffer, size_t* offset, uint32_t value) {
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// : report blocks :
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-void CreateXrHeader(const RTCPPacketXR& header,
- uint8_t* buffer,
- size_t* pos) {
- AssignUWord32(buffer, pos, header.OriginatorSSRC);
-}
-} // namespace
+//
+// Report header:
åsapersson 2016/01/29 12:46:09 maybe Report block header:
danilchap 2016/01/29 13:49:30 To match specification included full report block
+// 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
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | Block Type | reserved | block length |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ExtendedReports::ExtendedReports() : sender_ssrc_(0) {}
+ExtendedReports::~ExtendedReports() {}
-bool ExtendedReports::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(0U, PT_XR, HeaderLength(), packet, index);
- CreateXrHeader(xr_header_, packet, index);
- for (const Rrtr& block : rrtr_blocks_) {
- block.Create(packet + *index);
- *index += Rrtr::kLength;
- }
- for (const Dlrr& block : dlrr_blocks_) {
- block.Create(packet + *index);
- *index += block.BlockLength();
+bool ExtendedReports::Parse(const RtcpCommonHeader& header,
+ const uint8_t* payload) {
+ RTC_CHECK(header.packet_type == kPacketType);
+
+ if (header.payload_size_bytes < kXrHeaderLength) {
+ LOG(LS_WARNING) << "Packet is too small to be an ExtendedReports packet.";
+ return false;
}
- for (const VoipMetric& block : voip_metric_blocks_) {
- block.Create(packet + *index);
- *index += VoipMetric::kLength;
+
+ sender_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(payload);
+
åsapersson 2016/01/29 12:46:09 should the blocks be resized to zero here?
danilchap 2016/01/29 13:49:30 Done.
+ const uint8_t* current_block = payload + kXrHeaderLength;
+ const uint8_t* const packet_end = payload + header.payload_size_bytes;
+ const size_t kBlockHeaderSizeBytes = 4;
+ while (current_block + kBlockHeaderSizeBytes <= packet_end) {
+ uint8_t block_type = ByteReader<uint8_t>::ReadBigEndian(current_block);
+ uint16_t block_size =
åsapersson 2016/01/29 12:46:09 perhaps call block_length (as in figure)
danilchap 2016/01/29 13:49:30 Done. Word 'size' may also give false impression i
+ ByteReader<uint16_t>::ReadBigEndian(current_block + 2);
+ const uint8_t* next_block =
+ current_block + kBlockHeaderSizeBytes + block_size * 4;
+ if (next_block > packet_end) {
+ LOG(LS_WARNING) << "Report block in extended report packet is too big.";
+ return false;
+ }
+ switch (block_type) {
+ case Rrtr::kBlockType:
+ ParseRrtrBlock(current_block, block_size);
+ break;
+ case Dlrr::kBlockType:
+ ParseDlrrBlock(current_block, block_size);
+ break;
+ case VoipMetric::kBlockType:
+ ParseVoipMetricBlock(current_block, block_size);
+ break;
+ default:
+ // Unknown block, ignore.
+ LOG(LS_WARNING) << "Unknown extended report block type " << block_type;
+ break;
+ }
+ current_block = next_block;
}
+
return true;
}
-bool ExtendedReports::WithRrtr(Rrtr* rrtr) {
- RTC_DCHECK(rrtr);
+bool ExtendedReports::WithRrtr(const Rrtr& rrtr) {
if (rrtr_blocks_.size() >= kMaxNumberOfRrtrBlocks) {
LOG(LS_WARNING) << "Max RRTR blocks reached.";
return false;
}
- rrtr_blocks_.push_back(*rrtr);
+ rrtr_blocks_.push_back(rrtr);
return true;
}
-bool ExtendedReports::WithDlrr(Dlrr* dlrr) {
- RTC_DCHECK(dlrr);
+bool ExtendedReports::WithDlrr(const Dlrr& dlrr) {
if (dlrr_blocks_.size() >= kMaxNumberOfDlrrBlocks) {
LOG(LS_WARNING) << "Max DLRR blocks reached.";
return false;
}
- dlrr_blocks_.push_back(*dlrr);
+ dlrr_blocks_.push_back(dlrr);
return true;
}
-bool ExtendedReports::WithVoipMetric(VoipMetric* voip_metric) {
- assert(voip_metric);
+bool ExtendedReports::WithVoipMetric(const VoipMetric& voip_metric) {
if (voip_metric_blocks_.size() >= kMaxNumberOfVoipMetricBlocks) {
LOG(LS_WARNING) << "Max Voip Metric blocks reached.";
return false;
}
- voip_metric_blocks_.push_back(*voip_metric);
+ voip_metric_blocks_.push_back(voip_metric);
+ return true;
+}
+
+bool ExtendedReports::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;
+ }
+ size_t index_end = *index + BlockLength();
+ const uint8_t kReserved = 0;
+ CreateHeader(kReserved, kPacketType, HeaderLength(), packet, index);
+ ByteWriter<uint32_t>::WriteBigEndian(packet + *index, sender_ssrc_);
+ *index += sizeof(uint32_t);
+ for (const Rrtr& block : rrtr_blocks_) {
+ block.Create(packet + *index);
+ *index += Rrtr::kLength;
+ }
+ for (const Dlrr& block : dlrr_blocks_) {
+ block.Create(packet + *index);
+ *index += block.BlockLength();
+ }
+ for (const VoipMetric& block : voip_metric_blocks_) {
+ block.Create(packet + *index);
+ *index += VoipMetric::kLength;
+ }
+ RTC_CHECK_EQ(*index, index_end);
return true;
}
@@ -107,5 +150,34 @@ size_t ExtendedReports::DlrrLength() const {
return length;
}
+void ExtendedReports::ParseRrtrBlock(const uint8_t* block,
+ uint16_t block_size) {
+ if (block_size != Rrtr::kBlockLength) {
+ LOG(LS_WARNING) << "Incorrect rrtr block size " << block_size
+ << " Should be " << Rrtr::kBlockLength;
+ return;
+ }
+ rrtr_blocks_.push_back(Rrtr());
+ rrtr_blocks_.back().Parse(block);
+}
+
+void ExtendedReports::ParseDlrrBlock(const uint8_t* block,
+ uint16_t block_size) {
+ dlrr_blocks_.push_back(Dlrr());
+ if (!dlrr_blocks_.back().Parse(block, block_size)) {
+ dlrr_blocks_.pop_back();
+ }
+}
+
+void ExtendedReports::ParseVoipMetricBlock(const uint8_t* block,
+ uint16_t block_size) {
+ if (block_size != VoipMetric::kBlockLength) {
+ LOG(LS_WARNING) << "Incorrect voip metric block size " << block_size
+ << " Should be " << VoipMetric::kBlockLength;
+ return;
+ }
+ voip_metric_blocks_.push_back(VoipMetric());
+ voip_metric_blocks_.back().Parse(block);
+}
} // namespace rtcp
} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698