Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" | 11 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" |
| 12 | 12 |
| 13 #include <assert.h> | 13 #include <assert.h> |
| 14 #include <math.h> // ceil | 14 #include <math.h> // ceil |
| 15 #include <string.h> // memcpy | 15 #include <string.h> // memcpy |
| 16 | 16 |
| 17 #include "webrtc/base/checks.h" | |
| 18 #include "webrtc/base/logging.h" | |
| 19 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | |
| 20 | |
| 17 namespace webrtc { | 21 namespace webrtc { |
| 18 | 22 |
| 19 namespace RTCPUtility { | 23 namespace RTCPUtility { |
| 20 | 24 |
| 21 NackStats::NackStats() | 25 NackStats::NackStats() |
| 22 : max_sequence_number_(0), | 26 : max_sequence_number_(0), |
| 23 requests_(0), | 27 requests_(0), |
| 24 unique_requests_(0) {} | 28 unique_requests_(0) {} |
| 25 | 29 |
| 26 NackStats::~NackStats() {} | 30 NackStats::~NackStats() {} |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 } | 152 } |
| 149 } | 153 } |
| 150 return _packetType; | 154 return _packetType; |
| 151 } | 155 } |
| 152 | 156 |
| 153 void | 157 void |
| 154 RTCPUtility::RTCPParserV2::IterateTopLevel() | 158 RTCPUtility::RTCPParserV2::IterateTopLevel() |
| 155 { | 159 { |
| 156 for (;;) | 160 for (;;) |
| 157 { | 161 { |
| 158 RTCPCommonHeader header; | 162 RtcpCommonHeader header; |
| 163 size_t bytes_left = _ptrRTCPDataEnd - _ptrRTCPData; | |
| 164 if (bytes_left == 0) | |
|
åsapersson
2015/09/08 10:20:42
checked within RtcpParseCommonHeader?
sprang_webrtc
2015/09/09 09:18:54
I think it would be better for RtcpParseCommonHead
| |
| 165 return; | |
| 159 | 166 |
| 160 const bool success = RTCPParseCommonHeader(_ptrRTCPData, | 167 if (!RtcpParseCommonHeader(_ptrRTCPData, 0, bytes_left, &header)) { |
| 161 _ptrRTCPDataEnd, | |
| 162 header); | |
| 163 | |
| 164 if (!success) | |
| 165 { | |
| 166 return; | 168 return; |
| 167 } | 169 } |
| 168 _ptrRTCPBlockEnd = _ptrRTCPData + header.LengthInOctets; | 170 _ptrRTCPBlockEnd = _ptrRTCPData + header.BlockSize(); |
| 169 if (_ptrRTCPBlockEnd > _ptrRTCPDataEnd) | 171 if (_ptrRTCPBlockEnd > _ptrRTCPDataEnd) |
| 170 { | 172 { |
| 171 // Bad block! | 173 // Bad block! |
| 172 return; | 174 return; |
| 173 } | 175 } |
| 174 | 176 |
| 175 switch (header.PT) | 177 switch (header.packet_type) { |
| 176 { | |
| 177 case PT_SR: | 178 case PT_SR: |
| 178 { | 179 { |
| 179 // number of Report blocks | 180 // number of Report blocks |
| 180 _numberOfBlocks = header.IC; | 181 _numberOfBlocks = header.count_or_format; |
| 181 ParseSR(); | 182 ParseSR(); |
| 182 return; | 183 return; |
| 183 } | 184 } |
| 184 case PT_RR: | 185 case PT_RR: |
| 185 { | 186 { |
| 186 // number of Report blocks | 187 // number of Report blocks |
| 187 _numberOfBlocks = header.IC; | 188 _numberOfBlocks = header.count_or_format; |
| 188 ParseRR(); | 189 ParseRR(); |
| 189 return; | 190 return; |
| 190 } | 191 } |
| 191 case PT_SDES: | 192 case PT_SDES: |
| 192 { | 193 { |
| 193 // number of SDES blocks | 194 // number of SDES blocks |
| 194 _numberOfBlocks = header.IC; | 195 _numberOfBlocks = header.count_or_format; |
| 195 const bool ok = ParseSDES(); | 196 const bool ok = ParseSDES(); |
| 196 if (!ok) | 197 if (!ok) |
| 197 { | 198 { |
| 198 // Nothing supported found, continue to next block! | 199 // Nothing supported found, continue to next block! |
| 199 break; | 200 break; |
| 200 } | 201 } |
| 201 return; | 202 return; |
| 202 } | 203 } |
| 203 case PT_BYE: | 204 case PT_BYE: |
| 204 { | 205 { |
| 205 _numberOfBlocks = header.IC; | 206 _numberOfBlocks = header.count_or_format; |
| 206 const bool ok = ParseBYE(); | 207 const bool ok = ParseBYE(); |
| 207 if (!ok) | 208 if (!ok) |
| 208 { | 209 { |
| 209 // Nothing supported found, continue to next block! | 210 // Nothing supported found, continue to next block! |
| 210 break; | 211 break; |
| 211 } | 212 } |
| 212 return; | 213 return; |
| 213 } | 214 } |
| 214 case PT_IJ: | 215 case PT_IJ: |
| 215 { | 216 { |
| 216 // number of Report blocks | 217 // number of Report blocks |
| 217 _numberOfBlocks = header.IC; | 218 _numberOfBlocks = header.count_or_format; |
| 218 ParseIJ(); | 219 ParseIJ(); |
| 219 return; | 220 return; |
| 220 } | 221 } |
| 221 case PT_RTPFB: // Fall through! | 222 case PT_RTPFB: // Fall through! |
| 222 case PT_PSFB: | 223 case PT_PSFB: |
| 223 { | 224 { |
| 224 const bool ok = ParseFBCommon(header); | 225 const bool ok = ParseFBCommon(header); |
| 225 if (!ok) | 226 if (!ok) |
| 226 { | 227 { |
| 227 // Nothing supported found, continue to next block! | 228 // Nothing supported found, continue to next block! |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 408 } | 409 } |
| 409 | 410 |
| 410 void | 411 void |
| 411 RTCPUtility::RTCPParserV2::Validate() | 412 RTCPUtility::RTCPParserV2::Validate() |
| 412 { | 413 { |
| 413 if (_ptrRTCPData == NULL) | 414 if (_ptrRTCPData == NULL) |
| 414 { | 415 { |
| 415 return; // NOT VALID | 416 return; // NOT VALID |
| 416 } | 417 } |
| 417 | 418 |
| 418 RTCPCommonHeader header; | 419 RtcpCommonHeader header; |
| 419 const bool success = RTCPParseCommonHeader(_ptrRTCPDataBegin, | 420 const bool success = RtcpParseCommonHeader( |
|
åsapersson
2015/09/08 10:20:42
could _ptrRTCPDataBegin be larger than _ptrRTCPDat
sprang_webrtc
2015/09/09 09:18:54
It shouldn't, but I can add a check anyway.
| |
| 420 _ptrRTCPDataEnd, | 421 _ptrRTCPDataBegin, 0, _ptrRTCPDataEnd - _ptrRTCPDataBegin, &header); |
| 421 header); | |
| 422 | 422 |
| 423 if (!success) | 423 if (!success) |
| 424 { | 424 { |
| 425 return; // NOT VALID! | 425 return; // NOT VALID! |
| 426 } | 426 } |
| 427 | 427 |
| 428 // * if (!reducedSize) : first packet must be RR or SR. | 428 // * if (!reducedSize) : first packet must be RR or SR. |
| 429 // | 429 // |
| 430 // * The padding bit (P) should be zero for the first packet of a | 430 // * The padding bit (P) should be zero for the first packet of a |
| 431 // compound RTCP packet because padding should only be applied, | 431 // compound RTCP packet because padding should only be applied, |
| 432 // if it is needed, to the last packet. (NOT CHECKED!) | 432 // if it is needed, to the last packet. (NOT CHECKED!) |
| 433 // | 433 // |
| 434 // * The length fields of the individual RTCP packets must add up | 434 // * The length fields of the individual RTCP packets must add up |
| 435 // to the overall length of the compound RTCP packet as | 435 // to the overall length of the compound RTCP packet as |
| 436 // received. This is a fairly strong check. (NOT CHECKED!) | 436 // received. This is a fairly strong check. (NOT CHECKED!) |
| 437 | 437 |
| 438 if (!_RTCPReducedSizeEnable) | 438 if (!_RTCPReducedSizeEnable) |
| 439 { | 439 { |
| 440 if ((header.PT != PT_SR) && (header.PT != PT_RR)) | 440 if ((header.packet_type != PT_SR) && (header.packet_type != PT_RR)) { |
| 441 { | |
| 442 return; // NOT VALID | 441 return; // NOT VALID |
| 443 } | 442 } |
| 444 } | 443 } |
| 445 | 444 |
| 446 _validPacket = true; | 445 _validPacket = true; |
| 447 } | 446 } |
| 448 | 447 |
| 449 bool | 448 bool |
| 450 RTCPUtility::RTCPParserV2::IsValid() const | 449 RTCPUtility::RTCPParserV2::IsValid() const |
| 451 { | 450 { |
| 452 return _validPacket; | 451 return _validPacket; |
| 453 } | 452 } |
| 454 | 453 |
| 455 void | 454 void |
| 456 RTCPUtility::RTCPParserV2::EndCurrentBlock() | 455 RTCPUtility::RTCPParserV2::EndCurrentBlock() |
| 457 { | 456 { |
| 458 _ptrRTCPData = _ptrRTCPBlockEnd; | 457 _ptrRTCPData = _ptrRTCPBlockEnd; |
| 459 } | 458 } |
| 460 | 459 |
| 461 bool | 460 // 0 1 2 3 |
| 462 RTCPUtility::RTCPParseCommonHeader( const uint8_t* ptrDataBegin, | 461 // 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 |
| 463 const uint8_t* ptrDataEnd, | 462 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 464 RTCPCommonHeader& parsedHeader) | 463 // |V=2|P| IC | PT | length | |
| 465 { | 464 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 466 if (!ptrDataBegin || !ptrDataEnd) | 465 // |
| 467 { | 466 // Common header for all RTCP packets, 4 octets. |
| 468 return false; | 467 |
| 468 bool RTCPUtility::RtcpParseCommonHeader(const uint8_t* packet, | |
| 469 size_t index, | |
| 470 size_t max_length, | |
|
åsapersson
2015/09/08 10:20:42
maybe remove index
sprang_webrtc
2015/09/09 09:18:54
Ok. I use an offset in other upcoming CL's but I c
| |
| 471 RtcpCommonHeader* parsed_header) { | |
| 472 DCHECK(parsed_header != nullptr); | |
| 473 size_t length = max_length - index; | |
|
åsapersson
2015/09/08 10:20:42
what if index > max_length
sprang_webrtc
2015/09/09 09:18:54
Removed index.
| |
| 474 const size_t kHeaderLength = 4; | |
| 475 if (length < kHeaderLength) { | |
| 476 LOG(LS_WARNING) << "Too little data (" << length << " byte" | |
| 477 << (length != 1 ? "s" : "") | |
| 478 << ") remaining in buffer to parse RTCP header (4 bytes)."; | |
| 479 return false; | |
| 480 } | |
| 481 | |
| 482 const uint8_t kRtcpVersion = 2; | |
| 483 uint8_t version = packet[index] >> 6; | |
| 484 if (version != kRtcpVersion) { | |
| 485 LOG(LS_WARNING) << "Invalid RTCP header: Version must be " << kRtcpVersion | |
| 486 << " but was " << version; | |
| 487 return false; | |
| 488 } | |
| 489 | |
| 490 bool has_padding = (packet[index] & 0x20) != 0; | |
| 491 uint8_t format = packet[index] & 0x1F; | |
| 492 uint8_t packet_type = packet[index + 1]; | |
| 493 size_t packet_size_words = | |
| 494 ByteReader<uint16_t>::ReadBigEndian(&packet[index + 2]) + 1; | |
| 495 | |
| 496 if (length < packet_size_words * 4) { | |
| 497 LOG(LS_WARNING) << "Buffer too small (" << length | |
| 498 << " bytes) to fit a FeedbackPacket of " | |
|
åsapersson
2015/09/08 10:20:42
remove FeedbackPacket in comment
sprang_webrtc
2015/09/09 09:18:54
Done.
| |
| 499 << packet_size_words << " 32bit words."; | |
| 500 return false; | |
| 501 } | |
| 502 | |
| 503 size_t payload_size = packet_size_words * 4; | |
| 504 uint8_t padding_bytes = 0; | |
| 505 if (has_padding) { | |
| 506 padding_bytes = packet[index + payload_size - 1]; | |
| 507 if (kHeaderLength + padding_bytes > payload_size) { | |
| 508 LOG(LS_WARNING) << "Invalid RTCP header: Too many padding bytes (" | |
| 509 << padding_bytes << ") for a packet size of " | |
| 510 << payload_size << "bytes."; | |
| 511 return false; | |
| 469 } | 512 } |
| 513 payload_size -= padding_bytes; | |
| 514 } | |
| 515 payload_size -= kHeaderLength; | |
| 470 | 516 |
| 471 // 0 1 2 3 | 517 parsed_header->version = kRtcpVersion; |
| 472 // 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 | 518 parsed_header->count_or_format = format; |
| 473 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 519 parsed_header->packet_type = packet_type; |
| 474 // |V=2|P| IC | PT | length | | 520 parsed_header->payload_size_bytes = payload_size; |
| 475 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 521 parsed_header->padding_bytes = padding_bytes; |
| 476 // | |
| 477 // Common header for all RTCP packets, 4 octets. | |
| 478 | 522 |
| 479 if ((ptrDataEnd - ptrDataBegin) < 4) | 523 return true; |
| 480 { | |
| 481 return false; | |
| 482 } | |
| 483 | |
| 484 parsedHeader.V = ptrDataBegin[0] >> 6; | |
| 485 parsedHeader.P = ((ptrDataBegin[0] & 0x20) == 0) ? false : true ; | |
| 486 parsedHeader.IC = ptrDataBegin[0] & 0x1f; | |
| 487 parsedHeader.PT = ptrDataBegin[1]; | |
| 488 | |
| 489 parsedHeader.LengthInOctets = (ptrDataBegin[2] << 8) + ptrDataBegin[3] + 1; | |
| 490 parsedHeader.LengthInOctets *= 4; | |
| 491 | |
| 492 if(parsedHeader.LengthInOctets == 0) | |
| 493 { | |
| 494 return false; | |
| 495 } | |
| 496 // Check if RTP version field == 2 | |
| 497 if (parsedHeader.V != 2) | |
| 498 { | |
| 499 return false; | |
| 500 } | |
| 501 | |
| 502 return true; | |
| 503 } | 524 } |
| 504 | 525 |
| 505 bool | 526 bool |
| 506 RTCPUtility::RTCPParserV2::ParseRR() | 527 RTCPUtility::RTCPParserV2::ParseRR() |
| 507 { | 528 { |
| 508 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | 529 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; |
| 509 | 530 |
| 510 if (length < 8) | 531 if (length < 8) |
| 511 { | 532 { |
| 512 return false; | 533 return false; |
| (...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1130 _state = ParseState::State_TopLevel; | 1151 _state = ParseState::State_TopLevel; |
| 1131 EndCurrentBlock(); | 1152 EndCurrentBlock(); |
| 1132 return false; | 1153 return false; |
| 1133 } | 1154 } |
| 1134 // Skip block. | 1155 // Skip block. |
| 1135 _ptrRTCPData += kBlockLengthInBytes; | 1156 _ptrRTCPData += kBlockLengthInBytes; |
| 1136 _state = ParseState::State_XRItem; | 1157 _state = ParseState::State_XRItem; |
| 1137 return false; | 1158 return false; |
| 1138 } | 1159 } |
| 1139 | 1160 |
| 1140 bool | 1161 bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) { |
| 1141 RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header) | 1162 assert((header.packet_type == PT_RTPFB) || |
| 1142 { | 1163 (header.packet_type == PT_PSFB)); // Parser logic check |
| 1143 assert((header.PT == PT_RTPFB) || (header.PT == PT_PSFB)); // Parser logic c heck | |
| 1144 | 1164 |
| 1145 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | 1165 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; |
| 1146 | 1166 |
| 1147 if (length < 12) // 4 * 3, RFC4585 section 6.1 | 1167 if (length < 12) // 4 * 3, RFC4585 section 6.1 |
| 1148 { | 1168 { |
| 1149 EndCurrentBlock(); | 1169 EndCurrentBlock(); |
| 1150 return false; | 1170 return false; |
| 1151 } | 1171 } |
| 1152 | 1172 |
| 1153 _ptrRTCPData += 4; // Skip RTCP header | 1173 _ptrRTCPData += 4; // Skip RTCP header |
| 1154 | 1174 |
| 1155 uint32_t senderSSRC = *_ptrRTCPData++ << 24; | 1175 uint32_t senderSSRC = *_ptrRTCPData++ << 24; |
| 1156 senderSSRC += *_ptrRTCPData++ << 16; | 1176 senderSSRC += *_ptrRTCPData++ << 16; |
| 1157 senderSSRC += *_ptrRTCPData++ << 8; | 1177 senderSSRC += *_ptrRTCPData++ << 8; |
| 1158 senderSSRC += *_ptrRTCPData++; | 1178 senderSSRC += *_ptrRTCPData++; |
| 1159 | 1179 |
| 1160 uint32_t mediaSSRC = *_ptrRTCPData++ << 24; | 1180 uint32_t mediaSSRC = *_ptrRTCPData++ << 24; |
| 1161 mediaSSRC += *_ptrRTCPData++ << 16; | 1181 mediaSSRC += *_ptrRTCPData++ << 16; |
| 1162 mediaSSRC += *_ptrRTCPData++ << 8; | 1182 mediaSSRC += *_ptrRTCPData++ << 8; |
| 1163 mediaSSRC += *_ptrRTCPData++; | 1183 mediaSSRC += *_ptrRTCPData++; |
| 1164 | 1184 |
| 1165 if (header.PT == PT_RTPFB) | 1185 if (header.packet_type == PT_RTPFB) { |
| 1166 { | |
| 1167 // Transport layer feedback | 1186 // Transport layer feedback |
| 1168 | 1187 |
| 1169 switch (header.IC) | 1188 switch (header.count_or_format) { |
| 1170 { | |
| 1171 case 1: | 1189 case 1: |
| 1172 { | 1190 { |
| 1173 // NACK | 1191 // NACK |
| 1174 _packetType = RTCPPacketTypes::kRtpfbNack; | 1192 _packetType = RTCPPacketTypes::kRtpfbNack; |
| 1175 _packet.NACK.SenderSSRC = senderSSRC; | 1193 _packet.NACK.SenderSSRC = senderSSRC; |
| 1176 _packet.NACK.MediaSSRC = mediaSSRC; | 1194 _packet.NACK.MediaSSRC = mediaSSRC; |
| 1177 | 1195 |
| 1178 _state = ParseState::State_RTPFB_NACKItem; | 1196 _state = ParseState::State_RTPFB_NACKItem; |
| 1179 | 1197 |
| 1180 return true; | 1198 return true; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1215 _packetType = RTCPPacketTypes::kRtpfbSrReq; | 1233 _packetType = RTCPPacketTypes::kRtpfbSrReq; |
| 1216 | 1234 |
| 1217 // Note: No state transition, SR REQ is empty! | 1235 // Note: No state transition, SR REQ is empty! |
| 1218 return true; | 1236 return true; |
| 1219 } | 1237 } |
| 1220 default: | 1238 default: |
| 1221 break; | 1239 break; |
| 1222 } | 1240 } |
| 1223 EndCurrentBlock(); | 1241 EndCurrentBlock(); |
| 1224 return false; | 1242 return false; |
| 1225 } | 1243 } else if (header.packet_type == PT_PSFB) { |
| 1226 else if (header.PT == PT_PSFB) | |
| 1227 { | |
| 1228 // Payload specific feedback | 1244 // Payload specific feedback |
| 1229 switch (header.IC) | 1245 switch (header.count_or_format) { |
| 1230 { | |
| 1231 case 1: | 1246 case 1: |
| 1232 // PLI | 1247 // PLI |
| 1233 _packetType = RTCPPacketTypes::kPsfbPli; | 1248 _packetType = RTCPPacketTypes::kPsfbPli; |
| 1234 _packet.PLI.SenderSSRC = senderSSRC; | 1249 _packet.PLI.SenderSSRC = senderSSRC; |
| 1235 _packet.PLI.MediaSSRC = mediaSSRC; | 1250 _packet.PLI.MediaSSRC = mediaSSRC; |
| 1236 | 1251 |
| 1237 // Note: No state transition, PLI FCI is empty! | 1252 // Note: No state transition, PLI FCI is empty! |
| 1238 return true; | 1253 return true; |
| 1239 case 2: | 1254 case 2: |
| 1240 // SLI | 1255 // SLI |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1572 _packet.FIRItem.SSRC = *_ptrRTCPData++ << 24; | 1587 _packet.FIRItem.SSRC = *_ptrRTCPData++ << 24; |
| 1573 _packet.FIRItem.SSRC += *_ptrRTCPData++ << 16; | 1588 _packet.FIRItem.SSRC += *_ptrRTCPData++ << 16; |
| 1574 _packet.FIRItem.SSRC += *_ptrRTCPData++ << 8; | 1589 _packet.FIRItem.SSRC += *_ptrRTCPData++ << 8; |
| 1575 _packet.FIRItem.SSRC += *_ptrRTCPData++; | 1590 _packet.FIRItem.SSRC += *_ptrRTCPData++; |
| 1576 | 1591 |
| 1577 _packet.FIRItem.CommandSequenceNumber = *_ptrRTCPData++; | 1592 _packet.FIRItem.CommandSequenceNumber = *_ptrRTCPData++; |
| 1578 _ptrRTCPData += 3; // Skip "Reserved" bytes. | 1593 _ptrRTCPData += 3; // Skip "Reserved" bytes. |
| 1579 return true; | 1594 return true; |
| 1580 } | 1595 } |
| 1581 | 1596 |
| 1582 bool | 1597 bool RTCPUtility::RTCPParserV2::ParseAPP(const RtcpCommonHeader& header) { |
| 1583 RTCPUtility::RTCPParserV2::ParseAPP( const RTCPCommonHeader& header) | |
| 1584 { | |
| 1585 ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | 1598 ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; |
| 1586 | 1599 |
| 1587 if (length < 12) // 4 * 3, RFC 3550 6.7 APP: Application-Defined RTCP Packet | 1600 if (length < 12) // 4 * 3, RFC 3550 6.7 APP: Application-Defined RTCP Packet |
| 1588 { | 1601 { |
| 1589 EndCurrentBlock(); | 1602 EndCurrentBlock(); |
| 1590 return false; | 1603 return false; |
| 1591 } | 1604 } |
| 1592 | 1605 |
| 1593 _ptrRTCPData += 4; // Skip RTCP header | 1606 _ptrRTCPData += 4; // Skip RTCP header |
| 1594 | 1607 |
| 1595 uint32_t senderSSRC = *_ptrRTCPData++ << 24; | 1608 uint32_t senderSSRC = *_ptrRTCPData++ << 24; |
| 1596 senderSSRC += *_ptrRTCPData++ << 16; | 1609 senderSSRC += *_ptrRTCPData++ << 16; |
| 1597 senderSSRC += *_ptrRTCPData++ << 8; | 1610 senderSSRC += *_ptrRTCPData++ << 8; |
| 1598 senderSSRC += *_ptrRTCPData++; | 1611 senderSSRC += *_ptrRTCPData++; |
| 1599 | 1612 |
| 1600 uint32_t name = *_ptrRTCPData++ << 24; | 1613 uint32_t name = *_ptrRTCPData++ << 24; |
| 1601 name += *_ptrRTCPData++ << 16; | 1614 name += *_ptrRTCPData++ << 16; |
| 1602 name += *_ptrRTCPData++ << 8; | 1615 name += *_ptrRTCPData++ << 8; |
| 1603 name += *_ptrRTCPData++; | 1616 name += *_ptrRTCPData++; |
| 1604 | 1617 |
| 1605 length = _ptrRTCPBlockEnd - _ptrRTCPData; | 1618 length = _ptrRTCPBlockEnd - _ptrRTCPData; |
| 1606 | 1619 |
| 1607 _packetType = RTCPPacketTypes::kApp; | 1620 _packetType = RTCPPacketTypes::kApp; |
| 1608 | 1621 |
| 1609 _packet.APP.SubType = header.IC; | 1622 _packet.APP.SubType = header.count_or_format; |
| 1610 _packet.APP.Name = name; | 1623 _packet.APP.Name = name; |
| 1611 | 1624 |
| 1612 _state = ParseState::State_AppItem; | 1625 _state = ParseState::State_AppItem; |
| 1613 return true; | 1626 return true; |
| 1614 } | 1627 } |
| 1615 | 1628 |
| 1616 bool | 1629 bool |
| 1617 RTCPUtility::RTCPParserV2::ParseAPPItem() | 1630 RTCPUtility::RTCPParserV2::ParseAPPItem() |
| 1618 { | 1631 { |
| 1619 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | 1632 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1644 size_t rtcpDataLength) | 1657 size_t rtcpDataLength) |
| 1645 : _ptrBegin(rtcpData), | 1658 : _ptrBegin(rtcpData), |
| 1646 _ptrEnd(rtcpData + rtcpDataLength), | 1659 _ptrEnd(rtcpData + rtcpDataLength), |
| 1647 _ptrBlock(NULL) { | 1660 _ptrBlock(NULL) { |
| 1648 memset(&_header, 0, sizeof(_header)); | 1661 memset(&_header, 0, sizeof(_header)); |
| 1649 } | 1662 } |
| 1650 | 1663 |
| 1651 RTCPUtility::RTCPPacketIterator::~RTCPPacketIterator() { | 1664 RTCPUtility::RTCPPacketIterator::~RTCPPacketIterator() { |
| 1652 } | 1665 } |
| 1653 | 1666 |
| 1654 const RTCPUtility::RTCPCommonHeader* | 1667 const RTCPUtility::RtcpCommonHeader* RTCPUtility::RTCPPacketIterator::Begin() { |
| 1655 RTCPUtility::RTCPPacketIterator::Begin() | |
| 1656 { | |
| 1657 _ptrBlock = _ptrBegin; | 1668 _ptrBlock = _ptrBegin; |
| 1658 | 1669 |
| 1659 return Iterate(); | 1670 return Iterate(); |
| 1660 } | 1671 } |
| 1661 | 1672 |
| 1662 const RTCPUtility::RTCPCommonHeader* | 1673 const RTCPUtility::RtcpCommonHeader* |
| 1663 RTCPUtility::RTCPPacketIterator::Iterate() | 1674 RTCPUtility::RTCPPacketIterator::Iterate() { |
| 1664 { | 1675 const bool success = |
| 1665 const bool success = RTCPParseCommonHeader(_ptrBlock, _ptrEnd, _header); | 1676 RtcpParseCommonHeader(_ptrBlock, 0, _ptrEnd - _ptrBlock, &_header); |
| 1666 if (!success) | 1677 if (!success) |
| 1667 { | 1678 { |
| 1668 _ptrBlock = NULL; | 1679 _ptrBlock = NULL; |
| 1669 return NULL; | 1680 return NULL; |
| 1670 } | 1681 } |
| 1671 _ptrBlock += _header.LengthInOctets; | 1682 _ptrBlock += _header.BlockSize(); |
| 1672 | 1683 |
| 1673 if (_ptrBlock > _ptrEnd) | 1684 if (_ptrBlock > _ptrEnd) |
| 1674 { | 1685 { |
| 1675 _ptrBlock = NULL; | 1686 _ptrBlock = NULL; |
| 1676 return NULL; | 1687 return NULL; |
| 1677 } | 1688 } |
| 1678 | 1689 |
| 1679 return &_header; | 1690 return &_header; |
| 1680 } | 1691 } |
| 1681 | 1692 |
| 1682 const RTCPUtility::RTCPCommonHeader* | 1693 const RTCPUtility::RtcpCommonHeader* |
| 1683 RTCPUtility::RTCPPacketIterator::Current() | 1694 RTCPUtility::RTCPPacketIterator::Current() { |
| 1684 { | |
| 1685 if (!_ptrBlock) | 1695 if (!_ptrBlock) |
| 1686 { | 1696 { |
| 1687 return NULL; | 1697 return NULL; |
| 1688 } | 1698 } |
| 1689 | 1699 |
| 1690 return &_header; | 1700 return &_header; |
| 1691 } | 1701 } |
| 1692 } // namespace webrtc | 1702 } // namespace webrtc |
| OLD | NEW |