Refactor RtpVideoSender::SetActiveModules.

Rename RtpVideoSender::SetActiveModules to SetSending to better match
what it does. When a RtpVideoSender::SetSending(true) RTP packets can be
sent on all associcated RTP streams (simulcast streams).

Move registration of RtpRtcpModules to RtpTransportControllerSend to
allow RtpTransportControllerSend to know when there are sending RTP
streams. Purpose is to in later CLs allow RtpTransportControllerSend to
trigger BWE probes.

Bug: webrtc:14928
Change-Id: Ibf6c040b86713cdc4763c4691b7fd794b251eb49
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335961
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41620}
This commit is contained in:
Per K 2024-01-26 11:18:26 +01:00 committed by WebRTC LUCI CQ
parent 9c166e064f
commit 979b6d62a8
10 changed files with 102 additions and 148 deletions

View file

@ -159,6 +159,31 @@ void RtpTransportControllerSend::DestroyRtpVideoSender(
video_rtp_senders_.erase(it); video_rtp_senders_.erase(it);
} }
void RtpTransportControllerSend::RegisterSendingRtpStream(
RtpRtcpInterface& rtp_module) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
// Allow pacer to send packets using this module.
packet_router_.AddSendRtpModule(&rtp_module,
/*remb_candidate=*/true);
}
void RtpTransportControllerSend::DeRegisterSendingRtpStream(
RtpRtcpInterface& rtp_module) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
// Disabling media, remove from packet router map to reduce size and
// prevent any stray packets in the pacer from asynchronously arriving
// to a disabled module.
packet_router_.RemoveSendRtpModule(&rtp_module);
// Clear the pacer queue of any packets pertaining to this module.
pacer_.RemovePacketsForSsrc(rtp_module.SSRC());
if (rtp_module.RtxSsrc().has_value()) {
pacer_.RemovePacketsForSsrc(*rtp_module.RtxSsrc());
}
if (rtp_module.FlexfecSsrc().has_value()) {
pacer_.RemovePacketsForSsrc(*rtp_module.FlexfecSsrc());
}
}
void RtpTransportControllerSend::UpdateControlState() { void RtpTransportControllerSend::UpdateControlState() {
absl::optional<TargetTransferRate> update = control_handler_->GetUpdate(); absl::optional<TargetTransferRate> update = control_handler_->GetUpdate();
if (!update) if (!update)

View file

@ -75,6 +75,8 @@ class RtpTransportControllerSend final
RtpVideoSenderInterface* rtp_video_sender) override; RtpVideoSenderInterface* rtp_video_sender) override;
// Implements RtpTransportControllerSendInterface // Implements RtpTransportControllerSendInterface
void RegisterSendingRtpStream(RtpRtcpInterface& rtp_module) override;
void DeRegisterSendingRtpStream(RtpRtcpInterface& rtp_module) override;
PacketRouter* packet_router() override; PacketRouter* packet_router() override;
NetworkStateEstimateObserver* network_state_estimate_observer() override; NetworkStateEstimateObserver* network_state_estimate_observer() override;

View file

