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 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 const int frequency, | 307 const int frequency, |
308 const size_t channels, | 308 const size_t channels, |
309 const uint32_t rate) { | 309 const uint32_t rate) { |
310 RTC_NOTREACHED(); | 310 RTC_NOTREACHED(); |
311 return 0; | 311 return 0; |
312 } | 312 } |
313 | 313 |
314 // This method handles both regular RTP packets and packets recovered | 314 // This method handles both regular RTP packets and packets recovered |
315 // via FlexFEC. | 315 // via FlexFEC. |
316 void RtpVideoStreamReceiver::OnRtpPacket(const RtpPacketReceived& packet) { | 316 void RtpVideoStreamReceiver::OnRtpPacket(const RtpPacketReceived& packet) { |
317 // TODO(eladalon): https://bugs.chromium.org/p/webrtc/issues/detail?id=8056 | 317 RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_task_checker_); |
318 // RTC_DCHECK_RUN_ON(&worker_thread_checker_); | |
319 | 318 |
320 { | 319 if (!receiving_) { |
321 rtc::CritScope lock(&receive_cs_); | 320 return; |
322 if (!receiving_) { | 321 } |
323 return; | |
324 } | |
325 | 322 |
326 if (!packet.recovered()) { | 323 if (!packet.recovered()) { |
327 int64_t now_ms = clock_->TimeInMilliseconds(); | 324 int64_t now_ms = clock_->TimeInMilliseconds(); |
328 | 325 |
329 // Periodically log the RTP header of incoming packets. | 326 // Periodically log the RTP header of incoming packets. |
330 if (now_ms - last_packet_log_ms_ > kPacketLogIntervalMs) { | 327 if (now_ms - last_packet_log_ms_ > kPacketLogIntervalMs) { |
331 std::stringstream ss; | 328 std::stringstream ss; |
332 ss << "Packet received on SSRC: " << packet.Ssrc() | 329 ss << "Packet received on SSRC: " << packet.Ssrc() |
333 << " with payload type: " << static_cast<int>(packet.PayloadType()) | 330 << " with payload type: " << static_cast<int>(packet.PayloadType()) |
334 << ", timestamp: " << packet.Timestamp() | 331 << ", timestamp: " << packet.Timestamp() |
335 << ", sequence number: " << packet.SequenceNumber() | 332 << ", sequence number: " << packet.SequenceNumber() |
336 << ", arrival time: " << packet.arrival_time_ms(); | 333 << ", arrival time: " << packet.arrival_time_ms(); |
337 int32_t time_offset; | 334 int32_t time_offset; |
338 if (packet.GetExtension<TransmissionOffset>(&time_offset)) { | 335 if (packet.GetExtension<TransmissionOffset>(&time_offset)) { |
339 ss << ", toffset: " << time_offset; | 336 ss << ", toffset: " << time_offset; |
340 } | |
341 uint32_t send_time; | |
342 if (packet.GetExtension<AbsoluteSendTime>(&send_time)) { | |
343 ss << ", abs send time: " << send_time; | |
344 } | |
345 LOG(LS_INFO) << ss.str(); | |
346 last_packet_log_ms_ = now_ms; | |
347 } | 337 } |
| 338 uint32_t send_time; |
| 339 if (packet.GetExtension<AbsoluteSendTime>(&send_time)) { |
| 340 ss << ", abs send time: " << send_time; |
| 341 } |
| 342 LOG(LS_INFO) << ss.str(); |
| 343 last_packet_log_ms_ = now_ms; |
348 } | 344 } |
349 } | 345 } |
350 | 346 |
351 // TODO(nisse): Delete use of GetHeader, but needs refactoring of | 347 // TODO(nisse): Delete use of GetHeader, but needs refactoring of |
352 // ReceivePacket and IncomingPacket methods below. | 348 // ReceivePacket and IncomingPacket methods below. |
353 RTPHeader header; | 349 RTPHeader header; |
354 packet.GetHeader(&header); | 350 packet.GetHeader(&header); |
355 | 351 |
356 header.payload_type_frequency = kVideoPayloadTypeFrequency; | 352 header.payload_type_frequency = kVideoPayloadTypeFrequency; |
357 | 353 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 rtc::Optional<int64_t> RtpVideoStreamReceiver::LastReceivedPacketMs() const { | 431 rtc::Optional<int64_t> RtpVideoStreamReceiver::LastReceivedPacketMs() const { |
436 return packet_buffer_->LastReceivedPacketMs(); | 432 return packet_buffer_->LastReceivedPacketMs(); |
437 } | 433 } |
438 | 434 |
439 rtc::Optional<int64_t> RtpVideoStreamReceiver::LastReceivedKeyframePacketMs() | 435 rtc::Optional<int64_t> RtpVideoStreamReceiver::LastReceivedKeyframePacketMs() |
440 const { | 436 const { |
441 return packet_buffer_->LastReceivedKeyframePacketMs(); | 437 return packet_buffer_->LastReceivedKeyframePacketMs(); |
442 } | 438 } |
443 | 439 |
444 void RtpVideoStreamReceiver::AddSecondarySink(RtpPacketSinkInterface* sink) { | 440 void RtpVideoStreamReceiver::AddSecondarySink(RtpPacketSinkInterface* sink) { |
445 // TODO(eladalon): https://bugs.chromium.org/p/webrtc/issues/detail?id=8056 | 441 RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_task_checker_); |
446 // RTC_DCHECK_RUN_ON(&worker_thread_checker_); | |
447 RTC_DCHECK(std::find(secondary_sinks_.cbegin(), secondary_sinks_.cend(), | 442 RTC_DCHECK(std::find(secondary_sinks_.cbegin(), secondary_sinks_.cend(), |
448 sink) == secondary_sinks_.cend()); | 443 sink) == secondary_sinks_.cend()); |
449 secondary_sinks_.push_back(sink); | 444 secondary_sinks_.push_back(sink); |
450 } | 445 } |
451 | 446 |
452 void RtpVideoStreamReceiver::RemoveSecondarySink( | 447 void RtpVideoStreamReceiver::RemoveSecondarySink( |
453 const RtpPacketSinkInterface* sink) { | 448 const RtpPacketSinkInterface* sink) { |
454 // TODO(eladalon): https://bugs.chromium.org/p/webrtc/issues/detail?id=8056 | 449 RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_task_checker_); |
455 // RTC_DCHECK_RUN_ON(&worker_thread_checker_); | |
456 auto it = std::find(secondary_sinks_.begin(), secondary_sinks_.end(), sink); | 450 auto it = std::find(secondary_sinks_.begin(), secondary_sinks_.end(), sink); |
457 if (it == secondary_sinks_.end()) { | 451 if (it == secondary_sinks_.end()) { |
458 // We might be rolling-back a call whose setup failed mid-way. In such a | 452 // We might be rolling-back a call whose setup failed mid-way. In such a |
459 // case, it's simpler to remove "everything" rather than remember what | 453 // case, it's simpler to remove "everything" rather than remember what |
460 // has already been added. | 454 // has already been added. |
461 LOG(LS_WARNING) << "Removal of unknown sink."; | 455 LOG(LS_WARNING) << "Removal of unknown sink."; |
462 return; | 456 return; |
463 } | 457 } |
464 secondary_sinks_.erase(it); | 458 secondary_sinks_.erase(it); |
465 } | 459 } |
(...skipping 13 matching lines...) Expand all Loading... |
479 if (!rtp_payload_registry_.GetPayloadSpecifics(header.payloadType, | 473 if (!rtp_payload_registry_.GetPayloadSpecifics(header.payloadType, |
480 &payload_specific)) { | 474 &payload_specific)) { |
481 return; | 475 return; |
482 } | 476 } |
483 rtp_receiver_->IncomingRtpPacket(header, payload, payload_length, | 477 rtp_receiver_->IncomingRtpPacket(header, payload, payload_length, |
484 payload_specific, in_order); | 478 payload_specific, in_order); |
485 } | 479 } |
486 | 480 |
487 void RtpVideoStreamReceiver::ParseAndHandleEncapsulatingHeader( | 481 void RtpVideoStreamReceiver::ParseAndHandleEncapsulatingHeader( |
488 const uint8_t* packet, size_t packet_length, const RTPHeader& header) { | 482 const uint8_t* packet, size_t packet_length, const RTPHeader& header) { |
| 483 RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_task_checker_); |
489 if (rtp_payload_registry_.IsRed(header)) { | 484 if (rtp_payload_registry_.IsRed(header)) { |
490 int8_t ulpfec_pt = rtp_payload_registry_.ulpfec_payload_type(); | 485 int8_t ulpfec_pt = rtp_payload_registry_.ulpfec_payload_type(); |
491 if (packet[header.headerLength] == ulpfec_pt) { | 486 if (packet[header.headerLength] == ulpfec_pt) { |
492 rtp_receive_statistics_->FecPacketReceived(header, packet_length); | 487 rtp_receive_statistics_->FecPacketReceived(header, packet_length); |
493 // Notify video_receiver about received FEC packets to avoid NACKing these | 488 // Notify video_receiver about received FEC packets to avoid NACKing these |
494 // packets. | 489 // packets. |
495 NotifyReceiverOfFecPacket(header); | 490 NotifyReceiverOfFecPacket(header); |
496 } | 491 } |
497 if (ulpfec_receiver_->AddReceivedRedPacket(header, packet, packet_length, | 492 if (ulpfec_receiver_->AddReceivedRedPacket(header, packet, packet_length, |
498 ulpfec_pt) != 0) { | 493 ulpfec_pt) != 0) { |
499 return; | 494 return; |
500 } | 495 } |
501 ulpfec_receiver_->ProcessReceivedFec(); | 496 ulpfec_receiver_->ProcessReceivedFec(); |
502 } else if (rtp_payload_registry_.IsRtx(header)) { | 497 } else if (rtp_payload_registry_.IsRtx(header)) { |
503 if (header.headerLength + header.paddingLength == packet_length) { | 498 if (header.headerLength + header.paddingLength == packet_length) { |
504 // This is an empty packet and should be silently dropped before trying to | 499 // This is an empty packet and should be silently dropped before trying to |
505 // parse the RTX header. | 500 // parse the RTX header. |
506 return; | 501 return; |
507 } | 502 } |
508 // Remove the RTX header and parse the original RTP header. | 503 // Remove the RTX header and parse the original RTP header. |
509 if (packet_length < header.headerLength) | 504 if (packet_length < header.headerLength) |
510 return; | 505 return; |
511 if (packet_length > sizeof(restored_packet_)) | 506 if (packet_length > sizeof(restored_packet_)) |
512 return; | 507 return; |
513 rtc::CritScope lock(&receive_cs_); | |
514 if (restored_packet_in_use_) { | 508 if (restored_packet_in_use_) { |
515 LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet."; | 509 LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet."; |
516 return; | 510 return; |
517 } | 511 } |
518 if (!rtp_payload_registry_.RestoreOriginalPacket( | 512 if (!rtp_payload_registry_.RestoreOriginalPacket( |
519 restored_packet_, packet, &packet_length, config_.rtp.remote_ssrc, | 513 restored_packet_, packet, &packet_length, config_.rtp.remote_ssrc, |
520 header)) { | 514 header)) { |
521 LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header ssrc: " | 515 LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header ssrc: " |
522 << header.ssrc << " payload type: " | 516 << header.ssrc << " payload type: " |
523 << static_cast<int>(header.payloadType); | 517 << static_cast<int>(header.payloadType); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 if (header.extension.has_video_timing) { | 555 if (header.extension.has_video_timing) { |
562 rtp_header.type.Video.video_timing = header.extension.video_timing; | 556 rtp_header.type.Video.video_timing = header.extension.video_timing; |
563 } | 557 } |
564 rtp_header.type.Video.playout_delay = header.extension.playout_delay; | 558 rtp_header.type.Video.playout_delay = header.extension.playout_delay; |
565 | 559 |
566 OnReceivedPayloadData(nullptr, 0, &rtp_header); | 560 OnReceivedPayloadData(nullptr, 0, &rtp_header); |
567 } | 561 } |
568 | 562 |
569 bool RtpVideoStreamReceiver::DeliverRtcp(const uint8_t* rtcp_packet, | 563 bool RtpVideoStreamReceiver::DeliverRtcp(const uint8_t* rtcp_packet, |
570 size_t rtcp_packet_length) { | 564 size_t rtcp_packet_length) { |
571 { | 565 RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_task_checker_); |
572 rtc::CritScope lock(&receive_cs_); | 566 |
573 if (!receiving_) { | 567 if (!receiving_) { |
574 return false; | 568 return false; |
575 } | |
576 } | 569 } |
577 | 570 |
578 rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); | 571 rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); |
579 | 572 |
580 int64_t rtt = 0; | 573 int64_t rtt = 0; |
581 rtp_rtcp_->RTT(rtp_receiver_->SSRC(), &rtt, nullptr, nullptr, nullptr); | 574 rtp_rtcp_->RTT(rtp_receiver_->SSRC(), &rtt, nullptr, nullptr, nullptr); |
582 if (rtt == 0) { | 575 if (rtt == 0) { |
583 // Waiting for valid rtt. | 576 // Waiting for valid rtt. |
584 return true; | 577 return true; |
585 } | 578 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 reference_finder_->ClearTo(seq_num); | 620 reference_finder_->ClearTo(seq_num); |
628 } | 621 } |
629 } | 622 } |
630 | 623 |
631 void RtpVideoStreamReceiver::SignalNetworkState(NetworkState state) { | 624 void RtpVideoStreamReceiver::SignalNetworkState(NetworkState state) { |
632 rtp_rtcp_->SetRTCPStatus(state == kNetworkUp ? config_.rtp.rtcp_mode | 625 rtp_rtcp_->SetRTCPStatus(state == kNetworkUp ? config_.rtp.rtcp_mode |
633 : RtcpMode::kOff); | 626 : RtcpMode::kOff); |
634 } | 627 } |
635 | 628 |
636 void RtpVideoStreamReceiver::StartReceive() { | 629 void RtpVideoStreamReceiver::StartReceive() { |
637 rtc::CritScope lock(&receive_cs_); | 630 RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_task_checker_); |
638 receiving_ = true; | 631 receiving_ = true; |
639 } | 632 } |
640 | 633 |
641 void RtpVideoStreamReceiver::StopReceive() { | 634 void RtpVideoStreamReceiver::StopReceive() { |
642 rtc::CritScope lock(&receive_cs_); | 635 RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_task_checker_); |
643 receiving_ = false; | 636 receiving_ = false; |
644 } | 637 } |
645 | 638 |
646 bool RtpVideoStreamReceiver::IsPacketInOrder(const RTPHeader& header) const { | 639 bool RtpVideoStreamReceiver::IsPacketInOrder(const RTPHeader& header) const { |
647 StreamStatistician* statistician = | 640 StreamStatistician* statistician = |
648 rtp_receive_statistics_->GetStatistician(header.ssrc); | 641 rtp_receive_statistics_->GetStatistician(header.ssrc); |
649 if (!statistician) | 642 if (!statistician) |
650 return false; | 643 return false; |
651 return statistician->IsPacketInOrder(header.sequenceNumber); | 644 return statistician->IsPacketInOrder(header.sequenceNumber); |
652 } | 645 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 return; | 708 return; |
716 | 709 |
717 if (!sprop_decoder.DecodeSprop(sprop_base64_it->second.c_str())) | 710 if (!sprop_decoder.DecodeSprop(sprop_base64_it->second.c_str())) |
718 return; | 711 return; |
719 | 712 |
720 tracker_.InsertSpsPpsNalus(sprop_decoder.sps_nalu(), | 713 tracker_.InsertSpsPpsNalus(sprop_decoder.sps_nalu(), |
721 sprop_decoder.pps_nalu()); | 714 sprop_decoder.pps_nalu()); |
722 } | 715 } |
723 | 716 |
724 } // namespace webrtc | 717 } // namespace webrtc |
OLD | NEW |