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 caffb6342c0675896812f93adeecd24178d9745b..6c1deb467ef787de5947df7d70ef4384c56204fd 100644 |
--- a/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc |
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc |
@@ -8,7 +8,9 @@ |
* be found in the AUTHORS file in the root of the source tree. |
*/ |
+#include "webrtc/base/checks.h" |
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" |
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |
#include <assert.h> |
#include <math.h> // ceil |
@@ -55,6 +57,7 @@ RTCPUtility::RTCPParserV2::RTCPParserV2(const uint8_t* rtcpData, |
_ptrRTCPBlockEnd(NULL), |
_state(ParseState::State_TopLevel), |
_numberOfBlocks(0), |
+ num_skipped_blocks_(0), |
_packetType(RTCPPacketTypes::kInvalid) { |
Validate(); |
} |
@@ -80,6 +83,9 @@ RTCPUtility::RTCPParserV2::Packet() const |
return _packet; |
} |
+rtcp::RtcpPacket* RTCPUtility::RTCPParserV2::ReleaseRtcpPacket() { |
+ return rtcp_packet_.release(); |
+} |
RTCPUtility::RTCPPacketTypes |
RTCPUtility::RTCPParserV2::Begin() |
{ |
@@ -147,7 +153,7 @@ RTCPUtility::RTCPParserV2::Iterate() |
IterateAppItem(); |
break; |
default: |
- assert(false); // Invalid state! |
+ RTC_NOTREACHED() << "Invalid state!"; |
break; |
} |
} |
@@ -170,7 +176,7 @@ RTCPUtility::RTCPParserV2::IterateTopLevel() |
_ptrRTCPBlockEnd = _ptrRTCPData + header.BlockSize(); |
if (_ptrRTCPBlockEnd > _ptrRTCPDataEnd) |
{ |
- // Bad block! |
+ ++num_skipped_blocks_; |
return; |
} |
@@ -219,16 +225,15 @@ RTCPUtility::RTCPParserV2::IterateTopLevel() |
ParseIJ(); |
return; |
} |
- case PT_RTPFB: // Fall through! |
+ case PT_RTPFB: |
+ FALLTHROUGH(); |
case PT_PSFB: |
{ |
- const bool ok = ParseFBCommon(header); |
- if (!ok) |
- { |
- // Nothing supported found, continue to next block! |
- break; |
- } |
- return; |
+ if (!ParseFBCommon(header)) { |
+ // Nothing supported found, continue to next block! |
+ break; |
+ } |
+ return; |
} |
case PT_APP: |
{ |
@@ -252,6 +257,7 @@ RTCPUtility::RTCPParserV2::IterateTopLevel() |
} |
default: |
// Not supported! Skip! |
+ ++num_skipped_blocks_; |
EndCurrentBlock(); |
break; |
} |
@@ -1160,28 +1166,26 @@ bool RTCPUtility::RTCPParserV2::ParseXrUnsupportedBlockType( |
} |
bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) { |
- assert((header.packet_type == PT_RTPFB) || |
- (header.packet_type == PT_PSFB)); // Parser logic check |
+ RTC_CHECK((header.packet_type == PT_RTPFB) || |
+ (header.packet_type == PT_PSFB)); // Parser logic check |
const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; |
- if (length < 12) // 4 * 3, RFC4585 section 6.1 |
- { |
- EndCurrentBlock(); |
+ // 4 * 3, RFC4585 section 6.1 |
+ if (length < 12) { |
+ LOG(LS_WARNING) |
+ << "Invalid RTCP packet: Too little data (" << length |
+ << " bytes) left in buffer to parse a 12 byte RTPFB/PSFB message."; |
return false; |
} |
_ptrRTCPData += 4; // Skip RTCP header |
- uint32_t senderSSRC = *_ptrRTCPData++ << 24; |
- senderSSRC += *_ptrRTCPData++ << 16; |
- senderSSRC += *_ptrRTCPData++ << 8; |
- senderSSRC += *_ptrRTCPData++; |
+ uint32_t senderSSRC = ByteReader<uint32_t>::ReadBigEndian(_ptrRTCPData); |
+ _ptrRTCPData += 4; |
- uint32_t mediaSSRC = *_ptrRTCPData++ << 24; |
- mediaSSRC += *_ptrRTCPData++ << 16; |
- mediaSSRC += *_ptrRTCPData++ << 8; |
- mediaSSRC += *_ptrRTCPData++; |
+ uint32_t mediaSSRC = ByteReader<uint32_t>::ReadBigEndian(_ptrRTCPData); |
+ _ptrRTCPData += 4; |
if (header.packet_type == PT_RTPFB) { |
// Transport layer feedback |
@@ -1198,12 +1202,6 @@ bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) { |
return true; |
} |
- case 2: |
- { |
- // used to be ACK is this code point, which is removed |
- // conficts with http://tools.ietf.org/html/draft-levin-avt-rtcp-burst-00 |
- break; |
- } |
case 3: |
{ |
// TMMBR |
@@ -1236,10 +1234,23 @@ bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) { |
// Note: No state transition, SR REQ is empty! |
return true; |
} |
+ case 15: { |
+ _packetType = RTCPPacketTypes::kTransportFeedback; |
+ rtcp_packet_ = |
+ rtcp::TransportFeedback::ParseFrom(_ptrRTCPData - 12, length); |
+ // Since we parse the whole packet here, keep the TopLevel state and |
+ // just end the current block. |
+ if (rtcp_packet_.get()) { |
+ EndCurrentBlock(); |
+ return true; |
+ } |
+ break; |
+ } |
default: |
break; |
} |
- EndCurrentBlock(); |
+ // Unsupported RTPFB message. Skip and move to next block. |
+ ++num_skipped_blocks_; |
return false; |
} else if (header.packet_type == PT_PSFB) { |
// Payload specific feedback |
@@ -1287,14 +1298,11 @@ bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) { |
break; |
} |
- EndCurrentBlock(); |
return false; |
} |
else |
{ |
- assert(false); |
- |
- EndCurrentBlock(); |
+ RTC_NOTREACHED(); |
return false; |
} |
} |
@@ -1654,6 +1662,10 @@ RTCPUtility::RTCPParserV2::ParseAPPItem() |
return true; |
} |
+size_t RTCPUtility::RTCPParserV2::NumSkippedBlocks() const { |
+ return num_skipped_blocks_; |
+} |
+ |
RTCPUtility::RTCPPacketIterator::RTCPPacketIterator(uint8_t* rtcpData, |
size_t rtcpDataLength) |
: _ptrBegin(rtcpData), |