OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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/include/rtp_payload_registry.h" | 11 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 | 14 |
15 #include "webrtc/common_types.h" | 15 #include "webrtc/common_types.h" |
16 #include "webrtc/modules/audio_coding/codecs/audio_format_conversion.h" | 16 #include "webrtc/modules/audio_coding/codecs/audio_format_conversion.h" |
| 17 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
17 #include "webrtc/rtc_base/checks.h" | 18 #include "webrtc/rtc_base/checks.h" |
18 #include "webrtc/rtc_base/logging.h" | 19 #include "webrtc/rtc_base/logging.h" |
19 #include "webrtc/rtc_base/stringutils.h" | 20 #include "webrtc/rtc_base/stringutils.h" |
20 | 21 |
21 namespace webrtc { | 22 namespace webrtc { |
22 | 23 |
23 namespace { | 24 namespace { |
24 | 25 |
25 bool PayloadIsCompatible(const RtpUtility::Payload& payload, | 26 bool PayloadIsCompatible(const RtpUtility::Payload& payload, |
26 const CodecInst& audio_codec) { | 27 const CodecInst& audio_codec) { |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 } | 263 } |
263 } | 264 } |
264 return -1; | 265 return -1; |
265 } | 266 } |
266 | 267 |
267 bool RTPPayloadRegistry::RtxEnabled() const { | 268 bool RTPPayloadRegistry::RtxEnabled() const { |
268 rtc::CritScope cs(&crit_sect_); | 269 rtc::CritScope cs(&crit_sect_); |
269 return rtx_; | 270 return rtx_; |
270 } | 271 } |
271 | 272 |
| 273 bool RTPPayloadRegistry::IsRtx(const RTPHeader& header) const { |
| 274 rtc::CritScope cs(&crit_sect_); |
| 275 return IsRtxInternal(header); |
| 276 } |
| 277 |
272 bool RTPPayloadRegistry::IsRtxInternal(const RTPHeader& header) const { | 278 bool RTPPayloadRegistry::IsRtxInternal(const RTPHeader& header) const { |
273 return rtx_ && ssrc_rtx_ == header.ssrc; | 279 return rtx_ && ssrc_rtx_ == header.ssrc; |
274 } | 280 } |
275 | 281 |
| 282 bool RTPPayloadRegistry::RestoreOriginalPacket(uint8_t* restored_packet, |
| 283 const uint8_t* packet, |
| 284 size_t* packet_length, |
| 285 uint32_t original_ssrc, |
| 286 const RTPHeader& header) { |
| 287 if (kRtxHeaderSize + header.headerLength + header.paddingLength > |
| 288 *packet_length) { |
| 289 return false; |
| 290 } |
| 291 const uint8_t* rtx_header = packet + header.headerLength; |
| 292 uint16_t original_sequence_number = (rtx_header[0] << 8) + rtx_header[1]; |
| 293 |
| 294 // Copy the packet into the restored packet, except for the RTX header. |
| 295 memcpy(restored_packet, packet, header.headerLength); |
| 296 memcpy(restored_packet + header.headerLength, |
| 297 packet + header.headerLength + kRtxHeaderSize, |
| 298 *packet_length - header.headerLength - kRtxHeaderSize); |
| 299 *packet_length -= kRtxHeaderSize; |
| 300 |
| 301 // Replace the SSRC and the sequence number with the originals. |
| 302 ByteWriter<uint16_t>::WriteBigEndian(restored_packet + 2, |
| 303 original_sequence_number); |
| 304 ByteWriter<uint32_t>::WriteBigEndian(restored_packet + 8, original_ssrc); |
| 305 |
| 306 rtc::CritScope cs(&crit_sect_); |
| 307 if (!rtx_) |
| 308 return true; |
| 309 |
| 310 auto apt_mapping = rtx_payload_type_map_.find(header.payloadType); |
| 311 if (apt_mapping == rtx_payload_type_map_.end()) { |
| 312 // No associated payload type found. Warn, unless we have already done so. |
| 313 if (payload_types_with_suppressed_warnings_.find(header.payloadType) == |
| 314 payload_types_with_suppressed_warnings_.end()) { |
| 315 LOG(LS_WARNING) |
| 316 << "No RTX associated payload type mapping was available; " |
| 317 "not able to restore original packet from RTX packet " |
| 318 "with payload type: " |
| 319 << static_cast<int>(header.payloadType) << ". " |
| 320 << "Suppressing further warnings for this payload type."; |
| 321 payload_types_with_suppressed_warnings_.insert(header.payloadType); |
| 322 } |
| 323 return false; |
| 324 } |
| 325 restored_packet[1] = static_cast<uint8_t>(apt_mapping->second); |
| 326 if (header.markerBit) { |
| 327 restored_packet[1] |= kRtpMarkerBitMask; // Marker bit is set. |
| 328 } |
| 329 return true; |
| 330 } |
| 331 |
276 void RTPPayloadRegistry::SetRtxSsrc(uint32_t ssrc) { | 332 void RTPPayloadRegistry::SetRtxSsrc(uint32_t ssrc) { |
277 rtc::CritScope cs(&crit_sect_); | 333 rtc::CritScope cs(&crit_sect_); |
278 ssrc_rtx_ = ssrc; | 334 ssrc_rtx_ = ssrc; |
279 rtx_ = true; | 335 rtx_ = true; |
280 } | 336 } |
281 | 337 |
282 bool RTPPayloadRegistry::GetRtxSsrc(uint32_t* ssrc) const { | 338 bool RTPPayloadRegistry::GetRtxSsrc(uint32_t* ssrc) const { |
283 rtc::CritScope cs(&crit_sect_); | 339 rtc::CritScope cs(&crit_sect_); |
284 *ssrc = ssrc_rtx_; | 340 *ssrc = ssrc_rtx_; |
285 return rtx_; | 341 return rtx_; |
(...skipping 10 matching lines...) Expand all Loading... |
296 rtx_payload_type_map_[payload_type] = associated_payload_type; | 352 rtx_payload_type_map_[payload_type] = associated_payload_type; |
297 rtx_ = true; | 353 rtx_ = true; |
298 } | 354 } |
299 | 355 |
300 bool RTPPayloadRegistry::IsRed(const RTPHeader& header) const { | 356 bool RTPPayloadRegistry::IsRed(const RTPHeader& header) const { |
301 rtc::CritScope cs(&crit_sect_); | 357 rtc::CritScope cs(&crit_sect_); |
302 auto it = payload_type_map_.find(header.payloadType); | 358 auto it = payload_type_map_.find(header.payloadType); |
303 return it != payload_type_map_.end() && _stricmp(it->second.name, "red") == 0; | 359 return it != payload_type_map_.end() && _stricmp(it->second.name, "red") == 0; |
304 } | 360 } |
305 | 361 |
| 362 bool RTPPayloadRegistry::IsEncapsulated(const RTPHeader& header) const { |
| 363 return IsRed(header) || IsRtx(header); |
| 364 } |
| 365 |
306 bool RTPPayloadRegistry::GetPayloadSpecifics(uint8_t payload_type, | 366 bool RTPPayloadRegistry::GetPayloadSpecifics(uint8_t payload_type, |
307 PayloadUnion* payload) const { | 367 PayloadUnion* payload) const { |
308 rtc::CritScope cs(&crit_sect_); | 368 rtc::CritScope cs(&crit_sect_); |
309 auto it = payload_type_map_.find(payload_type); | 369 auto it = payload_type_map_.find(payload_type); |
310 | 370 |
311 // Check that this is a registered payload type. | 371 // Check that this is a registered payload type. |
312 if (it == payload_type_map_.end()) { | 372 if (it == payload_type_map_.end()) { |
313 return false; | 373 return false; |
314 } | 374 } |
315 *payload = it->second.typeSpecific; | 375 *payload = it->second.typeSpecific; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 const char* payload_name) const { | 422 const char* payload_name) const { |
363 rtc::CritScope cs(&crit_sect_); | 423 rtc::CritScope cs(&crit_sect_); |
364 for (const auto& it : payload_type_map_) { | 424 for (const auto& it : payload_type_map_) { |
365 if (_stricmp(it.second.name, payload_name) == 0) | 425 if (_stricmp(it.second.name, payload_name) == 0) |
366 return it.first; | 426 return it.first; |
367 } | 427 } |
368 return -1; | 428 return -1; |
369 } | 429 } |
370 | 430 |
371 } // namespace webrtc | 431 } // namespace webrtc |
OLD | NEW |