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