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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 return rtp_rtcp; | 79 return rtp_rtcp; |
80 } | 80 } |
81 | 81 |
82 static const int kPacketLogIntervalMs = 10000; | 82 static const int kPacketLogIntervalMs = 10000; |
83 | 83 |
84 RtpVideoStreamReceiver::RtpVideoStreamReceiver( | 84 RtpVideoStreamReceiver::RtpVideoStreamReceiver( |
85 Transport* transport, | 85 Transport* transport, |
86 RtcpRttStats* rtt_stats, | 86 RtcpRttStats* rtt_stats, |
87 PacketRouter* packet_router, | 87 PacketRouter* packet_router, |
88 const VideoReceiveStream::Config* config, | 88 const VideoReceiveStream::Config* config, |
89 ReceiveStatistics* rtp_receive_statistics, | |
90 ReceiveStatisticsProxy* receive_stats_proxy, | 89 ReceiveStatisticsProxy* receive_stats_proxy, |
91 ProcessThread* process_thread, | 90 ProcessThread* process_thread, |
92 NackSender* nack_sender, | 91 NackSender* nack_sender, |
93 KeyFrameRequestSender* keyframe_request_sender, | 92 KeyFrameRequestSender* keyframe_request_sender, |
94 video_coding::OnCompleteFrameCallback* complete_frame_callback, | 93 video_coding::OnCompleteFrameCallback* complete_frame_callback, |
95 VCMTiming* timing) | 94 VCMTiming* timing) |
96 : clock_(Clock::GetRealTimeClock()), | 95 : clock_(Clock::GetRealTimeClock()), |
97 config_(*config), | 96 config_(*config), |
98 packet_router_(packet_router), | 97 packet_router_(packet_router), |
99 process_thread_(process_thread), | 98 process_thread_(process_thread), |
100 ntp_estimator_(clock_), | 99 ntp_estimator_(clock_), |
101 rtp_header_parser_(RtpHeaderParser::Create()), | 100 rtp_header_parser_(RtpHeaderParser::Create()), |
102 rtp_receiver_(RtpReceiver::CreateVideoReceiver(clock_, | 101 rtp_receiver_(RtpReceiver::CreateVideoReceiver(clock_, |
103 this, | 102 this, |
104 this, | 103 this, |
105 &rtp_payload_registry_)), | 104 &rtp_payload_registry_)), |
106 rtp_receive_statistics_(rtp_receive_statistics), | 105 rtp_receive_statistics_(ReceiveStatistics::Create(clock_)), |
107 ulpfec_receiver_(UlpfecReceiver::Create(config->rtp.remote_ssrc, this)), | 106 ulpfec_receiver_(UlpfecReceiver::Create(config->rtp.remote_ssrc, this)), |
108 receiving_(false), | 107 receiving_(false), |
| 108 restored_packet_in_use_(false), |
109 last_packet_log_ms_(-1), | 109 last_packet_log_ms_(-1), |
110 rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_, | 110 rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(), |
111 transport, | 111 transport, |
112 rtt_stats, | 112 rtt_stats, |
113 receive_stats_proxy, | 113 receive_stats_proxy, |
114 packet_router)), | 114 packet_router)), |
115 complete_frame_callback_(complete_frame_callback), | 115 complete_frame_callback_(complete_frame_callback), |
116 keyframe_request_sender_(keyframe_request_sender), | 116 keyframe_request_sender_(keyframe_request_sender), |
117 timing_(timing), | 117 timing_(timing), |
118 has_received_frame_(false) { | 118 has_received_frame_(false) { |
119 constexpr bool remb_candidate = true; | 119 constexpr bool remb_candidate = true; |
120 packet_router_->AddReceiveRtpModule(rtp_rtcp_.get(), remb_candidate); | 120 packet_router_->AddReceiveRtpModule(rtp_rtcp_.get(), remb_candidate); |
(...skipping 18 matching lines...) Expand all Loading... |
139 config_.rtp.extensions[i].id); | 139 config_.rtp.extensions[i].id); |
140 } | 140 } |
141 | 141 |
142 static const int kMaxPacketAgeToNack = 450; | 142 static const int kMaxPacketAgeToNack = 450; |
143 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) |
144 ? kMaxPacketAgeToNack | 144 ? kMaxPacketAgeToNack |
145 : kDefaultMaxReorderingThreshold; | 145 : kDefaultMaxReorderingThreshold; |
146 rtp_receive_statistics_->SetMaxReorderingThreshold(max_reordering_threshold); | 146 rtp_receive_statistics_->SetMaxReorderingThreshold(max_reordering_threshold); |
147 | 147 |
148 if (config_.rtp.rtx_ssrc) { | 148 if (config_.rtp.rtx_ssrc) { |
149 // Needed for rtp_payload_registry_.RtxEnabled(). | |
150 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 } |
151 } | 155 } |
152 | 156 |
153 if (IsUlpfecEnabled()) { | 157 if (IsUlpfecEnabled()) { |
154 VideoCodec ulpfec_codec = {}; | 158 VideoCodec ulpfec_codec = {}; |
155 ulpfec_codec.codecType = kVideoCodecULPFEC; | 159 ulpfec_codec.codecType = kVideoCodecULPFEC; |
156 strncpy(ulpfec_codec.plName, "ulpfec", sizeof(ulpfec_codec.plName)); | 160 strncpy(ulpfec_codec.plName, "ulpfec", sizeof(ulpfec_codec.plName)); |
157 ulpfec_codec.plType = config_.rtp.ulpfec.ulpfec_payload_type; | 161 ulpfec_codec.plType = config_.rtp.ulpfec.ulpfec_payload_type; |
158 RTC_CHECK(AddReceiveCodec(ulpfec_codec)); | 162 RTC_CHECK(AddReceiveCodec(ulpfec_codec)); |
159 } | 163 } |
160 | 164 |
161 if (IsRedEnabled()) { | 165 if (IsRedEnabled()) { |
162 VideoCodec red_codec = {}; | 166 VideoCodec red_codec = {}; |
163 red_codec.codecType = kVideoCodecRED; | 167 red_codec.codecType = kVideoCodecRED; |
164 strncpy(red_codec.plName, "red", sizeof(red_codec.plName)); | 168 strncpy(red_codec.plName, "red", sizeof(red_codec.plName)); |
165 red_codec.plType = config_.rtp.ulpfec.red_payload_type; | 169 red_codec.plType = config_.rtp.ulpfec.red_payload_type; |
166 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 } |
167 } | 176 } |
168 | 177 |
169 if (config_.rtp.rtcp_xr.receiver_reference_time_report) | 178 if (config_.rtp.rtcp_xr.receiver_reference_time_report) |
170 rtp_rtcp_->SetRtcpXrRrtrStatus(true); | 179 rtp_rtcp_->SetRtcpXrRrtrStatus(true); |
171 | 180 |
172 // Stats callback for CNAME changes. | 181 // Stats callback for CNAME changes. |
173 rtp_rtcp_->RegisterRtcpStatisticsCallback(receive_stats_proxy); | 182 rtp_rtcp_->RegisterRtcpStatisticsCallback(receive_stats_proxy); |
174 | 183 |
175 process_thread_->RegisterModule(rtp_rtcp_.get(), RTC_FROM_HERE); | 184 process_thread_->RegisterModule(rtp_rtcp_.get(), RTC_FROM_HERE); |
176 | 185 |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 // Notify video_receiver about received FEC packets to avoid NACKing these | 488 // Notify video_receiver about received FEC packets to avoid NACKing these |
480 // packets. | 489 // packets. |
481 NotifyReceiverOfFecPacket(header); | 490 NotifyReceiverOfFecPacket(header); |
482 } | 491 } |
483 if (ulpfec_receiver_->AddReceivedRedPacket(header, packet, packet_length, | 492 if (ulpfec_receiver_->AddReceivedRedPacket(header, packet, packet_length, |
484 ulpfec_pt) != 0) { | 493 ulpfec_pt) != 0) { |
485 return; | 494 return; |
486 } | 495 } |
487 ulpfec_receiver_->ProcessReceivedFec(); | 496 ulpfec_receiver_->ProcessReceivedFec(); |
488 } else if (rtp_payload_registry_.IsRtx(header)) { | 497 } else if (rtp_payload_registry_.IsRtx(header)) { |
489 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; |
490 } | 523 } |
491 } | 524 } |
492 | 525 |
493 void RtpVideoStreamReceiver::NotifyReceiverOfFecPacket( | 526 void RtpVideoStreamReceiver::NotifyReceiverOfFecPacket( |
494 const RTPHeader& header) { | 527 const RTPHeader& header) { |
495 int8_t last_media_payload_type = | 528 int8_t last_media_payload_type = |
496 rtp_payload_registry_.last_received_media_payload_type(); | 529 rtp_payload_registry_.last_received_media_payload_type(); |
497 if (last_media_payload_type < 0) { | 530 if (last_media_payload_type < 0) { |
498 LOG(LS_WARNING) << "Failed to get last media payload type."; | 531 LOG(LS_WARNING) << "Failed to get last media payload type."; |
499 return; | 532 return; |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 return; | 708 return; |
676 | 709 |
677 if (!sprop_decoder.DecodeSprop(sprop_base64_it->second.c_str())) | 710 if (!sprop_decoder.DecodeSprop(sprop_base64_it->second.c_str())) |
678 return; | 711 return; |
679 | 712 |
680 tracker_.InsertSpsPpsNalus(sprop_decoder.sps_nalu(), | 713 tracker_.InsertSpsPpsNalus(sprop_decoder.sps_nalu(), |
681 sprop_decoder.pps_nalu()); | 714 sprop_decoder.pps_nalu()); |
682 } | 715 } |
683 | 716 |
684 } // namespace webrtc | 717 } // namespace webrtc |
OLD | NEW |