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 |
| 11 #include "webrtc/video/vie_receiver.h" | 11 #include "webrtc/video/vie_receiver.h" |
| 12 | 12 |
| 13 #include <vector> | 13 #include <vector> |
| 14 | 14 |
| 15 #include "webrtc/base/logging.h" | 15 #include "webrtc/base/logging.h" |
| 16 #include "webrtc/config.h" | 16 #include "webrtc/config.h" |
| 17 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat or.h" | 17 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat or.h" |
| 18 #include "webrtc/modules/rtp_rtcp/include/fec_receiver.h" | 18 #include "webrtc/modules/rtp_rtcp/include/fec_receiver.h" |
| 19 #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h" | 19 #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h" |
| 20 #include "webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h" | |
| 21 #include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h" | 20 #include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h" |
| 22 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" | 21 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" |
| 23 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" | |
| 24 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" | 22 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" |
| 25 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" | 23 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" |
| 26 #include "webrtc/modules/video_coding/include/video_coding.h" | 24 #include "webrtc/modules/video_coding/include/video_coding.h" |
| 27 #include "webrtc/system_wrappers/include/metrics.h" | 25 #include "webrtc/system_wrappers/include/metrics.h" |
| 28 #include "webrtc/system_wrappers/include/tick_util.h" | 26 #include "webrtc/system_wrappers/include/tick_util.h" |
| 29 #include "webrtc/system_wrappers/include/timestamp_extrapolator.h" | 27 #include "webrtc/system_wrappers/include/timestamp_extrapolator.h" |
| 30 #include "webrtc/system_wrappers/include/trace.h" | 28 #include "webrtc/system_wrappers/include/trace.h" |
| 31 | 29 |
| 32 namespace webrtc { | 30 namespace webrtc { |
| 33 | 31 |
| 34 static const int kPacketLogIntervalMs = 10000; | 32 static const int kPacketLogIntervalMs = 10000; |
| 35 | 33 |
| 36 ViEReceiver::ViEReceiver(VideoCodingModule* module_vcm, | 34 ViEReceiver::ViEReceiver(VideoCodingModule* module_vcm, |
| 37 RemoteBitrateEstimator* remote_bitrate_estimator, | 35 RemoteBitrateEstimator* remote_bitrate_estimator, |
| 38 RtpFeedback* rtp_feedback) | 36 RtpFeedback* rtp_feedback) |
| 39 : clock_(Clock::GetRealTimeClock()), | 37 : clock_(Clock::GetRealTimeClock()), |
| 38 vcm_(module_vcm), | |
| 39 remote_bitrate_estimator_(remote_bitrate_estimator), | |
| 40 ntp_estimator_(clock_), | |
| 41 rtp_payload_registry_(RTPPayloadStrategy::CreateStrategy(false)), | |
| 40 rtp_header_parser_(RtpHeaderParser::Create()), | 42 rtp_header_parser_(RtpHeaderParser::Create()), |
| 41 rtp_payload_registry_( | 43 rtp_receiver_(RtpReceiver::CreateVideoReceiver(clock_, |
| 42 new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(false))), | 44 this, |
| 43 rtp_receiver_( | 45 rtp_feedback, |
| 44 RtpReceiver::CreateVideoReceiver(clock_, | 46 &rtp_payload_registry_)), |
| 45 this, | |
| 46 rtp_feedback, | |
| 47 rtp_payload_registry_.get())), | |
| 48 rtp_receive_statistics_(ReceiveStatistics::Create(clock_)), | 47 rtp_receive_statistics_(ReceiveStatistics::Create(clock_)), |
| 49 fec_receiver_(FecReceiver::Create(this)), | 48 fec_receiver_(FecReceiver::Create(this)), |
| 50 rtp_rtcp_(NULL), | |
| 51 vcm_(module_vcm), | |
| 52 remote_bitrate_estimator_(remote_bitrate_estimator), | |
| 53 ntp_estimator_(new RemoteNtpTimeEstimator(clock_)), | |
| 54 receiving_(false), | 49 receiving_(false), |
| 55 restored_packet_in_use_(false), | 50 restored_packet_in_use_(false), |
| 56 last_packet_log_ms_(-1) {} | 51 last_packet_log_ms_(-1) {} |
| 57 | 52 |
| 58 ViEReceiver::~ViEReceiver() { | 53 ViEReceiver::~ViEReceiver() { |
| 59 UpdateHistograms(); | 54 UpdateHistograms(); |
| 60 } | 55 } |
| 61 | 56 |
| 62 void ViEReceiver::UpdateHistograms() { | 57 void ViEReceiver::UpdateHistograms() { |
| 63 FecPacketCounter counter = fec_receiver_->GetPacketCounter(); | 58 FecPacketCounter counter = fec_receiver_->GetPacketCounter(); |
| 64 if (counter.num_packets > 0) { | 59 if (counter.num_packets > 0) { |
| 65 RTC_HISTOGRAM_PERCENTAGE( | 60 RTC_HISTOGRAM_PERCENTAGE( |
| 66 "WebRTC.Video.ReceivedFecPacketsInPercent", | 61 "WebRTC.Video.ReceivedFecPacketsInPercent", |
| 67 static_cast<int>(counter.num_fec_packets * 100 / counter.num_packets)); | 62 static_cast<int>(counter.num_fec_packets * 100 / counter.num_packets)); |
| 68 } | 63 } |
| 69 if (counter.num_fec_packets > 0) { | 64 if (counter.num_fec_packets > 0) { |
| 70 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.RecoveredMediaPacketsInPercentOfFec", | 65 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.RecoveredMediaPacketsInPercentOfFec", |
| 71 static_cast<int>(counter.num_recovered_packets * | 66 static_cast<int>(counter.num_recovered_packets * |
| 72 100 / counter.num_fec_packets)); | 67 100 / counter.num_fec_packets)); |
| 73 } | 68 } |
| 74 } | 69 } |
| 75 | 70 |
| 76 bool ViEReceiver::SetReceiveCodec(const VideoCodec& video_codec) { | 71 bool ViEReceiver::SetReceiveCodec(const VideoCodec& video_codec) { |
| 77 int8_t old_pltype = -1; | 72 int8_t old_pltype = -1; |
| 78 if (rtp_payload_registry_->ReceivePayloadType(video_codec.plName, | 73 if (rtp_payload_registry_.ReceivePayloadType(video_codec.plName, |
| 79 kVideoPayloadTypeFrequency, | 74 kVideoPayloadTypeFrequency, |
| 80 0, | 75 0, |
| 81 video_codec.maxBitrate, | 76 video_codec.maxBitrate, |
| 82 &old_pltype) != -1) { | 77 &old_pltype) != -1) { |
| 83 rtp_payload_registry_->DeRegisterReceivePayload(old_pltype); | 78 rtp_payload_registry_.DeRegisterReceivePayload(old_pltype); |
| 84 } | 79 } |
| 85 | 80 |
| 86 return RegisterPayload(video_codec); | 81 return rtp_receiver_->RegisterReceivePayload( |
| 87 } | 82 video_codec.plName, video_codec.plType, kVideoPayloadTypeFrequency, |
| 88 | 83 0, 0) == 0; |
| 89 bool ViEReceiver::RegisterPayload(const VideoCodec& video_codec) { | |
| 90 return rtp_receiver_->RegisterReceivePayload(video_codec.plName, | |
| 91 video_codec.plType, | |
| 92 kVideoPayloadTypeFrequency, | |
| 93 0, | |
| 94 video_codec.maxBitrate) == 0; | |
| 95 } | 84 } |
| 96 | 85 |
| 97 void ViEReceiver::SetNackStatus(bool enable, | 86 void ViEReceiver::SetNackStatus(bool enable, |
| 98 int max_nack_reordering_threshold) { | 87 int max_nack_reordering_threshold) { |
| 99 if (!enable) { | 88 if (!enable) { |
| 100 // Reset the threshold back to the lower default threshold when NACK is | 89 // Reset the threshold back to the lower default threshold when NACK is |
| 101 // disabled since we no longer will be receiving retransmissions. | 90 // disabled since we no longer will be receiving retransmissions. |
| 102 max_nack_reordering_threshold = kDefaultMaxReorderingThreshold; | 91 max_nack_reordering_threshold = kDefaultMaxReorderingThreshold; |
| 103 } | 92 } |
| 104 rtp_receive_statistics_->SetMaxReorderingThreshold( | 93 rtp_receive_statistics_->SetMaxReorderingThreshold( |
| 105 max_nack_reordering_threshold); | 94 max_nack_reordering_threshold); |
| 106 rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff); | 95 rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff); |
| 107 } | 96 } |
| 108 | 97 |
| 109 void ViEReceiver::SetRtxPayloadType(int payload_type, | 98 void ViEReceiver::SetRtxPayloadType(int payload_type, |
| 110 int associated_payload_type) { | 99 int associated_payload_type) { |
| 111 rtp_payload_registry_->SetRtxPayloadType(payload_type, | 100 rtp_payload_registry_.SetRtxPayloadType(payload_type, |
| 112 associated_payload_type); | 101 associated_payload_type); |
| 113 } | 102 } |
| 114 | 103 |
| 115 void ViEReceiver::SetUseRtxPayloadMappingOnRestore(bool val) { | 104 void ViEReceiver::SetUseRtxPayloadMappingOnRestore(bool val) { |
| 116 rtp_payload_registry_->set_use_rtx_payload_mapping_on_restore(val); | 105 rtp_payload_registry_.set_use_rtx_payload_mapping_on_restore(val); |
| 117 } | 106 } |
| 118 | 107 |
| 119 void ViEReceiver::SetRtxSsrc(uint32_t ssrc) { | 108 void ViEReceiver::SetRtxSsrc(uint32_t ssrc) { |
| 120 rtp_payload_registry_->SetRtxSsrc(ssrc); | 109 rtp_payload_registry_.SetRtxSsrc(ssrc); |
| 121 } | 110 } |
| 122 | 111 |
| 123 bool ViEReceiver::GetRtxSsrc(uint32_t* ssrc) const { | 112 bool ViEReceiver::GetRtxSsrc(uint32_t* ssrc) const { |
| 124 return rtp_payload_registry_->GetRtxSsrc(ssrc); | 113 return rtp_payload_registry_.GetRtxSsrc(ssrc); |
| 125 } | 114 } |
| 126 | 115 |
| 127 bool ViEReceiver::IsFecEnabled() const { | 116 bool ViEReceiver::IsFecEnabled() const { |
| 128 return rtp_payload_registry_->ulpfec_payload_type() > -1; | 117 return rtp_payload_registry_.ulpfec_payload_type() > -1; |
| 129 } | 118 } |
| 130 | 119 |
| 131 uint32_t ViEReceiver::GetRemoteSsrc() const { | 120 uint32_t ViEReceiver::GetRemoteSsrc() const { |
| 132 return rtp_receiver_->SSRC(); | 121 return rtp_receiver_->SSRC(); |
| 133 } | 122 } |
| 134 | 123 |
| 135 int ViEReceiver::GetCsrcs(uint32_t* csrcs) const { | 124 int ViEReceiver::GetCsrcs(uint32_t* csrcs) const { |
| 136 return rtp_receiver_->CSRCs(csrcs); | 125 return rtp_receiver_->CSRCs(csrcs); |
| 137 } | 126 } |
| 138 | 127 |
| 139 void ViEReceiver::SetRtpRtcpModule(RtpRtcp* module) { | 128 void ViEReceiver::Init(const std::vector<RtpRtcp*>& modules) { |
| 140 rtp_rtcp_ = module; | 129 rtp_rtcp_ = modules; |
| 141 } | 130 } |
| 142 | 131 |
| 143 RtpReceiver* ViEReceiver::GetRtpReceiver() const { | 132 RtpReceiver* ViEReceiver::GetRtpReceiver() const { |
| 144 return rtp_receiver_.get(); | 133 return rtp_receiver_.get(); |
| 145 } | 134 } |
| 146 | 135 |
| 147 void ViEReceiver::RegisterRtpRtcpModules( | |
| 148 const std::vector<RtpRtcp*>& rtp_modules) { | |
| 149 rtc::CritScope lock(&receive_cs_); | |
| 150 // Only change the "simulcast" modules, the base module can be accessed | |
| 151 // without a lock whereas the simulcast modules require locking as they can be | |
| 152 // changed in runtime. | |
| 153 rtp_rtcp_simulcast_ = | |
| 154 std::vector<RtpRtcp*>(rtp_modules.begin() + 1, rtp_modules.end()); | |
| 155 } | |
| 156 | |
| 157 void ViEReceiver::EnableReceiveRtpHeaderExtension(const std::string& extension, | 136 void ViEReceiver::EnableReceiveRtpHeaderExtension(const std::string& extension, |
| 158 int id) { | 137 int id) { |
| 159 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension)); | 138 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension)); |
| 160 RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension( | 139 RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension( |
| 161 StringToRtpExtensionType(extension), id)); | 140 StringToRtpExtensionType(extension), id)); |
| 162 } | 141 } |
| 163 | 142 |
| 164 int32_t ViEReceiver::OnReceivedPayloadData(const uint8_t* payload_data, | 143 int32_t ViEReceiver::OnReceivedPayloadData(const uint8_t* payload_data, |
| 165 const size_t payload_size, | 144 const size_t payload_size, |
| 166 const WebRtcRTPHeader* rtp_header) { | 145 const WebRtcRTPHeader* rtp_header) { |
| 167 RTC_DCHECK(vcm_); | 146 RTC_DCHECK(vcm_); |
| 168 WebRtcRTPHeader rtp_header_with_ntp = *rtp_header; | 147 WebRtcRTPHeader rtp_header_with_ntp = *rtp_header; |
| 169 rtp_header_with_ntp.ntp_time_ms = | 148 rtp_header_with_ntp.ntp_time_ms = |
| 170 ntp_estimator_->Estimate(rtp_header->header.timestamp); | 149 ntp_estimator_.Estimate(rtp_header->header.timestamp); |
| 171 if (vcm_->IncomingPacket(payload_data, | 150 if (vcm_->IncomingPacket(payload_data, |
| 172 payload_size, | 151 payload_size, |
| 173 rtp_header_with_ntp) != 0) { | 152 rtp_header_with_ntp) != 0) { |
| 174 // Check this... | 153 // Check this... |
| 175 return -1; | 154 return -1; |
| 176 } | 155 } |
| 177 return 0; | 156 return 0; |
| 178 } | 157 } |
| 179 | 158 |
| 180 bool ViEReceiver::OnRecoveredPacket(const uint8_t* rtp_packet, | 159 bool ViEReceiver::OnRecoveredPacket(const uint8_t* rtp_packet, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 228 LOG(LS_INFO) << ss.str(); | 207 LOG(LS_INFO) << ss.str(); |
| 229 last_packet_log_ms_ = now_ms; | 208 last_packet_log_ms_ = now_ms; |
| 230 } | 209 } |
| 231 } | 210 } |
| 232 | 211 |
| 233 remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_length, | 212 remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_length, |
| 234 header, true); | 213 header, true); |
| 235 header.payload_type_frequency = kVideoPayloadTypeFrequency; | 214 header.payload_type_frequency = kVideoPayloadTypeFrequency; |
| 236 | 215 |
| 237 bool in_order = IsPacketInOrder(header); | 216 bool in_order = IsPacketInOrder(header); |
| 238 rtp_payload_registry_->SetIncomingPayloadType(header); | 217 rtp_payload_registry_.SetIncomingPayloadType(header); |
| 239 bool ret = ReceivePacket(rtp_packet, rtp_packet_length, header, in_order); | 218 bool ret = ReceivePacket(rtp_packet, rtp_packet_length, header, in_order); |
| 240 // Update receive statistics after ReceivePacket. | 219 // Update receive statistics after ReceivePacket. |
| 241 // Receive statistics will be reset if the payload type changes (make sure | 220 // Receive statistics will be reset if the payload type changes (make sure |
| 242 // that the first packet is included in the stats). | 221 // that the first packet is included in the stats). |
| 243 rtp_receive_statistics_->IncomingPacket( | 222 rtp_receive_statistics_->IncomingPacket( |
| 244 header, rtp_packet_length, IsPacketRetransmitted(header, in_order)); | 223 header, rtp_packet_length, IsPacketRetransmitted(header, in_order)); |
| 245 return ret; | 224 return ret; |
| 246 } | 225 } |
| 247 | 226 |
| 248 bool ViEReceiver::ReceivePacket(const uint8_t* packet, | 227 bool ViEReceiver::ReceivePacket(const uint8_t* packet, |
| 249 size_t packet_length, | 228 size_t packet_length, |
| 250 const RTPHeader& header, | 229 const RTPHeader& header, |
| 251 bool in_order) { | 230 bool in_order) { |
| 252 if (rtp_payload_registry_->IsEncapsulated(header)) { | 231 if (rtp_payload_registry_.IsEncapsulated(header)) { |
| 253 return ParseAndHandleEncapsulatingHeader(packet, packet_length, header); | 232 return ParseAndHandleEncapsulatingHeader(packet, packet_length, header); |
| 254 } | 233 } |
| 255 const uint8_t* payload = packet + header.headerLength; | 234 const uint8_t* payload = packet + header.headerLength; |
| 256 assert(packet_length >= header.headerLength); | 235 assert(packet_length >= header.headerLength); |
| 257 size_t payload_length = packet_length - header.headerLength; | 236 size_t payload_length = packet_length - header.headerLength; |
| 258 PayloadUnion payload_specific; | 237 PayloadUnion payload_specific; |
| 259 if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType, | 238 if (!rtp_payload_registry_.GetPayloadSpecifics(header.payloadType, |
| 260 &payload_specific)) { | 239 &payload_specific)) { |
| 261 return false; | 240 return false; |
| 262 } | 241 } |
| 263 return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length, | 242 return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length, |
| 264 payload_specific, in_order); | 243 payload_specific, in_order); |
| 265 } | 244 } |
| 266 | 245 |
| 267 bool ViEReceiver::ParseAndHandleEncapsulatingHeader(const uint8_t* packet, | 246 bool ViEReceiver::ParseAndHandleEncapsulatingHeader(const uint8_t* packet, |
| 268 size_t packet_length, | 247 size_t packet_length, |
| 269 const RTPHeader& header) { | 248 const RTPHeader& header) { |
| 270 if (rtp_payload_registry_->IsRed(header)) { | 249 if (rtp_payload_registry_.IsRed(header)) { |
| 271 int8_t ulpfec_pt = rtp_payload_registry_->ulpfec_payload_type(); | 250 int8_t ulpfec_pt = rtp_payload_registry_.ulpfec_payload_type(); |
| 272 if (packet[header.headerLength] == ulpfec_pt) { | 251 if (packet[header.headerLength] == ulpfec_pt) { |
| 273 rtp_receive_statistics_->FecPacketReceived(header, packet_length); | 252 rtp_receive_statistics_->FecPacketReceived(header, packet_length); |
| 274 // Notify vcm about received FEC packets to avoid NACKing these packets. | 253 // Notify vcm about received FEC packets to avoid NACKing these packets. |
| 275 NotifyReceiverOfFecPacket(header); | 254 NotifyReceiverOfFecPacket(header); |
| 276 } | 255 } |
| 277 if (fec_receiver_->AddReceivedRedPacket( | 256 if (fec_receiver_->AddReceivedRedPacket( |
| 278 header, packet, packet_length, ulpfec_pt) != 0) { | 257 header, packet, packet_length, ulpfec_pt) != 0) { |
| 279 return false; | 258 return false; |
| 280 } | 259 } |
| 281 return fec_receiver_->ProcessReceivedFec() == 0; | 260 return fec_receiver_->ProcessReceivedFec() == 0; |
| 282 } else if (rtp_payload_registry_->IsRtx(header)) { | 261 } else if (rtp_payload_registry_.IsRtx(header)) { |
| 283 if (header.headerLength + header.paddingLength == packet_length) { | 262 if (header.headerLength + header.paddingLength == packet_length) { |
| 284 // This is an empty packet and should be silently dropped before trying to | 263 // This is an empty packet and should be silently dropped before trying to |
| 285 // parse the RTX header. | 264 // parse the RTX header. |
| 286 return true; | 265 return true; |
| 287 } | 266 } |
| 288 // Remove the RTX header and parse the original RTP header. | 267 // Remove the RTX header and parse the original RTP header. |
| 289 if (packet_length < header.headerLength) | 268 if (packet_length < header.headerLength) |
| 290 return false; | 269 return false; |
| 291 if (packet_length > sizeof(restored_packet_)) | 270 if (packet_length > sizeof(restored_packet_)) |
| 292 return false; | 271 return false; |
| 293 rtc::CritScope lock(&receive_cs_); | 272 rtc::CritScope lock(&receive_cs_); |
| 294 if (restored_packet_in_use_) { | 273 if (restored_packet_in_use_) { |
| 295 LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet."; | 274 LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet."; |
| 296 return false; | 275 return false; |
| 297 } | 276 } |
| 298 if (!rtp_payload_registry_->RestoreOriginalPacket( | 277 if (!rtp_payload_registry_.RestoreOriginalPacket( |
| 299 restored_packet_, packet, &packet_length, rtp_receiver_->SSRC(), | 278 restored_packet_, packet, &packet_length, rtp_receiver_->SSRC(), |
| 300 header)) { | 279 header)) { |
| 301 LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header ssrc: " | 280 LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header ssrc: " |
| 302 << header.ssrc << " payload type: " | 281 << header.ssrc << " payload type: " |
| 303 << static_cast<int>(header.payloadType); | 282 << static_cast<int>(header.payloadType); |
| 304 return false; | 283 return false; |
| 305 } | 284 } |
| 306 restored_packet_in_use_ = true; | 285 restored_packet_in_use_ = true; |
| 307 bool ret = OnRecoveredPacket(restored_packet_, packet_length); | 286 bool ret = OnRecoveredPacket(restored_packet_, packet_length); |
| 308 restored_packet_in_use_ = false; | 287 restored_packet_in_use_ = false; |
| 309 return ret; | 288 return ret; |
| 310 } | 289 } |
| 311 return false; | 290 return false; |
| 312 } | 291 } |
| 313 | 292 |
| 314 void ViEReceiver::NotifyReceiverOfFecPacket(const RTPHeader& header) { | 293 void ViEReceiver::NotifyReceiverOfFecPacket(const RTPHeader& header) { |
| 315 int8_t last_media_payload_type = | 294 int8_t last_media_payload_type = |
| 316 rtp_payload_registry_->last_received_media_payload_type(); | 295 rtp_payload_registry_.last_received_media_payload_type(); |
| 317 if (last_media_payload_type < 0) { | 296 if (last_media_payload_type < 0) { |
| 318 LOG(LS_WARNING) << "Failed to get last media payload type."; | 297 LOG(LS_WARNING) << "Failed to get last media payload type."; |
| 319 return; | 298 return; |
| 320 } | 299 } |
| 321 // Fake an empty media packet. | 300 // Fake an empty media packet. |
| 322 WebRtcRTPHeader rtp_header = {}; | 301 WebRtcRTPHeader rtp_header = {}; |
| 323 rtp_header.header = header; | 302 rtp_header.header = header; |
| 324 rtp_header.header.payloadType = last_media_payload_type; | 303 rtp_header.header.payloadType = last_media_payload_type; |
| 325 rtp_header.header.paddingLength = 0; | 304 rtp_header.header.paddingLength = 0; |
| 326 PayloadUnion payload_specific; | 305 PayloadUnion payload_specific; |
| 327 if (!rtp_payload_registry_->GetPayloadSpecifics(last_media_payload_type, | 306 if (!rtp_payload_registry_.GetPayloadSpecifics(last_media_payload_type, |
| 328 &payload_specific)) { | 307 &payload_specific)) { |
| 329 LOG(LS_WARNING) << "Failed to get payload specifics."; | 308 LOG(LS_WARNING) << "Failed to get payload specifics."; |
| 330 return; | 309 return; |
| 331 } | 310 } |
| 332 rtp_header.type.Video.codec = payload_specific.Video.videoCodecType; | 311 rtp_header.type.Video.codec = payload_specific.Video.videoCodecType; |
| 333 rtp_header.type.Video.rotation = kVideoRotation_0; | 312 rtp_header.type.Video.rotation = kVideoRotation_0; |
| 334 if (header.extension.hasVideoRotation) { | 313 if (header.extension.hasVideoRotation) { |
| 335 rtp_header.type.Video.rotation = | 314 rtp_header.type.Video.rotation = |
| 336 ConvertCVOByteToVideoRotation(header.extension.videoRotation); | 315 ConvertCVOByteToVideoRotation(header.extension.videoRotation); |
| 337 } | 316 } |
| 338 OnReceivedPayloadData(NULL, 0, &rtp_header); | 317 OnReceivedPayloadData(NULL, 0, &rtp_header); |
| 339 } | 318 } |
| 340 | 319 |
| 341 bool ViEReceiver::DeliverRtcp(const uint8_t* rtcp_packet, | 320 bool ViEReceiver::DeliverRtcp(const uint8_t* rtcp_packet, |
| 342 size_t rtcp_packet_length) { | 321 size_t rtcp_packet_length) { |
|
stefan-webrtc
2016/02/29 09:15:04
DCHECK or CHECK
pbos-webrtc
2016/02/29 09:58:57
Done.
| |
| 322 assert(!rtp_rtcp_.empty()); // Should be set by owner at construction time. | |
| 343 { | 323 { |
| 344 rtc::CritScope lock(&receive_cs_); | 324 rtc::CritScope lock(&receive_cs_); |
| 345 if (!receiving_) { | 325 if (!receiving_) { |
| 346 return false; | 326 return false; |
| 347 } | 327 } |
| 348 | |
| 349 for (RtpRtcp* rtp_rtcp : rtp_rtcp_simulcast_) | |
| 350 rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); | |
| 351 } | |
| 352 assert(rtp_rtcp_); // Should be set by owner at construction time. | |
| 353 int ret = rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); | |
| 354 if (ret != 0) { | |
| 355 return false; | |
| 356 } | 328 } |
| 357 | 329 |
| 330 // Deliver to simulcast modules first, then base one. | |
|
stefan-webrtc
2016/02/29 09:15:04
Do you know why? Seems like it would be cleaner to
pbos-webrtc
2016/02/29 09:58:57
Done.
| |
| 331 for (size_t i = 1; i < rtp_rtcp_.size(); ++i) | |
| 332 rtp_rtcp_[i]->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); | |
| 333 // TODO(pbos): Is it important to check the return code here? | |
| 334 if (rtp_rtcp_[0]->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length) != 0) | |
| 335 return false; | |
| 336 | |
| 358 int64_t rtt = 0; | 337 int64_t rtt = 0; |
| 359 rtp_rtcp_->RTT(rtp_receiver_->SSRC(), &rtt, NULL, NULL, NULL); | 338 rtp_rtcp_[0]->RTT(rtp_receiver_->SSRC(), &rtt, NULL, NULL, NULL); |
| 360 if (rtt == 0) { | 339 if (rtt == 0) { |
| 361 // Waiting for valid rtt. | 340 // Waiting for valid rtt. |
| 362 return true; | 341 return true; |
| 363 } | 342 } |
| 364 uint32_t ntp_secs = 0; | 343 uint32_t ntp_secs = 0; |
| 365 uint32_t ntp_frac = 0; | 344 uint32_t ntp_frac = 0; |
| 366 uint32_t rtp_timestamp = 0; | 345 uint32_t rtp_timestamp = 0; |
| 367 if (0 != rtp_rtcp_->RemoteNTP(&ntp_secs, &ntp_frac, NULL, NULL, | 346 if (rtp_rtcp_[0]->RemoteNTP(&ntp_secs, &ntp_frac, NULL, NULL, |
| 368 &rtp_timestamp)) { | 347 &rtp_timestamp) != 0) { |
| 369 // Waiting for RTCP. | 348 // Waiting for RTCP. |
| 370 return true; | 349 return true; |
| 371 } | 350 } |
| 372 ntp_estimator_->UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp); | 351 ntp_estimator_.UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp); |
| 373 | 352 |
| 374 return true; | 353 return true; |
| 375 } | 354 } |
| 376 | 355 |
| 377 void ViEReceiver::StartReceive() { | 356 void ViEReceiver::StartReceive() { |
| 378 rtc::CritScope lock(&receive_cs_); | 357 rtc::CritScope lock(&receive_cs_); |
| 379 receiving_ = true; | 358 receiving_ = true; |
| 380 } | 359 } |
| 381 | 360 |
| 382 void ViEReceiver::StopReceive() { | 361 void ViEReceiver::StopReceive() { |
| 383 rtc::CritScope lock(&receive_cs_); | 362 rtc::CritScope lock(&receive_cs_); |
| 384 receiving_ = false; | 363 receiving_ = false; |
| 385 } | 364 } |
| 386 | 365 |
| 387 ReceiveStatistics* ViEReceiver::GetReceiveStatistics() const { | 366 ReceiveStatistics* ViEReceiver::GetReceiveStatistics() const { |
| 388 return rtp_receive_statistics_.get(); | 367 return rtp_receive_statistics_.get(); |
| 389 } | 368 } |
| 390 | 369 |
| 391 bool ViEReceiver::IsPacketInOrder(const RTPHeader& header) const { | 370 bool ViEReceiver::IsPacketInOrder(const RTPHeader& header) const { |
| 392 StreamStatistician* statistician = | 371 StreamStatistician* statistician = |
| 393 rtp_receive_statistics_->GetStatistician(header.ssrc); | 372 rtp_receive_statistics_->GetStatistician(header.ssrc); |
| 394 if (!statistician) | 373 if (!statistician) |
| 395 return false; | 374 return false; |
| 396 return statistician->IsPacketInOrder(header.sequenceNumber); | 375 return statistician->IsPacketInOrder(header.sequenceNumber); |
| 397 } | 376 } |
| 398 | 377 |
| 399 bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header, | 378 bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header, |
| 400 bool in_order) const { | 379 bool in_order) const { |
| 401 // Retransmissions are handled separately if RTX is enabled. | 380 // Retransmissions are handled separately if RTX is enabled. |
| 402 if (rtp_payload_registry_->RtxEnabled()) | 381 if (rtp_payload_registry_.RtxEnabled()) |
| 403 return false; | 382 return false; |
| 404 StreamStatistician* statistician = | 383 StreamStatistician* statistician = |
| 405 rtp_receive_statistics_->GetStatistician(header.ssrc); | 384 rtp_receive_statistics_->GetStatistician(header.ssrc); |
| 406 if (!statistician) | 385 if (!statistician) |
| 407 return false; | 386 return false; |
| 408 // Check if this is a retransmission. | 387 // Check if this is a retransmission. |
| 409 int64_t min_rtt = 0; | 388 int64_t min_rtt = 0; |
| 410 rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL); | 389 rtp_rtcp_[0]->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL); |
| 411 return !in_order && | 390 return !in_order && |
| 412 statistician->IsRetransmitOfOldPacket(header, min_rtt); | 391 statistician->IsRetransmitOfOldPacket(header, min_rtt); |
| 413 } | 392 } |
| 414 } // namespace webrtc | 393 } // namespace webrtc |
| OLD | NEW |