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