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 |