Enables/disables simulcast streams by allocating a bitrate of 0 to the spatial layer.

Creates VideoStreams & VideoCodec.simulcastStreams with an active field, and then allocates 0 bitrate to simulcast streams that are inactive. This turns off the encoder for specific simulcast streams.

Bug: webrtc:8653
Change-Id: Id93b03dcd8d1191a7d3300bd77882c8af96ee469
Reviewed-on: https://webrtc-review.googlesource.com/37740
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Seth Hampson <shampson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21646}
This commit is contained in:
Seth Hampson
2018-01-12 11:33:12 -08:00
committed by Commit Bot
parent 4aa8ab5d56
commit 18c4261339
18 changed files with 516 additions and 76 deletions

View File

@ -203,6 +203,7 @@ class TestVp8Simulcast : public ::testing::Test {
settings->width = kDefaultWidth;
settings->height = kDefaultHeight;
settings->numberOfSimulcastStreams = kNumberOfSimulcastStreams;
settings->active = true;
ASSERT_EQ(3, kNumberOfSimulcastStreams);
settings->timing_frame_thresholds = {kDefaultTimingFramesDelayMs,
kDefaultOutlierFrameSizePercent};
@ -238,6 +239,7 @@ class TestVp8Simulcast : public ::testing::Test {
stream->targetBitrate = target_bitrate;
stream->numberOfTemporalLayers = num_temporal_layers;
stream->qpMax = 45;
stream->active = true;
}
protected:
@ -282,10 +284,22 @@ class TestVp8Simulcast : public ::testing::Test {
rate_allocator_->GetAllocation(bitrate_kbps * 1000, fps), fps);
}
void ExpectStreams(FrameType frame_type, int expected_video_streams) {
ASSERT_GE(expected_video_streams, 0);
ASSERT_LE(expected_video_streams, kNumberOfSimulcastStreams);
if (expected_video_streams >= 1) {
void UpdateActiveStreams(const std::vector<bool> active_streams) {
ASSERT_EQ(static_cast<int>(active_streams.size()),
kNumberOfSimulcastStreams);
for (size_t i = 0; i < active_streams.size(); ++i) {
settings_.simulcastStream[i].active = active_streams[i];
}
// Re initialize the allocator and encoder with the new settings.
SetUpRateAllocator();
EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200));
}
void ExpectStreams(FrameType frame_type,
const std::vector<bool> expected_streams_active) {
ASSERT_EQ(static_cast<int>(expected_streams_active.size()),
kNumberOfSimulcastStreams);
if (expected_streams_active[0]) {
EXPECT_CALL(
encoder_callback_,
OnEncodedImage(
@ -297,7 +311,7 @@ class TestVp8Simulcast : public ::testing::Test {
.WillRepeatedly(Return(EncodedImageCallback::Result(
EncodedImageCallback::Result::OK, 0)));
}
if (expected_video_streams >= 2) {
if (expected_streams_active[1]) {
EXPECT_CALL(
encoder_callback_,
OnEncodedImage(
@ -309,7 +323,7 @@ class TestVp8Simulcast : public ::testing::Test {
.WillRepeatedly(Return(EncodedImageCallback::Result(
EncodedImageCallback::Result::OK, 0)));
}
if (expected_video_streams >= 3) {
if (expected_streams_active[2]) {
EXPECT_CALL(
encoder_callback_,
OnEncodedImage(
@ -323,6 +337,16 @@ class TestVp8Simulcast : public ::testing::Test {
}
}
void ExpectStreams(FrameType frame_type, int expected_video_streams) {
ASSERT_GE(expected_video_streams, 0);
ASSERT_LE(expected_video_streams, kNumberOfSimulcastStreams);
std::vector<bool> expected_streams_active(kNumberOfSimulcastStreams, false);
for (int i = 0; i < expected_video_streams; ++i) {
expected_streams_active[i] = true;
}
ExpectStreams(frame_type, expected_streams_active);
}
void VerifyTemporalIdxAndSyncForAllSpatialLayers(
Vp8TestEncodedImageCallback* encoder_callback,
const int* expected_temporal_idx,
@ -501,6 +525,43 @@ class TestVp8Simulcast : public ::testing::Test {
EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL, &frame_types));
}
void TestActiveStreams() {
const int kEnoughBitrateAllStreams =
kMaxBitrates[0] + kMaxBitrates[1] + kMaxBitrates[2];
std::vector<FrameType> frame_types(kNumberOfSimulcastStreams,
kVideoFrameDelta);
// TODO(shampson): Currently turning off the base stream causes unexpected
// behavior in the libvpx encoder. The libvpx encoder labels key frames
// based upon the base stream. If the base stream is never enabled, it
// will continue to spit out encoded images labeled as key frames for the
// other streams that are enabled. Once this is fixed in libvpx, update this
// test to reflect that change.
// Only turn on the the base stream.
std::vector<bool> active_streams = {true, false, false};
UpdateActiveStreams(active_streams);
SetRates(kEnoughBitrateAllStreams, 30);
ExpectStreams(kVideoFrameKey, active_streams);
input_frame_->set_timestamp(input_frame_->timestamp() + 3000);
EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL, &frame_types));
ExpectStreams(kVideoFrameDelta, active_streams);
input_frame_->set_timestamp(input_frame_->timestamp() + 3000);
EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL, &frame_types));
// Turn off only the middle stream.
active_streams = {true, false, true};
UpdateActiveStreams(active_streams);
SetRates(kEnoughBitrateAllStreams, 30);
ExpectStreams(kVideoFrameKey, active_streams);
input_frame_->set_timestamp(input_frame_->timestamp() + 3000);
EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL, &frame_types));
ExpectStreams(kVideoFrameDelta, active_streams);
input_frame_->set_timestamp(input_frame_->timestamp() + 3000);
EXPECT_EQ(0, encoder_->Encode(*input_frame_, NULL, &frame_types));
}
void SwitchingToOneStream(int width, int height) {
// Disable all streams except the last and set the bitrate of the last to
// 100 kbps. This verifies the way GTP switches to screenshare mode.