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 |