Add support for target rate constraints
WebRTC video engine now configures bitrate on media transport correctly. Bug: webrtc:9719 Change-Id: I85884cd76644b7eca3763cec8ce9e31b5b64db27 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/127941 Commit-Queue: Peter Slatala <psla@webrtc.org> Reviewed-by: Steve Anton <steveanton@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Bjorn Mellem <mellem@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27167}
This commit is contained in:

committed by
Commit Bot

parent
6b6f537e83
commit
946b968111
@ -50,12 +50,22 @@ class AudioPacketReceivedObserver {
|
|||||||
virtual void OnFirstAudioPacketReceived(int64_t channel_id) = 0;
|
virtual void OnFirstAudioPacketReceived(int64_t channel_id) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Used to configure stream allocations.
|
||||||
struct MediaTransportAllocatedBitrateLimits {
|
struct MediaTransportAllocatedBitrateLimits {
|
||||||
DataRate min_pacing_rate = DataRate::Zero();
|
DataRate min_pacing_rate = DataRate::Zero();
|
||||||
DataRate max_padding_bitrate = DataRate::Zero();
|
DataRate max_padding_bitrate = DataRate::Zero();
|
||||||
DataRate max_total_allocated_bitrate = DataRate::Zero();
|
DataRate max_total_allocated_bitrate = DataRate::Zero();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Used to configure target bitrate constraints.
|
||||||
|
// If the value is provided, the constraint is updated.
|
||||||
|
// If the value is omitted, the value is left unchanged.
|
||||||
|
struct MediaTransportTargetRateConstraints {
|
||||||
|
absl::optional<DataRate> min_bitrate;
|
||||||
|
absl::optional<DataRate> max_bitrate;
|
||||||
|
absl::optional<DataRate> starting_bitrate;
|
||||||
|
};
|
||||||
|
|
||||||
// A collection of settings for creation of media transport.
|
// A collection of settings for creation of media transport.
|
||||||
struct MediaTransportSettings final {
|
struct MediaTransportSettings final {
|
||||||
MediaTransportSettings();
|
MediaTransportSettings();
|
||||||
@ -315,6 +325,11 @@ class MediaTransportInterface {
|
|||||||
virtual void SetAllocatedBitrateLimits(
|
virtual void SetAllocatedBitrateLimits(
|
||||||
const MediaTransportAllocatedBitrateLimits& limits);
|
const MediaTransportAllocatedBitrateLimits& limits);
|
||||||
|
|
||||||
|
// Sets starting rate.
|
||||||
|
// TODO(psla): Make abstract when downstream implementation implement it.
|
||||||
|
virtual void SetTargetBitrateLimits(
|
||||||
|
const MediaTransportTargetRateConstraints& target_rate_constraints) {}
|
||||||
|
|
||||||
// Opens a data |channel_id| for sending. May return an error if the
|
// Opens a data |channel_id| for sending. May return an error if the
|
||||||
// specified |channel_id| is unusable. Must be called before |SendData|.
|
// specified |channel_id| is unusable. Must be called before |SendData|.
|
||||||
virtual RTCError OpenChannel(int channel_id) = 0;
|
virtual RTCError OpenChannel(int channel_id) = 0;
|
||||||
|
@ -103,6 +103,16 @@ class FakeMediaTransport : public MediaTransportInterface {
|
|||||||
void SetAllocatedBitrateLimits(
|
void SetAllocatedBitrateLimits(
|
||||||
const MediaTransportAllocatedBitrateLimits& limits) override {}
|
const MediaTransportAllocatedBitrateLimits& limits) override {}
|
||||||
|
|
||||||
|
void SetTargetBitrateLimits(const MediaTransportTargetRateConstraints&
|
||||||
|
target_rate_constraints) override {
|
||||||
|
target_rate_constraints_in_order_.push_back(target_rate_constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<MediaTransportTargetRateConstraints>&
|
||||||
|
target_rate_constraints_in_order() {
|
||||||
|
return target_rate_constraints_in_order_;
|
||||||
|
}
|
||||||
|
|
||||||
int target_rate_observers_size() { return target_rate_observers_.size(); }
|
int target_rate_observers_size() { return target_rate_observers_.size(); }
|
||||||
|
|
||||||
// Settings that were passed down to fake media transport.
|
// Settings that were passed down to fake media transport.
|
||||||
@ -133,6 +143,8 @@ class FakeMediaTransport : public MediaTransportInterface {
|
|||||||
const absl::optional<std::string> transport_offer_;
|
const absl::optional<std::string> transport_offer_;
|
||||||
const absl::optional<std::string> remote_transport_parameters_;
|
const absl::optional<std::string> remote_transport_parameters_;
|
||||||
bool is_connected_ = false;
|
bool is_connected_ = false;
|
||||||
|
std::vector<MediaTransportTargetRateConstraints>
|
||||||
|
target_rate_constraints_in_order_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fake media transport factory creates fake media transport.
|
// Fake media transport factory creates fake media transport.
|
||||||
|
14
call/call.cc
14
call/call.cc
@ -567,6 +567,20 @@ void Call::MediaTransportChange(MediaTransportInterface* media_transport) {
|
|||||||
<< ", (media_transport_==media_transport)="
|
<< ", (media_transport_==media_transport)="
|
||||||
<< (media_transport_ == media_transport);
|
<< (media_transport_ == media_transport);
|
||||||
media_transport_ = media_transport;
|
media_transport_ = media_transport;
|
||||||
|
MediaTransportTargetRateConstraints constraints;
|
||||||
|
if (config_.bitrate_config.start_bitrate_bps > 0) {
|
||||||
|
constraints.starting_bitrate =
|
||||||
|
DataRate::bps(config_.bitrate_config.start_bitrate_bps);
|
||||||
|
}
|
||||||
|
if (config_.bitrate_config.max_bitrate_bps > 0) {
|
||||||
|
constraints.max_bitrate =
|
||||||
|
DataRate::bps(config_.bitrate_config.max_bitrate_bps);
|
||||||
|
}
|
||||||
|
if (config_.bitrate_config.min_bitrate_bps > 0) {
|
||||||
|
constraints.min_bitrate =
|
||||||
|
DataRate::bps(config_.bitrate_config.min_bitrate_bps);
|
||||||
|
}
|
||||||
|
media_transport_->SetTargetBitrateLimits(constraints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,6 +492,7 @@ if (rtc_include_tests) {
|
|||||||
":rtc_constants",
|
":rtc_constants",
|
||||||
":rtc_data",
|
":rtc_data",
|
||||||
"../:webrtc_common",
|
"../:webrtc_common",
|
||||||
|
"../api:fake_media_transport",
|
||||||
"../api:scoped_refptr",
|
"../api:scoped_refptr",
|
||||||
"../api/test/video:function_video_factory",
|
"../api/test/video:function_video_factory",
|
||||||
"../api/units:time_delta",
|
"../api/units:time_delta",
|
||||||
|
@ -717,8 +717,26 @@ bool WebRtcVideoChannel::SetSendParameters(const VideoSendParameters& params) {
|
|||||||
bitrate_config_.max_bitrate_bps =
|
bitrate_config_.max_bitrate_bps =
|
||||||
params.max_bandwidth_bps == 0 ? -1 : params.max_bandwidth_bps;
|
params.max_bandwidth_bps == 0 ? -1 : params.max_bandwidth_bps;
|
||||||
}
|
}
|
||||||
call_->GetTransportControllerSend()->SetSdpBitrateParameters(
|
|
||||||
bitrate_config_);
|
if (media_transport()) {
|
||||||
|
webrtc::MediaTransportTargetRateConstraints constraints;
|
||||||
|
if (bitrate_config_.start_bitrate_bps >= 0) {
|
||||||
|
constraints.starting_bitrate =
|
||||||
|
webrtc::DataRate::bps(bitrate_config_.start_bitrate_bps);
|
||||||
|
}
|
||||||
|
if (bitrate_config_.max_bitrate_bps > 0) {
|
||||||
|
constraints.max_bitrate =
|
||||||
|
webrtc::DataRate::bps(bitrate_config_.max_bitrate_bps);
|
||||||
|
}
|
||||||
|
if (bitrate_config_.min_bitrate_bps >= 0) {
|
||||||
|
constraints.min_bitrate =
|
||||||
|
webrtc::DataRate::bps(bitrate_config_.min_bitrate_bps);
|
||||||
|
}
|
||||||
|
media_transport()->SetTargetBitrateLimits(constraints);
|
||||||
|
} else {
|
||||||
|
call_->GetTransportControllerSend()->SetSdpBitrateParameters(
|
||||||
|
bitrate_config_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& kv : send_streams_) {
|
for (auto& kv : send_streams_) {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/strings/match.h"
|
#include "absl/strings/match.h"
|
||||||
#include "api/rtp_parameters.h"
|
#include "api/rtp_parameters.h"
|
||||||
|
#include "api/test/fake_media_transport.h"
|
||||||
#include "api/test/mock_video_bitrate_allocator.h"
|
#include "api/test/mock_video_bitrate_allocator.h"
|
||||||
#include "api/test/mock_video_bitrate_allocator_factory.h"
|
#include "api/test/mock_video_bitrate_allocator_factory.h"
|
||||||
#include "api/test/mock_video_decoder_factory.h"
|
#include "api/test/mock_video_decoder_factory.h"
|
||||||
@ -3892,6 +3893,81 @@ TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitratesAndMaxSendBandwidth) {
|
|||||||
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
|
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that when both the codec-specific bitrate params and max_bandwidth_bps
|
||||||
|
// are present in the same send parameters, the settings are combined correctly.
|
||||||
|
TEST_F(WebRtcVideoChannelTest,
|
||||||
|
SetSendCodecsWithBitratesAndMaxSendBandwidthForMediaTransport) {
|
||||||
|
// Same as SetSendCodecsWithBitratesAndMaxSendBandwidth but with Media
|
||||||
|
// Transport.
|
||||||
|
webrtc::MediaTransportSettings settings;
|
||||||
|
settings.is_caller = true;
|
||||||
|
webrtc::FakeMediaTransport fake_media_transport(settings);
|
||||||
|
std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
|
||||||
|
new cricket::FakeNetworkInterface);
|
||||||
|
channel_->SetInterface(network_interface.get(), &fake_media_transport);
|
||||||
|
|
||||||
|
send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
|
||||||
|
send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
|
||||||
|
send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
|
||||||
|
send_parameters_.max_bandwidth_bps = 400000;
|
||||||
|
{
|
||||||
|
// We expect max_bandwidth_bps to take priority, if set.
|
||||||
|
ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
|
||||||
|
ASSERT_EQ(1u,
|
||||||
|
fake_media_transport.target_rate_constraints_in_order().size());
|
||||||
|
const webrtc::MediaTransportTargetRateConstraints& constraint =
|
||||||
|
fake_media_transport.target_rate_constraints_in_order()[0];
|
||||||
|
ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
|
||||||
|
ASSERT_EQ(webrtc::DataRate::bps(200000), constraint.starting_bitrate);
|
||||||
|
ASSERT_EQ(webrtc::DataRate::bps(400000), constraint.max_bitrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Decrease max_bandwidth_bps.
|
||||||
|
send_parameters_.max_bandwidth_bps = 350000;
|
||||||
|
ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
|
||||||
|
ASSERT_EQ(2u,
|
||||||
|
fake_media_transport.target_rate_constraints_in_order().size());
|
||||||
|
const webrtc::MediaTransportTargetRateConstraints& constraint =
|
||||||
|
fake_media_transport.target_rate_constraints_in_order()[1];
|
||||||
|
|
||||||
|
// Since the codec isn't changing, start_bitrate_bps should be 0.
|
||||||
|
ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
|
||||||
|
ASSERT_EQ(absl::nullopt, constraint.starting_bitrate);
|
||||||
|
ASSERT_EQ(webrtc::DataRate::bps(350000), constraint.max_bitrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Now try again with the values flipped around.
|
||||||
|
send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
|
||||||
|
send_parameters_.max_bandwidth_bps = 300000;
|
||||||
|
ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
|
||||||
|
ASSERT_EQ(3u,
|
||||||
|
fake_media_transport.target_rate_constraints_in_order().size());
|
||||||
|
const webrtc::MediaTransportTargetRateConstraints& constraint =
|
||||||
|
fake_media_transport.target_rate_constraints_in_order()[2];
|
||||||
|
|
||||||
|
ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
|
||||||
|
ASSERT_EQ(webrtc::DataRate::bps(200000), constraint.starting_bitrate);
|
||||||
|
ASSERT_EQ(webrtc::DataRate::bps(300000), constraint.max_bitrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Now try again with the values flipped around.
|
||||||
|
// If we change the codec max, max_bandwidth_bps should still apply.
|
||||||
|
send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
|
||||||
|
ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
|
||||||
|
ASSERT_EQ(4u,
|
||||||
|
fake_media_transport.target_rate_constraints_in_order().size());
|
||||||
|
const webrtc::MediaTransportTargetRateConstraints& constraint =
|
||||||
|
fake_media_transport.target_rate_constraints_in_order()[3];
|
||||||
|
|
||||||
|
ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
|
||||||
|
ASSERT_EQ(webrtc::DataRate::bps(200000), constraint.starting_bitrate);
|
||||||
|
ASSERT_EQ(webrtc::DataRate::bps(300000), constraint.max_bitrate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldPreserveOtherBitrates) {
|
TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldPreserveOtherBitrates) {
|
||||||
SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
|
SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
|
||||||
200000);
|
200000);
|
||||||
|
Reference in New Issue
Block a user