SimulcastEncoderAdapter, don't start streams without enough bitrate
Currently a bug in InitEncode() sets all stream initially to active. This CL actually bases the active-flag on available start bitrate. Bug: webrtc:9747 Change-Id: If197b0c69376d96c717f2a391fba8108895018f3 Reviewed-on: https://webrtc-review.googlesource.com/99960 Commit-Queue: Erik Språng <sprang@webrtc.org> Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24711}
This commit is contained in:
parent
21c663820f
commit
7d687b13ed
@ -208,12 +208,13 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
|
||||
for (int i = 0; i < number_of_streams; ++i) {
|
||||
VideoCodec stream_codec;
|
||||
uint32_t start_bitrate_kbps = start_bitrates[i];
|
||||
const bool send_stream = start_bitrate_kbps > 0;
|
||||
if (!doing_simulcast) {
|
||||
stream_codec = codec_;
|
||||
stream_codec.numberOfSimulcastStreams = 1;
|
||||
} else {
|
||||
// Cap start bitrate to the min bitrate in order to avoid strange codec
|
||||
// behavior. Since sending sending will be false, this should not matter.
|
||||
// behavior. Since sending will be false, this should not matter.
|
||||
start_bitrate_kbps =
|
||||
std::max(codec_.simulcastStream[i].minBitrate, start_bitrate_kbps);
|
||||
bool highest_resolution_stream = (i == (number_of_streams - 1));
|
||||
@ -251,7 +252,7 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
|
||||
encoder->RegisterEncodeCompleteCallback(callback.get());
|
||||
streaminfos_.emplace_back(std::move(encoder), std::move(callback),
|
||||
stream_codec.width, stream_codec.height,
|
||||
start_bitrate_kbps > 0);
|
||||
send_stream);
|
||||
|
||||
if (i != 0) {
|
||||
implementation_name += ", ";
|
||||
|
||||
@ -513,6 +513,10 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
|
||||
kVideoCodecVP8);
|
||||
rate_allocator_.reset(new SimulcastRateAllocator(codec_));
|
||||
adapter_->RegisterEncodeCompleteCallback(this);
|
||||
const uint32_t target_bitrate =
|
||||
1000 * (codec_.simulcastStream[0].targetBitrate +
|
||||
codec_.simulcastStream[1].targetBitrate +
|
||||
codec_.simulcastStream[2].minBitrate);
|
||||
|
||||
// Input data.
|
||||
rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
|
||||
@ -522,6 +526,9 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
|
||||
// Encode with three streams.
|
||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
||||
VerifyCodecSettings();
|
||||
adapter_->SetRateAllocation(
|
||||
rate_allocator_->GetAllocation(target_bitrate, 30), 30);
|
||||
|
||||
std::vector<MockVideoEncoder*> original_encoders =
|
||||
helper_->factory()->encoders();
|
||||
ASSERT_EQ(3u, original_encoders.size());
|
||||
@ -546,6 +553,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
|
||||
codec_.height /= 2;
|
||||
codec_.numberOfSimulcastStreams = 2;
|
||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
||||
adapter_->SetRateAllocation(
|
||||
rate_allocator_->GetAllocation(target_bitrate, 30), 30);
|
||||
std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
|
||||
ASSERT_EQ(2u, new_encoders.size());
|
||||
ASSERT_EQ(original_encoders[0], new_encoders[0]);
|
||||
@ -567,6 +576,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
|
||||
codec_.height /= 2;
|
||||
codec_.numberOfSimulcastStreams = 1;
|
||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
||||
adapter_->SetRateAllocation(
|
||||
rate_allocator_->GetAllocation(target_bitrate, 30), 30);
|
||||
new_encoders = helper_->factory()->encoders();
|
||||
ASSERT_EQ(1u, new_encoders.size());
|
||||
ASSERT_EQ(original_encoders[0], new_encoders[0]);
|
||||
@ -583,6 +594,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
|
||||
codec_.height *= 4;
|
||||
codec_.numberOfSimulcastStreams = 3;
|
||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
||||
adapter_->SetRateAllocation(
|
||||
rate_allocator_->GetAllocation(target_bitrate, 30), 30);
|
||||
new_encoders = helper_->factory()->encoders();
|
||||
ASSERT_EQ(3u, new_encoders.size());
|
||||
// The first encoder is reused.
|
||||
@ -902,5 +915,38 @@ TEST_F(TestSimulcastEncoderAdapterFake, DoesNotAlterMaxQpForScreenshare) {
|
||||
ref_codec.qpMax = kLowMaxQp;
|
||||
VerifyCodec(ref_codec, 0);
|
||||
}
|
||||
|
||||
TEST_F(TestSimulcastEncoderAdapterFake, ActivatesCorrectStreamsInInitEncode) {
|
||||
// Set up common settings for three streams.
|
||||
SimulcastTestFixtureImpl::DefaultSettings(
|
||||
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
|
||||
kVideoCodecVP8);
|
||||
rate_allocator_.reset(new SimulcastRateAllocator(codec_));
|
||||
adapter_->RegisterEncodeCompleteCallback(this);
|
||||
|
||||
// Only enough start bitrate for the lowest stream.
|
||||
ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
|
||||
codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
|
||||
codec_.simulcastStream[1].minBitrate - 1;
|
||||
|
||||
// Input data.
|
||||
rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
|
||||
VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
|
||||
|
||||
// Encode with three streams.
|
||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
||||
std::vector<MockVideoEncoder*> original_encoders =
|
||||
helper_->factory()->encoders();
|
||||
ASSERT_EQ(3u, original_encoders.size());
|
||||
// Only first encoder will be active and called.
|
||||
EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
|
||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||
EXPECT_CALL(*original_encoders[1], Encode(_, _, _)).Times(0);
|
||||
EXPECT_CALL(*original_encoders[2], Encode(_, _, _)).Times(0);
|
||||
|
||||
std::vector<FrameType> frame_types;
|
||||
frame_types.resize(3, kVideoFrameKey);
|
||||
EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
|
||||
}
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user