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