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" | |
18 #include "webrtc/rtc_base/checks.h" | 17 #include "webrtc/rtc_base/checks.h" |
19 #include "webrtc/rtc_base/logging.h" | 18 #include "webrtc/rtc_base/logging.h" |
20 #include "webrtc/rtc_base/stringutils.h" | 19 #include "webrtc/rtc_base/stringutils.h" |
21 | 20 |
22 namespace webrtc { | 21 namespace webrtc { |
23 | 22 |
24 namespace { | 23 namespace { |
25 | 24 |
26 bool PayloadIsCompatible(const RtpUtility::Payload& payload, | 25 bool PayloadIsCompatible(const RtpUtility::Payload& payload, |
27 const CodecInst& audio_codec) { | 26 const CodecInst& audio_codec) { |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 } | 262 } |
264 } | 263 } |
265 return -1; | 264 return -1; |
266 } | 265 } |
267 | 266 |
268 bool RTPPayloadRegistry::RtxEnabled() const { | 267 bool RTPPayloadRegistry::RtxEnabled() const { |
269 rtc::CritScope cs(&crit_sect_); | 268 rtc::CritScope cs(&crit_sect_); |
270 return rtx_; | 269 return rtx_; |
271 } | 270 } |
272 | 271 |
273 bool RTPPayloadRegistry::IsRtx(const RTPHeader& header) const { | |
274 rtc::CritScope cs(&crit_sect_); | |
275 return IsRtxInternal(header); | |
276 } | |
277 | |
278 bool RTPPayloadRegistry::IsRtxInternal(const RTPHeader& header) const { | 272 bool RTPPayloadRegistry::IsRtxInternal(const RTPHeader& header) const { |
279 return rtx_ && ssrc_rtx_ == header.ssrc; | 273 return rtx_ && ssrc_rtx_ == header.ssrc; |
280 } | 274 } |
281 | 275 |
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 | |
332 void RTPPayloadRegistry::SetRtxSsrc(uint32_t ssrc) { | 276 void RTPPayloadRegistry::SetRtxSsrc(uint32_t ssrc) { |
333 rtc::CritScope cs(&crit_sect_); | 277 rtc::CritScope cs(&crit_sect_); |
334 ssrc_rtx_ = ssrc; | 278 ssrc_rtx_ = ssrc; |
335 rtx_ = true; | 279 rtx_ = true; |
336 } | 280 } |
337 | 281 |
338 bool RTPPayloadRegistry::GetRtxSsrc(uint32_t* ssrc) const { | 282 bool RTPPayloadRegistry::GetRtxSsrc(uint32_t* ssrc) const { |
339 rtc::CritScope cs(&crit_sect_); | 283 rtc::CritScope cs(&crit_sect_); |
340 *ssrc = ssrc_rtx_; | 284 *ssrc = ssrc_rtx_; |
341 return rtx_; | 285 return rtx_; |
(...skipping 10 matching lines...) Expand all Loading... |
352 rtx_payload_type_map_[payload_type] = associated_payload_type; | 296 rtx_payload_type_map_[payload_type] = associated_payload_type; |
353 rtx_ = true; | 297 rtx_ = true; |
354 } | 298 } |
355 | 299 |
356 bool RTPPayloadRegistry::IsRed(const RTPHeader& header) const { | 300 bool RTPPayloadRegistry::IsRed(const RTPHeader& header) const { |
357 rtc::CritScope cs(&crit_sect_); | 301 rtc::CritScope cs(&crit_sect_); |
358 auto it = payload_type_map_.find(header.payloadType); | 302 auto it = payload_type_map_.find(header.payloadType); |
359 return it != payload_type_map_.end() && _stricmp(it->second.name, "red") == 0; | 303 return it != payload_type_map_.end() && _stricmp(it->second.name, "red") == 0; |
360 } | 304 } |
361 | 305 |
362 bool RTPPayloadRegistry::IsEncapsulated(const RTPHeader& header) const { | |
363 return IsRed(header) || IsRtx(header); | |
364 } | |
365 | |
366 bool RTPPayloadRegistry::GetPayloadSpecifics(uint8_t payload_type, | 306 bool RTPPayloadRegistry::GetPayloadSpecifics(uint8_t payload_type, |
367 PayloadUnion* payload) const { | 307 PayloadUnion* payload) const { |
368 rtc::CritScope cs(&crit_sect_); | 308 rtc::CritScope cs(&crit_sect_); |
369 auto it = payload_type_map_.find(payload_type); | 309 auto it = payload_type_map_.find(payload_type); |
370 | 310 |
371 // Check that this is a registered payload type. | 311 // Check that this is a registered payload type. |
372 if (it == payload_type_map_.end()) { | 312 if (it == payload_type_map_.end()) { |
373 return false; | 313 return false; |
374 } | 314 } |
375 *payload = it->second.typeSpecific; | 315 *payload = it->second.typeSpecific; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 const char* payload_name) const { | 362 const char* payload_name) const { |
423 rtc::CritScope cs(&crit_sect_); | 363 rtc::CritScope cs(&crit_sect_); |
424 for (const auto& it : payload_type_map_) { | 364 for (const auto& it : payload_type_map_) { |
425 if (_stricmp(it.second.name, payload_name) == 0) | 365 if (_stricmp(it.second.name, payload_name) == 0) |
426 return it.first; | 366 return it.first; |
427 } | 367 } |
428 return -1; | 368 return -1; |
429 } | 369 } |
430 | 370 |
431 } // namespace webrtc | 371 } // namespace webrtc |
OLD | NEW |