Add option for the audio encoder to allocate a bitrate range.

Bug: webrtc:15834
Change-Id: I3223162e747621983dbe2704661bb87f7890b3fa
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338221
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Jakob Ivarsson‎ <jakobi@webrtc.org>
Reviewed-by: Tomas Lundqvist <tomasl@google.com>
Cr-Commit-Position: refs/heads/main@{#41682}
This commit is contained in:
Jakob Ivarsson 2024-02-07 09:44:31 +01:00 committed by WebRTC LUCI CQ
parent 6de9d6add0
commit 9d9b3a3553
6 changed files with 52 additions and 3 deletions

View file

@ -42,6 +42,7 @@ rtc_library("audio_codecs_api") {
"../../rtc_base:refcount",
"../../rtc_base:sanitizer",
"../../rtc_base/system:rtc_export",
"../units:data_rate",
"../units:time_delta",
]
absl_deps = [

View file

@ -20,6 +20,7 @@
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/call/bitrate_allocation.h"
#include "api/units/data_rate.h"
#include "api/units/time_delta.h"
#include "rtc_base/buffer.h"
@ -240,12 +241,20 @@ class AudioEncoder {
// Get statistics related to audio network adaptation.
virtual ANAStats GetANAStats() const;
// The range of frame lengths that are supported or nullopt if there's no sch
// information. This is used to calculated the full bitrate range, including
// overhead.
// The range of frame lengths that are supported or nullopt if there's no such
// information. This is used together with the bitrate range to calculate the
// full bitrate range, including overhead.
virtual absl::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
const = 0;
// The range of payload bitrates that are supported. This is used together
// with the frame length range to calculate the full bitrate range, including
// overhead.
virtual absl::optional<std::pair<DataRate, DataRate>> GetBitrateRange()
const {
return absl::nullopt;
}
// The maximum number of audio channels supported by WebRTC encoders.
static constexpr int kMaxNumberOfChannels = 24;

View file

@ -333,6 +333,7 @@ void AudioSendStream::ConfigureStream(
return;
}
frame_length_range_ = encoder->GetFrameLengthRange();
bitrate_range_ = encoder->GetBitrateRange();
});
if (sending_) {
@ -848,6 +849,12 @@ AudioSendStream::GetMinMaxBitrateConstraints() const {
if (allocation_settings_.max_bitrate)
constraints.max = *allocation_settings_.max_bitrate;
// Use encoder defined bitrate range if available.
if (bitrate_range_) {
constraints.min = bitrate_range_->first;
constraints.max = bitrate_range_->second;
}
RTC_DCHECK_GE(constraints.min, DataRate::Zero());
RTC_DCHECK_GE(constraints.max, DataRate::Zero());
if (constraints.max < constraints.min) {

View file

@ -216,6 +216,8 @@ class AudioSendStream final : public webrtc::AudioSendStream,
false;
absl::optional<std::pair<TimeDelta, TimeDelta>> frame_length_range_
RTC_GUARDED_BY(worker_thread_checker_);
absl::optional<std::pair<DataRate, DataRate>> bitrate_range_
RTC_GUARDED_BY(worker_thread_checker_);
};
} // namespace internal
} // namespace webrtc

View file

@ -959,5 +959,31 @@ TEST(AudioSendStreamTest, OverridesPriorityBitrate) {
send_stream->Stop();
}
TEST(AudioSendStreamTest, UseEncoderBitrateRange) {
ConfigHelper helper(true, true, true);
std::pair<DataRate, DataRate> bitrate_range{DataRate::BitsPerSec(5000),
DataRate::BitsPerSec(10000)};
EXPECT_CALL(helper.mock_encoder_factory(), MakeAudioEncoderMock(_, _, _, _))
.WillOnce(Invoke([&](int payload_type, const SdpAudioFormat& format,
absl::optional<AudioCodecPairId> codec_pair_id,
std::unique_ptr<AudioEncoder>* return_value) {
auto mock_encoder = SetupAudioEncoderMock(payload_type, format);
EXPECT_CALL(*mock_encoder, GetBitrateRange())
.WillRepeatedly(Return(bitrate_range));
*return_value = std::move(mock_encoder);
}));
auto send_stream = helper.CreateAudioSendStream();
EXPECT_CALL(*helper.bitrate_allocator(), AddObserver(send_stream.get(), _))
.WillOnce(Invoke(
[&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) {
EXPECT_EQ(config.min_bitrate_bps, bitrate_range.first.bps());
EXPECT_EQ(config.max_bitrate_bps, bitrate_range.second.bps());
}));
EXPECT_CALL(*helper.channel_send(), StartSend());
send_stream->Start();
EXPECT_CALL(*helper.channel_send(), StopSend());
send_stream->Stop();
}
} // namespace test
} // namespace webrtc

View file

@ -33,6 +33,10 @@ class MockAudioEncoder : public AudioEncoder {
GetFrameLengthRange,
(),
(const, override));
MOCK_METHOD((absl::optional<std::pair<DataRate, DataRate>>),
GetBitrateRange,
(),
(const, override));
MOCK_METHOD(void, Reset, (), (override));
MOCK_METHOD(bool, SetFec, (bool enable), (override));