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 bool in_order = IsPacketInOrder(header); 197 return ReceivePacket(rtp_packet, rtp_packet_length, header, in_order); 198 } 199 200 void ViEReceiver::ReceivedBWEPacket( 201 int64_t arrival_time_ms, int payload_size, const RTPHeader& header) { 202 // Only forward if the incoming packet *and* the channel are both configured 203 // to receive absolute sender time. RTP time stamps may have different rates 204 // for audio and video and shouldn't be mixed. 205 if (header.extension.hasAbsoluteSendTime && receiving_ast_enabled_) { 206 remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_size, 207 header); 208 } 209 } 210 211 int ViEReceiver::InsertRTPPacket(const uint8_t* rtp_packet, 212 int rtp_packet_length, 213 const PacketTime& packet_time) { 214 { 215 CriticalSectionScoped cs(receive_cs_.get()); 216 if (!receiving_) { 217 return -1; 218 } 219 if (rtp_dump_) { 220 rtp_dump_->DumpPacket(rtp_packet, 221 static_cast<uint16_t>(rtp_packet_length)); 222 } 223 } 224 225 RTPHeader header; 226 if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, 227 &header)) { 228 return -1; 229 } 230 int payload_length = rtp_packet_length - header.headerLength; 231 int64_t arrival_time_ms; 232 if (packet_time.timestamp != -1) 233 arrival_time_ms = (packet_time.timestamp + 500) / 1000; 234 else 235 arrival_time_ms = TickTime::MillisecondTimestamp(); 236 237 remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, 238 payload_length, header); 239 header.payload_type_frequency = kVideoPayloadTypeFrequency; 240 241 bool in_order = IsPacketInOrder(header); 242 rtp_payload_registry_->SetIncomingPayloadType(header); 243 int ret = ReceivePacket(rtp_packet, rtp_packet_length, header, in_order) 244 ? 0 245 : -1; 246 // Update receive statistics after ReceivePacket. 247 // Receive statistics will be reset if the payload type changes (make sure 248 // that the first packet is included in the stats). 249 rtp_receive_statistics_->IncomingPacket( 250 header, rtp_packet_length, IsPacketRetransmitted(header, in_order)); 251 return ret; 252 } 253 254 bool ViEReceiver::ReceivePacket(const uint8_t* packet, 255 int packet_length, 256 const RTPHeader& header, 257 bool in_order) { 258 if (rtp_payload_registry_->IsEncapsulated(header)) { 259 return ParseAndHandleEncapsulatingHeader(packet, packet_length, header); 260 } 261 const uint8_t* payload = packet + header.headerLength; 262 int payload_length = packet_length - header.headerLength; 263 assert(payload_length >= 0); 264 PayloadUnion payload_specific; 265 if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType, 266 &payload_specific)) { 267 return false; 268 } 269 return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length, 270 payload_specific, in_order); 271 } 272 273 bool ViEReceiver::ParseAndHandleEncapsulatingHeader(const uint8_t* packet, 274 int packet_length, 275 const RTPHeader& header) { 276 if (rtp_payload_registry_->IsRed(header)) { 277 int8_t ulpfec_pt = rtp_payload_registry_->ulpfec_payload_type(); 278 if (packet[header.headerLength] == ulpfec_pt) 279 rtp_receive_statistics_->FecPacketReceived(header.ssrc); 280 if (fec_receiver_->AddReceivedRedPacket( 281 header, packet, packet_length, ulpfec_pt) != 0) { 282 return false; 283 } 284 return fec_receiver_->ProcessReceivedFec() == 0; 285 } else if (rtp_payload_registry_->IsRtx(header)) { 286 if (header.headerLength + header.paddingLength == packet_length) { 287 // This is an empty packet and should be silently dropped before trying to 288 // parse the RTX header. 289 return true; 290 } 291 // Remove the RTX header and parse the original RTP header. 292 if (packet_length < header.headerLength) 293 return false; 294 if (packet_length > static_cast<int>(sizeof(restored_packet_))) 295 return false; 296 CriticalSectionScoped cs(receive_cs_.get()); 297 if (restored_packet_in_use_) { 298 LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet."; 299 return false; 300 } 301 uint8_t* restored_packet_ptr = restored_packet_; 302 if (!rtp_payload_registry_->RestoreOriginalPacket( 303 &restored_packet_ptr, packet, &packet_length, rtp_receiver_->SSRC(), 304 header)) { 305 LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header"; 306 return false; 307 } 308 restored_packet_in_use_ = true; 309 bool ret = OnRecoveredPacket(restored_packet_ptr, packet_length); 310 restored_packet_in_use_ = false; 311 return ret; 312 } 313 return false; 314 } 315 316 int ViEReceiver::InsertRTCPPacket(const uint8_t* rtcp_packet, 317 int rtcp_packet_length) { 318 { 319 CriticalSectionScoped cs(receive_cs_.get()); 320 if (!receiving_) { 321 return -1; 322 } 323 324 if (rtp_dump_) { 325 rtp_dump_->DumpPacket( 326 rtcp_packet, static_cast<uint16_t>(rtcp_packet_length)); 327 } 328 329 std::list<RtpRtcp*>::iterator it = rtp_rtcp_simulcast_.begin(); 330 while (it != rtp_rtcp_simulcast_.end()) { 331 RtpRtcp* rtp_rtcp = *it++; 332 rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); 333 } 334 } 335 assert(rtp_rtcp_); // Should be set by owner at construction time. 336 int ret = rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); 337 if (ret != 0) { 338 return ret; 339 } 340 341 ntp_estimator_->UpdateRtcpTimestamp(rtp_receiver_->SSRC(), rtp_rtcp_); 342 343 return 0; 344 } 345 346 void ViEReceiver::StartReceive() { 347 CriticalSectionScoped cs(receive_cs_.get()); 348 receiving_ = true; 349 } 350 351 void ViEReceiver::StopReceive() { 352 CriticalSectionScoped cs(receive_cs_.get()); 353 receiving_ = false; 354 } 355 356 int ViEReceiver::StartRTPDump(const char file_nameUTF8[1024]) { 357 CriticalSectionScoped cs(receive_cs_.get()); 358 if (rtp_dump_) { 359 // Restart it if it already exists and is started 360 rtp_dump_->Stop(); 361 } else { 362 rtp_dump_ = RtpDump::CreateRtpDump(); 363 if (rtp_dump_ == NULL) { 364 return -1; 365 } 366 } 367 if (rtp_dump_->Start(file_nameUTF8) != 0) { 368 RtpDump::DestroyRtpDump(rtp_dump_); 369 rtp_dump_ = NULL; 370 return -1; 371 } 372 return 0; 373 } 374 375 int ViEReceiver::StopRTPDump() { 376 CriticalSectionScoped cs(receive_cs_.get()); 377 if (rtp_dump_) { 378 if (rtp_dump_->IsActive()) { 379 rtp_dump_->Stop(); 380 } 381 RtpDump::DestroyRtpDump(rtp_dump_); 382 rtp_dump_ = NULL; 383 } else { 384 return -1; 385 } 386 return 0; 387 } 388 389 void ViEReceiver::GetReceiveBandwidthEstimatorStats( 390 ReceiveBandwidthEstimatorStats* output) const { 391 remote_bitrate_estimator_->GetStats(output); 392 } 393 394 ReceiveStatistics* ViEReceiver::GetReceiveStatistics() const { 395 return rtp_receive_statistics_.get(); 396 } 397 398 bool ViEReceiver::IsPacketInOrder(const RTPHeader& header) const { 399 StreamStatistician* statistician = 400 rtp_receive_statistics_->GetStatistician(header.ssrc); 401 if (!statistician) 402 return false; 403 return statistician->IsPacketInOrder(header.sequenceNumber); 404 } 405 406 bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header, 407 bool in_order) const { 408 // Retransmissions are handled separately if RTX is enabled. 409 if (rtp_payload_registry_->RtxEnabled()) 410 return false; 411 StreamStatistician* statistician = 412 rtp_receive_statistics_->GetStatistician(header.ssrc); 413 if (!statistician) 414 return false; 415 // Check if this is a retransmission. 416 uint16_t min_rtt = 0; 417 rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL); 418 return !in_order && 419 statistician->IsRetransmitOfOldPacket(header, min_rtt); 420 } 421 } // namespace webrtc 422