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