tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 60a0cbe9ce5922d460632b7b32391a0cddba1894
parent ebb256065b0d789f59c37cdbd6a3774baac4c917
Author: Dan Baker <dbaker@mozilla.com>
Date:   Fri, 24 Oct 2025 11:40:38 -0600

Bug 1995393 - Vendor libwebrtc from c5360ff72e

Upstream commit: https://webrtc.googlesource.com/src/+/c5360ff72e6b86ab264fd7709fa54a7aee6c6d13
    Delete deprecated variant of the RtpRtcp module

    Bug: webrtc:42224904
    Change-Id: If73fa4274c73fa004473e9b6b6c15c28326223d3
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/405201
    Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org>
    Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
    Cr-Commit-Position: refs/heads/main@{#45387}

Diffstat:
Mthird_party/libwebrtc/README.mozilla.last-vendor | 4++--
Mthird_party/libwebrtc/modules/rtp_rtcp/BUILD.gn | 39---------------------------------------
Dthird_party/libwebrtc/modules/rtp_rtcp/include/rtp_rtcp.h | 35-----------------------------------
Dthird_party/libwebrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc | 367-------------------------------------------------------------------------------
Dthird_party/libwebrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h | 140-------------------------------------------------------------------------------
Dthird_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 746-------------------------------------------------------------------------------
Dthird_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h | 341-------------------------------------------------------------------------------
Dthird_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc | 718-------------------------------------------------------------------------------
Mthird_party/libwebrtc/moz-patch-stack/s0003.patch | 34+---------------------------------
Mthird_party/libwebrtc/moz-patch-stack/s0004.patch | 35+----------------------------------
Mthird_party/libwebrtc/moz-patch-stack/s0042.patch | 39+--------------------------------------
Mthird_party/libwebrtc/moz-patch-stack/s0082.patch | 15+--------------
12 files changed, 6 insertions(+), 2507 deletions(-)

diff --git a/third_party/libwebrtc/README.mozilla.last-vendor b/third_party/libwebrtc/README.mozilla.last-vendor @@ -1,4 +1,4 @@ # ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc -libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-23T23:45:36.154676+00:00. +libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-24T17:40:16.519528+00:00. # base of lastest vendoring -190613939f +c5360ff72e diff --git a/third_party/libwebrtc/modules/rtp_rtcp/BUILD.gn b/third_party/libwebrtc/modules/rtp_rtcp/BUILD.gn @@ -363,43 +363,6 @@ rtc_library("rtp_rtcp") { ] } -rtc_library("rtp_rtcp_legacy") { - sources = [ - "include/rtp_rtcp.h", - "source/deprecated/deprecated_rtp_sender_egress.cc", - "source/deprecated/deprecated_rtp_sender_egress.h", - "source/rtp_rtcp_impl.cc", - "source/rtp_rtcp_impl.h", - ] - deps = [ - ":ntp_time_util", - ":rtp_rtcp", - ":rtp_rtcp_format", - "..:module_fec_api", - "../../api:array_view", - "../../api:rtp_headers", - "../../api:rtp_packet_sender", - "../../api:transport_api", - "../../api/environment", - "../../api/rtc_event_log", - "../../api/transport:network_control", - "../../api/units:data_rate", - "../../api/units:time_delta", - "../../api/units:timestamp", - "../../api/video:video_bitrate_allocation", - "../../logging:rtc_event_rtp_rtcp", - "../../rtc_base:bitrate_tracker", - "../../rtc_base:checks", - "../../rtc_base:gtest_prod", - "../../rtc_base:logging", - "../../rtc_base:macromagic", - "../../rtc_base/synchronization:mutex", - "../../system_wrappers", - "//third_party/abseil-cpp/absl/base:core_headers", - "//third_party/abseil-cpp/absl/strings:string_view", - ] -} - rtc_library("ntp_time_util") { visibility = [ "*" ] sources = [ @@ -643,7 +606,6 @@ if (rtc_include_tests) { "source/rtp_packet_unittest.cc", "source/rtp_packetizer_av1_unittest.cc", "source/rtp_rtcp_impl2_unittest.cc", - "source/rtp_rtcp_impl_unittest.cc", "source/rtp_sender_audio_unittest.cc", "source/rtp_sender_egress_unittest.cc", "source/rtp_sender_unittest.cc", @@ -682,7 +644,6 @@ if (rtc_include_tests) { ":rtp_packetizer_av1_test_helper", ":rtp_rtcp", ":rtp_rtcp_format", - ":rtp_rtcp_legacy", ":rtp_video_header", ":rtp_video_header_unittest", "..:module_fec_api", diff --git a/third_party/libwebrtc/modules/rtp_rtcp/include/rtp_rtcp.h b/third_party/libwebrtc/modules/rtp_rtcp/include/rtp_rtcp.h @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_H_ -#define MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_H_ - -#include <memory> - -#include "api/environment/environment.h" -#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" - -namespace webrtc { - -// A deprecated version of the RtpRtcp module. -class [[deprecated("bugs.webrtc.org/42224904")]] RtpRtcp - : public RtpRtcpInterface { - public: - [[deprecated("bugs.webrtc.org/42224904")]] // - static std::unique_ptr<RtpRtcp> - Create(const Environment& env, const Configuration& configuration); - - // Process any pending tasks such as timeouts. - virtual void Process() = 0; -}; - -} // namespace webrtc - -#endif // MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_H_ diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc @@ -1,367 +0,0 @@ -/* - * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h" - -#include <cstddef> -#include <cstdint> -#include <memory> -#include <optional> -#include <vector> - -#include "api/array_view.h" -#include "api/call/transport.h" -#include "api/environment/environment.h" -#include "api/rtc_event_log/rtc_event_log.h" -#include "api/transport/network_types.h" -#include "api/units/data_rate.h" -#include "api/units/time_delta.h" -#include "api/units/timestamp.h" -#include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h" -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" -#include "modules/rtp_rtcp/source/packet_sequencer.h" -#include "modules/rtp_rtcp/source/rtp_header_extensions.h" -#include "modules/rtp_rtcp/source/rtp_packet_history.h" -#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" -#include "modules/rtp_rtcp/source/rtp_sequence_number_map.h" -#include "rtc_base/bitrate_tracker.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" -#include "rtc_base/synchronization/mutex.h" - -namespace webrtc { -namespace { -constexpr uint32_t kTimestampTicksPerMs = 90; -constexpr TimeDelta kBitrateStatisticsWindow = TimeDelta::Seconds(1); -constexpr size_t kRtpSequenceNumberMapMaxEntries = 1 << 13; - -} // namespace - -DEPRECATED_RtpSenderEgress::NonPacedPacketSender::NonPacedPacketSender( - DEPRECATED_RtpSenderEgress* sender, - PacketSequencer* sequence_number_assigner) - : transport_sequence_number_(0), - sender_(sender), - sequence_number_assigner_(sequence_number_assigner) { - RTC_DCHECK(sequence_number_assigner_); -} -DEPRECATED_RtpSenderEgress::NonPacedPacketSender::~NonPacedPacketSender() = - default; - -void DEPRECATED_RtpSenderEgress::NonPacedPacketSender::EnqueuePackets( - std::vector<std::unique_ptr<RtpPacketToSend>> packets) { - for (auto& packet : packets) { - // Assign sequence numbers, but not for flexfec which is already running on - // an internally maintained sequence number series. - if (packet->Ssrc() != sender_->FlexFecSsrc()) { - sequence_number_assigner_->Sequence(*packet); - } - if (!packet->SetExtension<TransportSequenceNumber>( - ++transport_sequence_number_)) { - --transport_sequence_number_; - } - packet->ReserveExtension<TransmissionOffset>(); - packet->ReserveExtension<AbsoluteSendTime>(); - sender_->SendPacket(packet.get(), PacedPacketInfo()); - } -} - -DEPRECATED_RtpSenderEgress::DEPRECATED_RtpSenderEgress( - const Environment& env, - const RtpRtcpInterface::Configuration& config, - RtpPacketHistory* packet_history) - : env_(env), - ssrc_(config.local_media_ssrc), - rtx_ssrc_(config.rtx_send_ssrc), - flexfec_ssrc_(config.fec_generator ? config.fec_generator->FecSsrc() - : std::nullopt), - populate_network2_timestamp_(config.populate_network2_timestamp), - packet_history_(packet_history), - transport_(config.outgoing_transport), - need_rtp_packet_infos_(config.need_rtp_packet_infos), - transport_feedback_observer_(config.transport_feedback_callback), - send_packet_observer_(config.send_packet_observer), - rtp_stats_callback_(config.rtp_stats_callback), - bitrate_callback_(config.send_bitrate_observer), - media_has_been_sent_(false), - force_part_of_allocation_(false), - timestamp_offset_(0), - send_rates_(kNumMediaTypes, BitrateTracker(kBitrateStatisticsWindow)), - rtp_sequence_number_map_(need_rtp_packet_infos_ - ? std::make_unique<RtpSequenceNumberMap>( - kRtpSequenceNumberMapMaxEntries) - : nullptr) {} - -void DEPRECATED_RtpSenderEgress::SendPacket( - RtpPacketToSend* packet, - const PacedPacketInfo& pacing_info) { - RTC_DCHECK(packet); - - const uint32_t packet_ssrc = packet->Ssrc(); - RTC_DCHECK(packet->packet_type().has_value()); - RTC_DCHECK(HasCorrectSsrc(*packet)); - Timestamp now = env_.clock().CurrentTime(); - int64_t now_ms = now.ms(); - PacketOptions options; - { - MutexLock lock(&lock_); - options.included_in_allocation = force_part_of_allocation_; - - if (need_rtp_packet_infos_ && - packet->packet_type() == RtpPacketToSend::Type::kVideo) { - RTC_DCHECK(rtp_sequence_number_map_); - // Last packet of a frame, add it to sequence number info map. - const uint32_t timestamp = packet->Timestamp() - timestamp_offset_; - bool is_first_packet_of_frame = packet->is_first_packet_of_frame(); - bool is_last_packet_of_frame = packet->Marker(); - - rtp_sequence_number_map_->InsertPacket( - packet->SequenceNumber(), - RtpSequenceNumberMap::Info(timestamp, is_first_packet_of_frame, - is_last_packet_of_frame)); - } - } - - // Bug webrtc:7859. While FEC is invoked from rtp_sender_video, and not after - // the pacer, these modifications of the header below are happening after the - // FEC protection packets are calculated. This will corrupt recovered packets - // at the same place. It's not an issue for extensions, which are present in - // all the packets (their content just may be incorrect on recovered packets). - // In case of VideoTimingExtension, since it's present not in every packet, - // data after rtp header may be corrupted if these packets are protected by - // the FEC. - int64_t diff_ms = now_ms - packet->capture_time().ms(); - if (packet->HasExtension<TransmissionOffset>()) { - packet->SetExtension<TransmissionOffset>(kTimestampTicksPerMs * diff_ms); - } - if (packet->HasExtension<AbsoluteSendTime>()) { - packet->SetExtension<AbsoluteSendTime>(AbsoluteSendTime::To24Bits(now)); - } - - if (packet->HasExtension<VideoTimingExtension>()) { - if (populate_network2_timestamp_) { - packet->set_network2_time(now); - } else { - packet->set_pacer_exit_time(now); - } - } - - options.is_media = packet->packet_type() == RtpPacketMediaType::kAudio || - packet->packet_type() == RtpPacketMediaType::kVideo; - - if (auto packet_id = packet->GetExtension<TransportSequenceNumber>()) { - options.packet_id = *packet_id; - options.included_in_feedback = true; - options.included_in_allocation = true; - AddPacketToTransportFeedback(*packet_id, *packet, pacing_info); - } - - if (packet->packet_type() != RtpPacketMediaType::kPadding && - packet->packet_type() != RtpPacketMediaType::kRetransmission) { - UpdateOnSendPacket(options.packet_id, packet->capture_time().ms(), - packet_ssrc); - } - - const bool send_success = SendPacketToNetwork(*packet, options, pacing_info); - - // Put packet in retransmission history or update pending status even if - // actual sending fails. - if (options.is_media && packet->allow_retransmission()) { - packet_history_->PutRtpPacket(std::make_unique<RtpPacketToSend>(*packet), - now); - } else if (packet->retransmitted_sequence_number()) { - packet_history_->MarkPacketAsSent(*packet->retransmitted_sequence_number()); - } - - if (send_success) { - MutexLock lock(&lock_); - UpdateRtpStats(*packet); - media_has_been_sent_ = true; - } -} - -void DEPRECATED_RtpSenderEgress::ProcessBitrateAndNotifyObservers() { - if (!bitrate_callback_) - return; - - MutexLock lock(&lock_); - RtpSendRates send_rates = GetSendRatesLocked(); - bitrate_callback_->Notify( - send_rates.Sum().bps(), - send_rates[RtpPacketMediaType::kRetransmission].bps(), ssrc_); -} - -RtpSendRates DEPRECATED_RtpSenderEgress::GetSendRates() const { - MutexLock lock(&lock_); - return GetSendRatesLocked(); -} - -RtpSendRates DEPRECATED_RtpSenderEgress::GetSendRatesLocked() const { - const Timestamp now = env_.clock().CurrentTime(); - RtpSendRates current_rates; - for (size_t i = 0; i < kNumMediaTypes; ++i) { - RtpPacketMediaType type = static_cast<RtpPacketMediaType>(i); - current_rates[type] = send_rates_[i].Rate(now).value_or(DataRate::Zero()); - } - return current_rates; -} - -void DEPRECATED_RtpSenderEgress::GetDataCounters( - StreamDataCounters* rtp_stats, - StreamDataCounters* rtx_stats) const { - MutexLock lock(&lock_); - if (rtp_stats_callback_) { - *rtp_stats = rtp_stats_callback_->GetDataCounters(ssrc_); - if (rtx_ssrc_.has_value()) { - *rtx_stats = rtp_stats_callback_->GetDataCounters(*rtx_ssrc_); - } - } else { - *rtp_stats = rtp_stats_; - *rtx_stats = rtx_rtp_stats_; - } -} - -void DEPRECATED_RtpSenderEgress::ForceIncludeSendPacketsInAllocation( - bool part_of_allocation) { - MutexLock lock(&lock_); - force_part_of_allocation_ = part_of_allocation; -} - -bool DEPRECATED_RtpSenderEgress::MediaHasBeenSent() const { - MutexLock lock(&lock_); - return media_has_been_sent_; -} - -void DEPRECATED_RtpSenderEgress::SetMediaHasBeenSent(bool media_sent) { - MutexLock lock(&lock_); - media_has_been_sent_ = media_sent; -} - -void DEPRECATED_RtpSenderEgress::SetTimestampOffset(uint32_t timestamp) { - MutexLock lock(&lock_); - timestamp_offset_ = timestamp; -} - -std::vector<RtpSequenceNumberMap::Info> -DEPRECATED_RtpSenderEgress::GetSentRtpPacketInfos( - ArrayView<const uint16_t> sequence_numbers) const { - RTC_DCHECK(!sequence_numbers.empty()); - if (!need_rtp_packet_infos_) { - return std::vector<RtpSequenceNumberMap::Info>(); - } - - std::vector<RtpSequenceNumberMap::Info> results; - results.reserve(sequence_numbers.size()); - - MutexLock lock(&lock_); - for (uint16_t sequence_number : sequence_numbers) { - const auto& info = rtp_sequence_number_map_->Get(sequence_number); - if (!info) { - // The empty vector will be returned. We can delay the clearing - // of the vector until after we exit the critical section. - return std::vector<RtpSequenceNumberMap::Info>(); - } - results.push_back(*info); - } - - return results; -} - -bool DEPRECATED_RtpSenderEgress::HasCorrectSsrc( - const RtpPacketToSend& packet) const { - switch (*packet.packet_type()) { - case RtpPacketMediaType::kAudio: - case RtpPacketMediaType::kVideo: - return packet.Ssrc() == ssrc_; - case RtpPacketMediaType::kRetransmission: - case RtpPacketMediaType::kPadding: - // Both padding and retransmission must be on either the media or the - // RTX stream. - return packet.Ssrc() == rtx_ssrc_ || packet.Ssrc() == ssrc_; - case RtpPacketMediaType::kForwardErrorCorrection: - // FlexFEC is on separate SSRC, ULPFEC uses media SSRC. - return packet.Ssrc() == ssrc_ || packet.Ssrc() == flexfec_ssrc_; - } - return false; -} - -void DEPRECATED_RtpSenderEgress::AddPacketToTransportFeedback( - uint16_t packet_id, - const RtpPacketToSend& packet, - const PacedPacketInfo& pacing_info) { - if (transport_feedback_observer_) { - RtpPacketSendInfo packet_info; - packet_info.media_ssrc = ssrc_; - packet_info.transport_sequence_number = packet_id; - packet_info.rtp_sequence_number = packet.SequenceNumber(); - packet_info.length = packet.size(); - packet_info.pacing_info = pacing_info; - packet_info.packet_type = packet.packet_type(); - transport_feedback_observer_->OnAddPacket(packet_info); - } -} - -void DEPRECATED_RtpSenderEgress::UpdateOnSendPacket(int packet_id, - int64_t capture_time_ms, - uint32_t ssrc) { - if (!send_packet_observer_ || capture_time_ms <= 0 || packet_id == -1) { - return; - } - - send_packet_observer_->OnSendPacket(packet_id, - Timestamp::Millis(capture_time_ms), ssrc); -} - -bool DEPRECATED_RtpSenderEgress::SendPacketToNetwork( - const RtpPacketToSend& packet, - const PacketOptions& options, - const PacedPacketInfo& pacing_info) { - if (transport_ == nullptr || !transport_->SendRtp(packet, options)) { - RTC_LOG(LS_WARNING) << "Transport failed to send packet."; - return false; - } - - env_.event_log().Log(std::make_unique<RtcEventRtpPacketOutgoing>( - packet, pacing_info.probe_cluster_id)); - return true; -} - -void DEPRECATED_RtpSenderEgress::UpdateRtpStats(const RtpPacketToSend& packet) { - Timestamp now = env_.clock().CurrentTime(); - - StreamDataCounters* counters = nullptr; - if (rtp_stats_callback_) { - rtp_stats_ = rtp_stats_callback_->GetDataCounters(packet.Ssrc()); - counters = &rtp_stats_; - } else { - counters = packet.Ssrc() == rtx_ssrc_ ? &rtx_rtp_stats_ : &rtp_stats_; - } - - counters->MaybeSetFirstPacketTime(now); - - if (packet.packet_type() == RtpPacketMediaType::kForwardErrorCorrection) { - counters->fec.AddPacket(packet); - } - - if (packet.packet_type() == RtpPacketMediaType::kRetransmission) { - counters->retransmitted.AddPacket(packet); - } - counters->transmitted.AddPacket(packet); - - RTC_DCHECK(packet.packet_type().has_value()); - send_rates_[static_cast<size_t>(*packet.packet_type())].Update(packet.size(), - now); - - if (rtp_stats_callback_) { - rtp_stats_callback_->DataCountersUpdated(*counters, packet.Ssrc()); - } -} - -} // namespace webrtc diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h b/third_party/libwebrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef MODULES_RTP_RTCP_SOURCE_DEPRECATED_DEPRECATED_RTP_SENDER_EGRESS_H_ -#define MODULES_RTP_RTCP_SOURCE_DEPRECATED_DEPRECATED_RTP_SENDER_EGRESS_H_ - -#include <cstdint> -#include <memory> -#include <optional> -#include <vector> - -#include "api/array_view.h" -#include "api/call/transport.h" -#include "api/environment/environment.h" -#include "api/rtp_packet_sender.h" -#include "api/transport/network_types.h" -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" -#include "modules/rtp_rtcp/source/packet_sequencer.h" -#include "modules/rtp_rtcp/source/rtp_packet_history.h" -#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" -#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" -#include "modules/rtp_rtcp/source/rtp_sequence_number_map.h" -#include "rtc_base/bitrate_tracker.h" -#include "rtc_base/synchronization/mutex.h" -#include "rtc_base/thread_annotations.h" - -namespace webrtc { - -class DEPRECATED_RtpSenderEgress { - public: - // Helper class that redirects packets directly to the send part of this class - // without passing through an actual paced sender. - class NonPacedPacketSender : public RtpPacketSender { - public: - NonPacedPacketSender(DEPRECATED_RtpSenderEgress* sender, - PacketSequencer* sequence_number_assigner); - virtual ~NonPacedPacketSender(); - - void EnqueuePackets( - std::vector<std::unique_ptr<RtpPacketToSend>> packets) override; - void RemovePacketsForSsrc(uint32_t /* ssrc */) override {} - - private: - uint16_t transport_sequence_number_; - DEPRECATED_RtpSenderEgress* const sender_; - PacketSequencer* sequence_number_assigner_; - }; - - DEPRECATED_RtpSenderEgress(const Environment& env, - const RtpRtcpInterface::Configuration& config, - RtpPacketHistory* packet_history); - ~DEPRECATED_RtpSenderEgress() = default; - - void SendPacket(RtpPacketToSend* packet, const PacedPacketInfo& pacing_info) - RTC_LOCKS_EXCLUDED(lock_); - uint32_t Ssrc() const { return ssrc_; } - std::optional<uint32_t> RtxSsrc() const { return rtx_ssrc_; } - std::optional<uint32_t> FlexFecSsrc() const { return flexfec_ssrc_; } - - void ProcessBitrateAndNotifyObservers() RTC_LOCKS_EXCLUDED(lock_); - RtpSendRates GetSendRates() const RTC_LOCKS_EXCLUDED(lock_); - void GetDataCounters(StreamDataCounters* rtp_stats, - StreamDataCounters* rtx_stats) const - RTC_LOCKS_EXCLUDED(lock_); - - void ForceIncludeSendPacketsInAllocation(bool part_of_allocation) - RTC_LOCKS_EXCLUDED(lock_); - bool MediaHasBeenSent() const RTC_LOCKS_EXCLUDED(lock_); - void SetMediaHasBeenSent(bool media_sent) RTC_LOCKS_EXCLUDED(lock_); - void SetTimestampOffset(uint32_t timestamp) RTC_LOCKS_EXCLUDED(lock_); - - // For each sequence number in `sequence_number`, recall the last RTP packet - // which bore it - its timestamp and whether it was the first and/or last - // packet in that frame. If all of the given sequence numbers could be - // recalled, return a vector with all of them (in corresponding order). - // If any could not be recalled, return an empty vector. - std::vector<RtpSequenceNumberMap::Info> GetSentRtpPacketInfos( - ArrayView<const uint16_t> sequence_numbers) const - RTC_LOCKS_EXCLUDED(lock_); - - private: - RtpSendRates GetSendRatesLocked() const RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_); - bool HasCorrectSsrc(const RtpPacketToSend& packet) const; - void AddPacketToTransportFeedback(uint16_t packet_id, - const RtpPacketToSend& packet, - const PacedPacketInfo& pacing_info); - void UpdateOnSendPacket(int packet_id, - int64_t capture_time_ms, - uint32_t ssrc); - // Sends packet on to `transport_`, leaving the RTP module. - bool SendPacketToNetwork(const RtpPacketToSend& packet, - const PacketOptions& options, - const PacedPacketInfo& pacing_info); - void UpdateRtpStats(const RtpPacketToSend& packet) - RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_); - - const Environment env_; - const uint32_t ssrc_; - const std::optional<uint32_t> rtx_ssrc_; - const std::optional<uint32_t> flexfec_ssrc_; - const bool populate_network2_timestamp_; - RtpPacketHistory* const packet_history_; - Transport* const transport_; - const bool need_rtp_packet_infos_; - - TransportFeedbackObserver* const transport_feedback_observer_; - SendPacketObserver* const send_packet_observer_; - StreamDataCountersCallback* const rtp_stats_callback_; - BitrateStatisticsObserver* const bitrate_callback_; - - mutable Mutex lock_; - bool media_has_been_sent_ RTC_GUARDED_BY(lock_); - bool force_part_of_allocation_ RTC_GUARDED_BY(lock_); - uint32_t timestamp_offset_ RTC_GUARDED_BY(lock_); - - // These counters are only used if `rtp_stats_callback_` is null. - StreamDataCounters rtp_stats_ RTC_GUARDED_BY(lock_); - StreamDataCounters rtx_rtp_stats_ RTC_GUARDED_BY(lock_); - - // One element per value in RtpPacketMediaType, with index matching value. - std::vector<BitrateTracker> send_rates_ RTC_GUARDED_BY(lock_); - - // Maps sent packets' sequence numbers to a tuple consisting of: - // 1. The timestamp, without the randomizing offset mandated by the RFC. - // 2. Whether the packet was the first in its frame. - // 3. Whether the packet was the last in its frame. - const std::unique_ptr<RtpSequenceNumberMap> rtp_sequence_number_map_ - RTC_GUARDED_BY(lock_); -}; - -} // namespace webrtc - -#endif // MODULES_RTP_RTCP_SOURCE_DEPRECATED_DEPRECATED_RTP_SENDER_EGRESS_H_ diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -1,746 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "modules/rtp_rtcp/source/rtp_rtcp_impl.h" - -#include <cstdint> -#include <cstring> -#include <memory> -#include <optional> -#include <utility> -#include <vector> - -#include "absl/strings/string_view.h" -#include "api/array_view.h" -#include "api/environment/environment.h" -#include "api/rtp_headers.h" -#include "api/units/time_delta.h" -#include "api/units/timestamp.h" -#include "api/video/video_bitrate_allocation.h" -#include "modules/include/module_fec_types.h" -#include "modules/rtp_rtcp/include/report_block_data.h" -#include "modules/rtp_rtcp/include/rtp_rtcp.h" -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" -#include "modules/rtp_rtcp/source/ntp_time_util.h" -#include "modules/rtp_rtcp/source/rtcp_packet.h" -#include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h" -#include "modules/rtp_rtcp/source/rtcp_sender.h" -#include "modules/rtp_rtcp/source/rtp_packet_history.h" -#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" -#include "modules/rtp_rtcp/source/rtp_rtcp_config.h" -#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" -#include "modules/rtp_rtcp/source/rtp_sequence_number_map.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" -#include "rtc_base/synchronization/mutex.h" -#include "system_wrappers/include/ntp_time.h" - -#ifdef _WIN32 -// Disable warning C4355: 'this' : used in base member initializer list. -#pragma warning(disable : 4355) -#endif - -namespace webrtc { -namespace { -const int64_t kRtpRtcpRttProcessTimeMs = 1000; -const int64_t kRtpRtcpBitrateProcessTimeMs = 10; -constexpr TimeDelta kDefaultExpectedRetransmissionTime = TimeDelta::Millis(125); -} // namespace - -ModuleRtpRtcpImpl::RtpSenderContext::RtpSenderContext( - const Environment& env, - const RtpRtcpInterface::Configuration& config) - : packet_history(env, RtpPacketHistory::PaddingMode::kRecentLargePacket), - sequencer_(config.local_media_ssrc, - config.rtx_send_ssrc, - /*require_marker_before_media_padding=*/!config.audio, - &env.clock()), - packet_sender(env, config, &packet_history), - non_paced_sender(&packet_sender, &sequencer_), - packet_generator( - env, - config, - &packet_history, - config.paced_sender ? config.paced_sender : &non_paced_sender) {} - -std::unique_ptr<RtpRtcp> RtpRtcp::Create(const Environment& env, - const Configuration& configuration) { - return std::make_unique<ModuleRtpRtcpImpl>(env, configuration); -} - -ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Environment& env, - const Configuration& configuration) - : env_(env), - rtcp_sender_( - env_, - RTCPSender::Configuration::FromRtpRtcpConfiguration(configuration)), - rtcp_receiver_(env_, configuration, this), - last_bitrate_process_time_(env_.clock().TimeInMilliseconds()), - last_rtt_process_time_(env_.clock().TimeInMilliseconds()), - packet_overhead_(28), // IPV4 UDP. - nack_last_time_sent_full_ms_(0), - nack_last_seq_number_sent_(0), - rtt_stats_(configuration.rtt_stats), - rtt_ms_(0) { - if (!configuration.receiver_only) { - rtp_sender_ = std::make_unique<RtpSenderContext>(env, configuration); - // Make sure rtcp sender use same timestamp offset as rtp sender. - rtcp_sender_.SetTimestampOffset( - rtp_sender_->packet_generator.TimestampOffset()); - } - - // Set default packet size limit. - // TODO(nisse): Kind-of duplicates - // VideoSendStream::Config::Rtp::kDefaultMaxPacketSize. - const size_t kTcpOverIpv4HeaderSize = 40; - SetMaxRtpPacketSize(IP_PACKET_SIZE - kTcpOverIpv4HeaderSize); -} - -ModuleRtpRtcpImpl::~ModuleRtpRtcpImpl() = default; - -// Process any pending tasks such as timeouts (non time critical events). -void ModuleRtpRtcpImpl::Process() { - const int64_t now = env_.clock().TimeInMilliseconds(); - - if (rtp_sender_) { - if (now >= last_bitrate_process_time_ + kRtpRtcpBitrateProcessTimeMs) { - rtp_sender_->packet_sender.ProcessBitrateAndNotifyObservers(); - last_bitrate_process_time_ = now; - } - } - - // TODO(bugs.webrtc.org/11581): We update the RTT once a second, whereas other - // things that run in this method are updated much more frequently. Move the - // RTT checking over to the worker thread, which matches better with where the - // stats are maintained. - bool process_rtt = now >= last_rtt_process_time_ + kRtpRtcpRttProcessTimeMs; - if (rtcp_sender_.Sending()) { - // Process RTT if we have received a report block and we haven't - // processed RTT for at least `kRtpRtcpRttProcessTimeMs` milliseconds. - // Note that LastReceivedReportBlockMs() grabs a lock, so check - // `process_rtt` first. - if (process_rtt && rtt_stats_ != nullptr && - rtcp_receiver_.LastReceivedReportBlockMs() > last_rtt_process_time_) { - TimeDelta max_rtt = TimeDelta::Zero(); - for (const auto& block : rtcp_receiver_.GetLatestReportBlockData()) { - if (block.last_rtt() > max_rtt) { - max_rtt = block.last_rtt(); - } - } - // Report the rtt. - if (max_rtt > TimeDelta::Zero()) { - rtt_stats_->OnRttUpdate(max_rtt.ms()); - } - } - - // Verify receiver reports are delivered and the reported sequence number - // is increasing. - // TODO(bugs.webrtc.org/11581): The timeout value needs to be checked every - // few seconds (see internals of RtcpRrTimeout). Here, we may be polling it - // a couple of hundred times a second, which isn't great since it grabs a - // lock. Note also that LastReceivedReportBlockMs() (called above) and - // RtcpRrTimeout() both grab the same lock and check the same timer, so - // it should be possible to consolidate that work somehow. - if (rtcp_receiver_.RtcpRrTimeout()) { - RTC_LOG_F(LS_WARNING) << "Timeout: No RTCP RR received."; - } else if (rtcp_receiver_.RtcpRrSequenceNumberTimeout()) { - RTC_LOG_F(LS_WARNING) << "Timeout: No increase in RTCP RR extended " - "highest sequence number."; - } - } else { - // Report rtt from receiver. - if (process_rtt && rtt_stats_ != nullptr) { - std::optional<TimeDelta> rtt = rtcp_receiver_.GetAndResetXrRrRtt(); - if (rtt.has_value()) { - rtt_stats_->OnRttUpdate(rtt->ms()); - } - } - } - - // Get processed rtt. - if (process_rtt) { - last_rtt_process_time_ = now; - if (rtt_stats_) { - // Make sure we have a valid RTT before setting. - int64_t last_rtt = rtt_stats_->LastProcessedRtt(); - if (last_rtt >= 0) - set_rtt_ms(last_rtt); - } - } - - if (rtcp_sender_.TimeToSendRTCPReport()) - rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport); - - if (rtcp_sender_.TMMBR() && rtcp_receiver_.UpdateTmmbrTimers()) { - rtcp_receiver_.NotifyTmmbrUpdated(); - } -} - -void ModuleRtpRtcpImpl::SetRtxSendStatus(int mode) { - rtp_sender_->packet_generator.SetRtxStatus(mode); -} - -int ModuleRtpRtcpImpl::RtxSendStatus() const { - return rtp_sender_ ? rtp_sender_->packet_generator.RtxStatus() : kRtxOff; -} - -void ModuleRtpRtcpImpl::SetRtxSendPayloadType(int payload_type, - int associated_payload_type) { - rtp_sender_->packet_generator.SetRtxPayloadType(payload_type, - associated_payload_type); -} - -std::optional<uint32_t> ModuleRtpRtcpImpl::RtxSsrc() const { - return rtp_sender_ ? rtp_sender_->packet_generator.RtxSsrc() : std::nullopt; -} - -std::optional<uint32_t> ModuleRtpRtcpImpl::FlexfecSsrc() const { - if (rtp_sender_) { - return rtp_sender_->packet_generator.FlexfecSsrc(); - } - return std::nullopt; -} - -void ModuleRtpRtcpImpl::IncomingRtcpPacket( - ArrayView<const uint8_t> rtcp_packet) { - rtcp_receiver_.IncomingPacket(rtcp_packet); -} - -void ModuleRtpRtcpImpl::RegisterSendPayloadFrequency(int payload_type, - int payload_frequency) { - rtcp_sender_.SetRtpClockRate(payload_type, payload_frequency); -} - -int32_t ModuleRtpRtcpImpl::DeRegisterSendPayload( - const int8_t /* payload_type */) { - return 0; -} - -uint32_t ModuleRtpRtcpImpl::StartTimestamp() const { - return rtp_sender_->packet_generator.TimestampOffset(); -} - -// Configure start timestamp, default is a random number. -void ModuleRtpRtcpImpl::SetStartTimestamp(const uint32_t timestamp) { - rtcp_sender_.SetTimestampOffset(timestamp); - rtp_sender_->packet_generator.SetTimestampOffset(timestamp); - rtp_sender_->packet_sender.SetTimestampOffset(timestamp); -} - -uint16_t ModuleRtpRtcpImpl::SequenceNumber() const { - MutexLock lock(&rtp_sender_->sequencer_mutex); - return rtp_sender_->sequencer_.media_sequence_number(); -} - -// Set SequenceNumber, default is a random number. -void ModuleRtpRtcpImpl::SetSequenceNumber(const uint16_t seq_num) { - MutexLock lock(&rtp_sender_->sequencer_mutex); - rtp_sender_->sequencer_.set_media_sequence_number(seq_num); -} - -void ModuleRtpRtcpImpl::SetRtpState(const RtpState& rtp_state) { - MutexLock lock(&rtp_sender_->sequencer_mutex); - rtp_sender_->packet_generator.SetRtpState(rtp_state); - rtp_sender_->sequencer_.SetRtpState(rtp_state); - rtcp_sender_.SetTimestampOffset(rtp_state.start_timestamp); -} - -void ModuleRtpRtcpImpl::SetRtxState(const RtpState& rtp_state) { - MutexLock lock(&rtp_sender_->sequencer_mutex); - rtp_sender_->packet_generator.SetRtxRtpState(rtp_state); - rtp_sender_->sequencer_.set_rtx_sequence_number(rtp_state.sequence_number); -} - -RtpState ModuleRtpRtcpImpl::GetRtpState() const { - MutexLock lock(&rtp_sender_->sequencer_mutex); - RtpState state = rtp_sender_->packet_generator.GetRtpState(); - rtp_sender_->sequencer_.PopulateRtpState(state); - return state; -} - -RtpState ModuleRtpRtcpImpl::GetRtxState() const { - MutexLock lock(&rtp_sender_->sequencer_mutex); - RtpState state = rtp_sender_->packet_generator.GetRtxRtpState(); - state.sequence_number = rtp_sender_->sequencer_.rtx_sequence_number(); - return state; -} - -void ModuleRtpRtcpImpl::SetMid(absl::string_view mid) { - if (rtp_sender_) { - rtp_sender_->packet_generator.SetMid(mid); - } - // TODO(bugs.webrtc.org/4050): If we end up supporting the MID SDES item for - // RTCP, this will need to be passed down to the RTCPSender also. -} - -// TODO(pbos): Handle media and RTX streams separately (separate RTCP -// feedbacks). -RTCPSender::FeedbackState ModuleRtpRtcpImpl::GetFeedbackState() { - RTCPSender::FeedbackState state; - // This is called also when receiver_only is true. Hence below - // checks that rtp_sender_ exists. - if (rtp_sender_) { - StreamDataCounters rtp_stats; - StreamDataCounters rtx_stats; - rtp_sender_->packet_sender.GetDataCounters(&rtp_stats, &rtx_stats); - state.packets_sent = - rtp_stats.transmitted.packets + rtx_stats.transmitted.packets; - state.media_bytes_sent = rtp_stats.transmitted.payload_bytes + - rtx_stats.transmitted.payload_bytes; - state.send_bitrate = rtp_sender_->packet_sender.GetSendRates().Sum(); - } - state.receiver = &rtcp_receiver_; - - if (std::optional<RtpRtcpInterface::SenderReportStats> last_sr = - rtcp_receiver_.GetSenderReportStats(); - last_sr.has_value()) { - state.remote_sr = CompactNtp(last_sr->last_remote_ntp_timestamp); - state.last_rr = last_sr->last_arrival_ntp_timestamp; - } - - state.last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(); - - return state; -} - -int32_t ModuleRtpRtcpImpl::SetSendingStatus(const bool sending) { - if (rtcp_sender_.Sending() != sending) { - // Sends RTCP BYE when going from true to false - rtcp_sender_.SetSendingStatus(GetFeedbackState(), sending); - } - return 0; -} - -bool ModuleRtpRtcpImpl::Sending() const { - return rtcp_sender_.Sending(); -} - -void ModuleRtpRtcpImpl::SetSendingMediaStatus(const bool sending) { - rtp_sender_->packet_generator.SetSendingMediaStatus(sending); -} - -bool ModuleRtpRtcpImpl::SendingMedia() const { - return rtp_sender_ ? rtp_sender_->packet_generator.SendingMedia() : false; -} - -bool ModuleRtpRtcpImpl::IsAudioConfigured() const { - return rtp_sender_ ? rtp_sender_->packet_generator.IsAudioConfigured() - : false; -} - -void ModuleRtpRtcpImpl::SetAsPartOfAllocation(bool part_of_allocation) { - RTC_CHECK(rtp_sender_); - rtp_sender_->packet_sender.ForceIncludeSendPacketsInAllocation( - part_of_allocation); -} - -bool ModuleRtpRtcpImpl::OnSendingRtpFrame(uint32_t timestamp, - int64_t capture_time_ms, - int payload_type, - bool force_sender_report) { - if (!Sending()) - return false; - - // TODO(bugs.webrtc.org/12873): Migrate this method and it's users to use - // optional Timestamps. - std::optional<Timestamp> capture_time; - if (capture_time_ms > 0) { - capture_time = Timestamp::Millis(capture_time_ms); - } - std::optional<int> payload_type_optional; - if (payload_type >= 0) - payload_type_optional = payload_type; - rtcp_sender_.SetLastRtpTime(timestamp, capture_time, payload_type_optional); - // Make sure an RTCP report isn't queued behind a key frame. - if (rtcp_sender_.TimeToSendRTCPReport(force_sender_report)) - rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport); - - return true; -} - -bool ModuleRtpRtcpImpl::TrySendPacket(std::unique_ptr<RtpPacketToSend> packet, - const PacedPacketInfo& pacing_info) { - RTC_DCHECK(rtp_sender_); - // TODO(sprang): Consider if we can remove this check. - if (!rtp_sender_->packet_generator.SendingMedia()) { - return false; - } - { - MutexLock lock(&rtp_sender_->sequencer_mutex); - if (packet->packet_type() == RtpPacketMediaType::kPadding && - packet->Ssrc() == rtp_sender_->packet_generator.SSRC() && - !rtp_sender_->sequencer_.CanSendPaddingOnMediaSsrc()) { - // New media packet preempted this generated padding packet, discard it. - return false; - } - bool is_flexfec = - packet->packet_type() == RtpPacketMediaType::kForwardErrorCorrection && - packet->Ssrc() == rtp_sender_->packet_generator.FlexfecSsrc(); - if (!is_flexfec) { - rtp_sender_->sequencer_.Sequence(*packet); - } - } - rtp_sender_->packet_sender.SendPacket(packet.get(), pacing_info); - return true; -} - -void ModuleRtpRtcpImpl::SetFecProtectionParams(const FecProtectionParams&, - const FecProtectionParams&) { - // Deferred FEC not supported in deprecated RTP module. -} - -std::vector<std::unique_ptr<RtpPacketToSend>> -ModuleRtpRtcpImpl::FetchFecPackets() { - // Deferred FEC not supported in deprecated RTP module. - return {}; -} - -void ModuleRtpRtcpImpl::OnAbortedRetransmissions( - ArrayView<const uint16_t> /* sequence_numbers */) { - RTC_DCHECK_NOTREACHED() - << "Stream flushing not supported with legacy rtp modules."; -} - -void ModuleRtpRtcpImpl::OnPacketsAcknowledged( - ArrayView<const uint16_t> sequence_numbers) { - RTC_DCHECK(rtp_sender_); - rtp_sender_->packet_history.CullAcknowledgedPackets(sequence_numbers); -} - -bool ModuleRtpRtcpImpl::SupportsPadding() const { - RTC_DCHECK(rtp_sender_); - return rtp_sender_->packet_generator.SupportsPadding(); -} - -bool ModuleRtpRtcpImpl::SupportsRtxPayloadPadding() const { - RTC_DCHECK(rtp_sender_); - return rtp_sender_->packet_generator.SupportsRtxPayloadPadding(); -} - -std::vector<std::unique_ptr<RtpPacketToSend>> -ModuleRtpRtcpImpl::GeneratePadding(size_t target_size_bytes) { - RTC_DCHECK(rtp_sender_); - MutexLock lock(&rtp_sender_->sequencer_mutex); - return rtp_sender_->packet_generator.GeneratePadding( - target_size_bytes, rtp_sender_->packet_sender.MediaHasBeenSent(), - rtp_sender_->sequencer_.CanSendPaddingOnMediaSsrc()); -} - -std::vector<RtpSequenceNumberMap::Info> -ModuleRtpRtcpImpl::GetSentRtpPacketInfos( - ArrayView<const uint16_t> sequence_numbers) const { - RTC_DCHECK(rtp_sender_); - return rtp_sender_->packet_sender.GetSentRtpPacketInfos(sequence_numbers); -} - -size_t ModuleRtpRtcpImpl::ExpectedPerPacketOverhead() const { - if (!rtp_sender_) { - return 0; - } - return rtp_sender_->packet_generator.ExpectedPerPacketOverhead(); -} - -void ModuleRtpRtcpImpl::OnPacketSendingThreadSwitched() {} - -size_t ModuleRtpRtcpImpl::MaxRtpPacketSize() const { - RTC_DCHECK(rtp_sender_); - return rtp_sender_->packet_generator.MaxRtpPacketSize(); -} - -void ModuleRtpRtcpImpl::SetMaxRtpPacketSize(size_t rtp_packet_size) { - RTC_DCHECK_LE(rtp_packet_size, IP_PACKET_SIZE) - << "rtp packet size too large: " << rtp_packet_size; - RTC_DCHECK_GT(rtp_packet_size, packet_overhead_) - << "rtp packet size too small: " << rtp_packet_size; - - rtcp_sender_.SetMaxRtpPacketSize(rtp_packet_size); - if (rtp_sender_) { - rtp_sender_->packet_generator.SetMaxRtpPacketSize(rtp_packet_size); - } -} - -RtcpMode ModuleRtpRtcpImpl::RTCP() const { - return rtcp_sender_.Status(); -} - -// Configure RTCP status i.e on/off. -void ModuleRtpRtcpImpl::SetRTCPStatus(const RtcpMode method) { - rtcp_sender_.SetRTCPStatus(method); -} - -int32_t ModuleRtpRtcpImpl::SetCNAME(absl::string_view c_name) { - return rtcp_sender_.SetCNAME(c_name); -} - -std::optional<TimeDelta> ModuleRtpRtcpImpl::LastRtt() const { - std::optional<TimeDelta> rtt = rtcp_receiver_.LastRtt(); - if (!rtt.has_value()) { - MutexLock lock(&mutex_rtt_); - if (rtt_ms_ > 0) { - rtt = TimeDelta::Millis(rtt_ms_); - } - } - return rtt; -} - -TimeDelta ModuleRtpRtcpImpl::ExpectedRetransmissionTime() const { - int64_t expected_retransmission_time_ms = rtt_ms(); - if (expected_retransmission_time_ms > 0) { - return TimeDelta::Millis(expected_retransmission_time_ms); - } - // No rtt available (`kRtpRtcpRttProcessTimeMs` not yet passed?), so try to - // poll avg_rtt_ms directly from rtcp receiver. - if (std::optional<TimeDelta> rtt = rtcp_receiver_.AverageRtt()) { - return *rtt; - } - return kDefaultExpectedRetransmissionTime; -} - -// Force a send of an RTCP packet. -// Normal SR and RR are triggered via the process function. -int32_t ModuleRtpRtcpImpl::SendRTCP(RTCPPacketType packet_type) { - return rtcp_sender_.SendRTCP(GetFeedbackState(), packet_type); -} - -void ModuleRtpRtcpImpl::GetSendStreamDataCounters( - StreamDataCounters* rtp_counters, - StreamDataCounters* rtx_counters) const { - rtp_sender_->packet_sender.GetDataCounters(rtp_counters, rtx_counters); -} - -// Received RTCP report. -void ModuleRtpRtcpImpl::RemoteRTCPSenderInfo( - uint32_t* packet_count, uint32_t* octet_count, int64_t* ntp_timestamp_ms, - int64_t* remote_ntp_timestamp_ms) const { - return rtcp_receiver_.RemoteRTCPSenderInfo( - packet_count, octet_count, ntp_timestamp_ms, remote_ntp_timestamp_ms); -} - -std::vector<ReportBlockData> ModuleRtpRtcpImpl::GetLatestReportBlockData() - const { - return rtcp_receiver_.GetLatestReportBlockData(); -} - -std::optional<RtpRtcpInterface::SenderReportStats> -ModuleRtpRtcpImpl::GetSenderReportStats() const { - return rtcp_receiver_.GetSenderReportStats(); -} - -std::optional<RtpRtcpInterface::NonSenderRttStats> -ModuleRtpRtcpImpl::GetNonSenderRttStats() const { - // This is not implemented for this legacy class. - return std::nullopt; -} - -// (REMB) Receiver Estimated Max Bitrate. -void ModuleRtpRtcpImpl::SetRemb(int64_t bitrate_bps, - std::vector<uint32_t> ssrcs) { - rtcp_sender_.SetRemb(bitrate_bps, std::move(ssrcs)); -} - -void ModuleRtpRtcpImpl::UnsetRemb() { - rtcp_sender_.UnsetRemb(); -} - -void ModuleRtpRtcpImpl::SetExtmapAllowMixed(bool extmap_allow_mixed) { - rtp_sender_->packet_generator.SetExtmapAllowMixed(extmap_allow_mixed); -} - -void ModuleRtpRtcpImpl::RegisterRtpHeaderExtension(absl::string_view uri, - int id) { - bool registered = - rtp_sender_->packet_generator.RegisterRtpHeaderExtension(uri, id); - RTC_CHECK(registered); -} - -void ModuleRtpRtcpImpl::DeregisterSendRtpHeaderExtension( - absl::string_view uri) { - rtp_sender_->packet_generator.DeregisterRtpHeaderExtension(uri); -} - -void ModuleRtpRtcpImpl::SetTmmbn(std::vector<rtcp::TmmbItem> bounding_set) { - rtcp_sender_.SetTmmbn(std::move(bounding_set)); -} - -// Send a Negative acknowledgment packet. -int32_t ModuleRtpRtcpImpl::SendNACK(const uint16_t* nack_list, - const uint16_t size) { - uint16_t nack_length = size; - uint16_t start_id = 0; - int64_t now_ms = env_.clock().TimeInMilliseconds(); - if (TimeToSendFullNackList(now_ms)) { - nack_last_time_sent_full_ms_ = now_ms; - } else { - // Only send extended list. - if (nack_last_seq_number_sent_ == nack_list[size - 1]) { - // Last sequence number is the same, do not send list. - return 0; - } - // Send new sequence numbers. - for (int i = 0; i < size; ++i) { - if (nack_last_seq_number_sent_ == nack_list[i]) { - start_id = i + 1; - break; - } - } - nack_length = size - start_id; - } - - // Our RTCP NACK implementation is limited to kRtcpMaxNackFields sequence - // numbers per RTCP packet. - if (nack_length > kRtcpMaxNackFields) { - nack_length = kRtcpMaxNackFields; - } - nack_last_seq_number_sent_ = nack_list[start_id + nack_length - 1]; - - return rtcp_sender_.SendRTCP( - GetFeedbackState(), kRtcpNack, - MakeArrayView(&nack_list[start_id], nack_length)); -} - -void ModuleRtpRtcpImpl::SendNack( - const std::vector<uint16_t>& sequence_numbers) { - rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpNack, sequence_numbers); -} - -bool ModuleRtpRtcpImpl::TimeToSendFullNackList(int64_t now) const { - // Use RTT from RtcpRttStats class if provided. - int64_t rtt = rtt_ms(); - if (rtt == 0) { - if (std::optional<TimeDelta> average_rtt = rtcp_receiver_.AverageRtt()) { - rtt = average_rtt->ms(); - } - } - - const int64_t kStartUpRttMs = 100; - int64_t wait_time = 5 + ((rtt * 3) >> 1); // 5 + RTT * 1.5. - if (rtt == 0) { - wait_time = kStartUpRttMs; - } - - // Send a full NACK list once within every `wait_time`. - return now - nack_last_time_sent_full_ms_ > wait_time; -} - -// Store the sent packets, needed to answer to Negative acknowledgment requests. -void ModuleRtpRtcpImpl::SetStorePacketsStatus(const bool enable, - const uint16_t number_to_store) { - rtp_sender_->packet_history.SetStorePacketsStatus( - enable ? RtpPacketHistory::StorageMode::kStoreAndCull - : RtpPacketHistory::StorageMode::kDisabled, - number_to_store); -} - -bool ModuleRtpRtcpImpl::StorePackets() const { - return rtp_sender_->packet_history.GetStorageMode() != - RtpPacketHistory::StorageMode::kDisabled; -} - -void ModuleRtpRtcpImpl::SendCombinedRtcpPacket( - std::vector<std::unique_ptr<rtcp::RtcpPacket>> rtcp_packets) { - rtcp_sender_.SendCombinedRtcpPacket(std::move(rtcp_packets)); -} - -int32_t ModuleRtpRtcpImpl::SendLossNotification(uint16_t last_decoded_seq_num, - uint16_t last_received_seq_num, - bool decodability_flag, - bool buffering_allowed) { - return rtcp_sender_.SendLossNotification( - GetFeedbackState(), last_decoded_seq_num, last_received_seq_num, - decodability_flag, buffering_allowed); -} - -void ModuleRtpRtcpImpl::SetRemoteSSRC(const uint32_t ssrc) { - // Inform about the incoming SSRC. - rtcp_sender_.SetRemoteSSRC(ssrc); - rtcp_receiver_.SetRemoteSSRC(ssrc); -} - -void ModuleRtpRtcpImpl::SetLocalSsrc(uint32_t local_ssrc) { - rtcp_receiver_.set_local_media_ssrc(local_ssrc); - rtcp_sender_.SetSsrc(local_ssrc); -} - -RtpSendRates ModuleRtpRtcpImpl::GetSendRates() const { - return rtp_sender_->packet_sender.GetSendRates(); -} - -void ModuleRtpRtcpImpl::OnRequestSendReport() { - SendRTCP(kRtcpSr); -} - -void ModuleRtpRtcpImpl::OnReceivedNack( - const std::vector<uint16_t>& nack_sequence_numbers) { - if (!rtp_sender_) - return; - - if (!StorePackets() || nack_sequence_numbers.empty()) { - return; - } - // Use RTT from RtcpRttStats class if provided. - int64_t rtt = rtt_ms(); - if (rtt == 0) { - if (std::optional<TimeDelta> average_rtt = rtcp_receiver_.AverageRtt()) { - rtt = average_rtt->ms(); - } - } - rtp_sender_->packet_generator.OnReceivedNack(nack_sequence_numbers, rtt); -} - -void ModuleRtpRtcpImpl::OnReceivedRtcpReportBlocks( - ArrayView<const ReportBlockData> report_blocks) { - if (rtp_sender_) { - uint32_t ssrc = SSRC(); - std::optional<uint32_t> rtx_ssrc; - if (rtp_sender_->packet_generator.RtxStatus() != kRtxOff) { - rtx_ssrc = rtp_sender_->packet_generator.RtxSsrc(); - } - - for (const ReportBlockData& report_block : report_blocks) { - if (ssrc == report_block.source_ssrc()) { - rtp_sender_->packet_generator.OnReceivedAckOnSsrc( - report_block.extended_highest_sequence_number()); - } else if (rtx_ssrc == report_block.source_ssrc()) { - rtp_sender_->packet_generator.OnReceivedAckOnRtxSsrc( - report_block.extended_highest_sequence_number()); - } - } - } -} - -void ModuleRtpRtcpImpl::set_rtt_ms(int64_t rtt_ms) { - { - MutexLock lock(&mutex_rtt_); - rtt_ms_ = rtt_ms; - } - if (rtp_sender_) { - rtp_sender_->packet_history.SetRtt(TimeDelta::Millis(rtt_ms)); - } -} - -int64_t ModuleRtpRtcpImpl::rtt_ms() const { - MutexLock lock(&mutex_rtt_); - return rtt_ms_; -} - -void ModuleRtpRtcpImpl::SetVideoBitrateAllocation( - const VideoBitrateAllocation& bitrate) { - rtcp_sender_.SetVideoBitrateAllocation(bitrate); -} - -RTPSender* ModuleRtpRtcpImpl::RtpSender() { - return rtp_sender_ ? &rtp_sender_->packet_generator : nullptr; -} - -const RTPSender* ModuleRtpRtcpImpl::RtpSender() const { - return rtp_sender_ ? &rtp_sender_->packet_generator : nullptr; -} - -} // namespace webrtc diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef MODULES_RTP_RTCP_SOURCE_RTP_RTCP_IMPL_H_ -#define MODULES_RTP_RTCP_SOURCE_RTP_RTCP_IMPL_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <memory> -#include <optional> -#include <vector> - -#include "absl/base/attributes.h" -#include "absl/strings/string_view.h" -#include "api/array_view.h" -#include "api/environment/environment.h" -#include "api/rtp_headers.h" -#include "api/units/time_delta.h" -#include "api/video/video_bitrate_allocation.h" -#include "modules/include/module_fec_types.h" -#include "modules/rtp_rtcp/include/report_block_data.h" -#include "modules/rtp_rtcp/include/rtp_rtcp.h" -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" // RTCPPacketType -#include "modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h" -#include "modules/rtp_rtcp/source/packet_sequencer.h" -#include "modules/rtp_rtcp/source/rtcp_packet.h" -#include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h" -#include "modules/rtp_rtcp/source/rtcp_receiver.h" -#include "modules/rtp_rtcp/source/rtcp_sender.h" -#include "modules/rtp_rtcp/source/rtp_packet_history.h" -#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" -#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" -#include "modules/rtp_rtcp/source/rtp_sender.h" -#include "modules/rtp_rtcp/source/rtp_sequence_number_map.h" -#include "rtc_base/checks.h" -#include "rtc_base/gtest_prod_util.h" -#include "rtc_base/synchronization/mutex.h" -#include "rtc_base/thread_annotations.h" - -namespace webrtc { - -struct PacedPacketInfo; -struct RTPVideoHeader; - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -class ABSL_DEPRECATED("") ModuleRtpRtcpImpl - : public RtpRtcp, - public RTCPReceiver::ModuleRtpRtcp { -#pragma clang diagnostic pop - public: - ModuleRtpRtcpImpl(const Environment& env, - const RtpRtcpInterface::Configuration& configuration); - ~ModuleRtpRtcpImpl() override; - - // Process any pending tasks such as timeouts. - void Process() override; - - // Receiver part. - - // Called when we receive an RTCP packet. - void IncomingRtcpPacket(ArrayView<const uint8_t> packet) override; - - void SetRemoteSSRC(uint32_t ssrc) override; - void SetLocalSsrc(uint32_t ssrc) override; - - // Sender part. - void RegisterSendPayloadFrequency(int payload_type, - int payload_frequency) override; - - int32_t DeRegisterSendPayload(int8_t payload_type) override; - - void SetExtmapAllowMixed(bool extmap_allow_mixed) override; - - // Register RTP header extension. - void RegisterRtpHeaderExtension(absl::string_view uri, int id) override; - void DeregisterSendRtpHeaderExtension(absl::string_view uri) override; - - bool SupportsPadding() const override; - bool SupportsRtxPayloadPadding() const override; - - // Get start timestamp. - uint32_t StartTimestamp() const override; - - // Configure start timestamp, default is a random number. - void SetStartTimestamp(uint32_t timestamp) override; - - uint16_t SequenceNumber() const override; - - // Set SequenceNumber, default is a random number. - void SetSequenceNumber(uint16_t seq) override; - - void SetRtpState(const RtpState& rtp_state) override; - void SetRtxState(const RtpState& rtp_state) override; - RtpState GetRtpState() const override; - RtpState GetRtxState() const override; - - void SetNonSenderRttMeasurement(bool /* enabled */) override {} - - uint32_t SSRC() const override { return rtcp_sender_.SSRC(); } - - void SetMid(absl::string_view mid) override; - - RTCPSender::FeedbackState GetFeedbackState(); - - void SetRtxSendStatus(int mode) override; - int RtxSendStatus() const override; - std::optional<uint32_t> RtxSsrc() const override; - - void SetRtxSendPayloadType(int payload_type, - int associated_payload_type) override; - - std::optional<uint32_t> FlexfecSsrc() const override; - - // Sends kRtcpByeCode when going from true to false. - int32_t SetSendingStatus(bool sending) override; - - bool Sending() const override; - - // Drops or relays media packets. - void SetSendingMediaStatus(bool sending) override; - - bool SendingMedia() const override; - - bool IsAudioConfigured() const override; - - void SetAsPartOfAllocation(bool part_of_allocation) override; - - bool OnSendingRtpFrame(uint32_t timestamp, - int64_t capture_time_ms, - int payload_type, - bool force_sender_report) override; - - bool TrySendPacket(std::unique_ptr<RtpPacketToSend> packet, - const PacedPacketInfo& pacing_info) override; - - bool CanSendPacket(const RtpPacketToSend& /* packet */) const override { - RTC_DCHECK_NOTREACHED() << "Not implemented"; - return false; - } - - void AssignSequenceNumber(RtpPacketToSend& /* packet */) override { - RTC_DCHECK_NOTREACHED() << "Not implemented"; - } - - void SendPacket(std::unique_ptr<RtpPacketToSend> /* packet */, - const PacedPacketInfo& /* pacing_info */) override { - RTC_DCHECK_NOTREACHED() << "Not implemented"; - } - - void OnBatchComplete() override {} - - void SetFecProtectionParams(const FecProtectionParams& delta_params, - const FecProtectionParams& key_params) override; - - std::vector<std::unique_ptr<RtpPacketToSend>> FetchFecPackets() override; - - void OnAbortedRetransmissions( - ArrayView<const uint16_t> sequence_numbers) override; - - void OnPacketsAcknowledged( - ArrayView<const uint16_t> sequence_numbers) override; - - std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding( - size_t target_size_bytes) override; - - std::vector<RtpSequenceNumberMap::Info> GetSentRtpPacketInfos( - ArrayView<const uint16_t> sequence_numbers) const override; - - size_t ExpectedPerPacketOverhead() const override; - - void OnPacketSendingThreadSwitched() override; - - // RTCP part. - - // Get RTCP status. - RtcpMode RTCP() const override; - - // Configure RTCP status i.e on/off. - void SetRTCPStatus(RtcpMode method) override; - - // Set RTCP CName. - int32_t SetCNAME(absl::string_view c_name) override; - - // Get RoundTripTime. - std::optional<TimeDelta> LastRtt() const override; - - TimeDelta ExpectedRetransmissionTime() const override; - - // Force a send of an RTCP packet. - // Normal SR and RR are triggered via the process function. - int32_t SendRTCP(RTCPPacketType rtcpPacketType) override; - - void GetSendStreamDataCounters( - StreamDataCounters* rtp_counters, - StreamDataCounters* rtx_counters) const override; - - void RemoteRTCPSenderInfo(uint32_t* packet_count, - uint32_t* octet_count, - int64_t* ntp_timestamp_ms, - int64_t* remote_ntp_timestamp_ms) const override; - - // A snapshot of the most recent Report Block with additional data of - // interest to statistics. Used to implement RTCRemoteInboundRtpStreamStats. - // Within this list, the `ReportBlockData::source_ssrc()`, which is the SSRC - // of the corresponding outbound RTP stream, is unique. - std::vector<ReportBlockData> GetLatestReportBlockData() const override; - std::optional<SenderReportStats> GetSenderReportStats() const override; - // Round trip time statistics computed from the XR block contained in the last - // report. - std::optional<NonSenderRttStats> GetNonSenderRttStats() const override; - - // (REMB) Receiver Estimated Max Bitrate. - void SetRemb(int64_t bitrate_bps, std::vector<uint32_t> ssrcs) override; - void UnsetRemb() override; - - void SetTmmbn(std::vector<rtcp::TmmbItem> bounding_set) override; - - size_t MaxRtpPacketSize() const override; - - void SetMaxRtpPacketSize(size_t max_packet_size) override; - - // (NACK) Negative acknowledgment part. - - // Send a Negative acknowledgment packet. - // TODO(philipel): Deprecate SendNACK and use SendNack instead. - int32_t SendNACK(const uint16_t* nack_list, uint16_t size) override; - - void SendNack(const std::vector<uint16_t>& sequence_numbers) override; - - // Store the sent packets, needed to answer to a negative acknowledgment - // requests. - void SetStorePacketsStatus(bool enable, uint16_t number_to_store) override; - - void SendCombinedRtcpPacket( - std::vector<std::unique_ptr<rtcp::RtcpPacket>> rtcp_packets) override; - - // Video part. - int32_t SendLossNotification(uint16_t last_decoded_seq_num, - uint16_t last_received_seq_num, - bool decodability_flag, - bool buffering_allowed) override; - - RtpSendRates GetSendRates() const override; - - void OnReceivedNack( - const std::vector<uint16_t>& nack_sequence_numbers) override; - void OnReceivedRtcpReportBlocks( - ArrayView<const ReportBlockData> report_blocks) override; - void OnRequestSendReport() override; - - void SetVideoBitrateAllocation( - const VideoBitrateAllocation& bitrate) override; - - RTPSender* RtpSender() override; - const RTPSender* RtpSender() const override; - - protected: - bool UpdateRTCPReceiveInformationTimers(); - - RTPSender* rtp_sender() { - return rtp_sender_ ? &rtp_sender_->packet_generator : nullptr; - } - const RTPSender* rtp_sender() const { - return rtp_sender_ ? &rtp_sender_->packet_generator : nullptr; - } - - RTCPSender* rtcp_sender() { return &rtcp_sender_; } - const RTCPSender* rtcp_sender() const { return &rtcp_sender_; } - - RTCPReceiver* rtcp_receiver() { return &rtcp_receiver_; } - const RTCPReceiver* rtcp_receiver() const { return &rtcp_receiver_; } - - void SetMediaHasBeenSent(bool media_has_been_sent) { - rtp_sender_->packet_sender.SetMediaHasBeenSent(media_has_been_sent); - } - - private: - FRIEND_TEST_ALL_PREFIXES(RtpRtcpImplTest, Rtt); - FRIEND_TEST_ALL_PREFIXES(RtpRtcpImplTest, RttForReceiverOnly); - - struct RtpSenderContext { - RtpSenderContext(const Environment& env, - const RtpRtcpInterface::Configuration& config); - // Storage of packets, for retransmissions and padding, if applicable. - RtpPacketHistory packet_history; - // Handles sequence number assignment and padding timestamp generation. - mutable Mutex sequencer_mutex; - PacketSequencer sequencer_ RTC_GUARDED_BY(sequencer_mutex); - // Handles final time timestamping/stats/etc and handover to Transport. - DEPRECATED_RtpSenderEgress packet_sender; - // If no paced sender configured, this class will be used to pass packets - // from `packet_generator_` to `packet_sender_`. - DEPRECATED_RtpSenderEgress::NonPacedPacketSender non_paced_sender; - // Handles creation of RTP packets to be sent. - RTPSender packet_generator; - }; - - void set_rtt_ms(int64_t rtt_ms); - int64_t rtt_ms() const; - - bool TimeToSendFullNackList(int64_t now) const; - - // Returns true if the module is configured to store packets. - bool StorePackets() const; - - // Returns current Receiver Reference Time Report (RTTR) status. - bool RtcpXrRrtrStatus() const; - - const Environment env_; - std::unique_ptr<RtpSenderContext> rtp_sender_; - - RTCPSender rtcp_sender_; - RTCPReceiver rtcp_receiver_; - - int64_t last_bitrate_process_time_; - int64_t last_rtt_process_time_; - uint16_t packet_overhead_; - - // Send side - int64_t nack_last_time_sent_full_ms_; - uint16_t nack_last_seq_number_sent_; - - RtcpRttStats* const rtt_stats_; - - // The processed RTT from RtcpRttStats. - mutable Mutex mutex_rtt_; - int64_t rtt_ms_ RTC_GUARDED_BY(mutex_rtt_); -}; - -} // namespace webrtc - -#endif // MODULES_RTP_RTCP_SOURCE_RTP_RTCP_IMPL_H_ diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc @@ -1,718 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "modules/rtp_rtcp/source/rtp_rtcp_impl.h" - -#include <cstddef> -#include <cstdint> -#include <map> -#include <memory> -#include <optional> -#include <vector> - -#include "api/array_view.h" -#include "api/call/transport.h" -#include "api/environment/environment.h" -#include "api/environment/environment_factory.h" -#include "api/field_trials.h" -#include "api/rtp_headers.h" -#include "api/units/time_delta.h" -#include "api/video/video_codec_type.h" -#include "api/video/video_content_type.h" -#include "api/video/video_frame_type.h" -#include "api/video/video_rotation.h" -#include "modules/rtp_rtcp/include/receive_statistics.h" -#include "modules/rtp_rtcp/include/rtcp_statistics.h" -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" -#include "modules/rtp_rtcp/source/rtcp_packet/nack.h" -#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h" -#include "modules/rtp_rtcp/source/rtp_packet_received.h" -#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" -#include "modules/rtp_rtcp/source/rtp_sender_video.h" -#include "modules/rtp_rtcp/source/rtp_sequence_number_map.h" -#include "modules/video_coding/codecs/interface/common_constants.h" -#include "modules/video_coding/codecs/vp8/include/vp8_globals.h" -#include "system_wrappers/include/clock.h" -#include "system_wrappers/include/ntp_time.h" -#include "test/create_test_field_trials.h" -#include "test/gmock.h" -#include "test/gtest.h" -#include "test/rtcp_packet_parser.h" - -using ::testing::ElementsAre; -using ::testing::Eq; -using ::testing::Field; -using ::testing::Gt; -using ::testing::Not; -using ::testing::Optional; - -namespace webrtc { -namespace { -constexpr uint32_t kSenderSsrc = 0x12345; -constexpr uint32_t kReceiverSsrc = 0x23456; -constexpr TimeDelta kOneWayNetworkDelay = TimeDelta::Millis(100); -constexpr uint8_t kBaseLayerTid = 0; -constexpr uint8_t kHigherLayerTid = 1; -constexpr uint16_t kSequenceNumber = 100; -constexpr uint8_t kPayloadType = 100; -constexpr int kWidth = 320; -constexpr int kHeight = 100; - -MATCHER_P2(Near, value, margin, "") { - return value - margin <= arg && arg <= value + margin; -} - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -class RtcpRttStatsTestImpl : public RtcpRttStats { - public: - RtcpRttStatsTestImpl() : rtt_ms_(0) {} - ~RtcpRttStatsTestImpl() override = default; - - void OnRttUpdate(int64_t rtt_ms) override { rtt_ms_ = rtt_ms; } - int64_t LastProcessedRtt() const override { return rtt_ms_; } - int64_t rtt_ms_; -}; - -class SendTransport : public Transport { - public: - SendTransport() - : receiver_(nullptr), - clock_(nullptr), - delay_ms_(0), - rtp_packets_sent_(0), - rtcp_packets_sent_(0) {} - - void SetRtpRtcpModule(ModuleRtpRtcpImpl* receiver) { receiver_ = receiver; } - void SimulateNetworkDelay(int64_t delay_ms, SimulatedClock* clock) { - clock_ = clock; - delay_ms_ = delay_ms; - } - bool SendRtp(ArrayView<const uint8_t> data, - const PacketOptions& /* options */) override { - RtpPacket packet; - EXPECT_TRUE(packet.Parse(data)); - ++rtp_packets_sent_; - last_rtp_sequence_number_ = packet.SequenceNumber(); - return true; - } - bool SendRtcp(ArrayView<const uint8_t> data, - const PacketOptions& /* options */) override { - test::RtcpPacketParser parser; - parser.Parse(data); - last_nack_list_ = parser.nack()->packet_ids(); - - if (clock_) { - clock_->AdvanceTimeMilliseconds(delay_ms_); - } - EXPECT_TRUE(receiver_); - receiver_->IncomingRtcpPacket(data); - ++rtcp_packets_sent_; - return true; - } - size_t NumRtcpSent() { return rtcp_packets_sent_; } - ModuleRtpRtcpImpl* receiver_; - SimulatedClock* clock_; - int64_t delay_ms_; - int rtp_packets_sent_; - size_t rtcp_packets_sent_; - uint16_t last_rtp_sequence_number_; - std::vector<uint16_t> last_nack_list_; -}; - -class RtpRtcpModule : public RtcpPacketTypeCounterObserver { - public: - RtpRtcpModule(SimulatedClock* clock, bool is_sender) - : env_(CreateEnvironment(clock)), - is_sender_(is_sender), - receive_statistics_(ReceiveStatistics::Create(clock)) { - CreateModuleImpl(); - transport_.SimulateNetworkDelay(kOneWayNetworkDelay.ms(), clock); - } - - const Environment env_; - const bool is_sender_; - RtcpPacketTypeCounter packets_sent_; - RtcpPacketTypeCounter packets_received_; - std::unique_ptr<ReceiveStatistics> receive_statistics_; - SendTransport transport_; - RtcpRttStatsTestImpl rtt_stats_; - std::unique_ptr<ModuleRtpRtcpImpl> impl_; - int rtcp_report_interval_ms_ = 0; - - void RtcpPacketTypesCounterUpdated( - uint32_t ssrc, - const RtcpPacketTypeCounter& packet_counter) override { - counter_map_[ssrc] = packet_counter; - } - - RtcpPacketTypeCounter RtcpSent() { - // RTCP counters for remote SSRC. - return counter_map_[is_sender_ ? kReceiverSsrc : kSenderSsrc]; - } - - RtcpPacketTypeCounter RtcpReceived() { - // Received RTCP stats for (own) local SSRC. - return counter_map_[impl_->SSRC()]; - } - int RtpSent() { return transport_.rtp_packets_sent_; } - uint16_t LastRtpSequenceNumber() { - return transport_.last_rtp_sequence_number_; - } - std::vector<uint16_t> LastNackListSent() { - return transport_.last_nack_list_; - } - void SetRtcpReportIntervalAndReset(int rtcp_report_interval_ms) { - rtcp_report_interval_ms_ = rtcp_report_interval_ms; - CreateModuleImpl(); - } - - private: - void CreateModuleImpl() { - RtpRtcpInterface::Configuration config; - config.audio = false; - config.outgoing_transport = &transport_; - config.receive_statistics = receive_statistics_.get(); - config.rtcp_packet_type_counter_observer = this; - config.rtt_stats = &rtt_stats_; - config.rtcp_report_interval_ms = rtcp_report_interval_ms_; - config.local_media_ssrc = is_sender_ ? kSenderSsrc : kReceiverSsrc; - config.need_rtp_packet_infos = true; - config.non_sender_rtt_measurement = true; - - impl_.reset(new ModuleRtpRtcpImpl(env_, config)); - impl_->SetRemoteSSRC(is_sender_ ? kReceiverSsrc : kSenderSsrc); - impl_->SetRTCPStatus(RtcpMode::kCompound); - } - - std::map<uint32_t, RtcpPacketTypeCounter> counter_map_; -}; -} // namespace - -class RtpRtcpImplTest : public ::testing::Test { - protected: - RtpRtcpImplTest() - : clock_(133590000000000), - sender_(&clock_, /*is_sender=*/true), - receiver_(&clock_, /*is_sender=*/false) {} - - void SetUp() override { - // Send module. - EXPECT_EQ(0, sender_.impl_->SetSendingStatus(true)); - sender_.impl_->SetSendingMediaStatus(true); - sender_.impl_->SetSequenceNumber(kSequenceNumber); - sender_.impl_->SetStorePacketsStatus(true, 100); - - FieldTrials field_trials = CreateTestFieldTrials(); - RTPSenderVideo::Config video_config; - video_config.clock = &clock_; - video_config.rtp_sender = sender_.impl_->RtpSender(); - video_config.field_trials = &field_trials; - sender_video_ = std::make_unique<RTPSenderVideo>(video_config); - - // Receive module. - EXPECT_EQ(0, receiver_.impl_->SetSendingStatus(false)); - receiver_.impl_->SetSendingMediaStatus(false); - // Transport settings. - sender_.transport_.SetRtpRtcpModule(receiver_.impl_.get()); - receiver_.transport_.SetRtpRtcpModule(sender_.impl_.get()); - } - - SimulatedClock clock_; - RtpRtcpModule sender_; - std::unique_ptr<RTPSenderVideo> sender_video_; - RtpRtcpModule receiver_; - - void SendFrame(const RtpRtcpModule* module, - RTPSenderVideo* sender, - uint8_t tid) { - RTPVideoHeaderVP8 vp8_header = {}; - vp8_header.temporalIdx = tid; - RTPVideoHeader rtp_video_header; - rtp_video_header.frame_type = VideoFrameType::kVideoFrameKey; - rtp_video_header.width = kWidth; - rtp_video_header.height = kHeight; - rtp_video_header.rotation = kVideoRotation_0; - rtp_video_header.content_type = VideoContentType::UNSPECIFIED; - rtp_video_header.is_first_packet_in_frame = true; - rtp_video_header.simulcastIdx = 0; - rtp_video_header.codec = kVideoCodecVP8; - rtp_video_header.video_type_header = vp8_header; - rtp_video_header.video_timing = {0u, 0u, 0u, 0u, 0u, 0u, false}; - - const uint8_t payload[100] = {0}; - EXPECT_TRUE(module->impl_->OnSendingRtpFrame(0, 0, kPayloadType, true)); - EXPECT_TRUE(sender->SendVideo( - kPayloadType, VideoCodecType::kVideoCodecVP8, 0, clock_.CurrentTime(), - payload, sizeof(payload), rtp_video_header, TimeDelta::Zero(), {})); - } - - void IncomingRtcpNack(const RtpRtcpModule* module, uint16_t sequence_number) { - bool sender = module->impl_->SSRC() == kSenderSsrc; - rtcp::Nack nack; - uint16_t list[1]; - list[0] = sequence_number; - const uint16_t kListLength = sizeof(list) / sizeof(list[0]); - nack.SetSenderSsrc(sender ? kReceiverSsrc : kSenderSsrc); - nack.SetMediaSsrc(sender ? kSenderSsrc : kReceiverSsrc); - nack.SetPacketIds(list, kListLength); - module->impl_->IncomingRtcpPacket(nack.Build()); - } -}; - -TEST_F(RtpRtcpImplTest, RetransmitsAllLayers) { - // Send frames. - EXPECT_EQ(0, sender_.RtpSent()); - SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); // kSequenceNumber - SendFrame(&sender_, sender_video_.get(), - kHigherLayerTid); // kSequenceNumber + 1 - SendFrame(&sender_, sender_video_.get(), - kNoTemporalIdx); // kSequenceNumber + 2 - EXPECT_EQ(3, sender_.RtpSent()); - EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber()); - - // Min required delay until retransmit = 5 + RTT ms (RTT = 0). - clock_.AdvanceTimeMilliseconds(5); - - // Frame with kBaseLayerTid re-sent. - IncomingRtcpNack(&sender_, kSequenceNumber); - EXPECT_EQ(4, sender_.RtpSent()); - EXPECT_EQ(kSequenceNumber, sender_.LastRtpSequenceNumber()); - // Frame with kHigherLayerTid re-sent. - IncomingRtcpNack(&sender_, kSequenceNumber + 1); - EXPECT_EQ(5, sender_.RtpSent()); - EXPECT_EQ(kSequenceNumber + 1, sender_.LastRtpSequenceNumber()); - // Frame with kNoTemporalIdx re-sent. - IncomingRtcpNack(&sender_, kSequenceNumber + 2); - EXPECT_EQ(6, sender_.RtpSent()); - EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber()); -} - -TEST_F(RtpRtcpImplTest, Rtt) { - RtpPacketReceived packet; - packet.SetTimestamp(1); - packet.SetSequenceNumber(123); - packet.SetSsrc(kSenderSsrc); - packet.AllocatePayload(100 - 12); - receiver_.receive_statistics_->OnRtpPacket(packet); - - // Send Frame before sending an SR. - SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); - // Sender module should send an SR. - EXPECT_EQ(0, sender_.impl_->SendRTCP(kRtcpReport)); - - // Receiver module should send a RR with a response to the last received SR. - clock_.AdvanceTimeMilliseconds(1000); - EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpReport)); - - // Verify RTT. - EXPECT_THAT(sender_.impl_->LastRtt(), - Near(2 * kOneWayNetworkDelay, TimeDelta::Millis(1))); - - // Verify RTT from rtt_stats config. - EXPECT_EQ(0, sender_.rtt_stats_.LastProcessedRtt()); - EXPECT_EQ(0, sender_.impl_->rtt_ms()); - sender_.impl_->Process(); - EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(), - sender_.rtt_stats_.LastProcessedRtt(), 1); - EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(), sender_.impl_->rtt_ms(), 1); -} - -TEST_F(RtpRtcpImplTest, RttForReceiverOnly) { - // Receiver module should send a Receiver reference time report block (RRTR). - EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpReport)); - - // Sender module should send a response to the last received RRTR (DLRR). - clock_.AdvanceTimeMilliseconds(1000); - // Send Frame before sending a SR. - SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); - EXPECT_EQ(0, sender_.impl_->SendRTCP(kRtcpReport)); - - // Verify RTT. - EXPECT_EQ(0, receiver_.rtt_stats_.LastProcessedRtt()); - EXPECT_EQ(0, receiver_.impl_->rtt_ms()); - receiver_.impl_->Process(); - EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(), - receiver_.rtt_stats_.LastProcessedRtt(), 1); - EXPECT_NEAR(2 * kOneWayNetworkDelay.ms(), receiver_.impl_->rtt_ms(), 1); -} - -TEST_F(RtpRtcpImplTest, NoSrBeforeMedia) { - // Ignore fake transport delays in this test. - sender_.transport_.SimulateNetworkDelay(0, &clock_); - receiver_.transport_.SimulateNetworkDelay(0, &clock_); - - sender_.impl_->Process(); - EXPECT_EQ(sender_.transport_.NumRtcpSent(), 0u); - - // Verify no SR is sent before media has been sent, RR should still be sent - // from the receiving module though. - clock_.AdvanceTimeMilliseconds(2000); - sender_.impl_->Process(); - receiver_.impl_->Process(); - EXPECT_EQ(sender_.transport_.NumRtcpSent(), 0u); - EXPECT_EQ(receiver_.transport_.NumRtcpSent(), 1u); - - SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); - EXPECT_EQ(sender_.transport_.NumRtcpSent(), 1u); -} - -TEST_F(RtpRtcpImplTest, RtcpPacketTypeCounter_Nack) { - EXPECT_EQ(0U, sender_.RtcpReceived().nack_packets); - EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets); - - // Receive module sends a NACK. - const uint16_t kNackLength = 1; - uint16_t nack_list[kNackLength] = {123}; - EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength)); - EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets); - - // Send module receives the NACK. - EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets); -} - -TEST_F(RtpRtcpImplTest, AddStreamDataCounters) { - StreamDataCounters rtp; - rtp.transmitted.packets = 1; - rtp.transmitted.payload_bytes = 1; - rtp.transmitted.header_bytes = 2; - rtp.transmitted.padding_bytes = 3; - EXPECT_EQ(rtp.transmitted.TotalBytes(), rtp.transmitted.payload_bytes + - rtp.transmitted.header_bytes + - rtp.transmitted.padding_bytes); - - StreamDataCounters rtp2; - rtp2.transmitted.packets = 10; - rtp2.transmitted.payload_bytes = 10; - rtp2.retransmitted.header_bytes = 4; - rtp2.retransmitted.payload_bytes = 5; - rtp2.retransmitted.padding_bytes = 6; - rtp2.retransmitted.packets = 7; - rtp2.fec.packets = 8; - - StreamDataCounters sum = rtp; - sum.Add(rtp2); - EXPECT_EQ(11U, sum.transmitted.packets); - EXPECT_EQ(11U, sum.transmitted.payload_bytes); - EXPECT_EQ(2U, sum.transmitted.header_bytes); - EXPECT_EQ(3U, sum.transmitted.padding_bytes); - EXPECT_EQ(4U, sum.retransmitted.header_bytes); - EXPECT_EQ(5U, sum.retransmitted.payload_bytes); - EXPECT_EQ(6U, sum.retransmitted.padding_bytes); - EXPECT_EQ(7U, sum.retransmitted.packets); - EXPECT_EQ(8U, sum.fec.packets); - EXPECT_EQ(sum.transmitted.TotalBytes(), - rtp.transmitted.TotalBytes() + rtp2.transmitted.TotalBytes()); -} - -TEST_F(RtpRtcpImplTest, SendsInitialNackList) { - // Send module sends a NACK. - const uint16_t kNackLength = 1; - uint16_t nack_list[kNackLength] = {123}; - EXPECT_EQ(0U, sender_.RtcpSent().nack_packets); - // Send Frame before sending a compound RTCP that starts with SR. - SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); - EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength)); - EXPECT_EQ(1U, sender_.RtcpSent().nack_packets); - EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123)); -} - -TEST_F(RtpRtcpImplTest, SendsExtendedNackList) { - // Send module sends a NACK. - const uint16_t kNackLength = 1; - uint16_t nack_list[kNackLength] = {123}; - EXPECT_EQ(0U, sender_.RtcpSent().nack_packets); - // Send Frame before sending a compound RTCP that starts with SR. - SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); - EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength)); - EXPECT_EQ(1U, sender_.RtcpSent().nack_packets); - EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123)); - - // Same list not re-send. - EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength)); - EXPECT_EQ(1U, sender_.RtcpSent().nack_packets); - EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123)); - - // Only extended list sent. - const uint16_t kNackExtLength = 2; - uint16_t nack_list_ext[kNackExtLength] = {123, 124}; - EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list_ext, kNackExtLength)); - EXPECT_EQ(2U, sender_.RtcpSent().nack_packets); - EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(124)); -} - -TEST_F(RtpRtcpImplTest, ReSendsNackListAfterRttMs) { - sender_.transport_.SimulateNetworkDelay(0, &clock_); - // Send module sends a NACK. - const uint16_t kNackLength = 2; - uint16_t nack_list[kNackLength] = {123, 125}; - EXPECT_EQ(0U, sender_.RtcpSent().nack_packets); - // Send Frame before sending a compound RTCP that starts with SR. - SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); - EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength)); - EXPECT_EQ(1U, sender_.RtcpSent().nack_packets); - EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123, 125)); - - // Same list not re-send, rtt interval has not passed. - const int kStartupRttMs = 100; - clock_.AdvanceTimeMilliseconds(kStartupRttMs); - EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength)); - EXPECT_EQ(1U, sender_.RtcpSent().nack_packets); - - // Rtt interval passed, full list sent. - clock_.AdvanceTimeMilliseconds(1); - EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength)); - EXPECT_EQ(2U, sender_.RtcpSent().nack_packets); - EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123, 125)); -} - -TEST_F(RtpRtcpImplTest, UniqueNackRequests) { - receiver_.transport_.SimulateNetworkDelay(0, &clock_); - EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets); - EXPECT_EQ(0U, receiver_.RtcpSent().nack_requests); - EXPECT_EQ(0U, receiver_.RtcpSent().unique_nack_requests); - EXPECT_EQ(0, receiver_.RtcpSent().UniqueNackRequestsInPercent()); - - // Receive module sends NACK request. - const uint16_t kNackLength = 4; - uint16_t nack_list[kNackLength] = {10, 11, 13, 18}; - EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength)); - EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets); - EXPECT_EQ(4U, receiver_.RtcpSent().nack_requests); - EXPECT_EQ(4U, receiver_.RtcpSent().unique_nack_requests); - EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(10, 11, 13, 18)); - - // Send module receives the request. - EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets); - EXPECT_EQ(4U, sender_.RtcpReceived().nack_requests); - EXPECT_EQ(4U, sender_.RtcpReceived().unique_nack_requests); - EXPECT_EQ(100, sender_.RtcpReceived().UniqueNackRequestsInPercent()); - - // Receive module sends new request with duplicated packets. - const int kStartupRttMs = 100; - clock_.AdvanceTimeMilliseconds(kStartupRttMs + 1); - const uint16_t kNackLength2 = 4; - uint16_t nack_list2[kNackLength2] = {11, 18, 20, 21}; - EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list2, kNackLength2)); - EXPECT_EQ(2U, receiver_.RtcpSent().nack_packets); - EXPECT_EQ(8U, receiver_.RtcpSent().nack_requests); - EXPECT_EQ(6U, receiver_.RtcpSent().unique_nack_requests); - EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(11, 18, 20, 21)); - - // Send module receives the request. - EXPECT_EQ(2U, sender_.RtcpReceived().nack_packets); - EXPECT_EQ(8U, sender_.RtcpReceived().nack_requests); - EXPECT_EQ(6U, sender_.RtcpReceived().unique_nack_requests); - EXPECT_EQ(75, sender_.RtcpReceived().UniqueNackRequestsInPercent()); -} - -TEST_F(RtpRtcpImplTest, ConfigurableRtcpReportInterval) { - const int kVideoReportInterval = 3000; - - // Recreate sender impl with new configuration, and redo setup. - sender_.SetRtcpReportIntervalAndReset(kVideoReportInterval); - SetUp(); - - SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); - - // Initial state - sender_.impl_->Process(); - EXPECT_EQ(0u, sender_.transport_.NumRtcpSent()); - - // Move ahead to the last ms before a rtcp is expected, no action. - clock_.AdvanceTimeMilliseconds(kVideoReportInterval / 2 - 1); - sender_.impl_->Process(); - EXPECT_EQ(sender_.transport_.NumRtcpSent(), 0u); - - // Move ahead to the first rtcp. Send RTCP. - clock_.AdvanceTimeMilliseconds(1); - sender_.impl_->Process(); - EXPECT_EQ(sender_.transport_.NumRtcpSent(), 1u); - - SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); - - // Move ahead to the last possible second before second rtcp is expected. - clock_.AdvanceTimeMilliseconds(kVideoReportInterval * 1 / 2 - 1); - sender_.impl_->Process(); - EXPECT_EQ(sender_.transport_.NumRtcpSent(), 1u); - - // Move ahead into the range of second rtcp, the second rtcp may be sent. - clock_.AdvanceTimeMilliseconds(1); - sender_.impl_->Process(); - EXPECT_GE(sender_.transport_.NumRtcpSent(), 1u); - - clock_.AdvanceTimeMilliseconds(kVideoReportInterval / 2); - sender_.impl_->Process(); - EXPECT_GE(sender_.transport_.NumRtcpSent(), 1u); - - // Move out the range of second rtcp, the second rtcp must have been sent. - clock_.AdvanceTimeMilliseconds(kVideoReportInterval / 2); - sender_.impl_->Process(); - EXPECT_EQ(sender_.transport_.NumRtcpSent(), 2u); -} - -TEST_F(RtpRtcpImplTest, StoresPacketInfoForSentPackets) { - const uint32_t kStartTimestamp = 1u; - SetUp(); - sender_.impl_->SetStartTimestamp(kStartTimestamp); - sender_.impl_->SetSequenceNumber(1); - - PacedPacketInfo pacing_info; - RtpPacketToSend packet(nullptr); - packet.set_packet_type(RtpPacketToSend::Type::kVideo); - packet.SetSsrc(kSenderSsrc); - - // Single-packet frame. - packet.SetTimestamp(1); - packet.set_first_packet_of_frame(true); - packet.SetMarker(true); - sender_.impl_->TrySendPacket(std::make_unique<RtpPacketToSend>(packet), - pacing_info); - - std::vector<RtpSequenceNumberMap::Info> seqno_info = - sender_.impl_->GetSentRtpPacketInfos(std::vector<uint16_t>{1}); - - EXPECT_THAT(seqno_info, ElementsAre(RtpSequenceNumberMap::Info( - /*timestamp=*/1 - kStartTimestamp, - /*is_first=*/1, - /*is_last=*/1))); - - // Three-packet frame. - packet.SetTimestamp(2); - packet.set_first_packet_of_frame(true); - packet.SetMarker(false); - sender_.impl_->TrySendPacket(std::make_unique<RtpPacketToSend>(packet), - pacing_info); - - packet.set_first_packet_of_frame(false); - sender_.impl_->TrySendPacket(std::make_unique<RtpPacketToSend>(packet), - pacing_info); - - packet.SetMarker(true); - sender_.impl_->TrySendPacket(std::make_unique<RtpPacketToSend>(packet), - pacing_info); - - seqno_info = - sender_.impl_->GetSentRtpPacketInfos(std::vector<uint16_t>{2, 3, 4}); - - EXPECT_THAT(seqno_info, ElementsAre(RtpSequenceNumberMap::Info( - /*timestamp=*/2 - kStartTimestamp, - /*is_first=*/1, - /*is_last=*/0), - RtpSequenceNumberMap::Info( - /*timestamp=*/2 - kStartTimestamp, - /*is_first=*/0, - /*is_last=*/0), - RtpSequenceNumberMap::Info( - /*timestamp=*/2 - kStartTimestamp, - /*is_first=*/0, - /*is_last=*/1))); -} - -// Checks that the remote sender stats are not available if no RTCP SR was sent. -TEST_F(RtpRtcpImplTest, SenderReportStatsNotAvailable) { - EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Eq(std::nullopt)); -} - -// Checks that the remote sender stats are available if an RTCP SR was sent. -TEST_F(RtpRtcpImplTest, SenderReportStatsAvailable) { - // Send a frame in order to send an SR. - SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); - // Send an SR. - ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0)); - EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Not(Eq(std::nullopt))); -} - -// Checks that the remote sender stats are not available if an RTCP SR with an -// unexpected SSRC is received. -TEST_F(RtpRtcpImplTest, SenderReportStatsNotUpdatedWithUnexpectedSsrc) { - constexpr uint32_t kUnexpectedSenderSsrc = 0x87654321; - static_assert(kUnexpectedSenderSsrc != kSenderSsrc, ""); - // Forge a sender report and pass it to the receiver as if an RTCP SR were - // sent by an unexpected sender. - rtcp::SenderReport sr; - sr.SetSenderSsrc(kUnexpectedSenderSsrc); - sr.SetNtp({/*seconds=*/1u, /*fractions=*/1u << 31}); - sr.SetPacketCount(123u); - sr.SetOctetCount(456u); - receiver_.impl_->IncomingRtcpPacket(sr.Build()); - EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), Eq(std::nullopt)); -} - -// Checks the stats derived from the last received RTCP SR are set correctly. -TEST_F(RtpRtcpImplTest, SenderReportStatsCheckStatsFromLastReport) { - using SenderReportStats = RtpRtcpInterface::SenderReportStats; - const NtpTime ntp(/*seconds=*/1u, /*fractions=*/1u << 31); - constexpr uint32_t kPacketCount = 123u; - constexpr uint32_t kOctetCount = 456u; - // Forge a sender report and pass it to the receiver as if an RTCP SR were - // sent by the sender. - rtcp::SenderReport sr; - sr.SetSenderSsrc(kSenderSsrc); - sr.SetNtp(ntp); - sr.SetPacketCount(kPacketCount); - sr.SetOctetCount(kOctetCount); - receiver_.impl_->IncomingRtcpPacket(sr.Build()); - - EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), - Optional(AllOf( - Field(&SenderReportStats::last_remote_ntp_timestamp, Eq(ntp)), - Field(&SenderReportStats::packets_sent, Eq(kPacketCount)), - Field(&SenderReportStats::bytes_sent, Eq(kOctetCount))))); -} - -// Checks that the remote sender stats count equals the number of sent RTCP SRs. -TEST_F(RtpRtcpImplTest, SenderReportStatsCount) { - using SenderReportStats = RtpRtcpInterface::SenderReportStats; - // Send a frame in order to send an SR. - SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); - // Send the first SR. - ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0)); - EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), - Optional(Field(&SenderReportStats::reports_count, Eq(1u)))); - // Send the second SR. - ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0)); - EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), - Optional(Field(&SenderReportStats::reports_count, Eq(2u)))); -} - -// Checks that the remote sender stats include a valid arrival time if an RTCP -// SR was sent. -TEST_F(RtpRtcpImplTest, SenderReportStatsArrivalTimestampSet) { - // Send a frame in order to send an SR. - SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); - // Send an SR. - ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0)); - auto stats = receiver_.impl_->GetSenderReportStats(); - ASSERT_THAT(stats, Not(Eq(std::nullopt))); - EXPECT_TRUE(stats->last_arrival_ntp_timestamp.Valid()); -} - -// Checks that the packet and byte counters from an RTCP SR are not zero once -// a frame is sent. -TEST_F(RtpRtcpImplTest, SenderReportStatsPacketByteCounters) { - using SenderReportStats = RtpRtcpInterface::SenderReportStats; - // Send a frame in order to send an SR. - SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); - ASSERT_THAT(sender_.transport_.rtp_packets_sent_, Gt(0)); - // Advance time otherwise the RTCP SR report will not include any packets - // generated by `SendFrame()`. - clock_.AdvanceTimeMilliseconds(1); - // Send an SR. - ASSERT_THAT(sender_.impl_->SendRTCP(kRtcpReport), Eq(0)); - EXPECT_THAT(receiver_.impl_->GetSenderReportStats(), - Optional(AllOf(Field(&SenderReportStats::packets_sent, Gt(0u)), - Field(&SenderReportStats::bytes_sent, Gt(0u))))); -} - -#pragma clang diagnostic pop - -} // namespace webrtc diff --git a/third_party/libwebrtc/moz-patch-stack/s0003.patch b/third_party/libwebrtc/moz-patch-stack/s0003.patch @@ -8,12 +8,10 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/b55b0368d9f21849f call/video_receive_stream.h | 3 +++ modules/rtp_rtcp/source/rtcp_receiver.cc | 7 +++++++ modules/rtp_rtcp/source/rtcp_receiver.h | 4 ++++ - modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 5 +++++ - modules/rtp_rtcp/source/rtp_rtcp_impl.h | 3 +++ modules/rtp_rtcp/source/rtp_rtcp_impl2.cc | 5 +++++ modules/rtp_rtcp/source/rtp_rtcp_impl2.h | 3 +++ modules/rtp_rtcp/source/rtp_rtcp_interface.h | 4 ++++ - 8 files changed, 34 insertions(+) + 6 files changed, 26 insertions(+) diff --git a/call/video_receive_stream.h b/call/video_receive_stream.h index b1a99c5519..c2f27ec5f3 100644 @@ -62,36 +60,6 @@ index 1dab65f7f6..c5a17b7763 100644 std::optional<TimeDelta> AverageRtt() const; std::optional<TimeDelta> LastRtt() const; -diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -index 5750a7038a..c5cdeb5c47 100644 ---- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -@@ -515,6 +515,11 @@ void ModuleRtpRtcpImpl::GetSendStreamDataCounters( - } - - // Received RTCP report. -+void ModuleRtpRtcpImpl::RemoteRTCPSenderInfo(uint32_t* packet_count, -+ uint32_t* octet_count) const { -+ return rtcp_receiver_.RemoteRTCPSenderInfo(packet_count, octet_count); -+} -+ - std::vector<ReportBlockData> ModuleRtpRtcpImpl::GetLatestReportBlockData() - const { - return rtcp_receiver_.GetLatestReportBlockData(); -diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h -index 32aba69a9a..34a2bc3dd7 100644 ---- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h -+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h -@@ -203,6 +203,9 @@ class ABSL_DEPRECATED("") ModuleRtpRtcpImpl - StreamDataCounters* rtp_counters, - StreamDataCounters* rtx_counters) const override; - -+ void RemoteRTCPSenderInfo(uint32_t* packet_count, -+ uint32_t* octet_count) const override; -+ - // A snapshot of the most recent Report Block with additional data of - // interest to statistics. Used to implement RTCRemoteInboundRtpStreamStats. - // Within this list, the `ReportBlockData::source_ssrc()`, which is the SSRC diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc index 3e90e257b6..c48d70e172 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc diff --git a/third_party/libwebrtc/moz-patch-stack/s0004.patch b/third_party/libwebrtc/moz-patch-stack/s0004.patch @@ -13,12 +13,10 @@ Bug 1654112 - Replace custom upstream code for remote received audio stats with call/video_receive_stream.h | 1 + modules/rtp_rtcp/source/rtcp_receiver.cc | 4 +++- modules/rtp_rtcp/source/rtcp_receiver.h | 3 ++- - modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 6 ++++-- - modules/rtp_rtcp/source/rtp_rtcp_impl.h | 3 ++- modules/rtp_rtcp/source/rtp_rtcp_impl2.cc | 6 ++++-- modules/rtp_rtcp/source/rtp_rtcp_impl2.h | 3 ++- modules/rtp_rtcp/source/rtp_rtcp_interface.h | 5 +++-- - 8 files changed, 21 insertions(+), 10 deletions(-) + 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/call/video_receive_stream.h b/call/video_receive_stream.h index c2f27ec5f3..ae9951e6f9 100644 @@ -64,37 +62,6 @@ index c5a17b7763..8fc8ea4bf6 100644 std::optional<TimeDelta> AverageRtt() const; std::optional<TimeDelta> LastRtt() const; -diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -index c5cdeb5c47..5999b255b1 100644 ---- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -@@ -516,8 +516,10 @@ void ModuleRtpRtcpImpl::GetSendStreamDataCounters( - - // Received RTCP report. - void ModuleRtpRtcpImpl::RemoteRTCPSenderInfo(uint32_t* packet_count, -- uint32_t* octet_count) const { -- return rtcp_receiver_.RemoteRTCPSenderInfo(packet_count, octet_count); -+ uint32_t* octet_count, -+ int64_t* ntp_timestamp_ms) const { -+ return rtcp_receiver_.RemoteRTCPSenderInfo(packet_count, octet_count, -+ ntp_timestamp_ms); - } - - std::vector<ReportBlockData> ModuleRtpRtcpImpl::GetLatestReportBlockData() -diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h -index 34a2bc3dd7..b0218aadc0 100644 ---- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h -+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h -@@ -204,7 +204,8 @@ class ABSL_DEPRECATED("") ModuleRtpRtcpImpl - StreamDataCounters* rtx_counters) const override; - - void RemoteRTCPSenderInfo(uint32_t* packet_count, -- uint32_t* octet_count) const override; -+ uint32_t* octet_count, -+ int64_t* ntp_timestamp_ms) const override; - - // A snapshot of the most recent Report Block with additional data of - // interest to statistics. Used to implement RTCRemoteInboundRtpStreamStats. diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc index c48d70e172..27c22f4c88 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc diff --git a/third_party/libwebrtc/moz-patch-stack/s0042.patch b/third_party/libwebrtc/moz-patch-stack/s0042.patch @@ -9,15 +9,13 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/99267b6d193fbcb3e call/video_receive_stream.h | 3 ++- modules/rtp_rtcp/source/rtcp_receiver.cc | 6 ++++-- modules/rtp_rtcp/source/rtcp_receiver.h | 3 ++- - modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 10 +++++----- - modules/rtp_rtcp/source/rtp_rtcp_impl.h | 3 ++- modules/rtp_rtcp/source/rtp_rtcp_impl2.cc | 10 +++++----- modules/rtp_rtcp/source/rtp_rtcp_impl2.h | 3 ++- modules/rtp_rtcp/source/rtp_rtcp_interface.h | 5 +++-- video/rtp_video_stream_receiver2.cc | 5 +++-- video/rtp_video_stream_receiver2.h | 3 ++- video/video_receive_stream2.cc | 3 ++- - 11 files changed, 32 insertions(+), 22 deletions(-) + 9 files changed, 25 insertions(+), 16 deletions(-) diff --git a/call/video_receive_stream.h b/call/video_receive_stream.h index 5800598b75..17c56bb2b1 100644 @@ -70,41 +68,6 @@ index 9b9ddb4987..05f7024d62 100644 std::optional<TimeDelta> AverageRtt() const; std::optional<TimeDelta> LastRtt() const; -diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -index 5999b255b1..a1e04d3882 100644 ---- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -@@ -515,11 +515,11 @@ void ModuleRtpRtcpImpl::GetSendStreamDataCounters( - } - - // Received RTCP report. --void ModuleRtpRtcpImpl::RemoteRTCPSenderInfo(uint32_t* packet_count, -- uint32_t* octet_count, -- int64_t* ntp_timestamp_ms) const { -- return rtcp_receiver_.RemoteRTCPSenderInfo(packet_count, octet_count, -- ntp_timestamp_ms); -+void ModuleRtpRtcpImpl::RemoteRTCPSenderInfo( -+ uint32_t* packet_count, uint32_t* octet_count, int64_t* ntp_timestamp_ms, -+ int64_t* remote_ntp_timestamp_ms) const { -+ return rtcp_receiver_.RemoteRTCPSenderInfo( -+ packet_count, octet_count, ntp_timestamp_ms, remote_ntp_timestamp_ms); - } - - std::vector<ReportBlockData> ModuleRtpRtcpImpl::GetLatestReportBlockData() -diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h -index b0218aadc0..20f9397e91 100644 ---- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h -+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h -@@ -205,7 +205,8 @@ class ABSL_DEPRECATED("") ModuleRtpRtcpImpl - - void RemoteRTCPSenderInfo(uint32_t* packet_count, - uint32_t* octet_count, -- int64_t* ntp_timestamp_ms) const override; -+ int64_t* ntp_timestamp_ms, -+ int64_t* remote_ntp_timestamp_ms) const override; - - // A snapshot of the most recent Report Block with additional data of - // interest to statistics. Used to implement RTCRemoteInboundRtpStreamStats. diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc index 27c22f4c88..c44664b73e 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc diff --git a/third_party/libwebrtc/moz-patch-stack/s0082.patch b/third_party/libwebrtc/moz-patch-stack/s0082.patch @@ -14,9 +14,8 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/d92a578327f524ec3 call/rtp_video_sender.cc | 1 + modules/rtp_rtcp/source/rtcp_sender.cc | 19 +++++++++++++++++-- .../rtp_rtcp/source/rtcp_sender_unittest.cc | 5 +++-- - modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 1 + modules/rtp_rtcp/source/rtp_rtcp_interface.h | 2 +- - 5 files changed, 23 insertions(+), 5 deletions(-) + 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/call/rtp_video_sender.cc b/call/rtp_video_sender.cc index 25cc81396c..4fa0e8c5e7 100644 @@ -80,18 +79,6 @@ index 4184f22e1b..0e8163ccf7 100644 } TEST_F(RtcpSenderTest, SendFir) { -diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -index a1e04d3882..241f17539d 100644 ---- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -@@ -312,6 +312,7 @@ RTCPSender::FeedbackState ModuleRtpRtcpImpl::GetFeedbackState() { - - int32_t ModuleRtpRtcpImpl::SetSendingStatus(const bool sending) { - if (rtcp_sender_.Sending() != sending) { -+ // Sends RTCP BYE when going from true to false - rtcp_sender_.SetSendingStatus(GetFeedbackState(), sending); - } - return 0; diff --git a/modules/rtp_rtcp/source/rtp_rtcp_interface.h b/modules/rtp_rtcp/source/rtp_rtcp_interface.h index bbdb38864e..be120a82da 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_interface.h