| 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/modules/remote_bitrate_estimator/include/remote_bitrate_estimat
or.h" | 16 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat
or.h" |
| 17 #include "webrtc/modules/rtp_rtcp/include/fec_receiver.h" | 17 #include "webrtc/modules/rtp_rtcp/include/fec_receiver.h" |
| 18 #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h" | 18 #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h" |
| 19 #include "webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h" | 19 #include "webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h" |
| 20 #include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h" | 20 #include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h" |
| 21 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" | 21 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" |
| 22 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" | 22 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" |
| 23 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" | 23 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" |
| 24 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" | 24 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" |
| 25 #include "webrtc/modules/video_coding/include/video_coding.h" | 25 #include "webrtc/modules/video_coding/include/video_coding.h" |
| 26 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | |
| 27 #include "webrtc/system_wrappers/include/metrics.h" | 26 #include "webrtc/system_wrappers/include/metrics.h" |
| 28 #include "webrtc/system_wrappers/include/tick_util.h" | 27 #include "webrtc/system_wrappers/include/tick_util.h" |
| 29 #include "webrtc/system_wrappers/include/timestamp_extrapolator.h" | 28 #include "webrtc/system_wrappers/include/timestamp_extrapolator.h" |
| 30 #include "webrtc/system_wrappers/include/trace.h" | 29 #include "webrtc/system_wrappers/include/trace.h" |
| 31 | 30 |
| 32 namespace webrtc { | 31 namespace webrtc { |
| 33 | 32 |
| 34 static const int kPacketLogIntervalMs = 10000; | 33 static const int kPacketLogIntervalMs = 10000; |
| 35 | 34 |
| 36 ViEReceiver::ViEReceiver(VideoCodingModule* module_vcm, | 35 ViEReceiver::ViEReceiver(VideoCodingModule* module_vcm, |
| 37 RemoteBitrateEstimator* remote_bitrate_estimator, | 36 RemoteBitrateEstimator* remote_bitrate_estimator, |
| 38 RtpFeedback* rtp_feedback) | 37 RtpFeedback* rtp_feedback) |
| 39 : receive_cs_(CriticalSectionWrapper::CreateCriticalSection()), | 38 : clock_(Clock::GetRealTimeClock()), |
| 40 clock_(Clock::GetRealTimeClock()), | |
| 41 rtp_header_parser_(RtpHeaderParser::Create()), | 39 rtp_header_parser_(RtpHeaderParser::Create()), |
| 42 rtp_payload_registry_( | 40 rtp_payload_registry_( |
| 43 new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(false))), | 41 new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(false))), |
| 44 rtp_receiver_( | 42 rtp_receiver_( |
| 45 RtpReceiver::CreateVideoReceiver(clock_, | 43 RtpReceiver::CreateVideoReceiver(clock_, |
| 46 this, | 44 this, |
| 47 rtp_feedback, | 45 rtp_feedback, |
| 48 rtp_payload_registry_.get())), | 46 rtp_payload_registry_.get())), |
| 49 rtp_receive_statistics_(ReceiveStatistics::Create(clock_)), | 47 rtp_receive_statistics_(ReceiveStatistics::Create(clock_)), |
| 50 fec_receiver_(FecReceiver::Create(this)), | 48 fec_receiver_(FecReceiver::Create(this)), |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 void ViEReceiver::SetRtpRtcpModule(RtpRtcp* module) { | 144 void ViEReceiver::SetRtpRtcpModule(RtpRtcp* module) { |
| 147 rtp_rtcp_ = module; | 145 rtp_rtcp_ = module; |
| 148 } | 146 } |
| 149 | 147 |
| 150 RtpReceiver* ViEReceiver::GetRtpReceiver() const { | 148 RtpReceiver* ViEReceiver::GetRtpReceiver() const { |
| 151 return rtp_receiver_.get(); | 149 return rtp_receiver_.get(); |
| 152 } | 150 } |
| 153 | 151 |
| 154 void ViEReceiver::RegisterRtpRtcpModules( | 152 void ViEReceiver::RegisterRtpRtcpModules( |
| 155 const std::vector<RtpRtcp*>& rtp_modules) { | 153 const std::vector<RtpRtcp*>& rtp_modules) { |
| 156 CriticalSectionScoped cs(receive_cs_.get()); | 154 rtc::CritScope lock(&receive_cs_); |
| 157 // Only change the "simulcast" modules, the base module can be accessed | 155 // Only change the "simulcast" modules, the base module can be accessed |
| 158 // without a lock whereas the simulcast modules require locking as they can be | 156 // without a lock whereas the simulcast modules require locking as they can be |
| 159 // changed in runtime. | 157 // changed in runtime. |
| 160 rtp_rtcp_simulcast_ = | 158 rtp_rtcp_simulcast_ = |
| 161 std::vector<RtpRtcp*>(rtp_modules.begin() + 1, rtp_modules.end()); | 159 std::vector<RtpRtcp*>(rtp_modules.begin() + 1, rtp_modules.end()); |
| 162 } | 160 } |
| 163 | 161 |
| 164 bool ViEReceiver::SetReceiveTimestampOffsetStatus(bool enable, int id) { | 162 bool ViEReceiver::SetReceiveTimestampOffsetStatus(bool enable, int id) { |
| 165 if (enable) { | 163 if (enable) { |
| 166 return rtp_header_parser_->RegisterRtpHeaderExtension( | 164 return rtp_header_parser_->RegisterRtpHeaderExtension( |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 } | 253 } |
| 256 header.payload_type_frequency = kVideoPayloadTypeFrequency; | 254 header.payload_type_frequency = kVideoPayloadTypeFrequency; |
| 257 bool in_order = IsPacketInOrder(header); | 255 bool in_order = IsPacketInOrder(header); |
| 258 return ReceivePacket(rtp_packet, rtp_packet_length, header, in_order); | 256 return ReceivePacket(rtp_packet, rtp_packet_length, header, in_order); |
| 259 } | 257 } |
| 260 | 258 |
| 261 int ViEReceiver::InsertRTPPacket(const uint8_t* rtp_packet, | 259 int ViEReceiver::InsertRTPPacket(const uint8_t* rtp_packet, |
| 262 size_t rtp_packet_length, | 260 size_t rtp_packet_length, |
| 263 const PacketTime& packet_time) { | 261 const PacketTime& packet_time) { |
| 264 { | 262 { |
| 265 CriticalSectionScoped cs(receive_cs_.get()); | 263 rtc::CritScope lock(&receive_cs_); |
| 266 if (!receiving_) { | 264 if (!receiving_) { |
| 267 return -1; | 265 return -1; |
| 268 } | 266 } |
| 269 } | 267 } |
| 270 | 268 |
| 271 RTPHeader header; | 269 RTPHeader header; |
| 272 if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, | 270 if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, |
| 273 &header)) { | 271 &header)) { |
| 274 return -1; | 272 return -1; |
| 275 } | 273 } |
| 276 size_t payload_length = rtp_packet_length - header.headerLength; | 274 size_t payload_length = rtp_packet_length - header.headerLength; |
| 277 int64_t arrival_time_ms; | 275 int64_t arrival_time_ms; |
| 278 int64_t now_ms = clock_->TimeInMilliseconds(); | 276 int64_t now_ms = clock_->TimeInMilliseconds(); |
| 279 if (packet_time.timestamp != -1) | 277 if (packet_time.timestamp != -1) |
| 280 arrival_time_ms = (packet_time.timestamp + 500) / 1000; | 278 arrival_time_ms = (packet_time.timestamp + 500) / 1000; |
| 281 else | 279 else |
| 282 arrival_time_ms = now_ms; | 280 arrival_time_ms = now_ms; |
| 283 | 281 |
| 284 { | 282 { |
| 285 // Periodically log the RTP header of incoming packets. | 283 // Periodically log the RTP header of incoming packets. |
| 286 CriticalSectionScoped cs(receive_cs_.get()); | 284 rtc::CritScope lock(&receive_cs_); |
| 287 if (now_ms - last_packet_log_ms_ > kPacketLogIntervalMs) { | 285 if (now_ms - last_packet_log_ms_ > kPacketLogIntervalMs) { |
| 288 std::stringstream ss; | 286 std::stringstream ss; |
| 289 ss << "Packet received on SSRC: " << header.ssrc << " with payload type: " | 287 ss << "Packet received on SSRC: " << header.ssrc << " with payload type: " |
| 290 << static_cast<int>(header.payloadType) << ", timestamp: " | 288 << static_cast<int>(header.payloadType) << ", timestamp: " |
| 291 << header.timestamp << ", sequence number: " << header.sequenceNumber | 289 << header.timestamp << ", sequence number: " << header.sequenceNumber |
| 292 << ", arrival time: " << arrival_time_ms; | 290 << ", arrival time: " << arrival_time_ms; |
| 293 if (header.extension.hasTransmissionTimeOffset) | 291 if (header.extension.hasTransmissionTimeOffset) |
| 294 ss << ", toffset: " << header.extension.transmissionTimeOffset; | 292 ss << ", toffset: " << header.extension.transmissionTimeOffset; |
| 295 if (header.extension.hasAbsoluteSendTime) | 293 if (header.extension.hasAbsoluteSendTime) |
| 296 ss << ", abs send time: " << header.extension.absoluteSendTime; | 294 ss << ", abs send time: " << header.extension.absoluteSendTime; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 if (header.headerLength + header.paddingLength == packet_length) { | 352 if (header.headerLength + header.paddingLength == packet_length) { |
| 355 // This is an empty packet and should be silently dropped before trying to | 353 // This is an empty packet and should be silently dropped before trying to |
| 356 // parse the RTX header. | 354 // parse the RTX header. |
| 357 return true; | 355 return true; |
| 358 } | 356 } |
| 359 // Remove the RTX header and parse the original RTP header. | 357 // Remove the RTX header and parse the original RTP header. |
| 360 if (packet_length < header.headerLength) | 358 if (packet_length < header.headerLength) |
| 361 return false; | 359 return false; |
| 362 if (packet_length > sizeof(restored_packet_)) | 360 if (packet_length > sizeof(restored_packet_)) |
| 363 return false; | 361 return false; |
| 364 CriticalSectionScoped cs(receive_cs_.get()); | 362 rtc::CritScope lock(&receive_cs_); |
| 365 if (restored_packet_in_use_) { | 363 if (restored_packet_in_use_) { |
| 366 LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet."; | 364 LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet."; |
| 367 return false; | 365 return false; |
| 368 } | 366 } |
| 369 if (!rtp_payload_registry_->RestoreOriginalPacket( | 367 if (!rtp_payload_registry_->RestoreOriginalPacket( |
| 370 restored_packet_, packet, &packet_length, rtp_receiver_->SSRC(), | 368 restored_packet_, packet, &packet_length, rtp_receiver_->SSRC(), |
| 371 header)) { | 369 header)) { |
| 372 LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header"; | 370 LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header"; |
| 373 return false; | 371 return false; |
| 374 } | 372 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 403 if (header.extension.hasVideoRotation) { | 401 if (header.extension.hasVideoRotation) { |
| 404 rtp_header.type.Video.rotation = | 402 rtp_header.type.Video.rotation = |
| 405 ConvertCVOByteToVideoRotation(header.extension.videoRotation); | 403 ConvertCVOByteToVideoRotation(header.extension.videoRotation); |
| 406 } | 404 } |
| 407 OnReceivedPayloadData(NULL, 0, &rtp_header); | 405 OnReceivedPayloadData(NULL, 0, &rtp_header); |
| 408 } | 406 } |
| 409 | 407 |
| 410 int ViEReceiver::InsertRTCPPacket(const uint8_t* rtcp_packet, | 408 int ViEReceiver::InsertRTCPPacket(const uint8_t* rtcp_packet, |
| 411 size_t rtcp_packet_length) { | 409 size_t rtcp_packet_length) { |
| 412 { | 410 { |
| 413 CriticalSectionScoped cs(receive_cs_.get()); | 411 rtc::CritScope lock(&receive_cs_); |
| 414 if (!receiving_) { | 412 if (!receiving_) { |
| 415 return -1; | 413 return -1; |
| 416 } | 414 } |
| 417 | 415 |
| 418 for (RtpRtcp* rtp_rtcp : rtp_rtcp_simulcast_) | 416 for (RtpRtcp* rtp_rtcp : rtp_rtcp_simulcast_) |
| 419 rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); | 417 rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); |
| 420 } | 418 } |
| 421 assert(rtp_rtcp_); // Should be set by owner at construction time. | 419 assert(rtp_rtcp_); // Should be set by owner at construction time. |
| 422 int ret = rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); | 420 int ret = rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); |
| 423 if (ret != 0) { | 421 if (ret != 0) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 437 &rtp_timestamp)) { | 435 &rtp_timestamp)) { |
| 438 // Waiting for RTCP. | 436 // Waiting for RTCP. |
| 439 return 0; | 437 return 0; |
| 440 } | 438 } |
| 441 ntp_estimator_->UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp); | 439 ntp_estimator_->UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp); |
| 442 | 440 |
| 443 return 0; | 441 return 0; |
| 444 } | 442 } |
| 445 | 443 |
| 446 void ViEReceiver::StartReceive() { | 444 void ViEReceiver::StartReceive() { |
| 447 CriticalSectionScoped cs(receive_cs_.get()); | 445 rtc::CritScope lock(&receive_cs_); |
| 448 receiving_ = true; | 446 receiving_ = true; |
| 449 } | 447 } |
| 450 | 448 |
| 451 void ViEReceiver::StopReceive() { | 449 void ViEReceiver::StopReceive() { |
| 452 CriticalSectionScoped cs(receive_cs_.get()); | 450 rtc::CritScope lock(&receive_cs_); |
| 453 receiving_ = false; | 451 receiving_ = false; |
| 454 } | 452 } |
| 455 | 453 |
| 456 ReceiveStatistics* ViEReceiver::GetReceiveStatistics() const { | 454 ReceiveStatistics* ViEReceiver::GetReceiveStatistics() const { |
| 457 return rtp_receive_statistics_.get(); | 455 return rtp_receive_statistics_.get(); |
| 458 } | 456 } |
| 459 | 457 |
| 460 bool ViEReceiver::IsPacketInOrder(const RTPHeader& header) const { | 458 bool ViEReceiver::IsPacketInOrder(const RTPHeader& header) const { |
| 461 StreamStatistician* statistician = | 459 StreamStatistician* statistician = |
| 462 rtp_receive_statistics_->GetStatistician(header.ssrc); | 460 rtp_receive_statistics_->GetStatistician(header.ssrc); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 474 rtp_receive_statistics_->GetStatistician(header.ssrc); | 472 rtp_receive_statistics_->GetStatistician(header.ssrc); |
| 475 if (!statistician) | 473 if (!statistician) |
| 476 return false; | 474 return false; |
| 477 // Check if this is a retransmission. | 475 // Check if this is a retransmission. |
| 478 int64_t min_rtt = 0; | 476 int64_t min_rtt = 0; |
| 479 rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL); | 477 rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL); |
| 480 return !in_order && | 478 return !in_order && |
| 481 statistician->IsRetransmitOfOldPacket(header, min_rtt); | 479 statistician->IsRetransmitOfOldPacket(header, min_rtt); |
| 482 } | 480 } |
| 483 } // namespace webrtc | 481 } // namespace webrtc |
| OLD | NEW |