| 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/interface/rtp_payload_registry.h" | 11 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" |
| 12 | 12 |
| 13 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 13 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| 14 #include "webrtc/system_wrappers/interface/logging.h" | 14 #include "webrtc/system_wrappers/interface/logging.h" |
| 15 | 15 |
| 16 namespace webrtc { | 16 namespace webrtc { |
| 17 | 17 |
| 18 RTPPayloadRegistry::RTPPayloadRegistry(RTPPayloadStrategy* rtp_payload_strategy) | 18 RTPPayloadRegistry::RTPPayloadRegistry(RTPPayloadStrategy* rtp_payload_strategy) |
| 19 : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), | 19 : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), |
| 20 rtp_payload_strategy_(rtp_payload_strategy), | 20 rtp_payload_strategy_(rtp_payload_strategy), |
| 21 red_payload_type_(-1), | 21 red_payload_type_(-1), |
| 22 ulpfec_payload_type_(-1), | 22 ulpfec_payload_type_(-1), |
| 23 incoming_payload_type_(-1), | 23 incoming_payload_type_(-1), |
| 24 last_received_payload_type_(-1), | 24 last_received_payload_type_(-1), |
| 25 last_received_media_payload_type_(-1), | 25 last_received_media_payload_type_(-1), |
| 26 rtx_(false), | 26 rtx_(false), |
| 27 rtx_payload_type_(-1), | 27 rtx_payload_type_(-1), |
| 28 ssrc_rtx_(0) { | 28 use_rtx_payload_mapping_on_restore_(false), |
| 29 } | 29 ssrc_rtx_(0) {} |
| 30 | 30 |
| 31 RTPPayloadRegistry::~RTPPayloadRegistry() { | 31 RTPPayloadRegistry::~RTPPayloadRegistry() { |
| 32 while (!payload_type_map_.empty()) { | 32 while (!payload_type_map_.empty()) { |
| 33 RtpUtility::PayloadTypeMap::iterator it = payload_type_map_.begin(); | 33 RtpUtility::PayloadTypeMap::iterator it = payload_type_map_.begin(); |
| 34 delete it->second; | 34 delete it->second; |
| 35 payload_type_map_.erase(it); | 35 payload_type_map_.erase(it); |
| 36 } | 36 } |
| 37 } | 37 } |
| 38 | 38 |
| 39 int32_t RTPPayloadRegistry::RegisterReceivePayload( | 39 int32_t RTPPayloadRegistry::RegisterReceivePayload( |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 | 225 |
| 226 bool RTPPayloadRegistry::IsRtx(const RTPHeader& header) const { | 226 bool RTPPayloadRegistry::IsRtx(const RTPHeader& header) const { |
| 227 CriticalSectionScoped cs(crit_sect_.get()); | 227 CriticalSectionScoped cs(crit_sect_.get()); |
| 228 return IsRtxInternal(header); | 228 return IsRtxInternal(header); |
| 229 } | 229 } |
| 230 | 230 |
| 231 bool RTPPayloadRegistry::IsRtxInternal(const RTPHeader& header) const { | 231 bool RTPPayloadRegistry::IsRtxInternal(const RTPHeader& header) const { |
| 232 return rtx_ && ssrc_rtx_ == header.ssrc; | 232 return rtx_ && ssrc_rtx_ == header.ssrc; |
| 233 } | 233 } |
| 234 | 234 |
| 235 bool RTPPayloadRegistry::RestoreOriginalPacket(uint8_t** restored_packet, | 235 bool RTPPayloadRegistry::RestoreOriginalPacket(uint8_t* restored_packet, |
| 236 const uint8_t* packet, | 236 const uint8_t* packet, |
| 237 size_t* packet_length, | 237 size_t* packet_length, |
| 238 uint32_t original_ssrc, | 238 uint32_t original_ssrc, |
| 239 const RTPHeader& header) const { | 239 const RTPHeader& header) const { |
| 240 if (kRtxHeaderSize + header.headerLength + header.paddingLength > | 240 if (kRtxHeaderSize + header.headerLength + header.paddingLength > |
| 241 *packet_length) { | 241 *packet_length) { |
| 242 return false; | 242 return false; |
| 243 } | 243 } |
| 244 const uint8_t* rtx_header = packet + header.headerLength; | 244 const uint8_t* rtx_header = packet + header.headerLength; |
| 245 uint16_t original_sequence_number = (rtx_header[0] << 8) + rtx_header[1]; | 245 uint16_t original_sequence_number = (rtx_header[0] << 8) + rtx_header[1]; |
| 246 | 246 |
| 247 // Copy the packet into the restored packet, except for the RTX header. | 247 // Copy the packet into the restored packet, except for the RTX header. |
| 248 memcpy(*restored_packet, packet, header.headerLength); | 248 memcpy(restored_packet, packet, header.headerLength); |
| 249 memcpy(*restored_packet + header.headerLength, | 249 memcpy(restored_packet + header.headerLength, |
| 250 packet + header.headerLength + kRtxHeaderSize, | 250 packet + header.headerLength + kRtxHeaderSize, |
| 251 *packet_length - header.headerLength - kRtxHeaderSize); | 251 *packet_length - header.headerLength - kRtxHeaderSize); |
| 252 *packet_length -= kRtxHeaderSize; | 252 *packet_length -= kRtxHeaderSize; |
| 253 | 253 |
| 254 // Replace the SSRC and the sequence number with the originals. | 254 // Replace the SSRC and the sequence number with the originals. |
| 255 ByteWriter<uint16_t>::WriteBigEndian(*restored_packet + 2, | 255 ByteWriter<uint16_t>::WriteBigEndian(restored_packet + 2, |
| 256 original_sequence_number); | 256 original_sequence_number); |
| 257 ByteWriter<uint32_t>::WriteBigEndian(*restored_packet + 8, original_ssrc); | 257 ByteWriter<uint32_t>::WriteBigEndian(restored_packet + 8, original_ssrc); |
| 258 | 258 |
| 259 CriticalSectionScoped cs(crit_sect_.get()); | 259 CriticalSectionScoped cs(crit_sect_.get()); |
| 260 if (!rtx_) | 260 if (!rtx_) |
| 261 return true; | 261 return true; |
| 262 | 262 |
| 263 if (rtx_payload_type_ == -1 || incoming_payload_type_ == -1) { | 263 int associated_payload_type; |
| 264 LOG(LS_WARNING) << "Incorrect RTX configuration, dropping packet."; | 264 auto apt_mapping = rtx_payload_type_map_.find(header.payloadType); |
| 265 return false; | 265 if (use_rtx_payload_mapping_on_restore_ && |
| 266 apt_mapping != rtx_payload_type_map_.end()) { |
| 267 associated_payload_type = apt_mapping->second; |
| 268 } else { |
| 269 // In the future, this will be a bug. For now, just assume this RTX packet |
| 270 // matches the last non-RTX payload type we received. There are cases where |
| 271 // this could break, especially where RTX is sent outside of NACKing (e.g. |
| 272 // padding with redundant payloads). |
| 273 if (rtx_payload_type_ == -1 || incoming_payload_type_ == -1) { |
| 274 LOG(LS_WARNING) << "Incorrect RTX configuration, dropping packet."; |
| 275 return false; |
| 276 } |
| 277 associated_payload_type = incoming_payload_type_; |
| 266 } | 278 } |
| 267 // TODO(changbin): Will use RTX APT map for restoring packets, | 279 |
| 268 // thus incoming_payload_type_ should be removed in future. | 280 restored_packet[1] = static_cast<uint8_t>(associated_payload_type); |
| 269 (*restored_packet)[1] = static_cast<uint8_t>(incoming_payload_type_); | |
| 270 if (header.markerBit) { | 281 if (header.markerBit) { |
| 271 (*restored_packet)[1] |= kRtpMarkerBitMask; // Marker bit is set. | 282 restored_packet[1] |= kRtpMarkerBitMask; // Marker bit is set. |
| 272 } | 283 } |
| 273 return true; | 284 return true; |
| 274 } | 285 } |
| 275 | 286 |
| 276 void RTPPayloadRegistry::SetRtxSsrc(uint32_t ssrc) { | 287 void RTPPayloadRegistry::SetRtxSsrc(uint32_t ssrc) { |
| 277 CriticalSectionScoped cs(crit_sect_.get()); | 288 CriticalSectionScoped cs(crit_sect_.get()); |
| 278 ssrc_rtx_ = ssrc; | 289 ssrc_rtx_ = ssrc; |
| 279 rtx_ = true; | 290 rtx_ = true; |
| 280 } | 291 } |
| 281 | 292 |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 RTPPayloadStrategy* RTPPayloadStrategy::CreateStrategy( | 474 RTPPayloadStrategy* RTPPayloadStrategy::CreateStrategy( |
| 464 const bool handling_audio) { | 475 const bool handling_audio) { |
| 465 if (handling_audio) { | 476 if (handling_audio) { |
| 466 return new RTPPayloadAudioStrategy(); | 477 return new RTPPayloadAudioStrategy(); |
| 467 } else { | 478 } else { |
| 468 return new RTPPayloadVideoStrategy(); | 479 return new RTPPayloadVideoStrategy(); |
| 469 } | 480 } |
| 470 } | 481 } |
| 471 | 482 |
| 472 } // namespace webrtc | 483 } // namespace webrtc |
| OLD | NEW |