Use LastRtt from RTCP module in ChannelSend.

It is a bit more flexible than the current implementation.

Also cleanup ChannelSend::GetRTT since it is not called from the receive stream anymore.

Bug: none
Change-Id: I4403c8b1840012f2287d189be934fd1069de85fb
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/374160
Commit-Queue: Jakob Ivarsson‎ <jakobi@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43728}
This commit is contained in:
Jakob Ivarsson 2025-01-10 15:30:32 +00:00 committed by WebRTC LUCI CQ
parent b099e0d7ef
commit 9986ff7f4a
4 changed files with 52 additions and 49 deletions

View File

@ -39,6 +39,7 @@ rtc_library("audio") {
deps = [ deps = [
"../api:array_view", "../api:array_view",
"../api:bitrate_allocation",
"../api:call_api", "../api:call_api",
"../api:field_trials_view", "../api:field_trials_view",
"../api:frame_transformer_interface", "../api:frame_transformer_interface",
@ -67,6 +68,8 @@ rtc_library("audio") {
"../api/task_queue", "../api/task_queue",
"../api/task_queue:pending_task_safety_flag", "../api/task_queue:pending_task_safety_flag",
"../api/transport/rtp:rtp_source", "../api/transport/rtp:rtp_source",
"../api/units:data_rate",
"../api/units:data_size",
"../api/units:time_delta", "../api/units:time_delta",
"../api/units:timestamp", "../api/units:timestamp",
"../call:audio_sender_interface", "../call:audio_sender_interface",

View File

@ -11,39 +11,62 @@
#include "audio/channel_send.h" #include "audio/channel_send.h"
#include <algorithm> #include <algorithm>
#include <map> #include <atomic>
#include <cstddef>
#include <cstdint>
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h" #include "api/array_view.h"
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/call/bitrate_allocation.h"
#include "api/call/transport.h" #include "api/call/transport.h"
#include "api/crypto/crypto_options.h"
#include "api/crypto/frame_encryptor_interface.h" #include "api/crypto/frame_encryptor_interface.h"
#include "api/rtc_event_log/rtc_event_log.h" #include "api/environment/environment.h"
#include "api/frame_transformer_interface.h"
#include "api/function_view.h"
#include "api/make_ref_counted.h"
#include "api/media_types.h"
#include "api/rtp_headers.h"
#include "api/scoped_refptr.h"
#include "api/sequence_checker.h" #include "api/sequence_checker.h"
#include "api/task_queue/task_queue_base.h"
#include "api/task_queue/task_queue_factory.h" #include "api/task_queue/task_queue_factory.h"
#include "api/units/data_rate.h"
#include "api/units/data_size.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "audio/channel_send_frame_transformer_delegate.h" #include "audio/channel_send_frame_transformer_delegate.h"
#include "audio/utility/audio_frame_operations.h" #include "audio/utility/audio_frame_operations.h"
#include "call/rtp_transport_controller_send_interface.h" #include "call/rtp_transport_controller_send_interface.h"
#include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
#include "modules/audio_coding/include/audio_coding_module.h" #include "modules/audio_coding/include/audio_coding_module.h"
#include "modules/audio_coding/include/audio_coding_module_typedefs.h"
#include "modules/audio_processing/rms_level.h" #include "modules/audio_processing/rms_level.h"
#include "modules/pacing/packet_router.h" #include "modules/pacing/packet_router.h"
#include "modules/rtp_rtcp/include/report_block_data.h"
#include "modules/rtp_rtcp/include/rtcp_statistics.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h" #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
#include "modules/rtp_rtcp/source/rtp_sender_audio.h"
#include "rtc_base/buffer.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/event.h" #include "rtc_base/event.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/race_checker.h" #include "rtc_base/race_checker.h"
#include "rtc_base/rate_limiter.h" #include "rtc_base/rate_limiter.h"
#include "rtc_base/strings/string_builder.h" #include "rtc_base/strings/string_builder.h"
#include "rtc_base/synchronization/mutex.h" #include "rtc_base/synchronization/mutex.h"
#include "rtc_base/system/no_unique_address.h" #include "rtc_base/system/no_unique_address.h"
#include "rtc_base/time_utils.h" #include "rtc_base/thread_annotations.h"
#include "rtc_base/trace_event.h" #include "rtc_base/trace_event.h"
#include "system_wrappers/include/clock.h"
#include "system_wrappers/include/metrics.h" #include "system_wrappers/include/metrics.h"
namespace webrtc { namespace webrtc {
@ -51,8 +74,8 @@ namespace voe {
namespace { namespace {
constexpr int64_t kMaxRetransmissionWindowMs = 1000; constexpr TimeDelta kMaxRetransmissionWindow = TimeDelta::Seconds(1);
constexpr int64_t kMinRetransmissionWindowMs = 30; constexpr TimeDelta kMinRetransmissionWindow = TimeDelta::Millis(30);
class RtpPacketSenderProxy; class RtpPacketSenderProxy;
class TransportSequenceNumberProxy; class TransportSequenceNumberProxy;
@ -173,8 +196,6 @@ class ChannelSend : public ChannelSendInterface,
// packet. // packet.
void ProcessAndEncodeAudio(std::unique_ptr<AudioFrame> audio_frame) override; void ProcessAndEncodeAudio(std::unique_ptr<AudioFrame> audio_frame) override;
int64_t GetRTT() const override;
// E2EE Custom Audio Frame Encryption // E2EE Custom Audio Frame Encryption
void SetFrameEncryptor( void SetFrameEncryptor(
rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) override; rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) override;
@ -474,7 +495,7 @@ ChannelSend::ChannelSend(
ssrc_(ssrc), ssrc_(ssrc),
rtp_packet_pacer_proxy_(new RtpPacketSenderProxy()), rtp_packet_pacer_proxy_(new RtpPacketSenderProxy()),
retransmission_rate_limiter_( retransmission_rate_limiter_(
new RateLimiter(&env_.clock(), kMaxRetransmissionWindowMs)), new RateLimiter(&env_.clock(), kMaxRetransmissionWindow.ms())),
frame_encryptor_(frame_encryptor), frame_encryptor_(frame_encryptor),
crypto_options_(crypto_options), crypto_options_(crypto_options),
encoder_queue_(env_.task_queue_factory().CreateTaskQueue( encoder_queue_(env_.task_queue_factory().CreateTaskQueue(
@ -646,21 +667,16 @@ void ChannelSend::ReceivedRTCPPacket(const uint8_t* data, size_t length) {
// Deliver RTCP packet to RTP/RTCP module for parsing // Deliver RTCP packet to RTP/RTCP module for parsing
rtp_rtcp_->IncomingRtcpPacket(rtc::MakeArrayView(data, length)); rtp_rtcp_->IncomingRtcpPacket(rtc::MakeArrayView(data, length));
int64_t rtt = GetRTT(); std::optional<TimeDelta> rtt = rtp_rtcp_->LastRtt();
if (rtt == 0) { if (!rtt.has_value()) {
// Waiting for valid RTT. // Waiting for valid RTT.
return; return;
} }
int64_t nack_window_ms = rtt; retransmission_rate_limiter_->SetWindowSize(
if (nack_window_ms < kMinRetransmissionWindowMs) { rtt->Clamped(kMinRetransmissionWindow, kMaxRetransmissionWindow).ms());
nack_window_ms = kMinRetransmissionWindowMs;
} else if (nack_window_ms > kMaxRetransmissionWindowMs) {
nack_window_ms = kMaxRetransmissionWindowMs;
}
retransmission_rate_limiter_->SetWindowSize(nack_window_ms);
OnReceivedRtt(rtt); OnReceivedRtt(rtt->ms());
} }
void ChannelSend::SetInputMute(bool enable) { void ChannelSend::SetInputMute(bool enable) {
@ -759,7 +775,7 @@ std::vector<ReportBlockData> ChannelSend::GetRemoteRTCPReportBlocks() const {
CallSendStatistics ChannelSend::GetRTCPStatistics() const { CallSendStatistics ChannelSend::GetRTCPStatistics() const {
RTC_DCHECK_RUN_ON(&worker_thread_checker_); RTC_DCHECK_RUN_ON(&worker_thread_checker_);
CallSendStatistics stats = {0}; CallSendStatistics stats = {0};
stats.rttMs = GetRTT(); stats.rttMs = rtp_rtcp_->LastRtt().value_or(TimeDelta::Zero()).ms();
StreamDataCounters rtp_stats; StreamDataCounters rtp_stats;
StreamDataCounters rtx_stats; StreamDataCounters rtx_stats;
@ -888,18 +904,6 @@ RtpRtcpInterface* ChannelSend::GetRtpRtcp() const {
return rtp_rtcp_.get(); return rtp_rtcp_.get();
} }
int64_t ChannelSend::GetRTT() const {
std::vector<ReportBlockData> report_blocks =
rtp_rtcp_->GetLatestReportBlockData();
if (report_blocks.empty()) {
return 0;
}
// We don't know in advance the remote ssrc used by the other end's receiver
// reports, so use the first report block for the RTT.
return report_blocks.front().last_rtt().ms();
}
void ChannelSend::SetFrameEncryptor( void ChannelSend::SetFrameEncryptor(
rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) { rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) {
RTC_DCHECK_RUN_ON(&worker_thread_checker_); RTC_DCHECK_RUN_ON(&worker_thread_checker_);

View File

@ -11,19 +11,27 @@
#ifndef AUDIO_CHANNEL_SEND_H_ #ifndef AUDIO_CHANNEL_SEND_H_
#define AUDIO_CHANNEL_SEND_H_ #define AUDIO_CHANNEL_SEND_H_
#include <cstddef>
#include <cstdint>
#include <memory> #include <memory>
#include <string> #include <optional>
#include <vector> #include <vector>
#include "absl/strings/string_view.h"
#include "api/audio/audio_frame.h" #include "api/audio/audio_frame.h"
#include "api/audio_codecs/audio_encoder.h" #include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/call/bitrate_allocation.h"
#include "api/crypto/crypto_options.h" #include "api/crypto/crypto_options.h"
#include "api/environment/environment.h" #include "api/environment/environment.h"
#include "api/frame_transformer_interface.h" #include "api/frame_transformer_interface.h"
#include "api/function_view.h" #include "api/function_view.h"
#include "api/scoped_refptr.h"
#include "api/units/data_rate.h"
#include "api/units/time_delta.h"
#include "modules/rtp_rtcp/include/report_block_data.h" #include "modules/rtp_rtcp/include/report_block_data.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
#include "modules/rtp_rtcp/source/rtp_sender_audio.h"
namespace webrtc { namespace webrtc {
@ -87,17 +95,6 @@ class ChannelSendInterface {
std::unique_ptr<AudioFrame> audio_frame) = 0; std::unique_ptr<AudioFrame> audio_frame) = 0;
virtual RtpRtcpInterface* GetRtpRtcp() const = 0; virtual RtpRtcpInterface* GetRtpRtcp() const = 0;
// In RTP we currently rely on RTCP packets (`ReceivedRTCPPacket`) to inform
// about RTT.
// In media transport we rely on the TargetTransferRateObserver instead.
// In other words, if you are using RTP, you should expect
// `ReceivedRTCPPacket` to be called, if you are using media transport,
// `OnTargetTransferRate` will be called.
//
// In future, RTP media will move to the media transport implementation and
// these conditions will be removed.
// Returns the RTT in milliseconds.
virtual int64_t GetRTT() const = 0;
virtual void StartSend() = 0; virtual void StartSend() = 0;
virtual void StopSend() = 0; virtual void StopSend() = 0;

View File

@ -185,7 +185,6 @@ class MockChannelSend : public voe::ChannelSendInterface {
(override)); (override));
MOCK_METHOD(RtpRtcpInterface*, GetRtpRtcp, (), (const, override)); MOCK_METHOD(RtpRtcpInterface*, GetRtpRtcp, (), (const, override));
MOCK_METHOD(int, GetTargetBitrate, (), (const, override)); MOCK_METHOD(int, GetTargetBitrate, (), (const, override));
MOCK_METHOD(int64_t, GetRTT, (), (const, override));
MOCK_METHOD(void, StartSend, (), (override)); MOCK_METHOD(void, StartSend, (), (override));
MOCK_METHOD(void, StopSend, (), (override)); MOCK_METHOD(void, StopSend, (), (override));
MOCK_METHOD(void, MOCK_METHOD(void,