LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/rtp_rtcp/source - rtp_utility.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 209 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
      12             : 
      13             : #include <string.h>
      14             : 
      15             : #include "webrtc/base/logging.h"
      16             : #include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h"
      17             : #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
      18             : 
      19             : namespace webrtc {
      20             : 
      21           0 : RtpData* NullObjectRtpData() {
      22           0 :   static NullRtpData null_rtp_data;
      23           0 :   return &null_rtp_data;
      24             : }
      25             : 
      26           0 : RtpFeedback* NullObjectRtpFeedback() {
      27           0 :   static NullRtpFeedback null_rtp_feedback;
      28           0 :   return &null_rtp_feedback;
      29             : }
      30             : 
      31           0 : ReceiveStatistics* NullObjectReceiveStatistics() {
      32           0 :   static NullReceiveStatistics null_receive_statistics;
      33           0 :   return &null_receive_statistics;
      34             : }
      35             : 
      36             : namespace RtpUtility {
      37             : 
      38             : enum {
      39             :   kRtcpExpectedVersion = 2,
      40             :   kRtcpMinHeaderLength = 4,
      41             :   kRtcpMinParseLength = 8,
      42             : 
      43             :   kRtpExpectedVersion = 2,
      44             :   kRtpMinParseLength = 12
      45             : };
      46             : 
      47             : /*
      48             :  * Misc utility routines
      49             :  */
      50             : 
      51             : #if defined(_WIN32)
      52             : bool StringCompare(const char* str1, const char* str2,
      53             :                    const uint32_t length) {
      54             :   return _strnicmp(str1, str2, length) == 0;
      55             : }
      56             : #elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC)
      57           0 : bool StringCompare(const char* str1, const char* str2,
      58             :                    const uint32_t length) {
      59           0 :   return strncasecmp(str1, str2, length) == 0;
      60             : }
      61             : #endif
      62             : 
      63           0 : size_t Word32Align(size_t size) {
      64           0 :   uint32_t remainder = size % 4;
      65           0 :   if (remainder != 0)
      66           0 :     return size + 4 - remainder;
      67           0 :   return size;
      68             : }
      69             : 
      70           0 : RtpHeaderParser::RtpHeaderParser(const uint8_t* rtpData,
      71           0 :                                  const size_t rtpDataLength)
      72             :     : _ptrRTPDataBegin(rtpData),
      73           0 :       _ptrRTPDataEnd(rtpData ? (rtpData + rtpDataLength) : NULL) {
      74           0 : }
      75             : 
      76           0 : RtpHeaderParser::~RtpHeaderParser() {
      77           0 : }
      78             : 
      79           0 : bool RtpHeaderParser::RTCP() const {
      80             :   // 72 to 76 is reserved for RTP
      81             :   // 77 to 79 is not reserver but  they are not assigned we will block them
      82             :   // for RTCP 200 SR  == marker bit + 72
      83             :   // for RTCP 204 APP == marker bit + 76
      84             :   /*
      85             :   *       RTCP
      86             :   *
      87             :   * FIR      full INTRA-frame request             192     [RFC2032]   supported
      88             :   * NACK     negative acknowledgement             193     [RFC2032]
      89             :   * IJ       Extended inter-arrival jitter report 195     [RFC-ietf-avt-rtp-toff
      90             :   * set-07.txt] http://tools.ietf.org/html/draft-ietf-avt-rtp-toffset-07
      91             :   * SR       sender report                        200     [RFC3551]   supported
      92             :   * RR       receiver report                      201     [RFC3551]   supported
      93             :   * SDES     source description                   202     [RFC3551]   supported
      94             :   * BYE      goodbye                              203     [RFC3551]   supported
      95             :   * APP      application-defined                  204     [RFC3551]   ignored
      96             :   * RTPFB    Transport layer FB message           205     [RFC4585]   supported
      97             :   * PSFB     Payload-specific FB message          206     [RFC4585]   supported
      98             :   * XR       extended report                      207     [RFC3611]   supported
      99             :   */
     100             : 
     101             :   /* 205       RFC 5104
     102             :    * FMT 1      NACK       supported
     103             :    * FMT 2      reserved
     104             :    * FMT 3      TMMBR      supported
     105             :    * FMT 4      TMMBN      supported
     106             :    */
     107             : 
     108             :   /* 206      RFC 5104
     109             :   * FMT 1:     Picture Loss Indication (PLI)                      supported
     110             :   * FMT 2:     Slice Lost Indication (SLI)
     111             :   * FMT 3:     Reference Picture Selection Indication (RPSI)
     112             :   * FMT 4:     Full Intra Request (FIR) Command                   supported
     113             :   * FMT 5:     Temporal-Spatial Trade-off Request (TSTR)
     114             :   * FMT 6:     Temporal-Spatial Trade-off Notification (TSTN)
     115             :   * FMT 7:     Video Back Channel Message (VBCM)
     116             :   * FMT 15:    Application layer FB message
     117             :   */
     118             : 
     119           0 :   const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin;
     120           0 :   if (length < kRtcpMinHeaderLength) {
     121           0 :     return false;
     122             :   }
     123             : 
     124           0 :   const uint8_t V = _ptrRTPDataBegin[0] >> 6;
     125           0 :   if (V != kRtcpExpectedVersion) {
     126           0 :     return false;
     127             :   }
     128             : 
     129           0 :   const uint8_t payloadType = _ptrRTPDataBegin[1];
     130           0 :   switch (payloadType) {
     131             :     case 192:
     132           0 :       return true;
     133             :     case 193:
     134             :       // not supported
     135             :       // pass through and check for a potential RTP packet
     136           0 :       return false;
     137             :     case 195:
     138             :     case 200:
     139             :     case 201:
     140             :     case 202:
     141             :     case 203:
     142             :     case 204:
     143             :     case 205:
     144             :     case 206:
     145             :     case 207:
     146           0 :       return true;
     147             :     default:
     148           0 :       return false;
     149             :   }
     150             : }
     151             : 
     152           0 : bool RtpHeaderParser::ParseRtcp(RTPHeader* header) const {
     153           0 :   assert(header != NULL);
     154             : 
     155           0 :   const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin;
     156           0 :   if (length < kRtcpMinParseLength) {
     157           0 :     return false;
     158             :   }
     159             : 
     160           0 :   const uint8_t V = _ptrRTPDataBegin[0] >> 6;
     161           0 :   if (V != kRtcpExpectedVersion) {
     162           0 :     return false;
     163             :   }
     164             : 
     165           0 :   const uint8_t PT = _ptrRTPDataBegin[1];
     166           0 :   const size_t len = (_ptrRTPDataBegin[2] << 8) + _ptrRTPDataBegin[3];
     167           0 :   const uint8_t* ptr = &_ptrRTPDataBegin[4];
     168             : 
     169           0 :   uint32_t SSRC = ByteReader<uint32_t>::ReadBigEndian(ptr);
     170           0 :   ptr += 4;
     171             : 
     172           0 :   header->payloadType  = PT;
     173           0 :   header->ssrc         = SSRC;
     174           0 :   header->headerLength = 4 + (len << 2);
     175           0 :   if (header->headerLength > static_cast<size_t>(length)) {
     176           0 :     return false;
     177             :   }
     178             : 
     179           0 :   return true;
     180             : }
     181             : 
     182           0 : bool RtpHeaderParser::Parse(RTPHeader* header,
     183             :                             RtpHeaderExtensionMap* ptrExtensionMap) const {
     184           0 :   const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin;
     185           0 :   if (length < kRtpMinParseLength) {
     186           0 :     return false;
     187             :   }
     188             : 
     189             :   // Version
     190           0 :   const uint8_t V  = _ptrRTPDataBegin[0] >> 6;
     191             :   // Padding
     192           0 :   const bool          P  = ((_ptrRTPDataBegin[0] & 0x20) == 0) ? false : true;
     193             :   // eXtension
     194           0 :   const bool          X  = ((_ptrRTPDataBegin[0] & 0x10) == 0) ? false : true;
     195           0 :   const uint8_t CC = _ptrRTPDataBegin[0] & 0x0f;
     196           0 :   const bool          M  = ((_ptrRTPDataBegin[1] & 0x80) == 0) ? false : true;
     197             : 
     198           0 :   const uint8_t PT = _ptrRTPDataBegin[1] & 0x7f;
     199             : 
     200           0 :   const uint16_t sequenceNumber = (_ptrRTPDataBegin[2] << 8) +
     201           0 :       _ptrRTPDataBegin[3];
     202             : 
     203           0 :   const uint8_t* ptr = &_ptrRTPDataBegin[4];
     204             : 
     205           0 :   uint32_t RTPTimestamp = ByteReader<uint32_t>::ReadBigEndian(ptr);
     206           0 :   ptr += 4;
     207             : 
     208           0 :   uint32_t SSRC = ByteReader<uint32_t>::ReadBigEndian(ptr);
     209           0 :   ptr += 4;
     210             : 
     211           0 :   if (V != kRtpExpectedVersion) {
     212           0 :     return false;
     213             :   }
     214             : 
     215           0 :   header->markerBit      = M;
     216           0 :   header->payloadType    = PT;
     217           0 :   header->sequenceNumber = sequenceNumber;
     218           0 :   header->timestamp      = RTPTimestamp;
     219           0 :   header->ssrc           = SSRC;
     220           0 :   header->numCSRCs       = CC;
     221           0 :   header->paddingLength  = P ? *(_ptrRTPDataEnd - 1) : 0;
     222             : 
     223             :   // 12 == sizeof(RFC rtp header) == kRtpMinParseLength, each CSRC=4 bytes
     224           0 :   header->headerLength   = 12 + (CC * 4);
     225             :   // not a full validation, just safety against underflow.  Padding must
     226             :   // start after the header.  We can have 0 payload bytes left, note.
     227           0 :   if (header->paddingLength + header->headerLength > (size_t) length) {
     228           0 :     return false;
     229             :   }
     230             : 
     231           0 :   for (uint8_t i = 0; i < CC; ++i) {
     232           0 :     uint32_t CSRC = ByteReader<uint32_t>::ReadBigEndian(ptr);
     233           0 :     ptr += 4;
     234           0 :     header->arrOfCSRCs[i] = CSRC;
     235             :   }
     236           0 :   assert((ptr - _ptrRTPDataBegin) == (ptrdiff_t) header->headerLength);
     237             : 
     238             :   // If in effect, MAY be omitted for those packets for which the offset
     239             :   // is zero.
     240           0 :   header->extension.hasTransmissionTimeOffset = false;
     241           0 :   header->extension.transmissionTimeOffset = 0;
     242             : 
     243             :   // May not be present in packet.
     244           0 :   header->extension.hasAbsoluteSendTime = false;
     245           0 :   header->extension.absoluteSendTime = 0;
     246             : 
     247             :   // May not be present in packet.
     248           0 :   header->extension.hasAudioLevel = false;
     249           0 :   header->extension.voiceActivity = false;
     250           0 :   header->extension.audioLevel = 0;
     251             : 
     252             :   // May not be present in packet.
     253           0 :   header->extension.hasVideoRotation = false;
     254           0 :   header->extension.videoRotation = kVideoRotation_0;
     255             : 
     256             :   // May not be present in packet.
     257           0 :   header->extension.hasRID = false;
     258           0 :   header->extension.rid = NULL;
     259             : 
     260             :   // May not be present in packet.
     261           0 :   header->extension.playout_delay.min_ms = -1;
     262           0 :   header->extension.playout_delay.max_ms = -1;
     263             : 
     264           0 :   if (X) {
     265             :     /* RTP header extension, RFC 3550.
     266             :      0                   1                   2                   3
     267             :      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
     268             :     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     269             :     |      defined by profile       |           length              |
     270             :     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     271             :     |                        header extension                       |
     272             :     |                             ....                              |
     273             :     */
     274             :     // earlier test ensures we have at least paddingLength bytes left
     275           0 :     const ptrdiff_t remain = (_ptrRTPDataEnd - ptr) - header->paddingLength;
     276           0 :     if (remain < 4) { // minimum header extension length = 32 bits
     277           0 :       return false;
     278             :     }
     279             : 
     280           0 :     header->headerLength += 4;
     281             : 
     282           0 :     uint16_t definedByProfile = ByteReader<uint16_t>::ReadBigEndian(ptr);
     283           0 :     ptr += 2;
     284             : 
     285             :     // in 32 bit words
     286           0 :     size_t XLen = ByteReader<uint16_t>::ReadBigEndian(ptr);
     287           0 :     ptr += 2;
     288           0 :     XLen *= 4;  // in bytes
     289             : 
     290           0 :     if (static_cast<size_t>(remain) < (4 + XLen)) {
     291           0 :       return false;
     292             :     }
     293           0 :     if (definedByProfile == kRtpOneByteHeaderExtensionId) {
     294           0 :       const uint8_t* ptrRTPDataExtensionEnd = ptr + XLen;
     295             :       ParseOneByteExtensionHeader(header,
     296             :                                   ptrExtensionMap,
     297             :                                   ptrRTPDataExtensionEnd,
     298           0 :                                   ptr);
     299             :     }
     300           0 :     header->headerLength += XLen;
     301             :   }
     302           0 :   if (header->headerLength + header->paddingLength >
     303           0 :       static_cast<size_t>(length))
     304           0 :     return false;
     305           0 :   return true;
     306             : }
     307             : 
     308           0 : void RtpHeaderParser::ParseOneByteExtensionHeader(
     309             :     RTPHeader* header,
     310             :     const RtpHeaderExtensionMap* ptrExtensionMap,
     311             :     const uint8_t* ptrRTPDataExtensionEnd,
     312             :     const uint8_t* ptr) const {
     313           0 :   if (!ptrExtensionMap) {
     314           0 :     return;
     315             :   }
     316             : 
     317           0 :   while (ptrRTPDataExtensionEnd - ptr > 0) {
     318             :     //  0
     319             :     //  0 1 2 3 4 5 6 7
     320             :     // +-+-+-+-+-+-+-+-+
     321             :     // |  ID   |  len  |
     322             :     // +-+-+-+-+-+-+-+-+
     323             : 
     324             :     // Note that 'len' is the header extension element length, which is the
     325             :     // number of bytes - 1.
     326           0 :     const int id = (*ptr & 0xf0) >> 4;
     327           0 :     const int len = (*ptr & 0x0f);
     328           0 :     if (ptr + len + 1 > ptrRTPDataExtensionEnd) {
     329           0 :       LOG(LS_WARNING)
     330           0 :           << "RTP extension header length out of bounds. Terminate parsing.";
     331           0 :       return;
     332             :     }
     333           0 :     ptr++;
     334             : 
     335           0 :     if (id == 0) {
     336             :       // Padding byte, skip ignoring len.
     337           0 :       continue;
     338             :     }
     339             : 
     340           0 :     if (id == 15) {
     341           0 :       LOG(LS_VERBOSE)
     342           0 :           << "RTP extension header 15 encountered. Terminate parsing.";
     343           0 :       return;
     344             :     }
     345             : 
     346           0 :     if (ptrRTPDataExtensionEnd - ptr < (len + 1)) {
     347           0 :       LOG(LS_WARNING) << "Incorrect one-byte extension len: " << (len + 1)
     348           0 :                       << ", bytes left in buffer: "
     349           0 :                       << (ptrRTPDataExtensionEnd - ptr);
     350           0 :       return;
     351             :     }
     352             : 
     353           0 :     RTPExtensionType type = ptrExtensionMap->GetType(id);
     354           0 :     if (type == RtpHeaderExtensionMap::kInvalidType) {
     355             :       // If we encounter an unknown extension, just skip over it.
     356             :       // Mozilla - we reuse the parse for demux, without registering extensions.
     357             :       // Reduce log-spam by switching to VERBOSE
     358           0 :       LOG(LS_VERBOSE) << "Failed to find extension id: " << id;
     359             :     } else {
     360           0 :       switch (type) {
     361             :         case kRtpExtensionTransmissionTimeOffset: {
     362           0 :           if (len != 2) {
     363           0 :             LOG(LS_WARNING) << "Incorrect transmission time offset len: "
     364           0 :                             << len;
     365           0 :             return;
     366             :           }
     367             :           //  0                   1                   2                   3
     368             :           //  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
     369             :           // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     370             :           // |  ID   | len=2 |              transmission offset              |
     371             :           // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     372             : 
     373           0 :           header->extension.transmissionTimeOffset =
     374           0 :               ByteReader<int32_t, 3>::ReadBigEndian(ptr);
     375           0 :           header->extension.hasTransmissionTimeOffset = true;
     376           0 :           break;
     377             :         }
     378             :         case kRtpExtensionAudioLevel: {
     379           0 :           if (len != 0) {
     380           0 :             LOG(LS_WARNING) << "Incorrect audio level len: " << len;
     381           0 :             return;
     382             :           }
     383             :           //  0                   1
     384             :           //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
     385             :           // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     386             :           // |  ID   | len=0 |V|   level     |
     387             :           // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     388             :           //
     389           0 :           header->extension.audioLevel = ptr[0] & 0x7f;
     390           0 :           header->extension.voiceActivity = (ptr[0] & 0x80) != 0;
     391           0 :           header->extension.hasAudioLevel = true;
     392           0 :           break;
     393             :         }
     394             :         case kRtpExtensionAbsoluteSendTime: {
     395           0 :           if (len != 2) {
     396           0 :             LOG(LS_WARNING) << "Incorrect absolute send time len: " << len;
     397           0 :             return;
     398             :           }
     399             :           //  0                   1                   2                   3
     400             :           //  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
     401             :           // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     402             :           // |  ID   | len=2 |              absolute send time               |
     403             :           // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     404             : 
     405           0 :           header->extension.absoluteSendTime =
     406           0 :               ByteReader<uint32_t, 3>::ReadBigEndian(ptr);
     407           0 :           header->extension.hasAbsoluteSendTime = true;
     408           0 :           break;
     409             :         }
     410             :         case kRtpExtensionVideoRotation: {
     411           0 :           if (len != 0) {
     412           0 :             LOG(LS_WARNING)
     413           0 :                 << "Incorrect coordination of video coordination len: " << len;
     414           0 :             return;
     415             :           }
     416             :           //  0                   1
     417             :           //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
     418             :           // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     419             :           // |  ID   | len=0 |0 0 0 0 C F R R|
     420             :           // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     421           0 :           header->extension.hasVideoRotation = true;
     422           0 :           header->extension.videoRotation =
     423           0 :               ConvertCVOByteToVideoRotation(ptr[0]);
     424           0 :           break;
     425             :         }
     426             :         case kRtpExtensionTransportSequenceNumber: {
     427           0 :           if (len != 1) {
     428           0 :             LOG(LS_WARNING) << "Incorrect transport sequence number len: "
     429           0 :                             << len;
     430           0 :             return;
     431             :           }
     432             :           //   0                   1                   2
     433             :           //   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
     434             :           //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     435             :           //  |  ID   | L=1   |transport wide sequence number |
     436             :           //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     437             : 
     438           0 :           uint16_t sequence_number = ptr[0] << 8;
     439           0 :           sequence_number += ptr[1];
     440           0 :           header->extension.transportSequenceNumber = sequence_number;
     441           0 :           header->extension.hasTransportSequenceNumber = true;
     442           0 :           break;
     443             :         }
     444             :         case kRtpExtensionPlayoutDelay: {
     445           0 :           if (len != 2) {
     446           0 :             LOG(LS_WARNING) << "Incorrect playout delay len: " << len;
     447           0 :             return;
     448             :           }
     449             :           //   0                   1                   2                   3
     450             :           //   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
     451             :           //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     452             :           //  |  ID   | len=2 |   MIN delay           |   MAX delay           |
     453             :           //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     454             : 
     455           0 :           int min_playout_delay = (ptr[0] << 4) | ((ptr[1] >> 4) & 0xf);
     456           0 :           int max_playout_delay = ((ptr[1] & 0xf) << 8) | ptr[2];
     457           0 :           header->extension.playout_delay.min_ms =
     458           0 :               min_playout_delay * kPlayoutDelayGranularityMs;
     459           0 :           header->extension.playout_delay.max_ms =
     460           0 :               max_playout_delay * kPlayoutDelayGranularityMs;
     461           0 :           break;
     462             :         }
     463             :         case kRtpExtensionRtpStreamId: {
     464             :           //   0                   1                   2
     465             :           //   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
     466             :           //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     467             :           //  |  ID   | L=?   |UTF-8 RID value......          |...
     468             :           //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     469             : 
     470             :           // As per RFC 5285 section 4.2, len is the length of the header data
     471             :           // - 1. E.G. a len of 0 indicates a header data length of 1
     472           0 :           if ( &ptr[len + 1] > ptrRTPDataExtensionEnd ) {
     473           0 :             LOG(LS_WARNING) << "Extension RtpStreamId data length " << (len + 1)
     474           0 :               << " is longer than remaining input parse buffer "
     475           0 :               << static_cast<size_t>(ptrRTPDataExtensionEnd - ptr);
     476           0 :             return;
     477             :           }
     478             : 
     479           0 :           header->extension.rid.reset(new char[len + 2]);
     480           0 :           memcpy(header->extension.rid.get(), ptr, len + 1);
     481           0 :           header->extension.rid.get()[len + 1] = '\0';
     482           0 :           header->extension.hasRID = true;
     483           0 :           break;
     484             :         }
     485             :         default:
     486             :         case kRtpExtensionNone:
     487             :         case kRtpExtensionNumberOfExtensions: {
     488           0 :           RTC_NOTREACHED() << "Invalid extension type: " << type;
     489           0 :           return;
     490             :         }
     491             :       }
     492             :     }
     493           0 :     ptr += (len + 1);
     494             :   }
     495             : }
     496             : 
     497             : }  // namespace RtpUtility
     498             : }  // namespace webrtc

Generated by: LCOV version 1.13