@ -47,6 +47,7 @@ class Transport;
class PacketRouter; class PacketRouter;
class RtpVideoSenderInterface; class RtpVideoSenderInterface;
class RtpPacketSender; class RtpPacketSender;
class RtpRtcpInterface;
struct RtpSenderObservers { struct RtpSenderObservers {
RtcpRttStats* rtcp_rtt_stats; RtcpRttStats* rtcp_rtt_stats;
@ -108,6 +109,12 @@ class RtpTransportControllerSendInterface {
virtual void DestroyRtpVideoSender( virtual void DestroyRtpVideoSender(
RtpVideoSenderInterface* rtp_video_sender) = 0; RtpVideoSenderInterface* rtp_video_sender) = 0;
// Register a specific RTP stream as sending. This means that the pacer and
// packet router can send packets using this RTP stream.
virtual void RegisterSendingRtpStream(RtpRtcpInterface& rtp_module) = 0;
// Pacer and PacketRouter stop using this RTP stream.
virtual void DeRegisterSendingRtpStream(RtpRtcpInterface& rtp_module) = 0;
virtual NetworkStateEstimateObserver* network_state_estimate_observer() = 0; virtual NetworkStateEstimateObserver* network_state_estimate_observer() = 0;
virtual TransportFeedbackObserver* transport_feedback_observer() = 0; virtual TransportFeedbackObserver* transport_feedback_observer() = 0;

View file

@ -470,85 +470,41 @@ RtpVideoSender::RtpVideoSender(
} }
RtpVideoSender::~RtpVideoSender() { RtpVideoSender::~RtpVideoSender() {
// TODO(bugs.webrtc.org/13517): Remove once RtpVideoSender gets deleted on the RTC_DCHECK_RUN_ON(&transport_checker_);
// transport task queue.
transport_checker_.Detach();
SetActiveModulesLocked( SetActiveModulesLocked(
std::vector<bool>(rtp_streams_.size(), /*active=*/false)); /*sending=*/false);
RTC_DCHECK(!registered_for_feedback_);
} }
void RtpVideoSender::Stop() { void RtpVideoSender::SetSending(bool enabled) {
RTC_DCHECK_RUN_ON(&transport_checker_); RTC_DCHECK_RUN_ON(&transport_checker_);
MutexLock lock(&mutex_); MutexLock lock(&mutex_);
if (!active_) if (enabled == active_) {
return; return;
}
const std::vector<bool> active_modules(rtp_streams_.size(), false); SetActiveModulesLocked(/*sending=*/enabled);
SetActiveModulesLocked(active_modules);
} }
void RtpVideoSender::SetActiveModules(const std::vector<bool>& active_modules) { void RtpVideoSender::SetActiveModulesLocked(bool sending) {
RTC_DCHECK_RUN_ON(&transport_checker_); RTC_DCHECK_RUN_ON(&transport_checker_);
MutexLock lock(&mutex_); if (active_ == sending) {
return SetActiveModulesLocked(active_modules); return;
} }
active_ = sending;
void RtpVideoSender::SetActiveModulesLocked( for (size_t i = 0; i < rtp_streams_.size(); ++i) {
const std::vector<bool>& active_modules) {
RTC_DCHECK_RUN_ON(&transport_checker_);
RTC_CHECK_EQ(rtp_streams_.size(), active_modules.size());
active_ = false;
for (size_t i = 0; i < active_modules.size(); ++i) {
if (active_modules[i]) {
active_ = true;
}
RtpRtcpInterface& rtp_module = *rtp_streams_[i].rtp_rtcp; RtpRtcpInterface& rtp_module = *rtp_streams_[i].rtp_rtcp;
const bool was_active = rtp_module.Sending(); rtp_module.SetSendingStatus(sending);
const bool should_be_active = active_modules[i]; rtp_module.SetSendingMediaStatus(sending);
if (sending) {
rtp_module.SetSendingStatus(active_modules[i]); transport_->RegisterSendingRtpStream(rtp_module);
} else {
if (was_active && !should_be_active) { transport_->DeRegisterSendingRtpStream(rtp_module);
// Disabling media, remove from packet router map to reduce size and
// prevent any stray packets in the pacer from asynchronously arriving
// to a disabled module.
transport_->packet_router()->RemoveSendRtpModule(&rtp_module);
// Clear the pacer queue of any packets pertaining to this module.
transport_->packet_sender()->RemovePacketsForSsrc(rtp_module.SSRC());
if (rtp_module.RtxSsrc().has_value()) {
transport_->packet_sender()->RemovePacketsForSsrc(
*rtp_module.RtxSsrc());
}
if (rtp_module.FlexfecSsrc().has_value()) {
transport_->packet_sender()->RemovePacketsForSsrc(
*rtp_module.FlexfecSsrc());
}
}
// If set to false this module won't send media.
rtp_module.SetSendingMediaStatus(active_modules[i]);
if (!was_active && should_be_active) {
// Turning on media, register with packet router.
transport_->packet_router()->AddSendRtpModule(&rtp_module,
/*remb_candidate=*/true);
} }
} }
if (!active_) { auto* feedback_provider = transport_->GetStreamFeedbackProvider();
auto* feedback_provider = transport_->GetStreamFeedbackProvider(); if (!sending) {
if (registered_for_feedback_) { feedback_provider->DeRegisterStreamFeedbackObserver(this);
feedback_provider->DeRegisterStreamFeedbackObserver(this); } else {
registered_for_feedback_ = false;
}
} else if (!registered_for_feedback_) {
auto* feedback_provider = transport_->GetStreamFeedbackProvider();
feedback_provider->RegisterStreamFeedbackObserver(rtp_config_.ssrcs, this); feedback_provider->RegisterStreamFeedbackObserver(rtp_config_.ssrcs, this);
registered_for_feedback_ = true;
} }
} }

View file

@ -95,11 +95,7 @@ class RtpVideoSender : public RtpVideoSenderInterface,
RtpVideoSender(const RtpVideoSender&) = delete; RtpVideoSender(const RtpVideoSender&) = delete;
RtpVideoSender& operator=(const RtpVideoSender&) = delete; RtpVideoSender& operator=(const RtpVideoSender&) = delete;
// Sets the sending status of the rtp modules and appropriately sets the void SetSending(bool enabled) RTC_LOCKS_EXCLUDED(mutex_) override;
// payload router to active if any rtp modules are active.
void SetActiveModules(const std::vector<bool>& active_modules)
RTC_LOCKS_EXCLUDED(mutex_) override;
void Stop() RTC_LOCKS_EXCLUDED(mutex_) override;
bool IsActive() RTC_LOCKS_EXCLUDED(mutex_) override; bool IsActive() RTC_LOCKS_EXCLUDED(mutex_) override;
void OnNetworkAvailability(bool network_available) void OnNetworkAvailability(bool network_available)
@ -160,7 +156,7 @@ class RtpVideoSender : public RtpVideoSenderInterface,
private: private:
bool IsActiveLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); bool IsActiveLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void SetActiveModulesLocked(const std::vector<bool>& active_modules) void SetActiveModulesLocked(bool sending)
RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void UpdateModuleSendingState() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); void UpdateModuleSendingState() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void ConfigureProtection(); void ConfigureProtection();
@ -184,7 +180,6 @@ class RtpVideoSender : public RtpVideoSenderInterface,
// transport task queue. // transport task queue.
mutable Mutex mutex_; mutable Mutex mutex_;
bool active_ RTC_GUARDED_BY(mutex_); bool active_ RTC_GUARDED_BY(mutex_);
bool registered_for_feedback_ RTC_GUARDED_BY(transport_checker_) = false;
const std::unique_ptr<FecController> fec_controller_; const std::unique_ptr<FecController> fec_controller_;
bool fec_allowed_ RTC_GUARDED_BY(mutex_); bool fec_allowed_ RTC_GUARDED_BY(mutex_);

