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 11 matching lines...) Expand all Loading... |
22 #include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h" | 22 #include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h" |
23 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" | 23 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" |
24 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" | 24 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" |
25 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" | 25 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" |
26 #include "webrtc/modules/video_coding/video_coding_impl.h" | 26 #include "webrtc/modules/video_coding/video_coding_impl.h" |
27 #include "webrtc/system_wrappers/include/metrics.h" | 27 #include "webrtc/system_wrappers/include/metrics.h" |
28 #include "webrtc/system_wrappers/include/tick_util.h" | 28 #include "webrtc/system_wrappers/include/tick_util.h" |
29 #include "webrtc/system_wrappers/include/timestamp_extrapolator.h" | 29 #include "webrtc/system_wrappers/include/timestamp_extrapolator.h" |
30 #include "webrtc/system_wrappers/include/trace.h" | 30 #include "webrtc/system_wrappers/include/trace.h" |
31 #include "webrtc/video/receive_statistics_proxy.h" | 31 #include "webrtc/video/receive_statistics_proxy.h" |
| 32 #include "webrtc/video/vie_remb.h" |
32 | 33 |
33 namespace webrtc { | 34 namespace webrtc { |
34 | 35 |
35 std::unique_ptr<RtpRtcp> CreateRtpRtcpModule( | 36 std::unique_ptr<RtpRtcp> CreateRtpRtcpModule( |
36 ReceiveStatistics* receive_statistics, | 37 ReceiveStatistics* receive_statistics, |
37 Transport* outgoing_transport, | 38 Transport* outgoing_transport, |
38 RtcpRttStats* rtt_stats, | 39 RtcpRttStats* rtt_stats, |
39 RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer, | 40 RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer, |
40 RemoteBitrateEstimator* remote_bitrate_estimator, | 41 RemoteBitrateEstimator* remote_bitrate_estimator, |
41 RtpPacketSender* paced_sender, | 42 RtpPacketSender* paced_sender, |
(...skipping 27 matching lines...) Expand all Loading... |
69 | 70 |
70 static const int kPacketLogIntervalMs = 10000; | 71 static const int kPacketLogIntervalMs = 10000; |
71 | 72 |
72 RtpStreamReceiver::RtpStreamReceiver( | 73 RtpStreamReceiver::RtpStreamReceiver( |
73 vcm::VideoReceiver* video_receiver, | 74 vcm::VideoReceiver* video_receiver, |
74 RemoteBitrateEstimator* remote_bitrate_estimator, | 75 RemoteBitrateEstimator* remote_bitrate_estimator, |
75 Transport* transport, | 76 Transport* transport, |
76 RtcpRttStats* rtt_stats, | 77 RtcpRttStats* rtt_stats, |
77 PacedSender* paced_sender, | 78 PacedSender* paced_sender, |
78 PacketRouter* packet_router, | 79 PacketRouter* packet_router, |
| 80 VieRemb* remb, |
79 const VideoReceiveStream::Config& config, | 81 const VideoReceiveStream::Config& config, |
80 ReceiveStatisticsProxy* receive_stats_proxy) | 82 ReceiveStatisticsProxy* receive_stats_proxy, |
| 83 ProcessThread* process_thread) |
81 : clock_(Clock::GetRealTimeClock()), | 84 : clock_(Clock::GetRealTimeClock()), |
| 85 config_(config), |
82 video_receiver_(video_receiver), | 86 video_receiver_(video_receiver), |
83 remote_bitrate_estimator_(remote_bitrate_estimator), | 87 remote_bitrate_estimator_(remote_bitrate_estimator), |
84 packet_router_(packet_router), | 88 packet_router_(packet_router), |
| 89 remb_(remb), |
| 90 process_thread_(process_thread), |
85 ntp_estimator_(clock_), | 91 ntp_estimator_(clock_), |
86 rtp_payload_registry_(RTPPayloadStrategy::CreateStrategy(false)), | 92 rtp_payload_registry_(RTPPayloadStrategy::CreateStrategy(false)), |
87 rtp_header_parser_(RtpHeaderParser::Create()), | 93 rtp_header_parser_(RtpHeaderParser::Create()), |
88 rtp_receiver_(RtpReceiver::CreateVideoReceiver(clock_, | 94 rtp_receiver_(RtpReceiver::CreateVideoReceiver(clock_, |
89 this, | 95 this, |
90 this, | 96 this, |
91 &rtp_payload_registry_)), | 97 &rtp_payload_registry_)), |
92 rtp_receive_statistics_(ReceiveStatistics::Create(clock_)), | 98 rtp_receive_statistics_(ReceiveStatistics::Create(clock_)), |
93 fec_receiver_(FecReceiver::Create(this)), | 99 fec_receiver_(FecReceiver::Create(this)), |
94 receiving_(false), | 100 receiving_(false), |
95 restored_packet_in_use_(false), | 101 restored_packet_in_use_(false), |
96 last_packet_log_ms_(-1), | 102 last_packet_log_ms_(-1), |
97 rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(), | 103 rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(), |
98 transport, | 104 transport, |
99 rtt_stats, | 105 rtt_stats, |
100 receive_stats_proxy, | 106 receive_stats_proxy, |
101 remote_bitrate_estimator_, | 107 remote_bitrate_estimator_, |
102 paced_sender, | 108 paced_sender, |
103 packet_router)) { | 109 packet_router)) { |
104 packet_router_->AddRtpModule(rtp_rtcp_.get()); | 110 packet_router_->AddRtpModule(rtp_rtcp_.get()); |
105 rtp_receive_statistics_->RegisterRtpStatisticsCallback(receive_stats_proxy); | 111 rtp_receive_statistics_->RegisterRtpStatisticsCallback(receive_stats_proxy); |
106 rtp_receive_statistics_->RegisterRtcpStatisticsCallback(receive_stats_proxy); | 112 rtp_receive_statistics_->RegisterRtcpStatisticsCallback(receive_stats_proxy); |
107 | 113 |
108 RTC_DCHECK(config.rtp.rtcp_mode != RtcpMode::kOff) | 114 RTC_DCHECK(config.rtp.rtcp_mode != RtcpMode::kOff) |
109 << "A stream should not be configured with RTCP disabled. This value is " | 115 << "A stream should not be configured with RTCP disabled. This value is " |
110 "reserved for internal usage."; | 116 "reserved for internal usage."; |
| 117 RTC_DCHECK(config_.rtp.remote_ssrc != 0); |
| 118 // TODO(pbos): What's an appropriate local_ssrc for receive-only streams? |
| 119 RTC_DCHECK(config_.rtp.local_ssrc != 0); |
| 120 RTC_DCHECK(config_.rtp.remote_ssrc != config_.rtp.local_ssrc); |
| 121 |
111 rtp_rtcp_->SetRTCPStatus(config.rtp.rtcp_mode); | 122 rtp_rtcp_->SetRTCPStatus(config.rtp.rtcp_mode); |
| 123 rtp_rtcp_->SetSSRC(config.rtp.local_ssrc); |
112 rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp); | 124 rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp); |
| 125 if (config.rtp.remb) { |
| 126 rtp_rtcp_->SetREMBStatus(true); |
| 127 remb_->AddReceiveChannel(rtp_rtcp_.get()); |
| 128 } |
| 129 |
| 130 for (size_t i = 0; i < config.rtp.extensions.size(); ++i) { |
| 131 EnableReceiveRtpHeaderExtension(config.rtp.extensions[i].name, |
| 132 config.rtp.extensions[i].id); |
| 133 } |
113 | 134 |
114 static const int kMaxPacketAgeToNack = 450; | 135 static const int kMaxPacketAgeToNack = 450; |
115 NACKMethod nack_method = | 136 NACKMethod nack_method = |
116 config.rtp.nack.rtp_history_ms > 0 ? kNackRtcp : kNackOff; | 137 config.rtp.nack.rtp_history_ms > 0 ? kNackRtcp : kNackOff; |
117 const int max_reordering_threshold = (nack_method == kNackRtcp) | 138 const int max_reordering_threshold = (nack_method == kNackRtcp) |
118 ? kMaxPacketAgeToNack : kDefaultMaxReorderingThreshold; | 139 ? kMaxPacketAgeToNack : kDefaultMaxReorderingThreshold; |
119 rtp_receiver_->SetNACKStatus(nack_method); | 140 rtp_receiver_->SetNACKStatus(nack_method); |
120 rtp_receive_statistics_->SetMaxReorderingThreshold(max_reordering_threshold); | 141 rtp_receive_statistics_->SetMaxReorderingThreshold(max_reordering_threshold); |
| 142 |
| 143 // TODO(pbos): Support multiple RTX, per video payload. |
| 144 for (const auto& kv : config_.rtp.rtx) { |
| 145 RTC_DCHECK(kv.second.ssrc != 0); |
| 146 RTC_DCHECK(kv.second.payload_type != 0); |
| 147 |
| 148 rtp_payload_registry_.SetRtxSsrc(kv.second.ssrc); |
| 149 rtp_payload_registry_.SetRtxPayloadType(kv.second.payload_type, |
| 150 kv.first); |
| 151 } |
| 152 |
| 153 // If set to true, the RTX payload type mapping supplied in |
| 154 // |SetRtxPayloadType| will be used when restoring RTX packets. Without it, |
| 155 // RTX packets will always be restored to the last non-RTX packet payload type |
| 156 // received. |
| 157 // TODO(holmer): When Chrome no longer depends on this being false by default, |
| 158 // always use the mapping and remove this whole codepath. |
| 159 rtp_payload_registry_.set_use_rtx_payload_mapping_on_restore( |
| 160 config_.rtp.use_rtx_payload_mapping_on_restore); |
| 161 |
| 162 if (IsFecEnabled()) { |
| 163 VideoCodec ulpfec_codec = {}; |
| 164 ulpfec_codec.codecType = kVideoCodecULPFEC; |
| 165 strncpy(ulpfec_codec.plName, "ulpfec", sizeof(ulpfec_codec.plName)); |
| 166 ulpfec_codec.plType = config_.rtp.fec.ulpfec_payload_type; |
| 167 RTC_CHECK(SetReceiveCodec(ulpfec_codec)); |
| 168 |
| 169 VideoCodec red_codec = {}; |
| 170 red_codec.codecType = kVideoCodecRED; |
| 171 strncpy(red_codec.plName, "red", sizeof(red_codec.plName)); |
| 172 red_codec.plType = config_.rtp.fec.red_payload_type; |
| 173 RTC_CHECK(SetReceiveCodec(red_codec)); |
| 174 if (config_.rtp.fec.red_rtx_payload_type != -1) { |
| 175 rtp_payload_registry_.SetRtxPayloadType( |
| 176 config_.rtp.fec.red_rtx_payload_type, |
| 177 config_.rtp.fec.red_payload_type); |
| 178 } |
| 179 } |
| 180 |
| 181 if (config.rtp.rtcp_xr.receiver_reference_time_report) |
| 182 rtp_rtcp_->SetRtcpXrRrtrStatus(true); |
| 183 |
| 184 // Stats callback for CNAME changes. |
| 185 rtp_rtcp_->RegisterRtcpStatisticsCallback(receive_stats_proxy); |
| 186 |
| 187 process_thread_->RegisterModule(rtp_receive_statistics_.get()); |
| 188 process_thread_->RegisterModule(rtp_rtcp_.get()); |
121 } | 189 } |
122 | 190 |
123 RtpStreamReceiver::~RtpStreamReceiver() { | 191 RtpStreamReceiver::~RtpStreamReceiver() { |
| 192 process_thread_->DeRegisterModule(rtp_receive_statistics_.get()); |
| 193 process_thread_->DeRegisterModule(rtp_rtcp_.get()); |
| 194 |
124 packet_router_->RemoveRtpModule(rtp_rtcp_.get()); | 195 packet_router_->RemoveRtpModule(rtp_rtcp_.get()); |
| 196 rtp_rtcp_->SetREMBStatus(false); |
| 197 remb_->RemoveReceiveChannel(rtp_rtcp_.get()); |
125 UpdateHistograms(); | 198 UpdateHistograms(); |
126 } | 199 } |
127 | 200 |
128 void RtpStreamReceiver::UpdateHistograms() { | |
129 FecPacketCounter counter = fec_receiver_->GetPacketCounter(); | |
130 if (counter.num_packets > 0) { | |
131 RTC_LOGGED_HISTOGRAM_PERCENTAGE( | |
132 "WebRTC.Video.ReceivedFecPacketsInPercent", | |
133 static_cast<int>(counter.num_fec_packets * 100 / counter.num_packets)); | |
134 } | |
135 if (counter.num_fec_packets > 0) { | |
136 RTC_LOGGED_HISTOGRAM_PERCENTAGE( | |
137 "WebRTC.Video.RecoveredMediaPacketsInPercentOfFec", | |
138 static_cast<int>(counter.num_recovered_packets * 100 / | |
139 counter.num_fec_packets)); | |
140 } | |
141 } | |
142 | |
143 bool RtpStreamReceiver::SetReceiveCodec(const VideoCodec& video_codec) { | 201 bool RtpStreamReceiver::SetReceiveCodec(const VideoCodec& video_codec) { |
144 int8_t old_pltype = -1; | 202 int8_t old_pltype = -1; |
145 if (rtp_payload_registry_.ReceivePayloadType( | 203 if (rtp_payload_registry_.ReceivePayloadType( |
146 video_codec.plName, kVideoPayloadTypeFrequency, 0, | 204 video_codec.plName, kVideoPayloadTypeFrequency, 0, |
147 video_codec.maxBitrate, &old_pltype) != -1) { | 205 video_codec.maxBitrate, &old_pltype) != -1) { |
148 rtp_payload_registry_.DeRegisterReceivePayload(old_pltype); | 206 rtp_payload_registry_.DeRegisterReceivePayload(old_pltype); |
149 } | 207 } |
150 | 208 |
151 return rtp_receiver_->RegisterReceivePayload( | 209 return rtp_receiver_->RegisterReceivePayload( |
152 video_codec.plName, video_codec.plType, kVideoPayloadTypeFrequency, | 210 video_codec.plName, video_codec.plType, kVideoPayloadTypeFrequency, |
153 0, 0) == 0; | 211 0, 0) == 0; |
154 } | 212 } |
155 | 213 |
156 void RtpStreamReceiver::SetRtxPayloadType(int payload_type, | |
157 int associated_payload_type) { | |
158 rtp_payload_registry_.SetRtxPayloadType(payload_type, | |
159 associated_payload_type); | |
160 } | |
161 | |
162 void RtpStreamReceiver::SetUseRtxPayloadMappingOnRestore(bool val) { | |
163 rtp_payload_registry_.set_use_rtx_payload_mapping_on_restore(val); | |
164 } | |
165 | |
166 void RtpStreamReceiver::SetRtxSsrc(uint32_t ssrc) { | |
167 rtp_payload_registry_.SetRtxSsrc(ssrc); | |
168 } | |
169 | |
170 bool RtpStreamReceiver::GetRtxSsrc(uint32_t* ssrc) const { | |
171 return rtp_payload_registry_.GetRtxSsrc(ssrc); | |
172 } | |
173 | |
174 bool RtpStreamReceiver::IsFecEnabled() const { | |
175 return rtp_payload_registry_.ulpfec_payload_type() > -1; | |
176 } | |
177 | |
178 uint32_t RtpStreamReceiver::GetRemoteSsrc() const { | 214 uint32_t RtpStreamReceiver::GetRemoteSsrc() const { |
179 return rtp_receiver_->SSRC(); | 215 return rtp_receiver_->SSRC(); |
180 } | 216 } |
181 | 217 |
182 int RtpStreamReceiver::GetCsrcs(uint32_t* csrcs) const { | 218 int RtpStreamReceiver::GetCsrcs(uint32_t* csrcs) const { |
183 return rtp_receiver_->CSRCs(csrcs); | 219 return rtp_receiver_->CSRCs(csrcs); |
184 } | 220 } |
185 | 221 |
186 RtpReceiver* RtpStreamReceiver::GetRtpReceiver() const { | 222 RtpReceiver* RtpStreamReceiver::GetRtpReceiver() const { |
187 return rtp_receiver_.get(); | 223 return rtp_receiver_.get(); |
188 } | 224 } |
189 | 225 |
190 void RtpStreamReceiver::EnableReceiveRtpHeaderExtension( | |
191 const std::string& extension, int id) { | |
192 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension)); | |
193 RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension( | |
194 StringToRtpExtensionType(extension), id)); | |
195 } | |
196 | |
197 int32_t RtpStreamReceiver::OnReceivedPayloadData( | 226 int32_t RtpStreamReceiver::OnReceivedPayloadData( |
198 const uint8_t* payload_data, | 227 const uint8_t* payload_data, |
199 const size_t payload_size, | 228 const size_t payload_size, |
200 const WebRtcRTPHeader* rtp_header) { | 229 const WebRtcRTPHeader* rtp_header) { |
201 RTC_DCHECK(video_receiver_); | 230 RTC_DCHECK(video_receiver_); |
202 WebRtcRTPHeader rtp_header_with_ntp = *rtp_header; | 231 WebRtcRTPHeader rtp_header_with_ntp = *rtp_header; |
203 rtp_header_with_ntp.ntp_time_ms = | 232 rtp_header_with_ntp.ntp_time_ms = |
204 ntp_estimator_.Estimate(rtp_header->header.timestamp); | 233 ntp_estimator_.Estimate(rtp_header->header.timestamp); |
205 if (video_receiver_->IncomingPacket(payload_data, payload_size, | 234 if (video_receiver_->IncomingPacket(payload_data, payload_size, |
206 rtp_header_with_ntp) != 0) { | 235 rtp_header_with_ntp) != 0) { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 int32_t RtpStreamReceiver::RequestKeyFrame() { | 326 int32_t RtpStreamReceiver::RequestKeyFrame() { |
298 return rtp_rtcp_->RequestKeyFrame(); | 327 return rtp_rtcp_->RequestKeyFrame(); |
299 } | 328 } |
300 | 329 |
301 int32_t RtpStreamReceiver::SliceLossIndicationRequest( | 330 int32_t RtpStreamReceiver::SliceLossIndicationRequest( |
302 const uint64_t picture_id) { | 331 const uint64_t picture_id) { |
303 return rtp_rtcp_->SendRTCPSliceLossIndication( | 332 return rtp_rtcp_->SendRTCPSliceLossIndication( |
304 static_cast<uint8_t>(picture_id)); | 333 static_cast<uint8_t>(picture_id)); |
305 } | 334 } |
306 | 335 |
| 336 bool RtpStreamReceiver::IsFecEnabled() const { |
| 337 return config_.rtp.fec.red_payload_type != -1 && |
| 338 config_.rtp.fec.ulpfec_payload_type != -1; |
| 339 } |
| 340 |
| 341 bool RtpStreamReceiver::IsRetransmissionsEnabled() const { |
| 342 return config_.rtp.nack.rtp_history_ms > 0; |
| 343 } |
| 344 |
| 345 void RtpStreamReceiver::RequestPacketRetransmit( |
| 346 const std::vector<uint16_t>& sequence_numbers) { |
| 347 rtp_rtcp_->SendNack(sequence_numbers); |
| 348 } |
| 349 |
307 int32_t RtpStreamReceiver::ResendPackets(const uint16_t* sequence_numbers, | 350 int32_t RtpStreamReceiver::ResendPackets(const uint16_t* sequence_numbers, |
308 uint16_t length) { | 351 uint16_t length) { |
309 return rtp_rtcp_->SendNACK(sequence_numbers, length); | 352 return rtp_rtcp_->SendNACK(sequence_numbers, length); |
310 } | 353 } |
311 | 354 |
312 bool RtpStreamReceiver::ReceivePacket(const uint8_t* packet, | 355 bool RtpStreamReceiver::ReceivePacket(const uint8_t* packet, |
313 size_t packet_length, | 356 size_t packet_length, |
314 const RTPHeader& header, | 357 const RTPHeader& header, |
315 bool in_order) { | 358 bool in_order) { |
316 if (rtp_payload_registry_.IsEncapsulated(header)) { | 359 if (rtp_payload_registry_.IsEncapsulated(header)) { |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 if (rtp_rtcp_->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr, | 468 if (rtp_rtcp_->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr, |
426 &rtp_timestamp) != 0) { | 469 &rtp_timestamp) != 0) { |
427 // Waiting for RTCP. | 470 // Waiting for RTCP. |
428 return true; | 471 return true; |
429 } | 472 } |
430 ntp_estimator_.UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp); | 473 ntp_estimator_.UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp); |
431 | 474 |
432 return true; | 475 return true; |
433 } | 476 } |
434 | 477 |
| 478 void RtpStreamReceiver::SignalNetworkState(NetworkState state) { |
| 479 rtp_rtcp_->SetRTCPStatus(state == kNetworkUp ? config_.rtp.rtcp_mode |
| 480 : RtcpMode::kOff); |
| 481 } |
| 482 |
435 void RtpStreamReceiver::StartReceive() { | 483 void RtpStreamReceiver::StartReceive() { |
436 rtc::CritScope lock(&receive_cs_); | 484 rtc::CritScope lock(&receive_cs_); |
437 receiving_ = true; | 485 receiving_ = true; |
438 } | 486 } |
439 | 487 |
440 void RtpStreamReceiver::StopReceive() { | 488 void RtpStreamReceiver::StopReceive() { |
441 rtc::CritScope lock(&receive_cs_); | 489 rtc::CritScope lock(&receive_cs_); |
442 receiving_ = false; | 490 receiving_ = false; |
443 } | 491 } |
444 | 492 |
445 ReceiveStatistics* RtpStreamReceiver::GetReceiveStatistics() const { | |
446 return rtp_receive_statistics_.get(); | |
447 } | |
448 | |
449 bool RtpStreamReceiver::IsPacketInOrder(const RTPHeader& header) const { | 493 bool RtpStreamReceiver::IsPacketInOrder(const RTPHeader& header) const { |
450 StreamStatistician* statistician = | 494 StreamStatistician* statistician = |
451 rtp_receive_statistics_->GetStatistician(header.ssrc); | 495 rtp_receive_statistics_->GetStatistician(header.ssrc); |
452 if (!statistician) | 496 if (!statistician) |
453 return false; | 497 return false; |
454 return statistician->IsPacketInOrder(header.sequenceNumber); | 498 return statistician->IsPacketInOrder(header.sequenceNumber); |
455 } | 499 } |
456 | 500 |
457 bool RtpStreamReceiver::IsPacketRetransmitted(const RTPHeader& header, | 501 bool RtpStreamReceiver::IsPacketRetransmitted(const RTPHeader& header, |
458 bool in_order) const { | 502 bool in_order) const { |
459 // Retransmissions are handled separately if RTX is enabled. | 503 // Retransmissions are handled separately if RTX is enabled. |
460 if (rtp_payload_registry_.RtxEnabled()) | 504 if (rtp_payload_registry_.RtxEnabled()) |
461 return false; | 505 return false; |
462 StreamStatistician* statistician = | 506 StreamStatistician* statistician = |
463 rtp_receive_statistics_->GetStatistician(header.ssrc); | 507 rtp_receive_statistics_->GetStatistician(header.ssrc); |
464 if (!statistician) | 508 if (!statistician) |
465 return false; | 509 return false; |
466 // Check if this is a retransmission. | 510 // Check if this is a retransmission. |
467 int64_t min_rtt = 0; | 511 int64_t min_rtt = 0; |
468 rtp_rtcp_->RTT(rtp_receiver_->SSRC(), nullptr, nullptr, &min_rtt, nullptr); | 512 rtp_rtcp_->RTT(rtp_receiver_->SSRC(), nullptr, nullptr, &min_rtt, nullptr); |
469 return !in_order && | 513 return !in_order && |
470 statistician->IsRetransmitOfOldPacket(header, min_rtt); | 514 statistician->IsRetransmitOfOldPacket(header, min_rtt); |
471 } | 515 } |
| 516 |
| 517 void RtpStreamReceiver::UpdateHistograms() { |
| 518 FecPacketCounter counter = fec_receiver_->GetPacketCounter(); |
| 519 if (counter.num_packets > 0) { |
| 520 RTC_LOGGED_HISTOGRAM_PERCENTAGE( |
| 521 "WebRTC.Video.ReceivedFecPacketsInPercent", |
| 522 static_cast<int>(counter.num_fec_packets * 100 / counter.num_packets)); |
| 523 } |
| 524 if (counter.num_fec_packets > 0) { |
| 525 RTC_LOGGED_HISTOGRAM_PERCENTAGE( |
| 526 "WebRTC.Video.RecoveredMediaPacketsInPercentOfFec", |
| 527 static_cast<int>(counter.num_recovered_packets * 100 / |
| 528 counter.num_fec_packets)); |
| 529 } |
| 530 } |
| 531 |
| 532 void RtpStreamReceiver::EnableReceiveRtpHeaderExtension( |
| 533 const std::string& extension, int id) { |
| 534 // One-byte-extension local identifiers are in the range 1-14 inclusive. |
| 535 RTC_DCHECK_GE(id, 1); |
| 536 RTC_DCHECK_LE(id, 14); |
| 537 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension)); |
| 538 RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension( |
| 539 StringToRtpExtensionType(extension), id)); |
| 540 } |
| 541 |
472 } // namespace webrtc | 542 } // namespace webrtc |
OLD | NEW |