Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Side by Side Diff: webrtc/video/rtp_stream_receiver.cc

Issue 2709723003: Initial implementation of RtpTransportControllerReceive and related interfaces.
Patch Set: Rebase. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698