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 |