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

Unified Diff: webrtc/modules/rtp_rtcp/source/rtcp_utility.cc

Issue 1307663004: Add a ParseHeader method to RtcpPacket, for parsing common RTCP header. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Addressed comments, rebase Created 5 years, 3 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_utility.cc
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc b/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc
index 4e37cf3716d916c7ecb1bfd6185b1790dfa15f5f..47a63315acb39ed1122af69ace7c41fe34788d03 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc
@@ -14,6 +14,10 @@
#include <math.h> // ceil
#include <string.h> // memcpy
+#include "webrtc/base/checks.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+
namespace webrtc {
namespace RTCPUtility {
@@ -155,43 +159,40 @@ RTCPUtility::RTCPParserV2::IterateTopLevel()
{
for (;;)
{
- RTCPCommonHeader header;
-
- const bool success = RTCPParseCommonHeader(_ptrRTCPData,
- _ptrRTCPDataEnd,
- header);
+ RtcpCommonHeader header;
+ if (_ptrRTCPDataEnd <= _ptrRTCPData)
+ return;
- if (!success)
- {
+ if (!RtcpParseCommonHeader(_ptrRTCPData, _ptrRTCPDataEnd - _ptrRTCPData,
+ &header)) {
return;
}
- _ptrRTCPBlockEnd = _ptrRTCPData + header.LengthInOctets;
+ _ptrRTCPBlockEnd = _ptrRTCPData + header.BlockSize();
if (_ptrRTCPBlockEnd > _ptrRTCPDataEnd)
{
// Bad block!
return;
}
- switch (header.PT)
- {
+ switch (header.packet_type) {
case PT_SR:
{
// number of Report blocks
- _numberOfBlocks = header.IC;
+ _numberOfBlocks = header.count_or_format;
ParseSR();
return;
}
case PT_RR:
{
// number of Report blocks
- _numberOfBlocks = header.IC;
+ _numberOfBlocks = header.count_or_format;
ParseRR();
return;
}
case PT_SDES:
{
// number of SDES blocks
- _numberOfBlocks = header.IC;
+ _numberOfBlocks = header.count_or_format;
const bool ok = ParseSDES();
if (!ok)
{
@@ -202,7 +203,7 @@ RTCPUtility::RTCPParserV2::IterateTopLevel()
}
case PT_BYE:
{
- _numberOfBlocks = header.IC;
+ _numberOfBlocks = header.count_or_format;
const bool ok = ParseBYE();
if (!ok)
{
@@ -214,7 +215,7 @@ RTCPUtility::RTCPParserV2::IterateTopLevel()
case PT_IJ:
{
// number of Report blocks
- _numberOfBlocks = header.IC;
+ _numberOfBlocks = header.count_or_format;
ParseIJ();
return;
}
@@ -410,20 +411,16 @@ RTCPUtility::RTCPParserV2::IterateAppItem()
void
RTCPUtility::RTCPParserV2::Validate()
{
- if (_ptrRTCPData == NULL)
- {
- return; // NOT VALID
- }
+ if (_ptrRTCPData == nullptr)
+ return; // NOT VALID
- RTCPCommonHeader header;
- const bool success = RTCPParseCommonHeader(_ptrRTCPDataBegin,
- _ptrRTCPDataEnd,
- header);
+ RtcpCommonHeader header;
+ if (_ptrRTCPDataEnd <= _ptrRTCPDataBegin)
+ return; // NOT VALID
- if (!success)
- {
- return; // NOT VALID!
- }
+ if (!RtcpParseCommonHeader(_ptrRTCPDataBegin,
+ _ptrRTCPDataEnd - _ptrRTCPDataBegin, &header))
+ return; // NOT VALID!
// * if (!reducedSize) : first packet must be RR or SR.
//
@@ -437,8 +434,7 @@ RTCPUtility::RTCPParserV2::Validate()
if (!_RTCPReducedSizeEnable)
{
- if ((header.PT != PT_SR) && (header.PT != PT_RR))
- {
+ if ((header.packet_type != PT_SR) && (header.packet_type != PT_RR)) {
return; // NOT VALID
}
}
@@ -458,48 +454,74 @@ RTCPUtility::RTCPParserV2::EndCurrentBlock()
_ptrRTCPData = _ptrRTCPBlockEnd;
}
-bool
-RTCPUtility::RTCPParseCommonHeader( const uint8_t* ptrDataBegin,
- const uint8_t* ptrDataEnd,
- RTCPCommonHeader& parsedHeader)
-{
- if (!ptrDataBegin || !ptrDataEnd)
- {
- return false;
- }
-
- // 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| IC | PT | length |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- //
- // Common header for all RTCP packets, 4 octets.
+// 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| IC | PT | length |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//
+// Common header for all RTCP packets, 4 octets.
+
+bool RTCPUtility::RtcpParseCommonHeader(const uint8_t* packet,
+ size_t size_bytes,
+ RtcpCommonHeader* parsed_header) {
+ DCHECK(parsed_header != nullptr);
+ if (size_bytes < RtcpCommonHeader::kHeaderSizeBytes) {
+ LOG(LS_WARNING) << "Too little data (" << size_bytes << " byte"
+ << (size_bytes != 1 ? "s" : "")
+ << ") remaining in buffer to parse RTCP header (4 bytes).";
+ return false;
+ }
- if ((ptrDataEnd - ptrDataBegin) < 4)
- {
- return false;
- }
+ const uint8_t kRtcpVersion = 2;
+ uint8_t version = packet[0] >> 6;
+ if (version != kRtcpVersion) {
+ LOG(LS_WARNING) << "Invalid RTCP header: Version must be "
+ << static_cast<int>(kRtcpVersion) << " but was "
+ << static_cast<int>(version);
+ return false;
+ }
- parsedHeader.V = ptrDataBegin[0] >> 6;
- parsedHeader.P = ((ptrDataBegin[0] & 0x20) == 0) ? false : true;
- parsedHeader.IC = ptrDataBegin[0] & 0x1f;
- parsedHeader.PT = ptrDataBegin[1];
+ bool has_padding = (packet[0] & 0x20) != 0;
+ uint8_t format = packet[0] & 0x1F;
+ uint8_t packet_type = packet[1];
+ size_t packet_size_words =
+ ByteReader<uint16_t>::ReadBigEndian(&packet[2]) + 1;
- parsedHeader.LengthInOctets = (ptrDataBegin[2] << 8) + ptrDataBegin[3] + 1;
- parsedHeader.LengthInOctets *= 4;
+ if (size_bytes < packet_size_words * 4) {
+ LOG(LS_WARNING) << "Buffer too small (" << size_bytes
+ << " bytes) to fit an RtcpPacket of " << packet_size_words
+ << " 32bit words.";
+ return false;
+ }
- if(parsedHeader.LengthInOctets == 0)
- {
- return false;
+ size_t payload_size = packet_size_words * 4;
+ size_t padding_bytes = 0;
+ if (has_padding) {
+ if (payload_size <= RtcpCommonHeader::kHeaderSizeBytes) {
+ LOG(LS_WARNING) << "Invalid RTCP header: Padding bit set but 0 payload "
+ "size specified.";
+ return false;
}
- // Check if RTP version field == 2
- if (parsedHeader.V != 2)
- {
- return false;
+
+ padding_bytes = packet[payload_size - 1];
+ if (RtcpCommonHeader::kHeaderSizeBytes + padding_bytes > payload_size) {
+ LOG(LS_WARNING) << "Invalid RTCP header: Too many padding bytes ("
+ << padding_bytes << ") for a packet size of "
+ << payload_size << "bytes.";
+ return false;
}
+ payload_size -= padding_bytes;
+ }
+ payload_size -= RtcpCommonHeader::kHeaderSizeBytes;
- return true;
+ parsed_header->version = kRtcpVersion;
+ parsed_header->count_or_format = format;
+ parsed_header->packet_type = packet_type;
+ parsed_header->payload_size_bytes = payload_size;
+ parsed_header->padding_bytes = padding_bytes;
+
+ return true;
}
bool
@@ -1137,10 +1159,9 @@ bool RTCPUtility::RTCPParserV2::ParseXrUnsupportedBlockType(
return false;
}
-bool
-RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header)
-{
- assert((header.PT == PT_RTPFB) || (header.PT == PT_PSFB)); // Parser logic check
+bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) {
+ assert((header.packet_type == PT_RTPFB) ||
+ (header.packet_type == PT_PSFB)); // Parser logic check
const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
@@ -1162,12 +1183,10 @@ RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header)
mediaSSRC += *_ptrRTCPData++ << 8;
mediaSSRC += *_ptrRTCPData++;
- if (header.PT == PT_RTPFB)
- {
+ if (header.packet_type == PT_RTPFB) {
// Transport layer feedback
- switch (header.IC)
- {
+ switch (header.count_or_format) {
case 1:
{
// NACK
@@ -1222,12 +1241,9 @@ RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header)
}
EndCurrentBlock();
return false;
- }
- else if (header.PT == PT_PSFB)
- {
+ } else if (header.packet_type == PT_PSFB) {
// Payload specific feedback
- switch (header.IC)
- {
+ switch (header.count_or_format) {
case 1:
// PLI
_packetType = RTCPPacketTypes::kPsfbPli;
@@ -1579,9 +1595,7 @@ RTCPUtility::RTCPParserV2::ParseFIRItem()
return true;
}
-bool
-RTCPUtility::RTCPParserV2::ParseAPP( const RTCPCommonHeader& header)
-{
+bool RTCPUtility::RTCPParserV2::ParseAPP(const RtcpCommonHeader& header) {
ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
if (length < 12) // 4 * 3, RFC 3550 6.7 APP: Application-Defined RTCP Packet
@@ -1606,7 +1620,7 @@ RTCPUtility::RTCPParserV2::ParseAPP( const RTCPCommonHeader& header)
_packetType = RTCPPacketTypes::kApp;
- _packet.APP.SubType = header.IC;
+ _packet.APP.SubType = header.count_or_format;
_packet.APP.Name = name;
_state = ParseState::State_AppItem;
@@ -1651,37 +1665,31 @@ RTCPUtility::RTCPPacketIterator::RTCPPacketIterator(uint8_t* rtcpData,
RTCPUtility::RTCPPacketIterator::~RTCPPacketIterator() {
}
-const RTCPUtility::RTCPCommonHeader*
-RTCPUtility::RTCPPacketIterator::Begin()
-{
+const RTCPUtility::RtcpCommonHeader* RTCPUtility::RTCPPacketIterator::Begin() {
_ptrBlock = _ptrBegin;
return Iterate();
}
-const RTCPUtility::RTCPCommonHeader*
-RTCPUtility::RTCPPacketIterator::Iterate()
-{
- const bool success = RTCPParseCommonHeader(_ptrBlock, _ptrEnd, _header);
- if (!success)
- {
- _ptrBlock = NULL;
- return NULL;
- }
- _ptrBlock += _header.LengthInOctets;
+const RTCPUtility::RtcpCommonHeader*
+RTCPUtility::RTCPPacketIterator::Iterate() {
+ if ((_ptrEnd <= _ptrBlock) ||
+ !RtcpParseCommonHeader(_ptrBlock, _ptrEnd - _ptrBlock, &_header)) {
+ _ptrBlock = nullptr;
+ return nullptr;
+ }
+ _ptrBlock += _header.BlockSize();
- if (_ptrBlock > _ptrEnd)
- {
- _ptrBlock = NULL;
- return NULL;
- }
+ if (_ptrBlock > _ptrEnd) {
+ _ptrBlock = nullptr;
+ return nullptr;
+ }
- return &_header;
+ return &_header;
}
-const RTCPUtility::RTCPCommonHeader*
-RTCPUtility::RTCPPacketIterator::Current()
-{
+const RTCPUtility::RtcpCommonHeader*
+RTCPUtility::RTCPPacketIterator::Current() {
if (!_ptrBlock)
{
return NULL;
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtcp_utility.h ('k') | webrtc/modules/rtp_rtcp/source/rtcp_utility_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698