View file

@ -31,12 +31,8 @@ struct FecProtectionParams;
class RtpVideoSenderInterface : public EncodedImageCallback, class RtpVideoSenderInterface : public EncodedImageCallback,
public FecControllerOverride { public FecControllerOverride {
public: public:
// Sets the sending status of the rtp modules and appropriately sets the // Sets weather or not RTP packets is allowed to be sent on this sender.
// RtpVideoSender to active if any rtp modules are active. virtual void SetSending(bool enabled) = 0;
// A module will only send packet if beeing active.
virtual void SetActiveModules(const std::vector<bool>& active_modules) = 0;
// Set the sending status of all rtp modules to inactive.
virtual void Stop() = 0;
virtual bool IsActive() = 0; virtual bool IsActive() = 0;
virtual void OnNetworkAvailability(bool network_available) = 0; virtual void OnNetworkAvailability(bool network_available) = 0;

View file

@ -180,17 +180,13 @@ class RtpVideoSenderTestFixture {
/*frame_transformer=*/nullptr, /*frame_transformer=*/nullptr,
field_trials) {} field_trials) {}
~RtpVideoSenderTestFixture() { Stop(); } ~RtpVideoSenderTestFixture() { SetSending(false); }
RtpVideoSender* router() { return router_.get(); } RtpVideoSender* router() { return router_.get(); }
MockTransport& transport() { return transport_; } MockTransport& transport() { return transport_; }
void AdvanceTime(TimeDelta delta) { time_controller_.AdvanceTime(delta); } void AdvanceTime(TimeDelta delta) { time_controller_.AdvanceTime(delta); }
void Stop() { router_->Stop(); } void SetSending(bool sending) { router_->SetSending(sending); }
void SetActiveModules(const std::vector<bool>& active_modules) {
router_->SetActiveModules(active_modules);
}
private: private:
test::ScopedKeyValueConfig field_trials_; test::ScopedKeyValueConfig field_trials_;
@ -227,20 +223,20 @@ TEST(RtpVideoSenderTest, SendOnOneModule) {
EXPECT_NE(EncodedImageCallback::Result::OK, EXPECT_NE(EncodedImageCallback::Result::OK,
test.router()->OnEncodedImage(encoded_image, nullptr).error); test.router()->OnEncodedImage(encoded_image, nullptr).error);
test.SetActiveModules({true}); test.SetSending(true);
EXPECT_EQ(EncodedImageCallback::Result::OK, EXPECT_EQ(EncodedImageCallback::Result::OK,
test.router()->OnEncodedImage(encoded_image, nullptr).error); test.router()->OnEncodedImage(encoded_image, nullptr).error);
test.SetActiveModules({false}); test.SetSending(false);
EXPECT_NE(EncodedImageCallback::Result::OK, EXPECT_NE(EncodedImageCallback::Result::OK,
test.router()->OnEncodedImage(encoded_image, nullptr).error); test.router()->OnEncodedImage(encoded_image, nullptr).error);
test.SetActiveModules({true}); test.SetSending(true);
EXPECT_EQ(EncodedImageCallback::Result::OK, EXPECT_EQ(EncodedImageCallback::Result::OK,
test.router()->OnEncodedImage(encoded_image, nullptr).error); test.router()->OnEncodedImage(encoded_image, nullptr).error);
} }
TEST(RtpVideoSenderTest, SendSimulcastSetActive) { TEST(RtpVideoSenderTest, OnEncodedImageReturnOkWhenSendingTrue) {
constexpr uint8_t kPayload = 'a'; constexpr uint8_t kPayload = 'a';
EncodedImage encoded_image_1; EncodedImage encoded_image_1;
encoded_image_1.SetRtpTimestamp(1); encoded_image_1.SetRtpTimestamp(1);
@ -254,7 +250,7 @@ TEST(RtpVideoSenderTest, SendSimulcastSetActive) {
CodecSpecificInfo codec_info; CodecSpecificInfo codec_info;
codec_info.codecType = kVideoCodecVP8; codec_info.codecType = kVideoCodecVP8;
test.SetActiveModules({true, true}); test.SetSending(true);
EXPECT_EQ(EncodedImageCallback::Result::OK, EXPECT_EQ(EncodedImageCallback::Result::OK,
test.router()->OnEncodedImage(encoded_image_1, &codec_info).error); test.router()->OnEncodedImage(encoded_image_1, &codec_info).error);
@ -262,20 +258,9 @@ TEST(RtpVideoSenderTest, SendSimulcastSetActive) {
encoded_image_2.SetSimulcastIndex(1); encoded_image_2.SetSimulcastIndex(1);
EXPECT_EQ(EncodedImageCallback::Result::OK, EXPECT_EQ(EncodedImageCallback::Result::OK,
test.router()->OnEncodedImage(encoded_image_2, &codec_info).error); test.router()->OnEncodedImage(encoded_image_2, &codec_info).error);
// Inactive.
test.Stop();
EXPECT_NE(EncodedImageCallback::Result::OK,
test.router()->OnEncodedImage(encoded_image_1, &codec_info).error);
EXPECT_NE(EncodedImageCallback::Result::OK,
test.router()->OnEncodedImage(encoded_image_2, &codec_info).error);
} }
// Tests how setting individual rtp modules to active affects the overall TEST(RtpVideoSenderTest, OnEncodedImageReturnErrorCodeWhenSendingFalse) {
// behavior of the payload router. First sets one module to active and checks
// that outgoing data can be sent on this module, and checks that no data can
// be sent if both modules are inactive.
TEST(RtpVideoSenderTest, SendSimulcastSetActiveModules) {
constexpr uint8_t kPayload = 'a'; constexpr uint8_t kPayload = 'a';
EncodedImage encoded_image_1; EncodedImage encoded_image_1;
encoded_image_1.SetRtpTimestamp(1); encoded_image_1.SetRtpTimestamp(1);
@ -291,23 +276,15 @@ TEST(RtpVideoSenderTest, SendSimulcastSetActiveModules) {
CodecSpecificInfo codec_info; CodecSpecificInfo codec_info;
codec_info.codecType = kVideoCodecVP8; codec_info.codecType = kVideoCodecVP8;
// Only setting one stream to active will still set the payload router to // Setting rtp streams to inactive will turn the payload router to
// active and allow sending data on the active stream.
std::vector<bool> active_modules({true, false});
test.SetActiveModules(active_modules);
EXPECT_EQ(EncodedImageCallback::Result::OK,
test.router()->OnEncodedImage(encoded_image_1, &codec_info).error);
// Setting both streams to inactive will turn the payload router to
// inactive. // inactive.
active_modules = {false, false}; test.SetSending(false);
test.SetActiveModules(active_modules);
// An incoming encoded image will not ask the module to send outgoing data // An incoming encoded image will not ask the module to send outgoing data
// because the payload router is inactive. // because the payload router is inactive.
EXPECT_NE(EncodedImageCallback::Result::OK, EXPECT_NE(EncodedImageCallback::Result::OK,
test.router()->OnEncodedImage(encoded_image_1, &codec_info).error); test.router()->OnEncodedImage(encoded_image_1, &codec_info).error);
EXPECT_NE(EncodedImageCallback::Result::OK, EXPECT_NE(EncodedImageCallback::Result::OK,
test.router()->OnEncodedImage(encoded_image_1, &codec_info).error); test.router()->OnEncodedImage(encoded_image_2, &codec_info).error);
} }
TEST(RtpVideoSenderTest, TEST(RtpVideoSenderTest,
@ -324,7 +301,7 @@ TEST(RtpVideoSenderTest,
codec_info.codecType = kVideoCodecVP8; codec_info.codecType = kVideoCodecVP8;
RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
kPayloadType, {}); kPayloadType, {});
test.SetActiveModules({true, true}); test.SetSending(true);
// A layer is sent on both rtp streams. // A layer is sent on both rtp streams.
test.router()->OnVideoLayersAllocationUpdated( test.router()->OnVideoLayersAllocationUpdated(
{.active_spatial_layers = {{.rtp_stream_index = 0}, {.active_spatial_layers = {{.rtp_stream_index = 0},
@ -347,7 +324,7 @@ TEST(RtpVideoSenderTest,
TEST(RtpVideoSenderTest, CreateWithNoPreviousStates) { TEST(RtpVideoSenderTest, CreateWithNoPreviousStates) {
RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
kPayloadType, {}); kPayloadType, {});
test.SetActiveModules({true, true}); test.SetSending(true);
std::map<uint32_t, RtpPayloadState> initial_states = std::map<uint32_t, RtpPayloadState> initial_states =
test.router()->GetRtpPayloadStates(); test.router()->GetRtpPayloadStates();
@ -372,7 +349,7 @@ TEST(RtpVideoSenderTest, CreateWithPreviousStates) {
RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
kPayloadType, states); kPayloadType, states);
test.SetActiveModules({true, true}); test.SetSending(true);
std::map<uint32_t, RtpPayloadState> initial_states = std::map<uint32_t, RtpPayloadState> initial_states =
test.router()->GetRtpPayloadStates(); test.router()->GetRtpPayloadStates();
@ -412,7 +389,7 @@ TEST(RtpVideoSenderTest, FrameCountCallbacks) {
test.router()->OnEncodedImage(encoded_image, nullptr).error); test.router()->OnEncodedImage(encoded_image, nullptr).error);
::testing::Mock::VerifyAndClearExpectations(&callback); ::testing::Mock::VerifyAndClearExpectations(&callback);
test.SetActiveModules({true}); test.SetSending(true);
FrameCounts frame_counts; FrameCounts frame_counts;
EXPECT_CALL(callback, FrameCountUpdated(_, kSsrc1)) EXPECT_CALL(callback, FrameCountUpdated(_, kSsrc1))
@ -441,7 +418,7 @@ TEST(RtpVideoSenderTest, FrameCountCallbacks) {
TEST(RtpVideoSenderTest, DoesNotRetrasmitAckedPackets) { TEST(RtpVideoSenderTest, DoesNotRetrasmitAckedPackets) {
RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
kPayloadType, {}); kPayloadType, {});
test.SetActiveModules({true, true}); test.SetSending(true);
constexpr uint8_t kPayload = 'a'; constexpr uint8_t kPayload = 'a';
EncodedImage encoded_image; EncodedImage encoded_image;
@ -606,7 +583,7 @@ TEST(RtpVideoSenderTest, RetransmitsOnTransportWideLossInfo) {
TEST(RtpVideoSenderTest, EarlyRetransmits) { TEST(RtpVideoSenderTest, EarlyRetransmits) {
RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
kPayloadType, {}); kPayloadType, {});
test.SetActiveModules({true, true}); test.SetSending(true);
const uint8_t kPayload[1] = {'a'}; const uint8_t kPayload[1] = {'a'};
EncodedImage encoded_image; EncodedImage encoded_image;
@ -701,7 +678,7 @@ TEST(RtpVideoSenderTest, EarlyRetransmits) {
TEST(RtpVideoSenderTest, SupportsDependencyDescriptor) { TEST(RtpVideoSenderTest, SupportsDependencyDescriptor) {
RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}); RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {});
test.SetActiveModules({true}); test.SetSending(true);
RtpHeaderExtensionMap extensions; RtpHeaderExtensionMap extensions;
extensions.Register<RtpDependencyDescriptorExtension>( extensions.Register<RtpDependencyDescriptorExtension>(
@ -773,7 +750,7 @@ TEST(RtpVideoSenderTest,
EXPECT_TRUE(sent_packets.emplace_back(&extensions).Parse(packet)); EXPECT_TRUE(sent_packets.emplace_back(&extensions).Parse(packet));
return true; return true;
}); });
test.SetActiveModules({true}); test.SetSending(true);
EncodedImage key_frame_image; EncodedImage key_frame_image;
key_frame_image._frameType = VideoFrameType::kVideoFrameKey; key_frame_image._frameType = VideoFrameType::kVideoFrameKey;
@ -807,7 +784,7 @@ TEST(RtpVideoSenderTest,
TEST(RtpVideoSenderTest, SupportsDependencyDescriptorForVp9) { TEST(RtpVideoSenderTest, SupportsDependencyDescriptorForVp9) {
RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}); RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {});
test.SetActiveModules({true}); test.SetSending(true);
RtpHeaderExtensionMap extensions; RtpHeaderExtensionMap extensions;
extensions.Register<RtpDependencyDescriptorExtension>( extensions.Register<RtpDependencyDescriptorExtension>(
@ -863,7 +840,7 @@ TEST(RtpVideoSenderTest, SupportsDependencyDescriptorForVp9) {
TEST(RtpVideoSenderTest, TEST(RtpVideoSenderTest,
SupportsDependencyDescriptorForVp9NotProvidedByEncoder) { SupportsDependencyDescriptorForVp9NotProvidedByEncoder) {
RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}); RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {});
test.SetActiveModules({true}); test.SetSending(true);
RtpHeaderExtensionMap extensions; RtpHeaderExtensionMap extensions;
extensions.Register<RtpDependencyDescriptorExtension>( extensions.Register<RtpDependencyDescriptorExtension>(
@ -918,7 +895,7 @@ TEST(RtpVideoSenderTest, GenerateDependecyDescriptorForGenericCodecs) {
test::ScopedKeyValueConfig field_trials( test::ScopedKeyValueConfig field_trials(
"WebRTC-GenericCodecDependencyDescriptor/Enabled/"); "WebRTC-GenericCodecDependencyDescriptor/Enabled/");
RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}, &field_trials); RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}, &field_trials);
test.SetActiveModules({true}); test.SetSending(true);
RtpHeaderExtensionMap extensions; RtpHeaderExtensionMap extensions;
extensions.Register<RtpDependencyDescriptorExtension>( extensions.Register<RtpDependencyDescriptorExtension>(
@ -964,7 +941,7 @@ TEST(RtpVideoSenderTest, GenerateDependecyDescriptorForGenericCodecs) {
TEST(RtpVideoSenderTest, SupportsStoppingUsingDependencyDescriptor) { TEST(RtpVideoSenderTest, SupportsStoppingUsingDependencyDescriptor) {
RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}); RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {});
test.SetActiveModules({true}); test.SetSending(true);
RtpHeaderExtensionMap extensions; RtpHeaderExtensionMap extensions;
extensions.Register<RtpDependencyDescriptorExtension>( extensions.Register<RtpDependencyDescriptorExtension>(
@ -1049,7 +1026,7 @@ TEST(RtpVideoSenderTest, OverheadIsSubtractedFromTargetBitrate) {
kRtpHeaderSizeBytes + kTransportPacketOverheadBytes; kRtpHeaderSizeBytes + kTransportPacketOverheadBytes;
RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}, &field_trials); RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}, &field_trials);
test.router()->OnTransportOverheadChanged(kTransportPacketOverheadBytes); test.router()->OnTransportOverheadChanged(kTransportPacketOverheadBytes);
test.SetActiveModules({true}); test.SetSending(true);
{ {
test.router()->OnBitrateUpdated(CreateBitrateAllocationUpdate(300000), test.router()->OnBitrateUpdated(CreateBitrateAllocationUpdate(300000),
@ -1076,7 +1053,7 @@ TEST(RtpVideoSenderTest, OverheadIsSubtractedFromTargetBitrate) {
TEST(RtpVideoSenderTest, ClearsPendingPacketsOnInactivation) { TEST(RtpVideoSenderTest, ClearsPendingPacketsOnInactivation) {
RtpVideoSenderTestFixture test({kSsrc1}, {kRtxSsrc1}, kPayloadType, {}); RtpVideoSenderTestFixture test({kSsrc1}, {kRtxSsrc1}, kPayloadType, {});
test.SetActiveModules({true}); test.SetSending(true);
RtpHeaderExtensionMap extensions; RtpHeaderExtensionMap extensions;
extensions.Register<RtpDependencyDescriptorExtension>( extensions.Register<RtpDependencyDescriptorExtension>(
@ -1127,13 +1104,13 @@ TEST(RtpVideoSenderTest, ClearsPendingPacketsOnInactivation) {
// Disable the sending module and advance time slightly. No packets should be // Disable the sending module and advance time slightly. No packets should be
// sent. // sent.
test.SetActiveModules({false}); test.SetSending(false);
test.AdvanceTime(TimeDelta::Millis(20)); test.AdvanceTime(TimeDelta::Millis(20));
EXPECT_TRUE(sent_packets.empty()); EXPECT_TRUE(sent_packets.empty());
// Reactive the send module - any packets should have been removed, so nothing // Reactive the send module - any packets should have been removed, so nothing
// should be transmitted. // should be transmitted.
test.SetActiveModules({true}); test.SetSending(true);
test.AdvanceTime(TimeDelta::Millis(33)); test.AdvanceTime(TimeDelta::Millis(33));
EXPECT_TRUE(sent_packets.empty()); EXPECT_TRUE(sent_packets.empty());
@ -1156,7 +1133,7 @@ TEST(RtpVideoSenderTest, ClearsPendingPacketsOnInactivation) {
TEST(RtpVideoSenderTest, RetransmitsBaseLayerOnly) { TEST(RtpVideoSenderTest, RetransmitsBaseLayerOnly) {
RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
kPayloadType, {}); kPayloadType, {});
test.SetActiveModules({true, true}); test.SetSending(true);
test.router()->SetRetransmissionMode(kRetransmitBaseLayer); test.router()->SetRetransmissionMode(kRetransmitBaseLayer);
constexpr uint8_t kPayload = 'a'; constexpr uint8_t kPayload = 'a';

View file

@ -50,6 +50,11 @@ class MockRtpTransportControllerSend
DestroyRtpVideoSender, DestroyRtpVideoSender,
(RtpVideoSenderInterface*), (RtpVideoSenderInterface*),
(override)); (override));
MOCK_METHOD(void, RegisterSendingRtpStream, (RtpRtcpInterface&), (override));
MOCK_METHOD(void,
DeRegisterSendingRtpStream,
(RtpRtcpInterface&),
(override));
MOCK_METHOD(PacketRouter*, packet_router, (), (override)); MOCK_METHOD(PacketRouter*, packet_router, (), (override));
MOCK_METHOD(NetworkStateEstimateObserver*, MOCK_METHOD(NetworkStateEstimateObserver*,
network_state_estimate_observer, network_state_estimate_observer,

View file

@ -627,10 +627,9 @@ bool VideoSendStreamImpl::started() {
void VideoSendStreamImpl::Start() { void VideoSendStreamImpl::Start() {
RTC_DCHECK_RUN_ON(&thread_checker_); RTC_DCHECK_RUN_ON(&thread_checker_);
const std::vector<bool> active_layers(config_.rtp.ssrcs.size(), true);
// This sender is allowed to send RTP packets. Start monitoring and allocating // This sender is allowed to send RTP packets. Start monitoring and allocating
// a rate if there is also active encodings. (has_active_encodings_). // a rate if there is also active encodings. (has_active_encodings_).
rtp_video_sender_->SetActiveModules(active_layers); rtp_video_sender_->SetSending(true);
if (!IsRunning() && has_active_encodings_) { if (!IsRunning() && has_active_encodings_) {
StartupVideoSendStream(); StartupVideoSendStream();
} }
@ -681,7 +680,7 @@ void VideoSendStreamImpl::Stop() {
return; return;
TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop"); TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop");
rtp_video_sender_->Stop(); rtp_video_sender_->SetSending(false);
if (IsRunning()) { if (IsRunning()) {
StopVideoSendStream(); StopVideoSendStream();
} }

View file

@ -75,6 +75,7 @@ using ::testing::Invoke;
using ::testing::Mock; using ::testing::Mock;
using ::testing::NiceMock; using ::testing::NiceMock;
using ::testing::Return; using ::testing::Return;
using ::testing::SaveArg;
constexpr int64_t kDefaultInitialBitrateBps = 333000; constexpr int64_t kDefaultInitialBitrateBps = 333000;
const double kDefaultBitratePriority = 0.5; const double kDefaultBitratePriority = 0.5;
@ -87,8 +88,7 @@ std::string GetAlrProbingExperimentString() {
} }
class MockRtpVideoSender : public RtpVideoSenderInterface { class MockRtpVideoSender : public RtpVideoSenderInterface {
public: public:
MOCK_METHOD(void, SetActiveModules, (const std::vector<bool>&), (override)); MOCK_METHOD(void, SetSending, (bool sending), (override));
MOCK_METHOD(void, Stop, (), (override));
MOCK_METHOD(bool, IsActive, (), (override)); MOCK_METHOD(bool, IsActive, (), (override));
MOCK_METHOD(void, OnNetworkAvailability, (bool), (override)); MOCK_METHOD(void, OnNetworkAvailability, (bool), (override));
MOCK_METHOD((std::map<uint32_t, RtpState>), MOCK_METHOD((std::map<uint32_t, RtpState>),
@ -158,19 +158,11 @@ class VideoSendStreamImplTest : public ::testing::Test {
.WillRepeatedly(Return(&packet_router_)); .WillRepeatedly(Return(&packet_router_));
EXPECT_CALL(transport_controller_, CreateRtpVideoSender) EXPECT_CALL(transport_controller_, CreateRtpVideoSender)
.WillRepeatedly(Return(&rtp_video_sender_)); .WillRepeatedly(Return(&rtp_video_sender_));
ON_CALL(rtp_video_sender_, Stop()).WillByDefault(::testing::Invoke([&] { ON_CALL(rtp_video_sender_, IsActive()).WillByDefault(Invoke([&]() {
active_modules_.clear(); return rtp_sending_;
})); }));
ON_CALL(rtp_video_sender_, IsActive()) ON_CALL(rtp_video_sender_, SetSending)
.WillByDefault(::testing::Invoke([&]() { .WillByDefault(SaveArg<0>(&rtp_sending_));
for (bool enabled : active_modules_) {
if (enabled)
return true;
}
return false;
}));
ON_CALL(rtp_video_sender_, SetActiveModules)
.WillByDefault(::testing::SaveArg<0>(&active_modules_));
} }
~VideoSendStreamImplTest() {} ~VideoSendStreamImplTest() {}
@ -225,7 +217,7 @@ class VideoSendStreamImplTest : public ::testing::Test {
NiceMock<MockBitrateAllocator> bitrate_allocator_; NiceMock<MockBitrateAllocator> bitrate_allocator_;
NiceMock<MockVideoStreamEncoder>* video_stream_encoder_ = nullptr; NiceMock<MockVideoStreamEncoder>* video_stream_encoder_ = nullptr;
NiceMock<MockRtpVideoSender> rtp_video_sender_; NiceMock<MockRtpVideoSender> rtp_video_sender_;
std::vector<bool> active_modules_; bool rtp_sending_ = false;
RtcEventLogNull event_log_; RtcEventLogNull event_log_;
VideoSendStream::Config config_; VideoSendStream::Config config_;