| 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 |