Chromium Code Reviews| 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 |