Extract bitrate allocation of spatial/temporal layers out of codec impl.

This CL makes a number of intervowen changes:

* Add BitrateAllocation struct, that contains a codec independent view
  of how the target bitrate is distributed over spatial and temporal
  layers.

* Adds the BitrateAllocator interface, which takes a bitrate and frame
  rate and produces a BitrateAllocation.

* A default (non layered) implementation is added, and
  SimulcastRateAllocator is extended to fully handle VP8 allocation.
  This includes capturing TemporalLayer instances created by the
  encoder.

* ViEEncoder now owns both the bitrate allocator and the temporal layer
  factories for VP8. This allows allocation to happen fully outside of
  the encoder implementation.

This refactoring will make it possible for ViEEncoder to signal the
full picture of target bitrates to the RTCP module.

BUG=webrtc:6301

Review-Url: https://codereview.webrtc.org/2434073003
Cr-Commit-Position: refs/heads/master@{#14998}
This commit is contained in:
sprang
2016-11-09 05:09:06 -08:00
committed by Commit bot
parent 592baaf89a
commit 8f46c679d2
63 changed files with 1681 additions and 843 deletions

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/modules/video_coding/utility/default_video_bitrate_allocator.h"
#include "webrtc/base/basictypes.h"
#include "webrtc/base/constructormagic.h"
namespace webrtc {
DefaultVideoBitrateAllocator::DefaultVideoBitrateAllocator(
const VideoCodec& codec)
: codec_(codec) {}
DefaultVideoBitrateAllocator::~DefaultVideoBitrateAllocator() {}
BitrateAllocation DefaultVideoBitrateAllocator::GetAllocation(
uint32_t total_bitrate_bps,
uint32_t framerate) {
BitrateAllocation allocation;
if (total_bitrate_bps == 0)
return allocation;
if (total_bitrate_bps < codec_.minBitrate * 1000) {
allocation.SetBitrate(0, 0, codec_.minBitrate * 1000);
} else if (codec_.maxBitrate > 0 &&
total_bitrate_bps > codec_.maxBitrate * 1000) {
allocation.SetBitrate(0, 0, codec_.maxBitrate * 1000);
} else {
allocation.SetBitrate(0, 0, total_bitrate_bps);
}
return allocation;
}
uint32_t DefaultVideoBitrateAllocator::GetPreferredBitrateBps(
uint32_t framerate) {
return GetAllocation(codec_.maxBitrate * 1000, framerate).get_sum_bps();
}
} // namespace webrtc

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MODULES_VIDEO_CODING_UTILITY_DEFAULT_VIDEO_BITRATE_ALLOCATOR_H_
#define WEBRTC_MODULES_VIDEO_CODING_UTILITY_DEFAULT_VIDEO_BITRATE_ALLOCATOR_H_
#include "webrtc/common_video/include/video_bitrate_allocator.h"
namespace webrtc {
class DefaultVideoBitrateAllocator : public VideoBitrateAllocator {
public:
explicit DefaultVideoBitrateAllocator(const VideoCodec& codec);
~DefaultVideoBitrateAllocator() override;
BitrateAllocation GetAllocation(uint32_t total_bitrate,
uint32_t framerate) override;
uint32_t GetPreferredBitrateBps(uint32_t framerate) override;
private:
const VideoCodec codec_;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_DEFAULT_VIDEO_BITRATE_ALLOCATOR_H_

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <limits>
#include <memory>
#include "webrtc/modules/video_coding/utility/default_video_bitrate_allocator.h"
#include "webrtc/test/gtest.h"
namespace webrtc {
namespace {
uint32_t kMaxBitrateBps = 1000000;
uint32_t kMinBitrateBps = 50000;
uint32_t kMaxFramerate = 30;
} // namespace
class DefaultVideoBitrateAllocatorTest : public ::testing::Test {
public:
DefaultVideoBitrateAllocatorTest() {}
virtual ~DefaultVideoBitrateAllocatorTest() {}
void SetUp() override {
codec_.codecType = kVideoCodecVP8;
codec_.minBitrate = kMinBitrateBps / 1000;
codec_.maxBitrate = kMaxBitrateBps / 1000;
codec_.targetBitrate = (kMinBitrateBps + kMaxBitrateBps) / 2000;
codec_.maxFramerate = kMaxFramerate;
allocator_.reset(new DefaultVideoBitrateAllocator(codec_));
}
protected:
VideoCodec codec_;
std::unique_ptr<DefaultVideoBitrateAllocator> allocator_;
};
TEST_F(DefaultVideoBitrateAllocatorTest, ZeroIsOff) {
BitrateAllocation allocation = allocator_->GetAllocation(0, kMaxFramerate);
EXPECT_EQ(0u, allocation.get_sum_bps());
}
TEST_F(DefaultVideoBitrateAllocatorTest, CapsToMin) {
BitrateAllocation allocation = allocator_->GetAllocation(1, kMaxFramerate);
EXPECT_EQ(kMinBitrateBps, allocation.get_sum_bps());
allocation = allocator_->GetAllocation(kMinBitrateBps - 1, kMaxFramerate);
EXPECT_EQ(kMinBitrateBps, allocation.get_sum_bps());
allocation = allocator_->GetAllocation(kMinBitrateBps, kMaxFramerate);
EXPECT_EQ(kMinBitrateBps, allocation.get_sum_bps());
}
TEST_F(DefaultVideoBitrateAllocatorTest, CapsToMax) {
BitrateAllocation allocation =
allocator_->GetAllocation(kMaxBitrateBps, kMaxFramerate);
EXPECT_EQ(kMaxBitrateBps, allocation.get_sum_bps());
allocation = allocator_->GetAllocation(kMaxBitrateBps + 1, kMaxFramerate);
EXPECT_EQ(kMaxBitrateBps, allocation.get_sum_bps());
allocation = allocator_->GetAllocation(std::numeric_limits<uint32_t>::max(),
kMaxFramerate);
EXPECT_EQ(kMaxBitrateBps, allocation.get_sum_bps());
}
TEST_F(DefaultVideoBitrateAllocatorTest, GoodInBetween) {
BitrateAllocation allocation =
allocator_->GetAllocation(kMinBitrateBps + 1, kMaxFramerate);
EXPECT_EQ(kMinBitrateBps + 1, allocation.get_sum_bps());
allocation = allocator_->GetAllocation(kMaxBitrateBps - 1, kMaxFramerate);
EXPECT_EQ(kMaxBitrateBps - 1, allocation.get_sum_bps());
}
} // namespace webrtc

View File

@ -11,67 +11,133 @@
#include "webrtc/modules/video_coding/utility/simulcast_rate_allocator.h"
#include <algorithm>
#include <memory>
#include <vector>
#include <utility>
#include "webrtc/base/checks.h"
namespace webrtc {
webrtc::SimulcastRateAllocator::SimulcastRateAllocator(const VideoCodec& codec)
: codec_(codec) {}
SimulcastRateAllocator::SimulcastRateAllocator(
const VideoCodec& codec,
std::unique_ptr<TemporalLayersFactory> tl_factory)
: codec_(codec), tl_factory_(std::move(tl_factory)) {
if (tl_factory_.get())
tl_factory_->SetListener(this);
}
std::vector<uint32_t> webrtc::SimulcastRateAllocator::GetAllocation(
uint32_t bitrate_kbps) const {
// Always allocate enough bitrate for the minimum bitrate of the first layer.
// Suspending below min bitrate is controlled outside the codec implementation
// and is not overridden by this.
const uint32_t min_bitrate_bps = codec_.numberOfSimulcastStreams == 0
? codec_.minBitrate
: codec_.simulcastStream[0].minBitrate;
uint32_t left_to_allocate = std::max(min_bitrate_bps, bitrate_kbps);
if (codec_.maxBitrate)
left_to_allocate = std::min(left_to_allocate, codec_.maxBitrate);
void SimulcastRateAllocator::OnTemporalLayersCreated(int simulcast_id,
TemporalLayers* layers) {
RTC_DCHECK(temporal_layers_.find(simulcast_id) == temporal_layers_.end());
temporal_layers_[simulcast_id] = layers;
}
if (codec_.numberOfSimulcastStreams < 2) {
BitrateAllocation SimulcastRateAllocator::GetAllocation(
uint32_t total_bitrate_bps,
uint32_t framerate) {
uint32_t left_to_allocate = total_bitrate_bps;
if (codec_.maxBitrate && codec_.maxBitrate * 1000 < left_to_allocate)
left_to_allocate = codec_.maxBitrate * 1000;
BitrateAllocation allocated_bitrates_bps;
if (codec_.numberOfSimulcastStreams == 0) {
// No simulcast, just set the target as this has been capped already.
return std::vector<uint32_t>(1, left_to_allocate);
allocated_bitrates_bps.SetBitrate(
0, 0, std::max(codec_.minBitrate * 1000, left_to_allocate));
} else {
// Always allocate enough bitrate for the minimum bitrate of the first
// layer. Suspending below min bitrate is controlled outside the codec
// implementation and is not overridden by this.
left_to_allocate =
std::max(codec_.simulcastStream[0].minBitrate * 1000, left_to_allocate);
// Begin by allocating bitrate to simulcast streams, putting all bitrate in
// temporal layer 0. We'll then distribute this bitrate, across potential
// temporal layers, when stream allocation is done.
// Allocate up to the target bitrate for each simulcast layer.
size_t layer = 0;
for (; layer < codec_.numberOfSimulcastStreams; ++layer) {
const SimulcastStream& stream = codec_.simulcastStream[layer];
if (left_to_allocate < stream.minBitrate * 1000)
break;
uint32_t allocation =
std::min(left_to_allocate, stream.targetBitrate * 1000);
allocated_bitrates_bps.SetBitrate(layer, 0, allocation);
RTC_DCHECK_LE(allocation, left_to_allocate);
left_to_allocate -= allocation;
}
// Next, try allocate remaining bitrate, up to max bitrate, in top stream.
// TODO(sprang): Allocate up to max bitrate for all layers once we have a
// better idea of possible performance implications.
if (left_to_allocate > 0) {
size_t active_layer = layer - 1;
const SimulcastStream& stream = codec_.simulcastStream[active_layer];
uint32_t bitrate_bps =
allocated_bitrates_bps.GetSpatialLayerSum(active_layer);
uint32_t allocation =
std::min(left_to_allocate, stream.maxBitrate * 1000 - bitrate_bps);
bitrate_bps += allocation;
RTC_DCHECK_LE(allocation, left_to_allocate);
left_to_allocate -= allocation;
allocated_bitrates_bps.SetBitrate(active_layer, 0, bitrate_bps);
}
}
// Initialize bitrates with zeroes.
std::vector<uint32_t> allocated_bitrates_bps(codec_.numberOfSimulcastStreams,
0);
const int num_spatial_streams =
std::max(1, static_cast<int>(codec_.numberOfSimulcastStreams));
// First try to allocate up to the target bitrate for each substream.
size_t layer = 0;
for (; layer < codec_.numberOfSimulcastStreams; ++layer) {
const SimulcastStream& stream = codec_.simulcastStream[layer];
if (left_to_allocate < stream.minBitrate)
break;
uint32_t allocation = std::min(left_to_allocate, stream.targetBitrate);
allocated_bitrates_bps[layer] = allocation;
left_to_allocate -= allocation;
}
// Finally, distribute the bitrate for the simulcast streams across the
// available temporal layers.
for (int simulcast_id = 0; simulcast_id < num_spatial_streams;
++simulcast_id) {
auto tl_it = temporal_layers_.find(simulcast_id);
if (tl_it == temporal_layers_.end())
continue; // TODO(sprang): If > 1 SS, assume default TL alloc?
// Next, try allocate remaining bitrate, up to max bitrate, in top layer.
// TODO(sprang): Allocate up to max bitrate for all layers once we have a
// better idea of possible performance implications.
if (left_to_allocate > 0) {
size_t active_layer = layer - 1;
const SimulcastStream& stream = codec_.simulcastStream[active_layer];
uint32_t allocation =
std::min(left_to_allocate,
stream.maxBitrate - allocated_bitrates_bps[active_layer]);
left_to_allocate -= allocation;
allocated_bitrates_bps[active_layer] += allocation;
uint32_t target_bitrate_kbps =
allocated_bitrates_bps.GetBitrate(simulcast_id, 0) / 1000;
RTC_DCHECK_EQ(
target_bitrate_kbps,
allocated_bitrates_bps.GetSpatialLayerSum(simulcast_id) / 1000);
uint32_t max_bitrate_kbps;
if (codec_.numberOfSimulcastStreams == 0) {
max_bitrate_kbps = codec_.maxBitrate;
// TODO(holmer): This is a temporary hack for screensharing, where we
// interpret the startBitrate as the encoder target bitrate. This is
// to allow for a different max bitrate, so if the codec can't meet
// the target we still allow it to overshoot up to the max before dropping
// frames. This hack should be improved.
if (codec_.mode == kScreensharing && codec_.targetBitrate > 0 &&
(codec_.codecSpecific.VP8.numberOfTemporalLayers == 2 ||
codec_.simulcastStream[0].numberOfTemporalLayers == 2)) {
int tl0_bitrate = std::min(codec_.targetBitrate, target_bitrate_kbps);
max_bitrate_kbps = std::min(codec_.maxBitrate, target_bitrate_kbps);
target_bitrate_kbps = tl0_bitrate;
}
} else {
max_bitrate_kbps = codec_.simulcastStream[simulcast_id].maxBitrate;
}
std::vector<uint32_t> tl_allocation = tl_it->second->OnRatesUpdated(
target_bitrate_kbps, max_bitrate_kbps, framerate);
for (size_t tl_index = 0; tl_index < tl_allocation.size(); ++tl_index) {
allocated_bitrates_bps.SetBitrate(simulcast_id, tl_index,
tl_allocation[tl_index] * 1000);
}
}
return allocated_bitrates_bps;
}
uint32_t SimulcastRateAllocator::GetPreferedBitrate() const {
std::vector<uint32_t> rates = GetAllocation(codec_.maxBitrate);
uint32_t preferred_bitrate = 0;
for (const uint32_t& rate : rates) {
preferred_bitrate += rate;
}
return preferred_bitrate;
uint32_t SimulcastRateAllocator::GetPreferredBitrateBps(uint32_t framerate) {
BitrateAllocation allocation =
GetAllocation(codec_.maxBitrate * 1000, framerate);
return allocation.get_sum_bps();
}
const VideoCodec& webrtc::SimulcastRateAllocator::GetCodec() const {

View File

@ -11,24 +11,36 @@
#ifndef WEBRTC_MODULES_VIDEO_CODING_UTILITY_SIMULCAST_RATE_ALLOCATOR_H_
#define WEBRTC_MODULES_VIDEO_CODING_UTILITY_SIMULCAST_RATE_ALLOCATOR_H_
#include <vector>
#include <map>
#include <memory>
#include "webrtc/base/basictypes.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/common_video/include/video_bitrate_allocator.h"
#include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
#include "webrtc/video_encoder.h"
namespace webrtc {
class SimulcastRateAllocator {
class SimulcastRateAllocator : public VideoBitrateAllocator,
public TemporalLayersListener {
public:
explicit SimulcastRateAllocator(const VideoCodec& codec);
explicit SimulcastRateAllocator(
const VideoCodec& codec,
std::unique_ptr<TemporalLayersFactory> tl_factory);
std::vector<uint32_t> GetAllocation(uint32_t bitrate_kbps) const;
uint32_t GetPreferedBitrate() const;
void OnTemporalLayersCreated(int simulcast_id,
TemporalLayers* layers) override;
BitrateAllocation GetAllocation(uint32_t total_bitrate_bps,
uint32_t framerate) override;
uint32_t GetPreferredBitrateBps(uint32_t framerate) override;
const VideoCodec& GetCodec() const;
private:
const VideoCodec codec_;
std::map<uint32_t, TemporalLayers*> temporal_layers_;
std::unique_ptr<TemporalLayersFactory> tl_factory_;
RTC_DISALLOW_COPY_AND_ASSIGN(SimulcastRateAllocator);
};

View File

@ -12,6 +12,7 @@
#include <limits>
#include <memory>
#include <vector>
#include "webrtc/test/gtest.h"
@ -41,43 +42,59 @@ class SimulcastRateAllocatorTest : public ::testing::Test {
EXPECT_EQ(expected[i], actual[i]) << "Mismatch at index " << i;
}
template <size_t S>
void ExpectEqual(uint32_t (&expected)[S], const BitrateAllocation& actual) {
// EXPECT_EQ(S, actual.size());
uint32_t sum = 0;
for (size_t i = 0; i < S; ++i) {
uint32_t layer_bitrate = actual.GetSpatialLayerSum(i);
EXPECT_EQ(expected[i] * 1000, layer_bitrate) << "Mismatch at index " << i;
sum += layer_bitrate;
}
EXPECT_EQ(sum, actual.get_sum_bps());
}
void CreateAllocator() {
allocator_.reset(new SimulcastRateAllocator(codec_));
allocator_.reset(new SimulcastRateAllocator(codec_, nullptr));
}
BitrateAllocation GetAllocation(uint32_t target_bitrate) {
return allocator_->GetAllocation(target_bitrate * 1000, kDefaultFrameRate);
}
protected:
static const int kDefaultFrameRate = 30;
VideoCodec codec_;
std::unique_ptr<SimulcastRateAllocator> allocator_;
};
TEST_F(SimulcastRateAllocatorTest, NoSimulcastBelowMin) {
uint32_t expected[] = {codec_.minBitrate};
ExpectEqual(expected, allocator_->GetAllocation(codec_.minBitrate - 1));
ExpectEqual(expected, allocator_->GetAllocation(1));
ExpectEqual(expected, allocator_->GetAllocation(0));
ExpectEqual(expected, GetAllocation(codec_.minBitrate - 1));
ExpectEqual(expected, GetAllocation(1));
ExpectEqual(expected, GetAllocation(0));
}
TEST_F(SimulcastRateAllocatorTest, NoSimulcastAboveMax) {
uint32_t expected[] = {codec_.maxBitrate};
ExpectEqual(expected, allocator_->GetAllocation(codec_.maxBitrate + 1));
ExpectEqual(expected,
allocator_->GetAllocation(std::numeric_limits<uint32_t>::max()));
ExpectEqual(expected, GetAllocation(codec_.maxBitrate + 1));
ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max()));
}
TEST_F(SimulcastRateAllocatorTest, NoSimulcastNoMax) {
constexpr uint32_t kMax = std::numeric_limits<uint32_t>::max();
const uint32_t kMax = BitrateAllocation::kMaxBitrateBps / 1000;
codec_.maxBitrate = 0;
CreateAllocator();
uint32_t expected[] = {kMax};
ExpectEqual(expected, allocator_->GetAllocation(kMax));
ExpectEqual(expected, GetAllocation(kMax));
}
TEST_F(SimulcastRateAllocatorTest, NoSimulcastWithinLimits) {
for (uint32_t bitrate = codec_.minBitrate; bitrate <= codec_.maxBitrate;
++bitrate) {
uint32_t expected[] = {bitrate};
ExpectEqual(expected, allocator_->GetAllocation(bitrate));
ExpectEqual(expected, GetAllocation(bitrate));
}
}
@ -90,9 +107,9 @@ TEST_F(SimulcastRateAllocatorTest, SingleSimulcastBelowMin) {
CreateAllocator();
uint32_t expected[] = {kMin};
ExpectEqual(expected, allocator_->GetAllocation(kMin - 1));
ExpectEqual(expected, allocator_->GetAllocation(1));
ExpectEqual(expected, allocator_->GetAllocation(0));
ExpectEqual(expected, GetAllocation(kMin - 1));
ExpectEqual(expected, GetAllocation(1));
ExpectEqual(expected, GetAllocation(0));
}
TEST_F(SimulcastRateAllocatorTest, SingleSimulcastAboveMax) {
@ -103,9 +120,9 @@ TEST_F(SimulcastRateAllocatorTest, SingleSimulcastAboveMax) {
CreateAllocator();
uint32_t expected[] = {kMax};
ExpectEqual(expected, allocator_->GetAllocation(kMax + 1));
ExpectEqual(expected,
allocator_->GetAllocation(std::numeric_limits<uint32_t>::max()));
ExpectEqual(expected, GetAllocation(kMax));
ExpectEqual(expected, GetAllocation(kMax + 1));
ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max()));
}
TEST_F(SimulcastRateAllocatorTest, SingleSimulcastWithinLimits) {
@ -117,7 +134,7 @@ TEST_F(SimulcastRateAllocatorTest, SingleSimulcastWithinLimits) {
for (uint32_t bitrate = kMinBitrate; bitrate <= kMaxBitrate; ++bitrate) {
uint32_t expected[] = {bitrate};
ExpectEqual(expected, allocator_->GetAllocation(bitrate));
ExpectEqual(expected, GetAllocation(bitrate));
}
}
@ -139,14 +156,14 @@ TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
// Single stream, min bitrate.
const uint32_t bitrate = codec_.simulcastStream[0].minBitrate;
uint32_t expected[] = {bitrate, 0, 0};
ExpectEqual(expected, allocator_->GetAllocation(bitrate));
ExpectEqual(expected, GetAllocation(bitrate));
}
{
// Single stream at target bitrate.
const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate;
uint32_t expected[] = {bitrate, 0, 0};
ExpectEqual(expected, allocator_->GetAllocation(bitrate));
ExpectEqual(expected, GetAllocation(bitrate));
}
{
@ -154,7 +171,7 @@ TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
codec_.simulcastStream[1].minBitrate - 1;
uint32_t expected[] = {bitrate, 0, 0};
ExpectEqual(expected, allocator_->GetAllocation(bitrate));
ExpectEqual(expected, GetAllocation(bitrate));
}
{
@ -163,7 +180,7 @@ TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
codec_.simulcastStream[1].minBitrate;
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
codec_.simulcastStream[1].minBitrate, 0};
ExpectEqual(expected, allocator_->GetAllocation(bitrate));
ExpectEqual(expected, GetAllocation(bitrate));
}
{
@ -172,7 +189,7 @@ TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
codec_.simulcastStream[1].maxBitrate;
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
codec_.simulcastStream[1].maxBitrate, 0};
ExpectEqual(expected, allocator_->GetAllocation(bitrate));
ExpectEqual(expected, GetAllocation(bitrate));
}
{
@ -182,7 +199,7 @@ TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
codec_.simulcastStream[1].maxBitrate + 499;
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
codec_.simulcastStream[1].maxBitrate, 0};
ExpectEqual(expected, allocator_->GetAllocation(bitrate));
ExpectEqual(expected, GetAllocation(bitrate));
}
{
@ -193,7 +210,7 @@ TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
codec_.simulcastStream[1].targetBitrate,
codec_.simulcastStream[2].minBitrate};
ExpectEqual(expected, allocator_->GetAllocation(bitrate));
ExpectEqual(expected, GetAllocation(bitrate));
}
{
@ -204,12 +221,13 @@ TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
codec_.simulcastStream[1].targetBitrate,
codec_.simulcastStream[2].maxBitrate};
ExpectEqual(expected, allocator_->GetAllocation(bitrate));
ExpectEqual(expected, GetAllocation(bitrate));
}
}
TEST_F(SimulcastRateAllocatorTest, GetPreferredBitrate) {
EXPECT_EQ(codec_.maxBitrate, allocator_->GetPreferedBitrate());
TEST_F(SimulcastRateAllocatorTest, GetPreferredBitrateBps) {
EXPECT_EQ(codec_.maxBitrate * 1000,
allocator_->GetPreferredBitrateBps(codec_.maxFramerate));
}
TEST_F(SimulcastRateAllocatorTest, GetPreferredBitrateSimulcast) {
@ -228,12 +246,13 @@ TEST_F(SimulcastRateAllocatorTest, GetPreferredBitrateSimulcast) {
codec_.simulcastStream[2].maxBitrate = 4000;
CreateAllocator();
uint32_t preferred_bitrate;
preferred_bitrate = codec_.simulcastStream[0].targetBitrate;
preferred_bitrate += codec_.simulcastStream[1].targetBitrate;
preferred_bitrate += codec_.simulcastStream[2].maxBitrate;
uint32_t preferred_bitrate_kbps;
preferred_bitrate_kbps = codec_.simulcastStream[0].targetBitrate;
preferred_bitrate_kbps += codec_.simulcastStream[1].targetBitrate;
preferred_bitrate_kbps += codec_.simulcastStream[2].maxBitrate;
EXPECT_EQ(preferred_bitrate, allocator_->GetPreferedBitrate());
EXPECT_EQ(preferred_bitrate_kbps * 1000,
allocator_->GetPreferredBitrateBps(codec_.maxFramerate));
}
} // namespace webrtc

View File

@ -19,6 +19,8 @@
'<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers',
],
'sources': [
'default_video_bitrate_allocator.cc',
'default_video_bitrate_allocator.h',
'frame_dropper.cc',
'frame_dropper.h',
'ivf_file_writer.cc',