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}
This commit is contained in:
parent
53817b8c18
commit
52518633fb
@ -117,6 +117,7 @@ rtc_library("rtp_rtcp_format") {
|
||||
"../../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("fec_test_helper") {
|
||||
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 @@ rtc_library("mock_rtp_rtcp") {
|
||||
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",
|
||||
|
||||
@ -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 @@ class RtcpLossNotificationObserver {
|
||||
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 @@ class RtcpBandwidthObserver {
|
||||
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 @@ class TransportFeedbackObserver {
|
||||
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
|
||||
|
||||
47
modules/rtp_rtcp/mocks/mock_network_link_rtcp_observer.h
Normal file
47
modules/rtp_rtcp/mocks/mock_network_link_rtcp_observer.h
Normal file
@ -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_
|
||||
@ -130,7 +130,7 @@ struct RTCPReceiver::PacketInformation {
|
||||
// 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 @@ RTCPReceiver::RTCPReceiver(const RtpRtcpInterface::Configuration& config,
|
||||
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 @@ RTCPReceiver::RTCPReceiver(const RtpRtcpInterface::Configuration& config,
|
||||
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 @@ void RTCPReceiver::HandleReportBlock(const ReportBlock& report_block,
|
||||
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 @@ void RTCPReceiver::HandleTransportFeedback(
|
||||
// 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 @@ void RTCPReceiver::NotifyTmmbrUpdated() {
|
||||
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 @@ void RTCPReceiver::TriggerCallbacksFromRtcpPacket(
|
||||
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_ &&
|
||||
|
||||
@ -365,11 +365,12 @@ class RTCPReceiver final {
|
||||
// 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_;
|
||||
|
||||
|
||||
@ -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::AllOf;
|
||||
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 @@ struct ReceiverMocks {
|
||||
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 @@ TEST(RtcpReceiverTest,
|
||||
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 @@ TEST(RtcpReceiverTest, GetRtt) {
|
||||
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 @@ TEST(RtcpReceiverTest, ReceivesTransportFeedback) {
|
||||
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 @@ TEST(RtcpReceiverTest, ReceivesRemb) {
|
||||
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);
|
||||
|
||||
@ -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 @@ namespace webrtc {
|
||||
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.
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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 @@ class MockRtpStreamRtcpHandler : public RtpStreamRtcpHandler {
|
||||
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);
|
||||
|
||||
@ -71,8 +71,14 @@ class RtpRtcpInterface : public RtcpFeedbackSenderInterface {
|
||||
|
||||
// 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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user