In RtcpReceiver implement calling NetworkLinkRtcpObserver interface
With intent to fully replace RtcpBandwidthObserver interface
and half of the TransportFeedbackObserver interface
RtcpBandwidthObserver interfaces passed bitrate and time variables as
raw ints, NetworkLinkRtcpObserver uses more expressive types.
Bug: webrtc:13757, webrtc:8239
Change-Id: I0a8c8de626fbe0c190a0a1a9f6733d863494401c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/304700
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40043}
diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn
index 4bc68eb..fb2419c 100644
--- a/modules/rtp_rtcp/BUILD.gn
+++ b/modules/rtp_rtcp/BUILD.gn
@@ -117,6 +117,7 @@
"../../api/audio_codecs:audio_codecs_api",
"../../api/transport:network_control",
"../../api/transport/rtp:dependency_descriptor",
+ "../../api/units:data_rate",
"../../api/units:time_delta",
"../../api/units:timestamp",
"../../api/video:video_frame",
@@ -477,6 +478,7 @@
rtc_library("mock_rtp_rtcp") {
testonly = true
public = [
+ "mocks/mock_network_link_rtcp_observer.h",
"mocks/mock_recovered_packet_receiver.h",
"mocks/mock_rtcp_bandwidth_observer.h",
"mocks/mock_rtcp_rtt_stats.h",
@@ -485,6 +487,10 @@
deps = [
":rtp_rtcp",
":rtp_rtcp_format",
+ "../../api:array_view",
+ "../../api/units:data_rate",
+ "../../api/units:time_delta",
+ "../../api/units:timestamp",
"../../api/video:video_bitrate_allocation",
"../../rtc_base:checks",
"../../test:test_support",
diff --git a/modules/rtp_rtcp/include/rtp_rtcp_defines.h b/modules/rtp_rtcp/include/rtp_rtcp_defines.h
index f047a45..27fdf82 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp_defines.h
+++ b/modules/rtp_rtcp/include/rtp_rtcp_defines.h
@@ -25,7 +25,10 @@
#include "api/audio_codecs/audio_format.h"
#include "api/rtp_headers.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 "modules/rtp_rtcp/include/report_block_data.h"
#include "modules/rtp_rtcp/source/rtcp_packet/remote_estimate.h"
#include "system_wrappers/include/clock.h"
@@ -164,6 +167,8 @@
bool decodability_flag) = 0;
};
+// TODO(bugs.webrtc.org/13757): Remove this interface in favor of the
+// NetworkLinkRtcpObserver that uses more descriptive types.
class RtcpBandwidthObserver {
public:
// REMB or TMMBR
@@ -177,6 +182,27 @@
virtual ~RtcpBandwidthObserver() {}
};
+// Interface to watch incoming rtcp packets related to the link in general.
+// All message handlers have default empty implementation. This way users only
+// need to implement the ones they are interested in.
+// All message handles pass `receive_time` parameter, which is receive time
+// of the rtcp packet that triggered the update.
+class NetworkLinkRtcpObserver {
+ public:
+ virtual ~NetworkLinkRtcpObserver() = default;
+
+ virtual void OnTransportFeedback(Timestamp receive_time,
+ const rtcp::TransportFeedback& feedback) {}
+ virtual void OnReceiverEstimatedMaxBitrate(Timestamp receive_time,
+ DataRate bitrate) {}
+
+ // Called on an RTCP packet with sender or receiver reports with non zero
+ // report blocks. Report blocks are combined from all reports into one array.
+ virtual void OnReport(Timestamp receive_time,
+ rtc::ArrayView<const ReportBlockData> report_blocks) {}
+ virtual void OnRttUpdate(Timestamp receive_time, TimeDelta rtt) {}
+};
+
// NOTE! `kNumMediaTypes` must be kept in sync with RtpPacketMediaType!
static constexpr size_t kNumMediaTypes = 5;
enum class RtpPacketMediaType : size_t {
@@ -210,7 +236,10 @@
virtual ~TransportFeedbackObserver() {}
virtual void OnAddPacket(const RtpPacketSendInfo& packet_info) = 0;
- virtual void OnTransportFeedback(const rtcp::TransportFeedback& feedback) = 0;
+
+ // TODO(bugs.webrtc.org/8239): Remove this function in favor of receiving
+ // feedback message via `NetworkLinkRtcpObserver` interface.
+ virtual void OnTransportFeedback(const rtcp::TransportFeedback& feedback) {}
};
// Interface for PacketRouter to send rtcp feedback on behalf of
diff --git a/modules/rtp_rtcp/mocks/mock_network_link_rtcp_observer.h b/modules/rtp_rtcp/mocks/mock_network_link_rtcp_observer.h
new file mode 100644
index 0000000..16b7db7
--- /dev/null
+++ b/modules/rtp_rtcp/mocks/mock_network_link_rtcp_observer.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2023 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_MOCKS_MOCK_NETWORK_LINK_RTCP_OBSERVER_H_
+#define MODULES_RTP_RTCP_MOCKS_MOCK_NETWORK_LINK_RTCP_OBSERVER_H_
+
+#include "api/array_view.h"
+#include "api/units/data_rate.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
+#include "modules/rtp_rtcp/include/report_block_data.h"
+#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockNetworkLinkRtcpObserver : public NetworkLinkRtcpObserver {
+ public:
+ MOCK_METHOD(void,
+ OnRttUpdate,
+ (Timestamp receive_time, TimeDelta rtt),
+ (override));
+ MOCK_METHOD(void,
+ OnTransportFeedback,
+ (Timestamp receive_time, const rtcp::TransportFeedback& feedback),
+ (override));
+ MOCK_METHOD(void,
+ OnReceiverEstimatedMaxBitrate,
+ (Timestamp receive_time, DataRate bitrate),
+ (override));
+ MOCK_METHOD(void,
+ OnReport,
+ (Timestamp receive_time,
+ rtc::ArrayView<const ReportBlockData> report_blocks),
+ (override));
+};
+
+} // namespace webrtc
+#endif // MODULES_RTP_RTCP_MOCKS_MOCK_NETWORK_LINK_RTCP_OBSERVER_H_
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc
index 2039e8b..5e1e1c6 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -130,7 +130,7 @@
// TODO(hbos): Remove `report_blocks` in favor of `report_block_datas`.
ReportBlockList report_blocks;
std::vector<ReportBlockData> report_block_datas;
- int64_t rtt_ms = 0;
+ absl::optional<TimeDelta> rtt;
uint32_t receiver_estimated_max_bitrate_bps = 0;
std::unique_ptr<rtcp::TransportFeedback> transport_feedback;
absl::optional<VideoBitrateAllocation> target_bitrate_allocation;
@@ -144,11 +144,13 @@
receiver_only_(config.receiver_only),
rtp_rtcp_(owner),
registered_ssrcs_(false, config),
- rtcp_bandwidth_observer_(config.bandwidth_callback),
+ deprecated_rtcp_bandwidth_observer_(config.bandwidth_callback),
+ network_link_rtcp_observer_(config.network_link_rtcp_observer),
rtcp_intra_frame_observer_(config.intra_frame_callback),
rtcp_loss_notification_observer_(config.rtcp_loss_notification_observer),
network_state_estimate_observer_(config.network_state_estimate_observer),
- transport_feedback_observer_(config.transport_feedback_callback),
+ deprecated_transport_feedback_observer_(
+ config.transport_feedback_callback),
bitrate_allocation_observer_(config.bitrate_allocation_observer),
report_interval_(config.rtcp_report_interval_ms > 0
? TimeDelta::Millis(config.rtcp_report_interval_ms)
@@ -173,11 +175,13 @@
receiver_only_(config.receiver_only),
rtp_rtcp_(owner),
registered_ssrcs_(true, config),
- rtcp_bandwidth_observer_(config.bandwidth_callback),
+ deprecated_rtcp_bandwidth_observer_(config.bandwidth_callback),
+ network_link_rtcp_observer_(config.network_link_rtcp_observer),
rtcp_intra_frame_observer_(config.intra_frame_callback),
rtcp_loss_notification_observer_(config.rtcp_loss_notification_observer),
network_state_estimate_observer_(config.network_state_estimate_observer),
- transport_feedback_observer_(config.transport_feedback_callback),
+ deprecated_transport_feedback_observer_(
+ config.transport_feedback_callback),
bitrate_allocation_observer_(config.bitrate_allocation_observer),
report_interval_(config.rtcp_report_interval_ms > 0
? TimeDelta::Millis(config.rtcp_report_interval_ms)
@@ -652,7 +656,7 @@
rtts_[remote_ssrc].AddRtt(rtt);
}
- packet_information->rtt_ms = rtt.ms();
+ packet_information->rtt = rtt;
}
packet_information->report_blocks.push_back(
@@ -1091,9 +1095,12 @@
// invalid RTCP.
return;
}
-
- packet_information->packet_type_flags |= kRtcpTransportFeedback;
- packet_information->transport_feedback = std::move(transport_feedback);
+ uint32_t media_source_ssrc = transport_feedback->media_ssrc();
+ if (media_source_ssrc == local_media_ssrc() ||
+ registered_ssrcs_.contains(media_source_ssrc)) {
+ packet_information->packet_type_flags |= kRtcpTransportFeedback;
+ packet_information->transport_feedback = std::move(transport_feedback);
+ }
}
void RTCPReceiver::NotifyTmmbrUpdated() {
@@ -1101,11 +1108,19 @@
std::vector<rtcp::TmmbItem> bounding =
TMMBRHelp::FindBoundingSet(TmmbrReceived());
- if (!bounding.empty() && rtcp_bandwidth_observer_) {
+ if (!bounding.empty()) {
// We have a new bandwidth estimate on this channel.
uint64_t bitrate_bps = TMMBRHelp::CalcMinBitrateBps(bounding);
- if (bitrate_bps <= std::numeric_limits<uint32_t>::max())
- rtcp_bandwidth_observer_->OnReceivedEstimatedBitrate(bitrate_bps);
+ if (deprecated_rtcp_bandwidth_observer_ &&
+ bitrate_bps <= std::numeric_limits<uint32_t>::max()) {
+ deprecated_rtcp_bandwidth_observer_->OnReceivedEstimatedBitrate(
+ bitrate_bps);
+ }
+ if (network_link_rtcp_observer_ &&
+ bitrate_bps < std::numeric_limits<int64_t>::max()) {
+ network_link_rtcp_observer_->OnReceiverEstimatedMaxBitrate(
+ clock_->CurrentTime(), DataRate::BitsPerSec(bitrate_bps));
+ }
}
// Send tmmbn to inform remote clients about the new bandwidth.
@@ -1164,36 +1179,53 @@
loss_notification->decodability_flag());
}
}
- if (rtcp_bandwidth_observer_) {
+ if (deprecated_rtcp_bandwidth_observer_) {
RTC_DCHECK(!receiver_only_);
if (packet_information.packet_type_flags & kRtcpRemb) {
RTC_LOG(LS_VERBOSE)
<< "Incoming REMB: "
<< packet_information.receiver_estimated_max_bitrate_bps;
- rtcp_bandwidth_observer_->OnReceivedEstimatedBitrate(
+ deprecated_rtcp_bandwidth_observer_->OnReceivedEstimatedBitrate(
packet_information.receiver_estimated_max_bitrate_bps);
}
if ((packet_information.packet_type_flags & kRtcpSr) ||
(packet_information.packet_type_flags & kRtcpRr)) {
- int64_t now_ms = clock_->TimeInMilliseconds();
- rtcp_bandwidth_observer_->OnReceivedRtcpReceiverReport(
- packet_information.report_blocks, packet_information.rtt_ms, now_ms);
+ deprecated_rtcp_bandwidth_observer_->OnReceivedRtcpReceiverReport(
+ packet_information.report_blocks,
+ packet_information.rtt.value_or(TimeDelta::Zero()).ms(),
+ clock_->TimeInMilliseconds());
}
}
+
+ if (network_link_rtcp_observer_) {
+ Timestamp now = clock_->CurrentTime();
+ if (packet_information.packet_type_flags & kRtcpRemb) {
+ network_link_rtcp_observer_->OnReceiverEstimatedMaxBitrate(
+ now, DataRate::BitsPerSec(
+ packet_information.receiver_estimated_max_bitrate_bps));
+ }
+ if (!packet_information.report_block_datas.empty()) {
+ network_link_rtcp_observer_->OnReport(
+ now, packet_information.report_block_datas);
+ }
+ if (packet_information.rtt.has_value()) {
+ network_link_rtcp_observer_->OnRttUpdate(now, *packet_information.rtt);
+ }
+ if (packet_information.transport_feedback != nullptr) {
+ network_link_rtcp_observer_->OnTransportFeedback(
+ now, *packet_information.transport_feedback);
+ }
+ }
+
if ((packet_information.packet_type_flags & kRtcpSr) ||
(packet_information.packet_type_flags & kRtcpRr)) {
rtp_rtcp_->OnReceivedRtcpReportBlocks(packet_information.report_blocks);
}
- if (transport_feedback_observer_ &&
+ if (deprecated_transport_feedback_observer_ &&
(packet_information.packet_type_flags & kRtcpTransportFeedback)) {
- uint32_t media_source_ssrc =
- packet_information.transport_feedback->media_ssrc();
- if (media_source_ssrc == local_media_ssrc() ||
- registered_ssrcs_.contains(media_source_ssrc)) {
- transport_feedback_observer_->OnTransportFeedback(
- *packet_information.transport_feedback);
- }
+ deprecated_transport_feedback_observer_->OnTransportFeedback(
+ *packet_information.transport_feedback);
}
if (network_state_estimate_observer_ &&
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.h b/modules/rtp_rtcp/source/rtcp_receiver.h
index 2def970..c0fcc86 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.h
+++ b/modules/rtp_rtcp/source/rtcp_receiver.h
@@ -365,11 +365,12 @@
// The set of registered local SSRCs.
RegisteredSsrcs registered_ssrcs_;
- RtcpBandwidthObserver* const rtcp_bandwidth_observer_;
+ RtcpBandwidthObserver* const deprecated_rtcp_bandwidth_observer_;
+ NetworkLinkRtcpObserver* const network_link_rtcp_observer_;
RtcpIntraFrameObserver* const rtcp_intra_frame_observer_;
RtcpLossNotificationObserver* const rtcp_loss_notification_observer_;
NetworkStateEstimateObserver* const network_state_estimate_observer_;
- TransportFeedbackObserver* const transport_feedback_observer_;
+ TransportFeedbackObserver* const deprecated_transport_feedback_observer_;
VideoBitrateAllocationObserver* const bitrate_allocation_observer_;
const TimeDelta report_interval_;
diff --git a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
index 9cfc881..07fc96c 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
@@ -20,6 +20,7 @@
#include "api/video/video_bitrate_allocation.h"
#include "api/video/video_bitrate_allocator.h"
#include "modules/rtp_rtcp/include/report_block_data.h"
+#include "modules/rtp_rtcp/mocks/mock_network_link_rtcp_observer.h"
#include "modules/rtp_rtcp/mocks/mock_rtcp_bandwidth_observer.h"
#include "modules/rtp_rtcp/source/byte_io.h"
#include "modules/rtp_rtcp/source/rtcp_packet.h"
@@ -54,6 +55,7 @@
using ::testing::ElementsAreArray;
using ::testing::Eq;
using ::testing::Field;
+using ::testing::Gt;
using ::testing::InSequence;
using ::testing::IsEmpty;
using ::testing::NiceMock;
@@ -154,6 +156,7 @@
StrictMock<MockTransportFeedbackObserver> transport_feedback_observer;
StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer;
StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl;
+ NiceMock<MockNetworkLinkRtcpObserver> network_link_rtcp_observer;
};
RtpRtcpInterface::Configuration DefaultConfiguration(ReceiverMocks* mocks) {
@@ -549,11 +552,49 @@
kSequenceNumbers[1]))));
}
+TEST(RtcpReceiverTest, NotifiesNetworkLinkObserverOnReportBlocks) {
+ ReceiverMocks mocks;
+ RtpRtcpInterface::Configuration config = DefaultConfiguration(&mocks);
+ config.bandwidth_callback = nullptr;
+ config.transport_feedback_callback = nullptr;
+ config.network_link_rtcp_observer = &mocks.network_link_rtcp_observer;
+ RTCPReceiver receiver(config, &mocks.rtp_rtcp_impl);
+ receiver.SetRemoteSSRC(kSenderSsrc);
+
+ rtcp::ReportBlock rb1;
+ rb1.SetMediaSsrc(kReceiverMainSsrc);
+ rb1.SetFractionLost(10);
+
+ rtcp::ReportBlock rb2;
+ rb2.SetMediaSsrc(kNotToUsSsrc);
+ rb2.SetFractionLost(20);
+
+ rtcp::ReportBlock rb3;
+ rb3.SetMediaSsrc(kReceiverExtraSsrc);
+ rb3.SetFractionLost(0);
+
+ rtcp::ReceiverReport rr;
+ rr.SetSenderSsrc(kSenderSsrc);
+ rr.AddReportBlock(rb1);
+ rr.AddReportBlock(rb2);
+ rr.AddReportBlock(rb3);
+
+ EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks(SizeIs(2)));
+ EXPECT_CALL(mocks.network_link_rtcp_observer,
+ OnReport(mocks.clock.CurrentTime(),
+ UnorderedElementsAre(
+ Property(&ReportBlockData::fraction_lost_raw, 0),
+ Property(&ReportBlockData::fraction_lost_raw, 10))));
+ receiver.IncomingPacket(rr.Build());
+}
+
TEST(RtcpReceiverTest, GetRtt) {
const uint32_t kSentCompactNtp = 0x1234;
const uint32_t kDelayCompactNtp = 0x222;
ReceiverMocks mocks;
- RTCPReceiver receiver(DefaultConfiguration(&mocks), &mocks.rtp_rtcp_impl);
+ RtpRtcpInterface::Configuration config = DefaultConfiguration(&mocks);
+ config.network_link_rtcp_observer = &mocks.network_link_rtcp_observer;
+ RTCPReceiver receiver(config, &mocks.rtp_rtcp_impl);
receiver.SetRemoteSSRC(kSenderSsrc);
// No report block received.
@@ -567,13 +608,15 @@
rtcp::ReceiverReport rr;
rr.SetSenderSsrc(kSenderSsrc);
rr.AddReportBlock(rb);
- int64_t now = mocks.clock.TimeInMilliseconds();
+ Timestamp now = mocks.clock.CurrentTime();
EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
EXPECT_CALL(mocks.bandwidth_observer, OnReceivedRtcpReceiverReport);
+ EXPECT_CALL(mocks.network_link_rtcp_observer,
+ OnRttUpdate(now, Gt(TimeDelta::Zero())));
receiver.IncomingPacket(rr.Build());
- EXPECT_EQ(now, receiver.LastReceivedReportBlockMs());
+ EXPECT_EQ(receiver.LastReceivedReportBlockMs(), now.ms());
EXPECT_EQ(0, receiver.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
}
@@ -1755,6 +1798,72 @@
receiver.IncomingPacket(packet.Build());
}
+TEST(RtcpReceiverTest, NotifiesNetworkLinkObserverOnTransportFeedback) {
+ ReceiverMocks mocks;
+ RtpRtcpInterface::Configuration config = DefaultConfiguration(&mocks);
+ config.bandwidth_callback = nullptr;
+ config.transport_feedback_callback = nullptr;
+ config.network_link_rtcp_observer = &mocks.network_link_rtcp_observer;
+ RTCPReceiver receiver(config, &mocks.rtp_rtcp_impl);
+ receiver.SetRemoteSSRC(kSenderSsrc);
+
+ rtcp::TransportFeedback packet;
+ packet.SetMediaSsrc(config.local_media_ssrc);
+ packet.SetSenderSsrc(kSenderSsrc);
+ packet.SetBase(123, Timestamp::Millis(1));
+ packet.AddReceivedPacket(123, Timestamp::Millis(1));
+
+ EXPECT_CALL(
+ mocks.network_link_rtcp_observer,
+ OnTransportFeedback(
+ mocks.clock.CurrentTime(),
+ AllOf(Property(&rtcp::TransportFeedback::GetBaseSequence, 123),
+ Property(&rtcp::TransportFeedback::GetReceivedPackets,
+ SizeIs(1)))));
+
+ receiver.IncomingPacket(packet.Build());
+}
+
+TEST(RtcpReceiverTest,
+ NotifiesNetworkLinkObserverOnTransportFeedbackOnRtxSsrc) {
+ ReceiverMocks mocks;
+ RtpRtcpInterface::Configuration config = DefaultConfiguration(&mocks);
+ config.bandwidth_callback = nullptr;
+ config.transport_feedback_callback = nullptr;
+ config.network_link_rtcp_observer = &mocks.network_link_rtcp_observer;
+ RTCPReceiver receiver(config, &mocks.rtp_rtcp_impl);
+ receiver.SetRemoteSSRC(kSenderSsrc);
+
+ rtcp::TransportFeedback packet;
+ packet.SetMediaSsrc(*config.rtx_send_ssrc);
+ packet.SetSenderSsrc(kSenderSsrc);
+ packet.SetBase(1, Timestamp::Millis(1));
+ packet.AddReceivedPacket(1, Timestamp::Millis(1));
+
+ EXPECT_CALL(mocks.network_link_rtcp_observer, OnTransportFeedback);
+ receiver.IncomingPacket(packet.Build());
+}
+
+TEST(RtcpReceiverTest,
+ DoesNotNotifyNetworkLinkObserverOnTransportFeedbackForUnregistedSsrc) {
+ ReceiverMocks mocks;
+ RtpRtcpInterface::Configuration config = DefaultConfiguration(&mocks);
+ config.bandwidth_callback = nullptr;
+ config.transport_feedback_callback = nullptr;
+ config.network_link_rtcp_observer = &mocks.network_link_rtcp_observer;
+ RTCPReceiver receiver(config, &mocks.rtp_rtcp_impl);
+ receiver.SetRemoteSSRC(kSenderSsrc);
+
+ rtcp::TransportFeedback packet;
+ packet.SetMediaSsrc(kNotToUsSsrc);
+ packet.SetSenderSsrc(kSenderSsrc);
+ packet.SetBase(1, Timestamp::Millis(1));
+ packet.AddReceivedPacket(1, Timestamp::Millis(1));
+
+ EXPECT_CALL(mocks.network_link_rtcp_observer, OnTransportFeedback).Times(0);
+ receiver.IncomingPacket(packet.Build());
+}
+
TEST(RtcpReceiverTest, ReceivesRemb) {
ReceiverMocks mocks;
RTCPReceiver receiver(DefaultConfiguration(&mocks), &mocks.rtp_rtcp_impl);
@@ -1770,6 +1879,25 @@
receiver.IncomingPacket(remb.Build());
}
+TEST(RtcpReceiverTest, NotifiesNetworkLinkObserverOnRemb) {
+ ReceiverMocks mocks;
+ RtpRtcpInterface::Configuration config = DefaultConfiguration(&mocks);
+ config.bandwidth_callback = nullptr;
+ config.transport_feedback_callback = nullptr;
+ config.network_link_rtcp_observer = &mocks.network_link_rtcp_observer;
+ RTCPReceiver receiver(config, &mocks.rtp_rtcp_impl);
+ receiver.SetRemoteSSRC(kSenderSsrc);
+
+ rtcp::Remb remb;
+ remb.SetSenderSsrc(kSenderSsrc);
+ remb.SetBitrateBps(500'000);
+
+ EXPECT_CALL(mocks.network_link_rtcp_observer,
+ OnReceiverEstimatedMaxBitrate(mocks.clock.CurrentTime(),
+ DataRate::BitsPerSec(500'000)));
+ receiver.IncomingPacket(remb.Build());
+}
+
TEST(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
ReceiverMocks mocks;
RTCPReceiver receiver(DefaultConfiguration(&mocks), &mocks.rtp_rtcp_impl);
diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_config.h b/modules/rtp_rtcp/source/rtcp_transceiver_config.h
index fbaa917..62efa79 100644
--- a/modules/rtp_rtcp/source/rtcp_transceiver_config.h
+++ b/modules/rtp_rtcp/source/rtcp_transceiver_config.h
@@ -16,13 +16,11 @@
#include "api/array_view.h"
#include "api/rtp_headers.h"
#include "api/task_queue/task_queue_base.h"
-#include "api/units/data_rate.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "api/video/video_bitrate_allocation.h"
#include "modules/rtp_rtcp/include/report_block_data.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
-#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "system_wrappers/include/clock.h"
#include "system_wrappers/include/ntp_time.h"
@@ -30,27 +28,6 @@
class ReceiveStatisticsProvider;
class Transport;
-// Interface to watch incoming rtcp packets related to the link in general.
-// All message handlers have default empty implementation. This way users only
-// need to implement the ones they are interested in.
-// All message handles pass `receive_time` parameter, which is receive time
-// of the rtcp packet that triggered the update.
-class NetworkLinkRtcpObserver {
- public:
- virtual ~NetworkLinkRtcpObserver() = default;
-
- virtual void OnTransportFeedback(Timestamp receive_time,
- const rtcp::TransportFeedback& feedback) {}
- virtual void OnReceiverEstimatedMaxBitrate(Timestamp receive_time,
- DataRate bitrate) {}
-
- // Called on an RTCP packet with sender or receiver reports with non zero
- // report blocks. Report blocks are combined from all reports into one array.
- virtual void OnReport(Timestamp receive_time,
- rtc::ArrayView<const ReportBlockData> report_blocks) {}
- virtual void OnRttUpdate(Timestamp receive_time, TimeDelta rtt) {}
-};
-
// Interface to watch incoming rtcp packets by media (rtp) receiver.
// All message handlers have default empty implementation. This way users only
// need to implement the ones they are interested in.
diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
index bc54d9a..bcd9e02 100644
--- a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
+++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc
@@ -30,6 +30,7 @@
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
#include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "modules/rtp_rtcp/source/time_util.h"
#include "rtc_base/checks.h"
#include "rtc_base/containers/flat_map.h"
diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc b/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc
index 533e2d6..51b6988 100644
--- a/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc
@@ -24,6 +24,7 @@
#include "api/video/video_bitrate_allocation.h"
#include "modules/rtp_rtcp/include/receive_statistics.h"
#include "modules/rtp_rtcp/include/report_block_data.h"
+#include "modules/rtp_rtcp/mocks/mock_network_link_rtcp_observer.h"
#include "modules/rtp_rtcp/mocks/mock_rtcp_rtt_stats.h"
#include "modules/rtp_rtcp/source/rtcp_packet/app.h"
#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
@@ -96,27 +97,6 @@
int num_calls_ = 0;
};
-class MockNetworkLinkRtcpObserver : public NetworkLinkRtcpObserver {
- public:
- MOCK_METHOD(void,
- OnRttUpdate,
- (Timestamp receive_time, TimeDelta rtt),
- (override));
- MOCK_METHOD(void,
- OnTransportFeedback,
- (Timestamp receive_time, const rtcp::TransportFeedback& feedback),
- (override));
- MOCK_METHOD(void,
- OnReceiverEstimatedMaxBitrate,
- (Timestamp receive_time, DataRate bitrate),
- (override));
- MOCK_METHOD(void,
- OnReport,
- (Timestamp receive_time,
- rtc::ArrayView<const ReportBlockData> report_blocks),
- (override));
-};
-
constexpr TimeDelta kReportPeriod = TimeDelta::Seconds(1);
constexpr TimeDelta kAlmostForever = TimeDelta::Seconds(2);
constexpr TimeDelta kTimePrecision = TimeDelta::Millis(1);
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_interface.h b/modules/rtp_rtcp/source/rtp_rtcp_interface.h
index ebd16ee..6e62bf8 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_interface.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_interface.h
@@ -71,8 +71,14 @@
// Called when we receive a changed estimate from the receiver of out
// stream.
+ // TODO(bugs.webrtc.org/13757): Deprecated and Remove in favor of
+ // `network_link_rtcp_observer`
RtcpBandwidthObserver* bandwidth_callback = nullptr;
+ // Called when receive an RTCP message related to the link in general, e.g.
+ // bandwidth estimation related message.
+ NetworkLinkRtcpObserver* network_link_rtcp_observer = nullptr;
+
NetworkStateEstimateObserver* network_state_estimate_observer = nullptr;
TransportFeedbackObserver* transport_feedback_callback = nullptr;
VideoBitrateAllocationObserver* bitrate_allocation_observer = nullptr;