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 (config_.rtp.fec.ulpfec_payload_type != -1) { | |
philipel
2016/05/06 08:56:19
Check both FEC and RED and warn if one is set but
mflodman
2016/05/06 09:15:06
Done.
| |
163 // ULPFEC without RED doesn't make sense. | |
164 RTC_DCHECK(config_.rtp.fec.red_payload_type != -1); | |
165 VideoCodec codec; | |
philipel
2016/05/06 08:56:18
VideoCodec codec = {}; and remove memset on line 1
mflodman
2016/05/06 09:15:06
Done.
| |
166 memset(&codec, 0, sizeof(codec)); | |
167 codec.codecType = kVideoCodecULPFEC; | |
168 strncpy(codec.plName, "ulpfec", sizeof(codec.plName)); | |
169 codec.plType = config_.rtp.fec.ulpfec_payload_type; | |
170 RTC_CHECK(SetReceiveCodec(codec)); | |
171 } | |
172 if (config_.rtp.fec.red_payload_type != -1) { | |
philipel
2016/05/06 08:56:18
Merge this block of code with the block above.
mflodman
2016/05/06 09:15:06
Done.
| |
173 VideoCodec codec; | |
174 memset(&codec, 0, sizeof(codec)); | |
175 codec.codecType = kVideoCodecRED; | |
176 strncpy(codec.plName, "red", sizeof(codec.plName)); | |
177 codec.plType = config_.rtp.fec.red_payload_type; | |
178 RTC_CHECK(SetReceiveCodec(codec)); | |
179 if (config_.rtp.fec.red_rtx_payload_type != -1) { | |
180 rtp_payload_registry_.SetRtxPayloadType( | |
181 config_.rtp.fec.red_rtx_payload_type, | |
182 config_.rtp.fec.red_payload_type); | |
183 } | |
184 } | |
185 | |
186 if (config.rtp.rtcp_xr.receiver_reference_time_report) | |
187 rtp_rtcp_->SetRtcpXrRrtrStatus(true); | |
188 | |
189 // Stats callback for CNAME changes. | |
190 rtp_rtcp_->RegisterRtcpStatisticsCallback(receive_stats_proxy); | |
191 | |
192 process_thread_->RegisterModule(rtp_receive_statistics_.get()); | |
193 process_thread_->RegisterModule(rtp_rtcp_.get()); | |
121 } | 194 } |
122 | 195 |
123 RtpStreamReceiver::~RtpStreamReceiver() { | 196 RtpStreamReceiver::~RtpStreamReceiver() { |
197 process_thread_->DeRegisterModule(rtp_receive_statistics_.get()); | |
198 process_thread_->DeRegisterModule(rtp_rtcp_.get()); | |
199 | |
124 packet_router_->RemoveRtpModule(rtp_rtcp_.get()); | 200 packet_router_->RemoveRtpModule(rtp_rtcp_.get()); |
201 rtp_rtcp_->SetREMBStatus(false); | |
202 remb_->RemoveReceiveChannel(rtp_rtcp_.get()); | |
125 UpdateHistograms(); | 203 UpdateHistograms(); |
126 } | 204 } |
127 | 205 |
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) { | 206 bool RtpStreamReceiver::SetReceiveCodec(const VideoCodec& video_codec) { |
144 int8_t old_pltype = -1; | 207 int8_t old_pltype = -1; |
145 if (rtp_payload_registry_.ReceivePayloadType( | 208 if (rtp_payload_registry_.ReceivePayloadType( |
146 video_codec.plName, kVideoPayloadTypeFrequency, 0, | 209 video_codec.plName, kVideoPayloadTypeFrequency, 0, |
147 video_codec.maxBitrate, &old_pltype) != -1) { | 210 video_codec.maxBitrate, &old_pltype) != -1) { |
148 rtp_payload_registry_.DeRegisterReceivePayload(old_pltype); | 211 rtp_payload_registry_.DeRegisterReceivePayload(old_pltype); |
149 } | 212 } |
150 | 213 |
151 return rtp_receiver_->RegisterReceivePayload( | 214 return rtp_receiver_->RegisterReceivePayload( |
152 video_codec.plName, video_codec.plType, kVideoPayloadTypeFrequency, | 215 video_codec.plName, video_codec.plType, kVideoPayloadTypeFrequency, |
153 0, 0) == 0; | 216 0, 0) == 0; |
154 } | 217 } |
155 | 218 |
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 { | 219 uint32_t RtpStreamReceiver::GetRemoteSsrc() const { |
179 return rtp_receiver_->SSRC(); | 220 return rtp_receiver_->SSRC(); |
180 } | 221 } |
181 | 222 |
182 int RtpStreamReceiver::GetCsrcs(uint32_t* csrcs) const { | 223 int RtpStreamReceiver::GetCsrcs(uint32_t* csrcs) const { |
183 return rtp_receiver_->CSRCs(csrcs); | 224 return rtp_receiver_->CSRCs(csrcs); |
184 } | 225 } |
185 | 226 |
186 RtpReceiver* RtpStreamReceiver::GetRtpReceiver() const { | 227 RtpReceiver* RtpStreamReceiver::GetRtpReceiver() const { |
187 return rtp_receiver_.get(); | 228 return rtp_receiver_.get(); |
188 } | 229 } |
189 | 230 |
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( | 231 int32_t RtpStreamReceiver::OnReceivedPayloadData( |
198 const uint8_t* payload_data, | 232 const uint8_t* payload_data, |
199 const size_t payload_size, | 233 const size_t payload_size, |
200 const WebRtcRTPHeader* rtp_header) { | 234 const WebRtcRTPHeader* rtp_header) { |
201 RTC_DCHECK(video_receiver_); | 235 RTC_DCHECK(video_receiver_); |
202 WebRtcRTPHeader rtp_header_with_ntp = *rtp_header; | 236 WebRtcRTPHeader rtp_header_with_ntp = *rtp_header; |
203 rtp_header_with_ntp.ntp_time_ms = | 237 rtp_header_with_ntp.ntp_time_ms = |
204 ntp_estimator_.Estimate(rtp_header->header.timestamp); | 238 ntp_estimator_.Estimate(rtp_header->header.timestamp); |
205 if (video_receiver_->IncomingPacket(payload_data, payload_size, | 239 if (video_receiver_->IncomingPacket(payload_data, payload_size, |
206 rtp_header_with_ntp) != 0) { | 240 rtp_header_with_ntp) != 0) { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
297 int32_t RtpStreamReceiver::RequestKeyFrame() { | 331 int32_t RtpStreamReceiver::RequestKeyFrame() { |
298 return rtp_rtcp_->RequestKeyFrame(); | 332 return rtp_rtcp_->RequestKeyFrame(); |
299 } | 333 } |
300 | 334 |
301 int32_t RtpStreamReceiver::SliceLossIndicationRequest( | 335 int32_t RtpStreamReceiver::SliceLossIndicationRequest( |
302 const uint64_t picture_id) { | 336 const uint64_t picture_id) { |
303 return rtp_rtcp_->SendRTCPSliceLossIndication( | 337 return rtp_rtcp_->SendRTCPSliceLossIndication( |
304 static_cast<uint8_t>(picture_id)); | 338 static_cast<uint8_t>(picture_id)); |
305 } | 339 } |
306 | 340 |
341 bool RtpStreamReceiver::IsFecEnabled() const { | |
342 return config_.rtp.fec.red_payload_type != -1 && | |
343 config_.rtp.fec.ulpfec_payload_type != -1; | |
344 } | |
345 | |
346 bool RtpStreamReceiver::IsRetransmissionsEnabled() const { | |
347 return config_.rtp.nack.rtp_history_ms > 0; | |
348 } | |
349 | |
350 void RtpStreamReceiver::RequestPacketRetransmit( | |
351 const std::vector<uint16_t>& sequence_numbers) { | |
352 rtp_rtcp_->SendNack(sequence_numbers); | |
353 } | |
354 | |
307 int32_t RtpStreamReceiver::ResendPackets(const uint16_t* sequence_numbers, | 355 int32_t RtpStreamReceiver::ResendPackets(const uint16_t* sequence_numbers, |
308 uint16_t length) { | 356 uint16_t length) { |
309 return rtp_rtcp_->SendNACK(sequence_numbers, length); | 357 std::vector<uint16_t> sequence_number_vector(sequence_numbers, |
358 sequence_numbers + length); | |
359 rtp_rtcp_->SendNack(sequence_number_vector); | |
philipel
2016/05/06 08:56:18
Is the SendNACK function used anymore? If not it w
mflodman
2016/05/06 09:15:06
I just learnt the functionality is a bit different
| |
360 return 0; | |
310 } | 361 } |
311 | 362 |
312 bool RtpStreamReceiver::ReceivePacket(const uint8_t* packet, | 363 bool RtpStreamReceiver::ReceivePacket(const uint8_t* packet, |
313 size_t packet_length, | 364 size_t packet_length, |
314 const RTPHeader& header, | 365 const RTPHeader& header, |
315 bool in_order) { | 366 bool in_order) { |
316 if (rtp_payload_registry_.IsEncapsulated(header)) { | 367 if (rtp_payload_registry_.IsEncapsulated(header)) { |
317 return ParseAndHandleEncapsulatingHeader(packet, packet_length, header); | 368 return ParseAndHandleEncapsulatingHeader(packet, packet_length, header); |
318 } | 369 } |
319 const uint8_t* payload = packet + header.headerLength; | 370 const uint8_t* payload = packet + header.headerLength; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
425 if (rtp_rtcp_->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr, | 476 if (rtp_rtcp_->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr, |
426 &rtp_timestamp) != 0) { | 477 &rtp_timestamp) != 0) { |
427 // Waiting for RTCP. | 478 // Waiting for RTCP. |
428 return true; | 479 return true; |
429 } | 480 } |
430 ntp_estimator_.UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp); | 481 ntp_estimator_.UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp); |
431 | 482 |
432 return true; | 483 return true; |
433 } | 484 } |
434 | 485 |
486 void RtpStreamReceiver::SignalNetworkState(NetworkState state) { | |
487 rtp_rtcp_->SetRTCPStatus(state == kNetworkUp ? config_.rtp.rtcp_mode | |
488 : RtcpMode::kOff); | |
489 } | |
490 | |
435 void RtpStreamReceiver::StartReceive() { | 491 void RtpStreamReceiver::StartReceive() { |
436 rtc::CritScope lock(&receive_cs_); | 492 rtc::CritScope lock(&receive_cs_); |
437 receiving_ = true; | 493 receiving_ = true; |
438 } | 494 } |
439 | 495 |
440 void RtpStreamReceiver::StopReceive() { | 496 void RtpStreamReceiver::StopReceive() { |
441 rtc::CritScope lock(&receive_cs_); | 497 rtc::CritScope lock(&receive_cs_); |
442 receiving_ = false; | 498 receiving_ = false; |
443 } | 499 } |
444 | 500 |
445 ReceiveStatistics* RtpStreamReceiver::GetReceiveStatistics() const { | |
446 return rtp_receive_statistics_.get(); | |
447 } | |
448 | |
449 bool RtpStreamReceiver::IsPacketInOrder(const RTPHeader& header) const { | 501 bool RtpStreamReceiver::IsPacketInOrder(const RTPHeader& header) const { |
450 StreamStatistician* statistician = | 502 StreamStatistician* statistician = |
451 rtp_receive_statistics_->GetStatistician(header.ssrc); | 503 rtp_receive_statistics_->GetStatistician(header.ssrc); |
452 if (!statistician) | 504 if (!statistician) |
453 return false; | 505 return false; |
454 return statistician->IsPacketInOrder(header.sequenceNumber); | 506 return statistician->IsPacketInOrder(header.sequenceNumber); |
455 } | 507 } |
456 | 508 |
457 bool RtpStreamReceiver::IsPacketRetransmitted(const RTPHeader& header, | 509 bool RtpStreamReceiver::IsPacketRetransmitted(const RTPHeader& header, |
458 bool in_order) const { | 510 bool in_order) const { |
459 // Retransmissions are handled separately if RTX is enabled. | 511 // Retransmissions are handled separately if RTX is enabled. |
460 if (rtp_payload_registry_.RtxEnabled()) | 512 if (rtp_payload_registry_.RtxEnabled()) |
461 return false; | 513 return false; |
462 StreamStatistician* statistician = | 514 StreamStatistician* statistician = |
463 rtp_receive_statistics_->GetStatistician(header.ssrc); | 515 rtp_receive_statistics_->GetStatistician(header.ssrc); |
464 if (!statistician) | 516 if (!statistician) |
465 return false; | 517 return false; |
466 // Check if this is a retransmission. | 518 // Check if this is a retransmission. |
467 int64_t min_rtt = 0; | 519 int64_t min_rtt = 0; |
468 rtp_rtcp_->RTT(rtp_receiver_->SSRC(), nullptr, nullptr, &min_rtt, nullptr); | 520 rtp_rtcp_->RTT(rtp_receiver_->SSRC(), nullptr, nullptr, &min_rtt, nullptr); |
469 return !in_order && | 521 return !in_order && |
470 statistician->IsRetransmitOfOldPacket(header, min_rtt); | 522 statistician->IsRetransmitOfOldPacket(header, min_rtt); |
471 } | 523 } |
524 | |
525 void RtpStreamReceiver::UpdateHistograms() { | |
526 FecPacketCounter counter = fec_receiver_->GetPacketCounter(); | |
527 if (counter.num_packets > 0) { | |
528 RTC_LOGGED_HISTOGRAM_PERCENTAGE( | |
529 "WebRTC.Video.ReceivedFecPacketsInPercent", | |
530 static_cast<int>(counter.num_fec_packets * 100 / counter.num_packets)); | |
531 } | |
532 if (counter.num_fec_packets > 0) { | |
533 RTC_LOGGED_HISTOGRAM_PERCENTAGE( | |
534 "WebRTC.Video.RecoveredMediaPacketsInPercentOfFec", | |
535 static_cast<int>(counter.num_recovered_packets * 100 / | |
536 counter.num_fec_packets)); | |
537 } | |
538 } | |
539 | |
540 void RtpStreamReceiver::EnableReceiveRtpHeaderExtension( | |
541 const std::string& extension, int id) { | |
542 // One-byte-extension local identifiers are in the range 1-14 inclusive. | |
543 RTC_DCHECK_GE(id, 1); | |
544 RTC_DCHECK_LE(id, 14); | |
545 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension)); | |
546 RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension( | |
547 StringToRtpExtensionType(extension), id)); | |
548 } | |
549 | |
472 } // namespace webrtc | 550 } // namespace webrtc |
OLD | NEW |