1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/video_engine/vie_receiver.h" 12 13 #include <vector> 14 15 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" 16 #include "webrtc/modules/rtp_rtcp/interface/fec_receiver.h" 17 #include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h" 18 #include "webrtc/modules/rtp_rtcp/interface/remote_ntp_time_estimator.h" 19 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" 20 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" 21 #include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h" 22 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" 23 #include "webrtc/modules/utility/interface/rtp_dump.h" 24 #include "webrtc/modules/video_coding/main/interface/video_coding.h" 25 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 26 #include "webrtc/system_wrappers/interface/logging.h" 27 #include "webrtc/system_wrappers/interface/tick_util.h" 28 #include "webrtc/system_wrappers/interface/timestamp_extrapolator.h" 29 #include "webrtc/system_wrappers/interface/trace.h" 30 31 namespace webrtc { 32 33 ViEReceiver::ViEReceiver(const int32_t channel_id, 34 VideoCodingModule* module_vcm, 35 RemoteBitrateEstimator* remote_bitrate_estimator, 36 RtpFeedback* rtp_feedback) 37 : receive_cs_(CriticalSectionWrapper::CreateCriticalSection()), 38 rtp_header_parser_(RtpHeaderParser::Create()), 39 rtp_payload_registry_(new RTPPayloadRegistry( 40 RTPPayloadStrategy::CreateStrategy(false))), 41 rtp_receiver_(RtpReceiver::CreateVideoReceiver( 42 channel_id, Clock::GetRealTimeClock(), this, rtp_feedback, 43 rtp_payload_registry_.get())), 44 rtp_receive_statistics_(ReceiveStatistics::Create( 45 Clock::GetRealTimeClock())), 46 fec_receiver_(FecReceiver::Create(this)), 47 rtp_rtcp_(NULL), 48 vcm_(module_vcm), 49 remote_bitrate_estimator_(remote_bitrate_estimator), 50 ntp_estimator_(new RemoteNtpTimeEstimator(Clock::GetRealTimeClock())), 51 rtp_dump_(NULL), 52 receiving_(false), 53 restored_packet_in_use_(false), 54 receiving_ast_enabled_(false) { 55 assert(remote_bitrate_estimator); 56 } 57 58 ViEReceiver::~ViEReceiver() { 59 if (rtp_dump_) { 60 rtp_dump_->Stop(); 61 RtpDump::DestroyRtpDump(rtp_dump_); 62 rtp_dump_ = NULL; 63 } 64 } 65 66 bool ViEReceiver::SetReceiveCodec(const VideoCodec& video_codec) { 67 int8_t old_pltype = -1; 68 if (rtp_payload_registry_->ReceivePayloadType(video_codec.plName, 69 kVideoPayloadTypeFrequency, 70 0, 71 video_codec.maxBitrate, 72 &old_pltype) != -1) { 73 rtp_payload_registry_->DeRegisterReceivePayload(old_pltype); 74 } 75 76 return RegisterPayload(video_codec); 77 } 78 79 bool ViEReceiver::RegisterPayload(const VideoCodec& video_codec) { 80 return rtp_receiver_->RegisterReceivePayload(video_codec.plName, 81 video_codec.plType, 82 kVideoPayloadTypeFrequency, 83 0, 84 video_codec.maxBitrate) == 0; 85 } 86 87 void ViEReceiver::SetNackStatus(bool enable, 88 int max_nack_reordering_threshold) { 89 if (!enable) { 90 // Reset the threshold back to the lower default threshold when NACK is 91 // disabled since we no longer will be receiving retransmissions. 92 max_nack_reordering_threshold = kDefaultMaxReorderingThreshold; 93 } 94 rtp_receive_statistics_->SetMaxReorderingThreshold( 95 max_nack_reordering_threshold); 96 rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff); 97 } 98 99 void ViEReceiver::SetRtxPayloadType(int payload_type) { 100 rtp_payload_registry_->SetRtxPayloadType(payload_type); 101 } 102 103 void ViEReceiver::SetRtxSsrc(uint32_t ssrc) { 104 rtp_payload_registry_->SetRtxSsrc(ssrc); 105 } 106 107 uint32_t ViEReceiver::GetRemoteSsrc() const { 108 return rtp_receiver_->SSRC(); 109 } 110 111 int ViEReceiver::GetCsrcs(uint32_t* csrcs) const { 112 return rtp_receiver_->CSRCs(csrcs); 113 } 114 115 void ViEReceiver::SetRtpRtcpModule(RtpRtcp* module) { 116 rtp_rtcp_ = module; 117 } 118 119 RtpReceiver* ViEReceiver::GetRtpReceiver() const { 120 return rtp_receiver_.get(); 121 } 122 123 void ViEReceiver::RegisterSimulcastRtpRtcpModules( 124 const std::list<RtpRtcp*>& rtp_modules) { 125 CriticalSectionScoped cs(receive_cs_.get()); 126 rtp_rtcp_simulcast_.clear(); 127 128 if (!rtp_modules.empty()) { 129 rtp_rtcp_simulcast_.insert(rtp_rtcp_simulcast_.begin(), 130 rtp_modules.begin(), 131 rtp_modules.end()); 132 } 133 } 134 135 bool ViEReceiver::SetReceiveTimestampOffsetStatus(bool enable, int id) { 136 if (enable) { 137 return rtp_header_parser_->RegisterRtpHeaderExtension( 138 kRtpExtensionTransmissionTimeOffset, id); 139 } else { 140 return rtp_header_parser_->DeregisterRtpHeaderExtension( 141 kRtpExtensionTransmissionTimeOffset); 142 } 143 } 144 145 bool ViEReceiver::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) { 146 if (enable) { 147 if (rtp_header_parser_->RegisterRtpHeaderExtension( 148 kRtpExtensionAbsoluteSendTime, id)) { 149 receiving_ast_enabled_ = true; 150 return true; 151 } else { 152 return false; 153 } 154 } else { 155 receiving_ast_enabled_ = false; 156 return rtp_header_parser_->DeregisterRtpHeaderExtension( 157 kRtpExtensionAbsoluteSendTime); 158 } 159 } 160 161 int ViEReceiver::ReceivedRTPPacket(const void* rtp_packet, 162 int rtp_packet_length, 163 const PacketTime& packet_time) { 164 return InsertRTPPacket(static_cast<const uint8_t*>(rtp_packet), 165 rtp_packet_length, packet_time); 166 } 167 168 int ViEReceiver::ReceivedRTCPPacket(const void* rtcp_packet, 169 int rtcp_packet_length) { 170 return InsertRTCPPacket(static_cast<const uint8_t*>(rtcp_packet), 171 rtcp_packet_length); 172 } 173 174 int32_t ViEReceiver::OnReceivedPayloadData( 175 const uint8_t* payload_data, const uint16_t payload_size, 176 const WebRtcRTPHeader* rtp_header) { 177 WebRtcRTPHeader rtp_header_with_ntp = *rtp_header; 178 rtp_header_with_ntp.ntp_time_ms = 179 ntp_estimator_->Estimate(rtp_header->header.timestamp); 180 if (vcm_->IncomingPacket(payload_data, 181 payload_size, 182 rtp_header_with_ntp) != 0) { 183 // Check this... 184 return -1; 185 } 186 return 0; 187 } 188 189 bool ViEReceiver::OnRecoveredPacket(const uint8_t* rtp_packet, 190 int rtp_packet_length) { 191 RTPHeader header; 192 if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) { 193 return false; 194 } 195 header.payload_type_frequency = kVideoPayloadTypeFrequency; 196 return ReceivePacket(rtp_packet, rtp_packet_length, header, false); 197 } 198 199 void ViEReceiver::ReceivedBWEPacket( 200 int64_t arrival_time_ms, int payload_size, const RTPHeader& header) { 201 // Only forward if the incoming packet *and* the channel are both configured 202 // to receive absolute sender time. RTP time stamps may have different rates 203 // for audio and video and shouldn't be mixed. 204 if (header.extension.hasAbsoluteSendTime && receiving_ast_enabled_) { 205 remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_size, 206 header); 207 } 208 } 209 210 int ViEReceiver::InsertRTPPacket(const uint8_t* rtp_packet, 211 int rtp_packet_length, 212 const PacketTime& packet_time) { 213 { 214 CriticalSectionScoped cs(receive_cs_.get()); 215 if (!receiving_) { 216 return -1; 217 } 218 if (rtp_dump_) { 219 rtp_dump_->DumpPacket(rtp_packet, 220 static_cast<uint16_t>(rtp_packet_length)); 221 } 222 } 223 224 RTPHeader header; 225 if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, 226 &header)) { 227 return -1; 228 } 229 int payload_length = rtp_packet_length - header.headerLength; 230 int64_t arrival_time_ms; 231 if (packet_time.timestamp != -1) 232 arrival_time_ms = (packet_time.timestamp + 500) / 1000; 233 else 234 arrival_time_ms = TickTime::MillisecondTimestamp(); 235 236 remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, 237 payload_length, header); 238 header.payload_type_frequency = kVideoPayloadTypeFrequency; 239 240 bool in_order = IsPacketInOrder(header); 241 rtp_payload_registry_->SetIncomingPayloadType(header); 242 int ret = ReceivePacket(rtp_packet, rtp_packet_length, header, in_order) 243 ? 0 244 : -1; 245 // Update receive statistics after ReceivePacket. 246 // Receive statistics will be reset if the payload type changes (make sure 247 // that the first packet is included in the stats). 248 rtp_receive_statistics_->IncomingPacket( 249 header, rtp_packet_length, IsPacketRetransmitted(header, in_order)); 250 return ret; 251 } 252 253 bool ViEReceiver::ReceivePacket(const uint8_t* packet, 254 int packet_length, 255 const RTPHeader& header, 256 bool in_order) { 257 if (rtp_payload_registry_->IsEncapsulated(header)) { 258 return ParseAndHandleEncapsulatingHeader(packet, packet_length, header); 259 } 260 const uint8_t* payload = packet + header.headerLength; 261 int payload_length = packet_length - header.headerLength; 262 assert(payload_length >= 0); 263 PayloadUnion payload_specific; 264 if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType, 265 &payload_specific)) { 266 return false; 267 } 268 return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length, 269 payload_specific, in_order); 270 } 271 272 bool ViEReceiver::ParseAndHandleEncapsulatingHeader(const uint8_t* packet, 273 int packet_length, 274 const RTPHeader& header) { 275 if (rtp_payload_registry_->IsRed(header)) { 276 int8_t ulpfec_pt = rtp_payload_registry_->ulpfec_payload_type(); 277 if (packet[header.headerLength] == ulpfec_pt) 278 rtp_receive_statistics_->FecPacketReceived(header.ssrc); 279 if (fec_receiver_->AddReceivedRedPacket( 280 header, packet, packet_length, ulpfec_pt) != 0) { 281 return false; 282 } 283 return fec_receiver_->ProcessReceivedFec() == 0; 284 } else if (rtp_payload_registry_->IsRtx(header)) { 285 if (header.headerLength + header.paddingLength == packet_length) { 286 // This is an empty packet and should be silently dropped before trying to 287 // parse the RTX header. 288 return true; 289 } 290 // Remove the RTX header and parse the original RTP header. 291 if (packet_length < header.headerLength) 292 return false; 293 if (packet_length > static_cast<int>(sizeof(restored_packet_))) 294 return false; 295 CriticalSectionScoped cs(receive_cs_.get()); 296 if (restored_packet_in_use_) { 297 LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet."; 298 return false; 299 } 300 uint8_t* restored_packet_ptr = restored_packet_; 301 if (!rtp_payload_registry_->RestoreOriginalPacket( 302 &restored_packet_ptr, packet, &packet_length, rtp_receiver_->SSRC(), 303 header)) { 304 LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header"; 305 return false; 306 } 307 restored_packet_in_use_ = true; 308 bool ret = OnRecoveredPacket(restored_packet_ptr, packet_length); 309 restored_packet_in_use_ = false; 310 return ret; 311 } 312 return false; 313 } 314 315 int ViEReceiver::InsertRTCPPacket(const uint8_t* rtcp_packet, 316 int rtcp_packet_length) { 317 { 318 CriticalSectionScoped cs(receive_cs_.get()); 319 if (!receiving_) { 320 return -1; 321 } 322 323 if (rtp_dump_) { 324 rtp_dump_->DumpPacket( 325 rtcp_packet, static_cast<uint16_t>(rtcp_packet_length)); 326 } 327 328 std::list<RtpRtcp*>::iterator it = rtp_rtcp_simulcast_.begin(); 329 while (it != rtp_rtcp_simulcast_.end()) { 330 RtpRtcp* rtp_rtcp = *it++; 331 rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); 332 } 333 } 334 assert(rtp_rtcp_); // Should be set by owner at construction time. 335 int ret = rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); 336 if (ret != 0) { 337 return ret; 338 } 339 340 ntp_estimator_->UpdateRtcpTimestamp(rtp_receiver_->SSRC(), rtp_rtcp_); 341 342 return 0; 343 } 344 345 void ViEReceiver::StartReceive() { 346 CriticalSectionScoped cs(receive_cs_.get()); 347 receiving_ = true; 348 } 349 350 void ViEReceiver::StopReceive() { 351 CriticalSectionScoped cs(receive_cs_.get()); 352 receiving_ = false; 353 } 354 355 int ViEReceiver::StartRTPDump(const char file_nameUTF8[1024]) { 356 CriticalSectionScoped cs(receive_cs_.get()); 357 if (rtp_dump_) { 358 // Restart it if it already exists and is started 359 rtp_dump_->Stop(); 360 } else { 361 rtp_dump_ = RtpDump::CreateRtpDump(); 362 if (rtp_dump_ == NULL) { 363 return -1; 364 } 365 } 366 if (rtp_dump_->Start(file_nameUTF8) != 0) { 367 RtpDump::DestroyRtpDump(rtp_dump_); 368 rtp_dump_ = NULL; 369 return -1; 370 } 371 return 0; 372 } 373 374 int ViEReceiver::StopRTPDump() { 375 CriticalSectionScoped cs(receive_cs_.get()); 376 if (rtp_dump_) { 377 if (rtp_dump_->IsActive()) { 378 rtp_dump_->Stop(); 379 } 380 RtpDump::DestroyRtpDump(rtp_dump_); 381 rtp_dump_ = NULL; 382 } else { 383 return -1; 384 } 385 return 0; 386 } 387 388 void ViEReceiver::GetReceiveBandwidthEstimatorStats( 389 ReceiveBandwidthEstimatorStats* output) const { 390 remote_bitrate_estimator_->GetStats(output); 391 } 392 393 ReceiveStatistics* ViEReceiver::GetReceiveStatistics() const { 394 return rtp_receive_statistics_.get(); 395 } 396 397 bool ViEReceiver::IsPacketInOrder(const RTPHeader& header) const { 398 StreamStatistician* statistician = 399 rtp_receive_statistics_->GetStatistician(header.ssrc); 400 if (!statistician) 401 return false; 402 return statistician->IsPacketInOrder(header.sequenceNumber); 403 } 404 405 bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header, 406 bool in_order) const { 407 // Retransmissions are handled separately if RTX is enabled. 408 if (rtp_payload_registry_->RtxEnabled()) 409 return false; 410 StreamStatistician* statistician = 411 rtp_receive_statistics_->GetStatistician(header.ssrc); 412 if (!statistician) 413 return false; 414 // Check if this is a retransmission. 415 uint16_t min_rtt = 0; 416 rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL); 417 return !in_order && 418 statistician->IsRetransmitOfOldPacket(header, min_rtt); 419 } 420 } // namespace webrtc 421