| 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 NackSender* nack_sender, | 90 NackSender* nack_sender, |
| 91 KeyFrameRequestSender* keyframe_request_sender, | 91 KeyFrameRequestSender* keyframe_request_sender, |
| 92 video_coding::OnCompleteFrameCallback* complete_frame_callback, | 92 video_coding::OnCompleteFrameCallback* complete_frame_callback, |
| 93 VCMTiming* timing) | 93 VCMTiming* timing) |
| 94 : clock_(Clock::GetRealTimeClock()), | 94 : clock_(Clock::GetRealTimeClock()), |
| 95 config_(*config), | 95 config_(*config), |
| 96 packet_router_(packet_router), | 96 packet_router_(packet_router), |
| 97 remb_(remb), | 97 remb_(remb), |
| 98 process_thread_(process_thread), | 98 process_thread_(process_thread), |
| 99 ntp_estimator_(clock_), | 99 ntp_estimator_(clock_), |
| 100 rtp_header_parser_(RtpHeaderParser::Create()), | 100 rtp_header_extensions_(config_.rtp.extensions), |
| 101 rtp_receiver_(RtpReceiver::CreateVideoReceiver(clock_, | 101 rtp_receiver_(RtpReceiver::CreateVideoReceiver(clock_, |
| 102 this, | 102 this, |
| 103 this, | 103 this, |
| 104 &rtp_payload_registry_)), | 104 &rtp_payload_registry_)), |
| 105 rtp_receive_statistics_(ReceiveStatistics::Create(clock_)), | 105 rtp_receive_statistics_(ReceiveStatistics::Create(clock_)), |
| 106 ulpfec_receiver_(UlpfecReceiver::Create(this)), | 106 ulpfec_receiver_(UlpfecReceiver::Create(this)), |
| 107 receiving_(false), | 107 receiving_(false), |
| 108 restored_packet_in_use_(false), | 108 restored_packet_in_use_(false), |
| 109 last_packet_log_ms_(-1), | 109 last_packet_log_ms_(-1), |
| 110 rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(), | 110 rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(), |
| (...skipping 17 matching lines...) Expand all Loading... |
| 128 RTC_DCHECK(config_.rtp.remote_ssrc != config_.rtp.local_ssrc); | 128 RTC_DCHECK(config_.rtp.remote_ssrc != config_.rtp.local_ssrc); |
| 129 | 129 |
| 130 rtp_rtcp_->SetRTCPStatus(config_.rtp.rtcp_mode); | 130 rtp_rtcp_->SetRTCPStatus(config_.rtp.rtcp_mode); |
| 131 rtp_rtcp_->SetSSRC(config_.rtp.local_ssrc); | 131 rtp_rtcp_->SetSSRC(config_.rtp.local_ssrc); |
| 132 rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp); | 132 rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp); |
| 133 if (config_.rtp.remb) { | 133 if (config_.rtp.remb) { |
| 134 rtp_rtcp_->SetREMBStatus(true); | 134 rtp_rtcp_->SetREMBStatus(true); |
| 135 remb_->AddReceiveChannel(rtp_rtcp_.get()); | 135 remb_->AddReceiveChannel(rtp_rtcp_.get()); |
| 136 } | 136 } |
| 137 | 137 |
| 138 for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) { | |
| 139 EnableReceiveRtpHeaderExtension(config_.rtp.extensions[i].uri, | |
| 140 config_.rtp.extensions[i].id); | |
| 141 } | |
| 142 | |
| 143 static const int kMaxPacketAgeToNack = 450; | 138 static const int kMaxPacketAgeToNack = 450; |
| 144 const int max_reordering_threshold = (config_.rtp.nack.rtp_history_ms > 0) | 139 const int max_reordering_threshold = (config_.rtp.nack.rtp_history_ms > 0) |
| 145 ? kMaxPacketAgeToNack | 140 ? kMaxPacketAgeToNack |
| 146 : kDefaultMaxReorderingThreshold; | 141 : kDefaultMaxReorderingThreshold; |
| 147 rtp_receive_statistics_->SetMaxReorderingThreshold(max_reordering_threshold); | 142 rtp_receive_statistics_->SetMaxReorderingThreshold(max_reordering_threshold); |
| 148 | 143 |
| 149 if (config_.rtp.rtx_ssrc) { | 144 if (config_.rtp.rtx_ssrc) { |
| 150 rtp_payload_registry_.SetRtxSsrc(config_.rtp.rtx_ssrc); | 145 rtp_payload_registry_.SetRtxSsrc(config_.rtp.rtx_ssrc); |
| 151 | 146 |
| 152 for (const auto& kv : config_.rtp.rtx_payload_types) { | 147 for (const auto& kv : config_.rtp.rtx_payload_types) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 memcpy(data, packet.dataPtr, packet.sizeBytes); | 276 memcpy(data, packet.dataPtr, packet.sizeBytes); |
| 282 packet.dataPtr = data; | 277 packet.dataPtr = data; |
| 283 } | 278 } |
| 284 | 279 |
| 285 packet_buffer_->InsertPacket(&packet); | 280 packet_buffer_->InsertPacket(&packet); |
| 286 return 0; | 281 return 0; |
| 287 } | 282 } |
| 288 | 283 |
| 289 bool RtpStreamReceiver::OnRecoveredPacket(const uint8_t* rtp_packet, | 284 bool RtpStreamReceiver::OnRecoveredPacket(const uint8_t* rtp_packet, |
| 290 size_t rtp_packet_length) { | 285 size_t rtp_packet_length) { |
| 286 RtpPacketReceived packet; |
| 287 if (!packet.Parse(rtp_packet, rtp_packet_length)) |
| 288 return false; |
| 289 packet.IdentifyExtensions(rtp_header_extensions_); |
| 290 packet.set_payload_type_frequency(kVideoPayloadTypeFrequency); |
| 291 |
| 291 RTPHeader header; | 292 RTPHeader header; |
| 292 if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) { | 293 packet.GetHeader(&header); |
| 293 return false; | |
| 294 } | |
| 295 header.payload_type_frequency = kVideoPayloadTypeFrequency; | |
| 296 bool in_order = IsPacketInOrder(header); | 294 bool in_order = IsPacketInOrder(header); |
| 297 return ReceivePacket(rtp_packet, rtp_packet_length, header, in_order); | 295 return ReceivePacket(rtp_packet, rtp_packet_length, header, in_order); |
| 298 } | 296 } |
| 299 | 297 |
| 300 // TODO(pbos): Remove as soon as audio can handle a changing payload type | 298 // TODO(pbos): Remove as soon as audio can handle a changing payload type |
| 301 // without this callback. | 299 // without this callback. |
| 302 int32_t RtpStreamReceiver::OnInitializeDecoder( | 300 int32_t RtpStreamReceiver::OnInitializeDecoder( |
| 303 const int8_t payload_type, | 301 const int8_t payload_type, |
| 304 const char payload_name[RTP_PAYLOAD_NAME_SIZE], | 302 const char payload_name[RTP_PAYLOAD_NAME_SIZE], |
| 305 const int frequency, | 303 const int frequency, |
| 306 const size_t channels, | 304 const size_t channels, |
| 307 const uint32_t rate) { | 305 const uint32_t rate) { |
| 308 RTC_NOTREACHED(); | 306 RTC_NOTREACHED(); |
| 309 return 0; | 307 return 0; |
| 310 } | 308 } |
| 311 | 309 |
| 312 void RtpStreamReceiver::OnIncomingSSRCChanged(const uint32_t ssrc) { | 310 void RtpStreamReceiver::OnIncomingSSRCChanged(const uint32_t ssrc) { |
| 313 rtp_rtcp_->SetRemoteSSRC(ssrc); | 311 rtp_rtcp_->SetRemoteSSRC(ssrc); |
| 314 } | 312 } |
| 315 | 313 |
| 316 void RtpStreamReceiver::OnRtpPacket(const RtpPacketReceived& packet) { | 314 bool RtpStreamReceiver::OnRtpPacketReceive(RtpPacketReceived* packet) { |
| 317 { | 315 { |
| 318 rtc::CritScope lock(&receive_cs_); | 316 rtc::CritScope lock(&receive_cs_); |
| 319 if (!receiving_) { | 317 if (!receiving_) { |
| 320 return; | 318 return false; |
| 321 } | 319 } |
| 322 } | 320 } |
| 323 | 321 |
| 324 int64_t now_ms = clock_->TimeInMilliseconds(); | 322 int64_t now_ms = clock_->TimeInMilliseconds(); |
| 323 packet->IdentifyExtensions(rtp_header_extensions_); |
| 324 packet->set_payload_type_frequency(kVideoPayloadTypeFrequency); |
| 325 | 325 |
| 326 { | 326 { |
| 327 // Periodically log the RTP header of incoming packets. | 327 // Periodically log the RTP header of incoming packets. |
| 328 rtc::CritScope lock(&receive_cs_); | 328 rtc::CritScope lock(&receive_cs_); |
| 329 if (now_ms - last_packet_log_ms_ > kPacketLogIntervalMs) { | 329 if (now_ms - last_packet_log_ms_ > kPacketLogIntervalMs) { |
| 330 std::stringstream ss; | 330 std::stringstream ss; |
| 331 ss << "Packet received on SSRC: " << packet.Ssrc() | 331 ss << "Packet received on SSRC: " << packet->Ssrc() |
| 332 << " with payload type: " << static_cast<int>(packet.PayloadType()) | 332 << " with payload type: " << static_cast<int>(packet->PayloadType()) |
| 333 << ", timestamp: " << packet.Timestamp() | 333 << ", timestamp: " << packet->Timestamp() |
| 334 << ", sequence number: " << packet.SequenceNumber() | 334 << ", sequence number: " << packet->SequenceNumber() |
| 335 << ", arrival time: " << packet.arrival_time_ms(); | 335 << ", arrival time: " << packet->arrival_time_ms(); |
| 336 int32_t time_offset; | 336 int32_t time_offset; |
| 337 if (packet.GetExtension<TransmissionOffset>(&time_offset)) { | 337 if (packet->GetExtension<TransmissionOffset>(&time_offset)) { |
| 338 ss << ", toffset: " << time_offset; | 338 ss << ", toffset: " << time_offset; |
| 339 } | 339 } |
| 340 uint32_t send_time; | 340 uint32_t send_time; |
| 341 if (packet.GetExtension<AbsoluteSendTime>(&send_time)) { | 341 if (packet->GetExtension<AbsoluteSendTime>(&send_time)) { |
| 342 ss << ", abs send time: " << send_time; | 342 ss << ", abs send time: " << send_time; |
| 343 } | 343 } |
| 344 LOG(LS_INFO) << ss.str(); | 344 LOG(LS_INFO) << ss.str(); |
| 345 last_packet_log_ms_ = now_ms; | 345 last_packet_log_ms_ = now_ms; |
| 346 } | 346 } |
| 347 } | 347 } |
| 348 | 348 |
| 349 // TODO(nisse): Delete use of GetHeader, but needs refactoring of | 349 // TODO(nisse): Delete use of GetHeader, but needs refactoring of |
| 350 // ReceivePacket and IncomingPacket methods below. | 350 // ReceivePacket and IncomingPacket methods below. |
| 351 RTPHeader header; | 351 RTPHeader header; |
| 352 packet.GetHeader(&header); | 352 packet->GetHeader(&header); |
| 353 | |
| 354 header.payload_type_frequency = kVideoPayloadTypeFrequency; | |
| 355 | 353 |
| 356 bool in_order = IsPacketInOrder(header); | 354 bool in_order = IsPacketInOrder(header); |
| 357 rtp_payload_registry_.SetIncomingPayloadType(header); | 355 rtp_payload_registry_.SetIncomingPayloadType(header); |
| 358 ReceivePacket(packet.data(), packet.size(), header, in_order); | 356 ReceivePacket(packet->data(), packet->size(), header, in_order); |
| 359 // Update receive statistics after ReceivePacket. | 357 // Update receive statistics after ReceivePacket. |
| 360 // Receive statistics will be reset if the payload type changes (make sure | 358 // Receive statistics will be reset if the payload type changes (make sure |
| 361 // that the first packet is included in the stats). | 359 // that the first packet is included in the stats). |
| 362 rtp_receive_statistics_->IncomingPacket( | 360 rtp_receive_statistics_->IncomingPacket( |
| 363 header, packet.size(), IsPacketRetransmitted(header, in_order)); | 361 header, packet->size(), IsPacketRetransmitted(header, in_order)); |
| 362 |
| 363 return true; |
| 364 } | 364 } |
| 365 | 365 |
| 366 int32_t RtpStreamReceiver::RequestKeyFrame() { | 366 int32_t RtpStreamReceiver::RequestKeyFrame() { |
| 367 return rtp_rtcp_->RequestKeyFrame(); | 367 return rtp_rtcp_->RequestKeyFrame(); |
| 368 } | 368 } |
| 369 | 369 |
| 370 bool RtpStreamReceiver::IsUlpfecEnabled() const { | 370 bool RtpStreamReceiver::IsUlpfecEnabled() const { |
| 371 return config_.rtp.ulpfec.ulpfec_payload_type != -1; | 371 return config_.rtp.ulpfec.ulpfec_payload_type != -1; |
| 372 } | 372 } |
| 373 | 373 |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 "WebRTC.Video.ReceivedFecPacketsInPercent", | 623 "WebRTC.Video.ReceivedFecPacketsInPercent", |
| 624 static_cast<int>(counter.num_fec_packets * 100 / counter.num_packets)); | 624 static_cast<int>(counter.num_fec_packets * 100 / counter.num_packets)); |
| 625 } | 625 } |
| 626 if (counter.num_fec_packets > 0) { | 626 if (counter.num_fec_packets > 0) { |
| 627 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.RecoveredMediaPacketsInPercentOfFec", | 627 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.RecoveredMediaPacketsInPercentOfFec", |
| 628 static_cast<int>(counter.num_recovered_packets * | 628 static_cast<int>(counter.num_recovered_packets * |
| 629 100 / counter.num_fec_packets)); | 629 100 / counter.num_fec_packets)); |
| 630 } | 630 } |
| 631 } | 631 } |
| 632 | 632 |
| 633 void RtpStreamReceiver::EnableReceiveRtpHeaderExtension( | |
| 634 const std::string& extension, int id) { | |
| 635 // One-byte-extension local identifiers are in the range 1-14 inclusive. | |
| 636 RTC_DCHECK_GE(id, 1); | |
| 637 RTC_DCHECK_LE(id, 14); | |
| 638 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension)); | |
| 639 RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension( | |
| 640 StringToRtpExtensionType(extension), id)); | |
| 641 } | |
| 642 | |
| 643 void RtpStreamReceiver::InsertSpsPpsIntoTracker(uint8_t payload_type) { | 633 void RtpStreamReceiver::InsertSpsPpsIntoTracker(uint8_t payload_type) { |
| 644 auto codec_params_it = pt_codec_params_.find(payload_type); | 634 auto codec_params_it = pt_codec_params_.find(payload_type); |
| 645 if (codec_params_it == pt_codec_params_.end()) | 635 if (codec_params_it == pt_codec_params_.end()) |
| 646 return; | 636 return; |
| 647 | 637 |
| 648 LOG(LS_INFO) << "Found out of band supplied codec parameters for" | 638 LOG(LS_INFO) << "Found out of band supplied codec parameters for" |
| 649 << " payload type: " << static_cast<int>(payload_type); | 639 << " payload type: " << static_cast<int>(payload_type); |
| 650 | 640 |
| 651 H264SpropParameterSets sprop_decoder; | 641 H264SpropParameterSets sprop_decoder; |
| 652 auto sprop_base64_it = | 642 auto sprop_base64_it = |
| 653 codec_params_it->second.find(cricket::kH264FmtpSpropParameterSets); | 643 codec_params_it->second.find(cricket::kH264FmtpSpropParameterSets); |
| 654 | 644 |
| 655 if (sprop_base64_it == codec_params_it->second.end()) | 645 if (sprop_base64_it == codec_params_it->second.end()) |
| 656 return; | 646 return; |
| 657 | 647 |
| 658 if (!sprop_decoder.DecodeSprop(sprop_base64_it->second.c_str())) | 648 if (!sprop_decoder.DecodeSprop(sprop_base64_it->second.c_str())) |
| 659 return; | 649 return; |
| 660 | 650 |
| 661 tracker_.InsertSpsPpsNalus(sprop_decoder.sps_nalu(), | 651 tracker_.InsertSpsPpsNalus(sprop_decoder.sps_nalu(), |
| 662 sprop_decoder.pps_nalu()); | 652 sprop_decoder.pps_nalu()); |
| 663 } | 653 } |
| 664 | 654 |
| 665 } // namespace webrtc | 655 } // namespace webrtc |
| OLD | NEW |