| 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/base/checks.h" |
| 11 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" | 12 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" |
| 13 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |
| 12 | 14 |
| 13 #include <assert.h> | 15 #include <assert.h> |
| 14 #include <math.h> // ceil | 16 #include <math.h> // ceil |
| 15 #include <string.h> // memcpy | 17 #include <string.h> // memcpy |
| 16 | 18 |
| 17 #include "webrtc/base/checks.h" | 19 #include "webrtc/base/checks.h" |
| 18 #include "webrtc/base/logging.h" | 20 #include "webrtc/base/logging.h" |
| 19 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 21 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| 20 | 22 |
| 21 namespace webrtc { | 23 namespace webrtc { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 48 size_t rtcpDataLength, | 50 size_t rtcpDataLength, |
| 49 bool rtcpReducedSizeEnable) | 51 bool rtcpReducedSizeEnable) |
| 50 : _ptrRTCPDataBegin(rtcpData), | 52 : _ptrRTCPDataBegin(rtcpData), |
| 51 _RTCPReducedSizeEnable(rtcpReducedSizeEnable), | 53 _RTCPReducedSizeEnable(rtcpReducedSizeEnable), |
| 52 _ptrRTCPDataEnd(rtcpData + rtcpDataLength), | 54 _ptrRTCPDataEnd(rtcpData + rtcpDataLength), |
| 53 _validPacket(false), | 55 _validPacket(false), |
| 54 _ptrRTCPData(rtcpData), | 56 _ptrRTCPData(rtcpData), |
| 55 _ptrRTCPBlockEnd(NULL), | 57 _ptrRTCPBlockEnd(NULL), |
| 56 _state(ParseState::State_TopLevel), | 58 _state(ParseState::State_TopLevel), |
| 57 _numberOfBlocks(0), | 59 _numberOfBlocks(0), |
| 60 num_skipped_blocks_(0), |
| 58 _packetType(RTCPPacketTypes::kInvalid) { | 61 _packetType(RTCPPacketTypes::kInvalid) { |
| 59 Validate(); | 62 Validate(); |
| 60 } | 63 } |
| 61 | 64 |
| 62 RTCPUtility::RTCPParserV2::~RTCPParserV2() { | 65 RTCPUtility::RTCPParserV2::~RTCPParserV2() { |
| 63 } | 66 } |
| 64 | 67 |
| 65 ptrdiff_t | 68 ptrdiff_t |
| 66 RTCPUtility::RTCPParserV2::LengthLeft() const | 69 RTCPUtility::RTCPParserV2::LengthLeft() const |
| 67 { | 70 { |
| 68 return (_ptrRTCPDataEnd- _ptrRTCPData); | 71 return (_ptrRTCPDataEnd- _ptrRTCPData); |
| 69 } | 72 } |
| 70 | 73 |
| 71 RTCPUtility::RTCPPacketTypes | 74 RTCPUtility::RTCPPacketTypes |
| 72 RTCPUtility::RTCPParserV2::PacketType() const | 75 RTCPUtility::RTCPParserV2::PacketType() const |
| 73 { | 76 { |
| 74 return _packetType; | 77 return _packetType; |
| 75 } | 78 } |
| 76 | 79 |
| 77 const RTCPUtility::RTCPPacket& | 80 const RTCPUtility::RTCPPacket& |
| 78 RTCPUtility::RTCPParserV2::Packet() const | 81 RTCPUtility::RTCPParserV2::Packet() const |
| 79 { | 82 { |
| 80 return _packet; | 83 return _packet; |
| 81 } | 84 } |
| 82 | 85 |
| 86 rtcp::RtcpPacket* RTCPUtility::RTCPParserV2::ReleaseRtcpPacket() { |
| 87 return rtcp_packet_.release(); |
| 88 } |
| 83 RTCPUtility::RTCPPacketTypes | 89 RTCPUtility::RTCPPacketTypes |
| 84 RTCPUtility::RTCPParserV2::Begin() | 90 RTCPUtility::RTCPParserV2::Begin() |
| 85 { | 91 { |
| 86 _ptrRTCPData = _ptrRTCPDataBegin; | 92 _ptrRTCPData = _ptrRTCPDataBegin; |
| 87 | 93 |
| 88 return Iterate(); | 94 return Iterate(); |
| 89 } | 95 } |
| 90 | 96 |
| 91 RTCPUtility::RTCPPacketTypes | 97 RTCPUtility::RTCPPacketTypes |
| 92 RTCPUtility::RTCPParserV2::Iterate() | 98 RTCPUtility::RTCPParserV2::Iterate() |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 case ParseState::State_XRItem: | 146 case ParseState::State_XRItem: |
| 141 IterateXrItem(); | 147 IterateXrItem(); |
| 142 break; | 148 break; |
| 143 case ParseState::State_XR_DLLRItem: | 149 case ParseState::State_XR_DLLRItem: |
| 144 IterateXrDlrrItem(); | 150 IterateXrDlrrItem(); |
| 145 break; | 151 break; |
| 146 case ParseState::State_AppItem: | 152 case ParseState::State_AppItem: |
| 147 IterateAppItem(); | 153 IterateAppItem(); |
| 148 break; | 154 break; |
| 149 default: | 155 default: |
| 150 assert(false); // Invalid state! | 156 RTC_NOTREACHED() << "Invalid state!"; |
| 151 break; | 157 break; |
| 152 } | 158 } |
| 153 } | 159 } |
| 154 return _packetType; | 160 return _packetType; |
| 155 } | 161 } |
| 156 | 162 |
| 157 void | 163 void |
| 158 RTCPUtility::RTCPParserV2::IterateTopLevel() | 164 RTCPUtility::RTCPParserV2::IterateTopLevel() |
| 159 { | 165 { |
| 160 for (;;) | 166 for (;;) |
| 161 { | 167 { |
| 162 RtcpCommonHeader header; | 168 RtcpCommonHeader header; |
| 163 if (_ptrRTCPDataEnd <= _ptrRTCPData) | 169 if (_ptrRTCPDataEnd <= _ptrRTCPData) |
| 164 return; | 170 return; |
| 165 | 171 |
| 166 if (!RtcpParseCommonHeader(_ptrRTCPData, _ptrRTCPDataEnd - _ptrRTCPData, | 172 if (!RtcpParseCommonHeader(_ptrRTCPData, _ptrRTCPDataEnd - _ptrRTCPData, |
| 167 &header)) { | 173 &header)) { |
| 168 return; | 174 return; |
| 169 } | 175 } |
| 170 _ptrRTCPBlockEnd = _ptrRTCPData + header.BlockSize(); | 176 _ptrRTCPBlockEnd = _ptrRTCPData + header.BlockSize(); |
| 171 if (_ptrRTCPBlockEnd > _ptrRTCPDataEnd) | 177 if (_ptrRTCPBlockEnd > _ptrRTCPDataEnd) |
| 172 { | 178 { |
| 173 // Bad block! | 179 ++num_skipped_blocks_; |
| 174 return; | 180 return; |
| 175 } | 181 } |
| 176 | 182 |
| 177 switch (header.packet_type) { | 183 switch (header.packet_type) { |
| 178 case PT_SR: | 184 case PT_SR: |
| 179 { | 185 { |
| 180 // number of Report blocks | 186 // number of Report blocks |
| 181 _numberOfBlocks = header.count_or_format; | 187 _numberOfBlocks = header.count_or_format; |
| 182 ParseSR(); | 188 ParseSR(); |
| 183 return; | 189 return; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 212 } | 218 } |
| 213 return; | 219 return; |
| 214 } | 220 } |
| 215 case PT_IJ: | 221 case PT_IJ: |
| 216 { | 222 { |
| 217 // number of Report blocks | 223 // number of Report blocks |
| 218 _numberOfBlocks = header.count_or_format; | 224 _numberOfBlocks = header.count_or_format; |
| 219 ParseIJ(); | 225 ParseIJ(); |
| 220 return; | 226 return; |
| 221 } | 227 } |
| 222 case PT_RTPFB: // Fall through! | 228 case PT_RTPFB: |
| 229 FALLTHROUGH(); |
| 223 case PT_PSFB: | 230 case PT_PSFB: |
| 224 { | 231 { |
| 225 const bool ok = ParseFBCommon(header); | 232 if (!ParseFBCommon(header)) { |
| 226 if (!ok) | 233 // Nothing supported found, continue to next block! |
| 227 { | 234 break; |
| 228 // Nothing supported found, continue to next block! | 235 } |
| 229 break; | 236 return; |
| 230 } | |
| 231 return; | |
| 232 } | 237 } |
| 233 case PT_APP: | 238 case PT_APP: |
| 234 { | 239 { |
| 235 const bool ok = ParseAPP(header); | 240 const bool ok = ParseAPP(header); |
| 236 if (!ok) | 241 if (!ok) |
| 237 { | 242 { |
| 238 // Nothing supported found, continue to next block! | 243 // Nothing supported found, continue to next block! |
| 239 break; | 244 break; |
| 240 } | 245 } |
| 241 return; | 246 return; |
| 242 } | 247 } |
| 243 case PT_XR: | 248 case PT_XR: |
| 244 { | 249 { |
| 245 const bool ok = ParseXr(); | 250 const bool ok = ParseXr(); |
| 246 if (!ok) | 251 if (!ok) |
| 247 { | 252 { |
| 248 // Nothing supported found, continue to next block! | 253 // Nothing supported found, continue to next block! |
| 249 break; | 254 break; |
| 250 } | 255 } |
| 251 return; | 256 return; |
| 252 } | 257 } |
| 253 default: | 258 default: |
| 254 // Not supported! Skip! | 259 // Not supported! Skip! |
| 260 ++num_skipped_blocks_; |
| 255 EndCurrentBlock(); | 261 EndCurrentBlock(); |
| 256 break; | 262 break; |
| 257 } | 263 } |
| 258 } | 264 } |
| 259 } | 265 } |
| 260 | 266 |
| 261 void | 267 void |
| 262 RTCPUtility::RTCPParserV2::IterateXrItem() | 268 RTCPUtility::RTCPParserV2::IterateXrItem() |
| 263 { | 269 { |
| 264 const bool success = ParseXrItem(); | 270 const bool success = ParseXrItem(); |
| (...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1153 EndCurrentBlock(); | 1159 EndCurrentBlock(); |
| 1154 return false; | 1160 return false; |
| 1155 } | 1161 } |
| 1156 // Skip block. | 1162 // Skip block. |
| 1157 _ptrRTCPData += kBlockLengthInBytes; | 1163 _ptrRTCPData += kBlockLengthInBytes; |
| 1158 _state = ParseState::State_XRItem; | 1164 _state = ParseState::State_XRItem; |
| 1159 return false; | 1165 return false; |
| 1160 } | 1166 } |
| 1161 | 1167 |
| 1162 bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) { | 1168 bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) { |
| 1163 assert((header.packet_type == PT_RTPFB) || | 1169 RTC_CHECK((header.packet_type == PT_RTPFB) || |
| 1164 (header.packet_type == PT_PSFB)); // Parser logic check | 1170 (header.packet_type == PT_PSFB)); // Parser logic check |
| 1165 | 1171 |
| 1166 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; | 1172 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; |
| 1167 | 1173 |
| 1168 if (length < 12) // 4 * 3, RFC4585 section 6.1 | 1174 // 4 * 3, RFC4585 section 6.1 |
| 1169 { | 1175 if (length < 12) { |
| 1170 EndCurrentBlock(); | 1176 LOG(LS_WARNING) |
| 1177 << "Invalid RTCP packet: Too little data (" << length |
| 1178 << " bytes) left in buffer to parse a 12 byte RTPFB/PSFB message."; |
| 1171 return false; | 1179 return false; |
| 1172 } | 1180 } |
| 1173 | 1181 |
| 1174 _ptrRTCPData += 4; // Skip RTCP header | 1182 _ptrRTCPData += 4; // Skip RTCP header |
| 1175 | 1183 |
| 1176 uint32_t senderSSRC = *_ptrRTCPData++ << 24; | 1184 uint32_t senderSSRC = ByteReader<uint32_t>::ReadBigEndian(_ptrRTCPData); |
| 1177 senderSSRC += *_ptrRTCPData++ << 16; | 1185 _ptrRTCPData += 4; |
| 1178 senderSSRC += *_ptrRTCPData++ << 8; | |
| 1179 senderSSRC += *_ptrRTCPData++; | |
| 1180 | 1186 |
| 1181 uint32_t mediaSSRC = *_ptrRTCPData++ << 24; | 1187 uint32_t mediaSSRC = ByteReader<uint32_t>::ReadBigEndian(_ptrRTCPData); |
| 1182 mediaSSRC += *_ptrRTCPData++ << 16; | 1188 _ptrRTCPData += 4; |
| 1183 mediaSSRC += *_ptrRTCPData++ << 8; | |
| 1184 mediaSSRC += *_ptrRTCPData++; | |
| 1185 | 1189 |
| 1186 if (header.packet_type == PT_RTPFB) { | 1190 if (header.packet_type == PT_RTPFB) { |
| 1187 // Transport layer feedback | 1191 // Transport layer feedback |
| 1188 | 1192 |
| 1189 switch (header.count_or_format) { | 1193 switch (header.count_or_format) { |
| 1190 case 1: | 1194 case 1: |
| 1191 { | 1195 { |
| 1192 // NACK | 1196 // NACK |
| 1193 _packetType = RTCPPacketTypes::kRtpfbNack; | 1197 _packetType = RTCPPacketTypes::kRtpfbNack; |
| 1194 _packet.NACK.SenderSSRC = senderSSRC; | 1198 _packet.NACK.SenderSSRC = senderSSRC; |
| 1195 _packet.NACK.MediaSSRC = mediaSSRC; | 1199 _packet.NACK.MediaSSRC = mediaSSRC; |
| 1196 | 1200 |
| 1197 _state = ParseState::State_RTPFB_NACKItem; | 1201 _state = ParseState::State_RTPFB_NACKItem; |
| 1198 | 1202 |
| 1199 return true; | 1203 return true; |
| 1200 } | 1204 } |
| 1201 case 2: | |
| 1202 { | |
| 1203 // used to be ACK is this code point, which is removed | |
| 1204 // conficts with http://tools.ietf.org/html/draft-levin-avt-rtcp-bur
st-00 | |
| 1205 break; | |
| 1206 } | |
| 1207 case 3: | 1205 case 3: |
| 1208 { | 1206 { |
| 1209 // TMMBR | 1207 // TMMBR |
| 1210 _packetType = RTCPPacketTypes::kRtpfbTmmbr; | 1208 _packetType = RTCPPacketTypes::kRtpfbTmmbr; |
| 1211 _packet.TMMBR.SenderSSRC = senderSSRC; | 1209 _packet.TMMBR.SenderSSRC = senderSSRC; |
| 1212 _packet.TMMBR.MediaSSRC = mediaSSRC; | 1210 _packet.TMMBR.MediaSSRC = mediaSSRC; |
| 1213 | 1211 |
| 1214 _state = ParseState::State_RTPFB_TMMBRItem; | 1212 _state = ParseState::State_RTPFB_TMMBRItem; |
| 1215 | 1213 |
| 1216 return true; | 1214 return true; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1229 case 5: | 1227 case 5: |
| 1230 { | 1228 { |
| 1231 // RTCP-SR-REQ Rapid Synchronisation of RTP Flows | 1229 // RTCP-SR-REQ Rapid Synchronisation of RTP Flows |
| 1232 // draft-perkins-avt-rapid-rtp-sync-03.txt | 1230 // draft-perkins-avt-rapid-rtp-sync-03.txt |
| 1233 // trigger a new RTCP SR | 1231 // trigger a new RTCP SR |
| 1234 _packetType = RTCPPacketTypes::kRtpfbSrReq; | 1232 _packetType = RTCPPacketTypes::kRtpfbSrReq; |
| 1235 | 1233 |
| 1236 // Note: No state transition, SR REQ is empty! | 1234 // Note: No state transition, SR REQ is empty! |
| 1237 return true; | 1235 return true; |
| 1238 } | 1236 } |
| 1237 case 15: { |
| 1238 _packetType = RTCPPacketTypes::kTransportFeedback; |
| 1239 rtcp_packet_ = |
| 1240 rtcp::TransportFeedback::ParseFrom(_ptrRTCPData - 12, length); |
| 1241 // Since we parse the whole packet here, keep the TopLevel state and |
| 1242 // just end the current block. |
| 1243 if (rtcp_packet_.get()) { |
| 1244 EndCurrentBlock(); |
| 1245 return true; |
| 1246 } |
| 1247 break; |
| 1248 } |
| 1239 default: | 1249 default: |
| 1240 break; | 1250 break; |
| 1241 } | 1251 } |
| 1242 EndCurrentBlock(); | 1252 // Unsupported RTPFB message. Skip and move to next block. |
| 1253 ++num_skipped_blocks_; |
| 1243 return false; | 1254 return false; |
| 1244 } else if (header.packet_type == PT_PSFB) { | 1255 } else if (header.packet_type == PT_PSFB) { |
| 1245 // Payload specific feedback | 1256 // Payload specific feedback |
| 1246 switch (header.count_or_format) { | 1257 switch (header.count_or_format) { |
| 1247 case 1: | 1258 case 1: |
| 1248 // PLI | 1259 // PLI |
| 1249 _packetType = RTCPPacketTypes::kPsfbPli; | 1260 _packetType = RTCPPacketTypes::kPsfbPli; |
| 1250 _packet.PLI.SenderSSRC = senderSSRC; | 1261 _packet.PLI.SenderSSRC = senderSSRC; |
| 1251 _packet.PLI.MediaSSRC = mediaSSRC; | 1262 _packet.PLI.MediaSSRC = mediaSSRC; |
| 1252 | 1263 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1280 _packetType = RTCPPacketTypes::kPsfbApp; | 1291 _packetType = RTCPPacketTypes::kPsfbApp; |
| 1281 _packet.PSFBAPP.SenderSSRC = senderSSRC; | 1292 _packet.PSFBAPP.SenderSSRC = senderSSRC; |
| 1282 _packet.PSFBAPP.MediaSSRC = mediaSSRC; | 1293 _packet.PSFBAPP.MediaSSRC = mediaSSRC; |
| 1283 | 1294 |
| 1284 _state = ParseState::State_PSFB_AppItem; | 1295 _state = ParseState::State_PSFB_AppItem; |
| 1285 return true; | 1296 return true; |
| 1286 default: | 1297 default: |
| 1287 break; | 1298 break; |
| 1288 } | 1299 } |
| 1289 | 1300 |
| 1290 EndCurrentBlock(); | |
| 1291 return false; | 1301 return false; |
| 1292 } | 1302 } |
| 1293 else | 1303 else |
| 1294 { | 1304 { |
| 1295 assert(false); | 1305 RTC_NOTREACHED(); |
| 1296 | |
| 1297 EndCurrentBlock(); | |
| 1298 return false; | 1306 return false; |
| 1299 } | 1307 } |
| 1300 } | 1308 } |
| 1301 | 1309 |
| 1302 bool RTCPUtility::RTCPParserV2::ParseRPSIItem() { | 1310 bool RTCPUtility::RTCPParserV2::ParseRPSIItem() { |
| 1303 | 1311 |
| 1304 // RFC 4585 6.3.3. Reference Picture Selection Indication (RPSI). | 1312 // RFC 4585 6.3.3. Reference Picture Selection Indication (RPSI). |
| 1305 // | 1313 // |
| 1306 // 0 1 2 3 | 1314 // 0 1 2 3 |
| 1307 // 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 | 1315 // 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 |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1647 _ptrRTCPData += kRtcpAppCode_DATA_SIZE; | 1655 _ptrRTCPData += kRtcpAppCode_DATA_SIZE; |
| 1648 }else | 1656 }else |
| 1649 { | 1657 { |
| 1650 memcpy(_packet.APP.Data, _ptrRTCPData, length); | 1658 memcpy(_packet.APP.Data, _ptrRTCPData, length); |
| 1651 _packet.APP.Size = (uint16_t)length; | 1659 _packet.APP.Size = (uint16_t)length; |
| 1652 _ptrRTCPData += length; | 1660 _ptrRTCPData += length; |
| 1653 } | 1661 } |
| 1654 return true; | 1662 return true; |
| 1655 } | 1663 } |
| 1656 | 1664 |
| 1665 size_t RTCPUtility::RTCPParserV2::NumSkippedBlocks() const { |
| 1666 return num_skipped_blocks_; |
| 1667 } |
| 1668 |
| 1657 RTCPUtility::RTCPPacketIterator::RTCPPacketIterator(uint8_t* rtcpData, | 1669 RTCPUtility::RTCPPacketIterator::RTCPPacketIterator(uint8_t* rtcpData, |
| 1658 size_t rtcpDataLength) | 1670 size_t rtcpDataLength) |
| 1659 : _ptrBegin(rtcpData), | 1671 : _ptrBegin(rtcpData), |
| 1660 _ptrEnd(rtcpData + rtcpDataLength), | 1672 _ptrEnd(rtcpData + rtcpDataLength), |
| 1661 _ptrBlock(NULL) { | 1673 _ptrBlock(NULL) { |
| 1662 memset(&_header, 0, sizeof(_header)); | 1674 memset(&_header, 0, sizeof(_header)); |
| 1663 } | 1675 } |
| 1664 | 1676 |
| 1665 RTCPUtility::RTCPPacketIterator::~RTCPPacketIterator() { | 1677 RTCPUtility::RTCPPacketIterator::~RTCPPacketIterator() { |
| 1666 } | 1678 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1691 const RTCPUtility::RtcpCommonHeader* | 1703 const RTCPUtility::RtcpCommonHeader* |
| 1692 RTCPUtility::RTCPPacketIterator::Current() { | 1704 RTCPUtility::RTCPPacketIterator::Current() { |
| 1693 if (!_ptrBlock) | 1705 if (!_ptrBlock) |
| 1694 { | 1706 { |
| 1695 return NULL; | 1707 return NULL; |
| 1696 } | 1708 } |
| 1697 | 1709 |
| 1698 return &_header; | 1710 return &_header; |
| 1699 } | 1711 } |
| 1700 } // namespace webrtc | 1712 } // namespace webrtc |
| OLD | NEW |