blob: f36ac035e0505d7b7bbc0e17ad35bd05d1c7c646 [file] [log] [blame]
Åsa Persson31cb8f92018-06-27 10:44:56 +02001/*
2 * Copyright 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "media/engine/simulcast.h"
12
13#include "media/engine/constants.h"
14#include "test/field_trial.h"
15#include "test/gtest.h"
16
17namespace webrtc {
18namespace {
19constexpr int kQpMax = 55;
20constexpr double kBitratePriority = 2.0;
21constexpr int kMaxFps = 33;
22constexpr int kMaxBitrateBps = 0;
23constexpr bool kScreenshare = true;
24constexpr int kDefaultTemporalLayers = 3; // Value from simulcast.cc.
25
26// Values from kSimulcastConfigs in simulcast.cc.
27const std::vector<VideoStream> GetSimulcastBitrates720p() {
28 std::vector<VideoStream> streams(3);
29 streams[0].min_bitrate_bps = 30000;
30 streams[0].target_bitrate_bps = 150000;
31 streams[0].max_bitrate_bps = 200000;
32 streams[1].min_bitrate_bps = 150000;
33 streams[1].target_bitrate_bps = 500000;
34 streams[1].max_bitrate_bps = 700000;
35 streams[2].min_bitrate_bps = 600000;
36 streams[2].target_bitrate_bps = 2500000;
37 streams[2].max_bitrate_bps = 2500000;
38 return streams;
39}
40} // namespace
41
42TEST(SimulcastTest, TotalMaxBitrateIsZeroForNoStreams) {
43 std::vector<VideoStream> streams;
44 EXPECT_EQ(0, cricket::GetTotalMaxBitrateBps(streams));
45}
46
47TEST(SimulcastTest, GetTotalMaxBitrateForSingleStream) {
48 std::vector<VideoStream> streams(1);
49 streams[0].max_bitrate_bps = 100000;
50 EXPECT_EQ(100000, cricket::GetTotalMaxBitrateBps(streams));
51}
52
53TEST(SimulcastTest, GetTotalMaxBitrateForMultipleStreams) {
54 std::vector<VideoStream> streams(3);
55 streams[0].target_bitrate_bps = 100000;
56 streams[1].target_bitrate_bps = 200000;
57 streams[2].max_bitrate_bps = 400000;
58 EXPECT_EQ(700000, cricket::GetTotalMaxBitrateBps(streams));
59}
60
61TEST(SimulcastTest, BandwidthAboveTotalMaxBitrateGivenToHighestStream) {
62 std::vector<VideoStream> streams(3);
63 streams[0].target_bitrate_bps = 100000;
64 streams[1].target_bitrate_bps = 200000;
65 streams[2].max_bitrate_bps = 400000;
66
67 // No bitrate above the total max to give to the highest stream.
68 const int kMaxTotalBps = cricket::GetTotalMaxBitrateBps(streams);
69 cricket::BoostMaxSimulcastLayer(kMaxTotalBps, &streams);
70 EXPECT_EQ(400000, streams[2].max_bitrate_bps);
71 EXPECT_EQ(kMaxTotalBps, cricket::GetTotalMaxBitrateBps(streams));
72
73 // The bitrate above the total max should be given to the highest stream.
74 cricket::BoostMaxSimulcastLayer(kMaxTotalBps + 1, &streams);
75 EXPECT_EQ(400000 + 1, streams[2].max_bitrate_bps);
76 EXPECT_EQ(kMaxTotalBps + 1, cricket::GetTotalMaxBitrateBps(streams));
77}
78
79TEST(SimulcastTest, GetConfig) {
80 const std::vector<VideoStream> kExpected = GetSimulcastBitrates720p();
81
82 const size_t kMaxLayers = 3;
83 std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
84 kMaxLayers, 1280, 720, kMaxBitrateBps, kBitratePriority, kQpMax, kMaxFps,
85 !kScreenshare);
86
87 EXPECT_EQ(kMaxLayers, streams.size());
88 EXPECT_EQ(320u, streams[0].width);
89 EXPECT_EQ(180u, streams[0].height);
90 EXPECT_EQ(640u, streams[1].width);
91 EXPECT_EQ(360u, streams[1].height);
92 EXPECT_EQ(1280u, streams[2].width);
93 EXPECT_EQ(720u, streams[2].height);
94
95 for (size_t i = 0; i < streams.size(); ++i) {
96 EXPECT_EQ(kDefaultTemporalLayers, streams[i].num_temporal_layers);
97 EXPECT_EQ(kMaxFps, streams[i].max_framerate);
98 EXPECT_EQ(kQpMax, streams[i].max_qp);
99 EXPECT_EQ(kExpected[i].min_bitrate_bps, streams[i].min_bitrate_bps);
100 EXPECT_EQ(kExpected[i].target_bitrate_bps, streams[i].target_bitrate_bps);
101 EXPECT_EQ(kExpected[i].max_bitrate_bps, streams[i].max_bitrate_bps);
102 EXPECT_TRUE(streams[i].active);
103 }
104 // Currently set on lowest stream.
105 EXPECT_EQ(kBitratePriority, streams[0].bitrate_priority);
106 EXPECT_FALSE(streams[1].bitrate_priority);
107 EXPECT_FALSE(streams[2].bitrate_priority);
108}
109
110TEST(SimulcastTest, GetConfigWithLimitedMaxLayers) {
111 const size_t kMaxLayers = 2;
112 std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
113 kMaxLayers, 1280, 720, kMaxBitrateBps, kBitratePriority, kQpMax, kMaxFps,
114 !kScreenshare);
115
116 EXPECT_EQ(kMaxLayers, streams.size());
117 EXPECT_EQ(320u, streams[0].width);
118 EXPECT_EQ(180u, streams[0].height);
119 EXPECT_EQ(640u, streams[1].width);
120 EXPECT_EQ(360u, streams[1].height);
121}
122
123TEST(SimulcastTest, GetConfigWithNormalizedResolution) {
124 const size_t kMaxLayers = 2;
125 std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
126 kMaxLayers, 640 + 1, 360 + 1, kMaxBitrateBps, kBitratePriority, kQpMax,
127 kMaxFps, !kScreenshare);
128
129 // Must be dividable by |2 ^ (num_layers - 1)|.
130 EXPECT_EQ(kMaxLayers, streams.size());
131 EXPECT_EQ(320u, streams[0].width);
132 EXPECT_EQ(180u, streams[0].height);
133 EXPECT_EQ(640u, streams[1].width);
134 EXPECT_EQ(360u, streams[1].height);
135}
136
137TEST(SimulcastTest, GetConfigForScreenshare) {
138 const size_t kMaxLayers = 3;
139 std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
140 kMaxLayers, 1400, 800, kMaxBitrateBps, kBitratePriority, kQpMax, kMaxFps,
141 kScreenshare);
142
143 EXPECT_EQ(1u, streams.size()) << "No simulcast.";
144 EXPECT_EQ(1400u, streams[0].width);
145 EXPECT_EQ(800u, streams[0].height);
146 EXPECT_EQ(kQpMax, streams[0].max_qp);
147 EXPECT_EQ(kBitratePriority, streams[0].bitrate_priority);
148 EXPECT_TRUE(streams[0].active);
149 EXPECT_GT(streams[0].num_temporal_layers, 1);
150 EXPECT_GT(streams[0].max_framerate, 0);
151 EXPECT_EQ(cricket::kMinVideoBitrateBps, streams[0].min_bitrate_bps);
152 EXPECT_GT(streams[0].target_bitrate_bps, streams[0].min_bitrate_bps);
153 EXPECT_GT(streams[0].max_bitrate_bps, streams[0].target_bitrate_bps);
154}
155
156TEST(SimulcastTest, GetConfigForScreenshareSimulcast) {
157 test::ScopedFieldTrials field_trials("WebRTC-SimulcastScreenshare/Enabled/");
158
159 const size_t kMaxLayers = 3;
160 std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
161 kMaxLayers, 1400, 800, kMaxBitrateBps, kBitratePriority, kQpMax, kMaxFps,
162 kScreenshare);
163
164 EXPECT_GT(streams.size(), 1u);
165 for (size_t i = 0; i < streams.size(); ++i) {
166 EXPECT_EQ(1400u, streams[i].width) << "Screen content never scaled.";
167 EXPECT_EQ(800u, streams[i].height) << "Screen content never scaled.";
168 EXPECT_EQ(kQpMax, streams[i].max_qp);
169 EXPECT_TRUE(streams[i].active);
170 EXPECT_GT(streams[i].num_temporal_layers, 1);
171 EXPECT_GT(streams[i].max_framerate, 0);
172 EXPECT_GT(streams[i].min_bitrate_bps, 0);
173 EXPECT_GT(streams[i].target_bitrate_bps, streams[i].min_bitrate_bps);
174 EXPECT_GE(streams[i].max_bitrate_bps, streams[i].target_bitrate_bps);
175 }
176}
177
178TEST(SimulcastTest, GetConfigForScreenshareSimulcastWithLimitedMaxLayers) {
179 test::ScopedFieldTrials field_trials("WebRTC-SimulcastScreenshare/Enabled/");
180
181 const size_t kMaxLayers = 1;
182 std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
183 kMaxLayers, 1400, 800, kMaxBitrateBps, kBitratePriority, kQpMax, kMaxFps,
184 kScreenshare);
185
186 EXPECT_EQ(kMaxLayers, streams.size());
187}
188
189} // namespace webrtc