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 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 process_thread_(process_thread), | 98 process_thread_(process_thread), |
99 ntp_estimator_(clock_), | 99 ntp_estimator_(clock_), |
100 rtp_header_parser_(RtpHeaderParser::Create()), | 100 rtp_header_parser_(RtpHeaderParser::Create()), |
101 rtp_receiver_(RtpReceiver::CreateVideoReceiver(clock_, | 101 rtp_receiver_(RtpReceiver::CreateVideoReceiver(clock_, |
102 this, | 102 this, |
103 this, | 103 this, |
104 &rtp_payload_registry_)), | 104 &rtp_payload_registry_)), |
105 rtp_receive_statistics_(ReceiveStatistics::Create(clock_)), | 105 rtp_receive_statistics_(ReceiveStatistics::Create(clock_)), |
106 ulpfec_receiver_(UlpfecReceiver::Create(config->rtp.remote_ssrc, this)), | 106 ulpfec_receiver_(UlpfecReceiver::Create(config->rtp.remote_ssrc, this)), |
107 receiving_(false), | 107 receiving_(false), |
| 108 restored_packet_in_use_(false), |
108 last_packet_log_ms_(-1), | 109 last_packet_log_ms_(-1), |
109 rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(), | 110 rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(), |
110 transport, | 111 transport, |
111 rtt_stats, | 112 rtt_stats, |
112 receive_stats_proxy, | 113 receive_stats_proxy, |
113 packet_router)), | 114 packet_router)), |
114 complete_frame_callback_(complete_frame_callback), | 115 complete_frame_callback_(complete_frame_callback), |
115 keyframe_request_sender_(keyframe_request_sender), | 116 keyframe_request_sender_(keyframe_request_sender), |
116 timing_(timing), | 117 timing_(timing), |
117 has_received_frame_(false) { | 118 has_received_frame_(false) { |
(...skipping 20 matching lines...) Expand all Loading... |
138 config_.rtp.extensions[i].id); | 139 config_.rtp.extensions[i].id); |
139 } | 140 } |
140 | 141 |
141 static const int kMaxPacketAgeToNack = 450; | 142 static const int kMaxPacketAgeToNack = 450; |
142 const int max_reordering_threshold = (config_.rtp.nack.rtp_history_ms > 0) | 143 const int max_reordering_threshold = (config_.rtp.nack.rtp_history_ms > 0) |
143 ? kMaxPacketAgeToNack | 144 ? kMaxPacketAgeToNack |
144 : kDefaultMaxReorderingThreshold; | 145 : kDefaultMaxReorderingThreshold; |
145 rtp_receive_statistics_->SetMaxReorderingThreshold(max_reordering_threshold); | 146 rtp_receive_statistics_->SetMaxReorderingThreshold(max_reordering_threshold); |
146 | 147 |
147 if (config_.rtp.rtx_ssrc) { | 148 if (config_.rtp.rtx_ssrc) { |
148 // Needed for rtp_payload_registry_.RtxEnabled(). | |
149 rtp_payload_registry_.SetRtxSsrc(config_.rtp.rtx_ssrc); | 149 rtp_payload_registry_.SetRtxSsrc(config_.rtp.rtx_ssrc); |
| 150 |
| 151 for (const auto& kv : config_.rtp.rtx_associated_payload_types) { |
| 152 RTC_DCHECK_NE(kv.first, 0); |
| 153 rtp_payload_registry_.SetRtxPayloadType(kv.first, kv.second); |
| 154 } |
150 } | 155 } |
151 | 156 |
152 if (IsUlpfecEnabled()) { | 157 if (IsUlpfecEnabled()) { |
153 VideoCodec ulpfec_codec = {}; | 158 VideoCodec ulpfec_codec = {}; |
154 ulpfec_codec.codecType = kVideoCodecULPFEC; | 159 ulpfec_codec.codecType = kVideoCodecULPFEC; |
155 strncpy(ulpfec_codec.plName, "ulpfec", sizeof(ulpfec_codec.plName)); | 160 strncpy(ulpfec_codec.plName, "ulpfec", sizeof(ulpfec_codec.plName)); |
156 ulpfec_codec.plType = config_.rtp.ulpfec.ulpfec_payload_type; | 161 ulpfec_codec.plType = config_.rtp.ulpfec.ulpfec_payload_type; |
157 RTC_CHECK(AddReceiveCodec(ulpfec_codec)); | 162 RTC_CHECK(AddReceiveCodec(ulpfec_codec)); |
158 } | 163 } |
159 | 164 |
160 if (IsRedEnabled()) { | 165 if (IsRedEnabled()) { |
161 VideoCodec red_codec = {}; | 166 VideoCodec red_codec = {}; |
162 red_codec.codecType = kVideoCodecRED; | 167 red_codec.codecType = kVideoCodecRED; |
163 strncpy(red_codec.plName, "red", sizeof(red_codec.plName)); | 168 strncpy(red_codec.plName, "red", sizeof(red_codec.plName)); |
164 red_codec.plType = config_.rtp.ulpfec.red_payload_type; | 169 red_codec.plType = config_.rtp.ulpfec.red_payload_type; |
165 RTC_CHECK(AddReceiveCodec(red_codec)); | 170 RTC_CHECK(AddReceiveCodec(red_codec)); |
| 171 if (config_.rtp.ulpfec.red_rtx_payload_type != -1) { |
| 172 rtp_payload_registry_.SetRtxPayloadType( |
| 173 config_.rtp.ulpfec.red_rtx_payload_type, |
| 174 config_.rtp.ulpfec.red_payload_type); |
| 175 } |
166 } | 176 } |
167 | 177 |
168 if (config_.rtp.rtcp_xr.receiver_reference_time_report) | 178 if (config_.rtp.rtcp_xr.receiver_reference_time_report) |
169 rtp_rtcp_->SetRtcpXrRrtrStatus(true); | 179 rtp_rtcp_->SetRtcpXrRrtrStatus(true); |
170 | 180 |
171 // Stats callback for CNAME changes. | 181 // Stats callback for CNAME changes. |
172 rtp_rtcp_->RegisterRtcpStatisticsCallback(receive_stats_proxy); | 182 rtp_rtcp_->RegisterRtcpStatisticsCallback(receive_stats_proxy); |
173 | 183 |
174 process_thread_->RegisterModule(rtp_rtcp_.get(), RTC_FROM_HERE); | 184 process_thread_->RegisterModule(rtp_rtcp_.get(), RTC_FROM_HERE); |
175 | 185 |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 // Notify video_receiver about received FEC packets to avoid NACKing these | 488 // Notify video_receiver about received FEC packets to avoid NACKing these |
479 // packets. | 489 // packets. |
480 NotifyReceiverOfFecPacket(header); | 490 NotifyReceiverOfFecPacket(header); |
481 } | 491 } |
482 if (ulpfec_receiver_->AddReceivedRedPacket(header, packet, packet_length, | 492 if (ulpfec_receiver_->AddReceivedRedPacket(header, packet, packet_length, |
483 ulpfec_pt) != 0) { | 493 ulpfec_pt) != 0) { |
484 return; | 494 return; |
485 } | 495 } |
486 ulpfec_receiver_->ProcessReceivedFec(); | 496 ulpfec_receiver_->ProcessReceivedFec(); |
487 } else if (rtp_payload_registry_.IsRtx(header)) { | 497 } else if (rtp_payload_registry_.IsRtx(header)) { |
488 LOG(LS_WARNING) << "Unexpected RTX packet on media ssrc"; | 498 if (header.headerLength + header.paddingLength == packet_length) { |
| 499 // This is an empty packet and should be silently dropped before trying to |
| 500 // parse the RTX header. |
| 501 return; |
| 502 } |
| 503 // Remove the RTX header and parse the original RTP header. |
| 504 if (packet_length < header.headerLength) |
| 505 return; |
| 506 if (packet_length > sizeof(restored_packet_)) |
| 507 return; |
| 508 if (restored_packet_in_use_) { |
| 509 LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet."; |
| 510 return; |
| 511 } |
| 512 if (!rtp_payload_registry_.RestoreOriginalPacket( |
| 513 restored_packet_, packet, &packet_length, config_.rtp.remote_ssrc, |
| 514 header)) { |
| 515 LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header ssrc: " |
| 516 << header.ssrc << " payload type: " |
| 517 << static_cast<int>(header.payloadType); |
| 518 return; |
| 519 } |
| 520 restored_packet_in_use_ = true; |
| 521 OnRecoveredPacket(restored_packet_, packet_length); |
| 522 restored_packet_in_use_ = false; |
489 } | 523 } |
490 } | 524 } |
491 | 525 |
492 void RtpVideoStreamReceiver::NotifyReceiverOfFecPacket( | 526 void RtpVideoStreamReceiver::NotifyReceiverOfFecPacket( |
493 const RTPHeader& header) { | 527 const RTPHeader& header) { |
494 int8_t last_media_payload_type = | 528 int8_t last_media_payload_type = |
495 rtp_payload_registry_.last_received_media_payload_type(); | 529 rtp_payload_registry_.last_received_media_payload_type(); |
496 if (last_media_payload_type < 0) { | 530 if (last_media_payload_type < 0) { |
497 LOG(LS_WARNING) << "Failed to get last media payload type."; | 531 LOG(LS_WARNING) << "Failed to get last media payload type."; |
498 return; | 532 return; |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 return; | 708 return; |
675 | 709 |
676 if (!sprop_decoder.DecodeSprop(sprop_base64_it->second.c_str())) | 710 if (!sprop_decoder.DecodeSprop(sprop_base64_it->second.c_str())) |
677 return; | 711 return; |
678 | 712 |
679 tracker_.InsertSpsPpsNalus(sprop_decoder.sps_nalu(), | 713 tracker_.InsertSpsPpsNalus(sprop_decoder.sps_nalu(), |
680 sprop_decoder.pps_nalu()); | 714 sprop_decoder.pps_nalu()); |
681 } | 715 } |
682 | 716 |
683 } // namespace webrtc | 717 } // namespace webrtc |
OLD | NEW |