Adds WebRTC-AV1-OverridePriorityBitrate to change bit rate allocation between audio and video

Bug: webrtc:15763
Change-Id: If53cb2750756e40a226097638f2a3c96e154e83d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/333984
Commit-Queue: Dan Tan <dwtan@google.com>
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41586}
This commit is contained in:
Dan Tan 2024-01-18 11:13:32 -08:00 committed by WebRTC LUCI CQ
parent 5dc6c14747
commit 798e451878
4 changed files with 97 additions and 2 deletions

View File

@ -50,6 +50,9 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([
FieldTrial('WebRTC-Audio-OpusSetSignalVoiceWithDtx', FieldTrial('WebRTC-Audio-OpusSetSignalVoiceWithDtx',
'webrtc:4559', 'webrtc:4559',
date(2024, 4, 1)), date(2024, 4, 1)),
FieldTrial('WebRTC-AV1-OverridePriorityBitrate',
'webrtc:15763',
date(2024, 4, 1)),
FieldTrial('WebRTC-Av1-GetEncoderInfoOverride', FieldTrial('WebRTC-Av1-GetEncoderInfoOverride',
'webrtc:14931', 'webrtc:14931',
date(2024, 4, 1)), date(2024, 4, 1)),

View File

@ -224,6 +224,19 @@ absl::optional<float> GetConfiguredPacingFactor(
default_pacing_config.pacing_factor); default_pacing_config.pacing_factor);
} }
int GetEncoderPriorityBitrate(std::string codec_name,
const FieldTrialsView& field_trials) {
int priority_bitrate = 0;
if (PayloadStringToCodecType(codec_name) == VideoCodecType::kVideoCodecAV1) {
webrtc::FieldTrialParameter<int> av1_priority_bitrate("bitrate", 0);
webrtc::ParseFieldTrial(
{&av1_priority_bitrate},
field_trials.Lookup("WebRTC-AV1-OverridePriorityBitrate"));
priority_bitrate = av1_priority_bitrate;
}
return priority_bitrate;
}
uint32_t GetInitialEncoderMaxBitrate(int initial_encoder_max_bitrate) { uint32_t GetInitialEncoderMaxBitrate(int initial_encoder_max_bitrate) {
if (initial_encoder_max_bitrate > 0) if (initial_encoder_max_bitrate > 0)
return rtc::dchecked_cast<uint32_t>(initial_encoder_max_bitrate); return rtc::dchecked_cast<uint32_t>(initial_encoder_max_bitrate);
@ -432,6 +445,8 @@ VideoSendStreamImpl::VideoSendStreamImpl(
GetInitialEncoderMaxBitrate(encoder_config.max_bitrate_bps)), GetInitialEncoderMaxBitrate(encoder_config.max_bitrate_bps)),
encoder_target_rate_bps_(0), encoder_target_rate_bps_(0),
encoder_bitrate_priority_(encoder_config.bitrate_priority), encoder_bitrate_priority_(encoder_config.bitrate_priority),
encoder_av1_priority_bitrate_override_bps_(
GetEncoderPriorityBitrate(config_.rtp.payload_name, field_trials)),
configured_pacing_factor_(GetConfiguredPacingFactor(config_, configured_pacing_factor_(GetConfiguredPacingFactor(config_,
content_type_, content_type_,
pacing_config_, pacing_config_,
@ -757,7 +772,7 @@ MediaStreamAllocationConfig VideoSendStreamImpl::GetAllocationConfig() const {
static_cast<uint32_t>(encoder_min_bitrate_bps_), static_cast<uint32_t>(encoder_min_bitrate_bps_),
encoder_max_bitrate_bps_, encoder_max_bitrate_bps_,
static_cast<uint32_t>(disable_padding_ ? 0 : max_padding_bitrate_), static_cast<uint32_t>(disable_padding_ ? 0 : max_padding_bitrate_),
/* priority_bitrate */ 0, encoder_av1_priority_bitrate_override_bps_,
!config_.suspend_below_min_bitrate, !config_.suspend_below_min_bitrate,
encoder_bitrate_priority_}; encoder_bitrate_priority_};
} }

View File

@ -218,6 +218,8 @@ class VideoSendStreamImpl : public webrtc::VideoSendStream,
uint32_t encoder_max_bitrate_bps_ RTC_GUARDED_BY(thread_checker_); uint32_t encoder_max_bitrate_bps_ RTC_GUARDED_BY(thread_checker_);
uint32_t encoder_target_rate_bps_ RTC_GUARDED_BY(thread_checker_); uint32_t encoder_target_rate_bps_ RTC_GUARDED_BY(thread_checker_);
double encoder_bitrate_priority_ RTC_GUARDED_BY(thread_checker_); double encoder_bitrate_priority_ RTC_GUARDED_BY(thread_checker_);
const int encoder_av1_priority_bitrate_override_bps_
RTC_GUARDED_BY(thread_checker_);
ScopedTaskSafety worker_queue_safety_; ScopedTaskSafety worker_queue_safety_;

View File

@ -175,7 +175,8 @@ class VideoSendStreamImplTest : public ::testing::Test {
std::unique_ptr<VideoSendStreamImpl> CreateVideoSendStreamImpl( std::unique_ptr<VideoSendStreamImpl> CreateVideoSendStreamImpl(
int initial_encoder_max_bitrate, int initial_encoder_max_bitrate,
double initial_encoder_bitrate_priority, double initial_encoder_bitrate_priority,
VideoEncoderConfig::ContentType content_type) { VideoEncoderConfig::ContentType content_type,
absl::optional<std::string> codec = std::nullopt) {
EXPECT_CALL(bitrate_allocator_, GetStartBitrate(_)) EXPECT_CALL(bitrate_allocator_, GetStartBitrate(_))
.WillOnce(Return(123000)); .WillOnce(Return(123000));
@ -183,6 +184,9 @@ class VideoSendStreamImplTest : public ::testing::Test {
encoder_config.max_bitrate_bps = initial_encoder_max_bitrate; encoder_config.max_bitrate_bps = initial_encoder_max_bitrate;
encoder_config.bitrate_priority = initial_encoder_bitrate_priority; encoder_config.bitrate_priority = initial_encoder_bitrate_priority;
encoder_config.content_type = content_type; encoder_config.content_type = content_type;
if (codec) {
config_.rtp.payload_name = *codec;
}
std::map<uint32_t, RtpState> suspended_ssrcs; std::map<uint32_t, RtpState> suspended_ssrcs;
std::map<uint32_t, RtpPayloadState> suspended_payload_states; std::map<uint32_t, RtpPayloadState> suspended_payload_states;
@ -190,6 +194,7 @@ class VideoSendStreamImplTest : public ::testing::Test {
std::unique_ptr<NiceMock<MockVideoStreamEncoder>> video_stream_encoder = std::unique_ptr<NiceMock<MockVideoStreamEncoder>> video_stream_encoder =
std::make_unique<NiceMock<MockVideoStreamEncoder>>(); std::make_unique<NiceMock<MockVideoStreamEncoder>>();
video_stream_encoder_ = video_stream_encoder.get(); video_stream_encoder_ = video_stream_encoder.get();
auto ret = std::make_unique<VideoSendStreamImpl>( auto ret = std::make_unique<VideoSendStreamImpl>(
time_controller_.GetClock(), time_controller_.GetClock(),
/*num_cpu_cores=*/1, time_controller_.GetTaskQueueFactory(), /*num_cpu_cores=*/1, time_controller_.GetTaskQueueFactory(),
@ -714,6 +719,76 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
vss_impl->Stop(); vss_impl->Stop();
} }
TEST_F(VideoSendStreamImplTest, PriorityBitrateConfigInactiveByDefault) {
auto vss_impl = CreateVideoSendStreamImpl(
kDefaultInitialBitrateBps, kDefaultBitratePriority,
VideoEncoderConfig::ContentType::kRealtimeVideo);
EXPECT_CALL(
bitrate_allocator_,
AddObserver(
vss_impl.get(),
Field(&MediaStreamAllocationConfig::priority_bitrate_bps, 0)));
vss_impl->StartPerRtpStream({true});
EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1);
vss_impl->Stop();
}
TEST_F(VideoSendStreamImplTest, PriorityBitrateConfigAffectsAV1) {
test::ScopedFieldTrials override_priority_bitrate(
"WebRTC-AV1-OverridePriorityBitrate/bitrate:20000/");
auto vss_impl = CreateVideoSendStreamImpl(
kDefaultInitialBitrateBps, kDefaultBitratePriority,
VideoEncoderConfig::ContentType::kRealtimeVideo, "AV1");
EXPECT_CALL(
bitrate_allocator_,
AddObserver(
vss_impl.get(),
Field(&MediaStreamAllocationConfig::priority_bitrate_bps, 20000)));
vss_impl->StartPerRtpStream({true});
EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1);
vss_impl->Stop();
}
TEST_F(VideoSendStreamImplTest,
PriorityBitrateConfigSurvivesConfigurationChange) {
VideoStream qvga_stream;
qvga_stream.width = 320;
qvga_stream.height = 180;
qvga_stream.max_framerate = 30;
qvga_stream.min_bitrate_bps = 30000;
qvga_stream.target_bitrate_bps = 150000;
qvga_stream.max_bitrate_bps = 200000;
qvga_stream.max_qp = 56;
qvga_stream.bitrate_priority = 1;
int min_transmit_bitrate_bps = 30000;
test::ScopedFieldTrials override_priority_bitrate(
"WebRTC-AV1-OverridePriorityBitrate/bitrate:20000/");
auto vss_impl = CreateVideoSendStreamImpl(
kDefaultInitialBitrateBps, kDefaultBitratePriority,
VideoEncoderConfig::ContentType::kRealtimeVideo, "AV1");
EXPECT_CALL(
bitrate_allocator_,
AddObserver(
vss_impl.get(),
Field(&MediaStreamAllocationConfig::priority_bitrate_bps, 20000)))
.Times(2);
vss_impl->StartPerRtpStream({true});
encoder_queue_->PostTask([&] {
static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
->OnEncoderConfigurationChanged(
std::vector<VideoStream>{qvga_stream}, false,
VideoEncoderConfig::ContentType::kRealtimeVideo,
min_transmit_bitrate_bps);
});
time_controller_.AdvanceTime(TimeDelta::Zero());
EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1);
vss_impl->Stop();
}
TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) { TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
const bool kSuspend = false; const bool kSuspend = false;
config_.suspend_below_min_bitrate = kSuspend; config_.suspend_below_min_bitrate = kSuspend;