| 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 |