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 |