1 /*
2 * Copyright (c) 2020 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 "modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.h"
12
13 #include "api/video/video_layers_allocation.h"
14 #include "rtc_base/bit_buffer.h"
15 #include "rtc_base/buffer.h"
16
17 #include "test/gmock.h"
18
19 namespace webrtc {
20 namespace {
21
TEST(RtpVideoLayersAllocationExtension,WriteEmptyLayersAllocationReturnsTrue)22 TEST(RtpVideoLayersAllocationExtension, WriteEmptyLayersAllocationReturnsTrue) {
23 VideoLayersAllocation written_allocation;
24 rtc::Buffer buffer(
25 RtpVideoLayersAllocationExtension::ValueSize(written_allocation));
26 EXPECT_TRUE(
27 RtpVideoLayersAllocationExtension::Write(buffer, written_allocation));
28 }
29
TEST(RtpVideoLayersAllocationExtension,CanWriteAndParseLayersAllocationWithZeroSpatialLayers)30 TEST(RtpVideoLayersAllocationExtension,
31 CanWriteAndParseLayersAllocationWithZeroSpatialLayers) {
32 // We require the resolution_and_frame_rate_is_valid to be set to true in
33 // order to send an "empty" allocation.
34 VideoLayersAllocation written_allocation;
35 written_allocation.resolution_and_frame_rate_is_valid = true;
36 written_allocation.rtp_stream_index = 0;
37
38 rtc::Buffer buffer(
39 RtpVideoLayersAllocationExtension::ValueSize(written_allocation));
40 EXPECT_TRUE(
41 RtpVideoLayersAllocationExtension::Write(buffer, written_allocation));
42
43 VideoLayersAllocation parsed_allocation;
44 EXPECT_TRUE(
45 RtpVideoLayersAllocationExtension::Parse(buffer, &parsed_allocation));
46 EXPECT_EQ(written_allocation, parsed_allocation);
47 }
48
TEST(RtpVideoLayersAllocationExtension,CanWriteAndParse2SpatialWith2TemporalLayers)49 TEST(RtpVideoLayersAllocationExtension,
50 CanWriteAndParse2SpatialWith2TemporalLayers) {
51 VideoLayersAllocation written_allocation;
52 written_allocation.rtp_stream_index = 1;
53 written_allocation.active_spatial_layers = {
54 {
55 /*rtp_stream_index*/ 0,
56 /*spatial_id*/ 0,
57 /*target_bitrate_per_temporal_layer*/
58 {DataRate::KilobitsPerSec(25), DataRate::KilobitsPerSec(50)},
59 /*width*/ 0,
60 /*height*/ 0,
61 /*frame_rate_fps*/ 0,
62 },
63 {
64 /*rtp_stream_index*/ 1,
65 /*spatial_id*/ 0,
66 /*target_bitrate_per_temporal_layer*/
67 {DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200)},
68 /*width*/ 0,
69 /*height*/ 0,
70 /*frame_rate_fps*/ 0,
71 },
72 };
73 rtc::Buffer buffer(
74 RtpVideoLayersAllocationExtension::ValueSize(written_allocation));
75 EXPECT_TRUE(
76 RtpVideoLayersAllocationExtension::Write(buffer, written_allocation));
77 VideoLayersAllocation parsed_allocation;
78 EXPECT_TRUE(
79 RtpVideoLayersAllocationExtension::Parse(buffer, &parsed_allocation));
80 EXPECT_EQ(written_allocation, parsed_allocation);
81 }
82
TEST(RtpVideoLayersAllocationExtension,CanWriteAndParseAllocationWithDifferentNumerOfSpatialLayers)83 TEST(RtpVideoLayersAllocationExtension,
84 CanWriteAndParseAllocationWithDifferentNumerOfSpatialLayers) {
85 VideoLayersAllocation written_allocation;
86 written_allocation.rtp_stream_index = 1;
87 written_allocation.active_spatial_layers = {
88 {/*rtp_stream_index*/ 0,
89 /*spatial_id*/ 0,
90 /*target_bitrate_per_temporal_layer*/ {DataRate::KilobitsPerSec(50)},
91 /*width*/ 0,
92 /*height*/ 0,
93 /*frame_rate_fps*/ 0},
94 {/*rtp_stream_index*/ 1,
95 /*spatial_id*/ 0,
96 /*target_bitrate_per_temporal_layer*/ {DataRate::KilobitsPerSec(100)},
97 /*width*/ 0,
98 /*height*/ 0,
99 /*frame_rate_fps*/ 0},
100 {/*rtp_stream_index*/ 1,
101 /*spatial_id*/ 1,
102 /*target_bitrate_per_temporal_layer*/ {DataRate::KilobitsPerSec(200)},
103 /*width*/ 0,
104 /*height*/ 0,
105 /*frame_rate_fps*/ 0},
106 };
107 rtc::Buffer buffer(
108 RtpVideoLayersAllocationExtension::ValueSize(written_allocation));
109 EXPECT_TRUE(
110 RtpVideoLayersAllocationExtension::Write(buffer, written_allocation));
111 VideoLayersAllocation parsed_allocation;
112 EXPECT_TRUE(
113 RtpVideoLayersAllocationExtension::Parse(buffer, &parsed_allocation));
114 EXPECT_EQ(written_allocation, parsed_allocation);
115 }
116
TEST(RtpVideoLayersAllocationExtension,CanWriteAndParseAllocationWithSkippedLowerSpatialLayer)117 TEST(RtpVideoLayersAllocationExtension,
118 CanWriteAndParseAllocationWithSkippedLowerSpatialLayer) {
119 VideoLayersAllocation written_allocation;
120 written_allocation.rtp_stream_index = 1;
121 written_allocation.active_spatial_layers = {
122 {/*rtp_stream_index*/ 0,
123 /*spatial_id*/ 0,
124 /*target_bitrate_per_temporal_layer*/ {DataRate::KilobitsPerSec(50)},
125 /*width*/ 0,
126 /*height*/ 0,
127 /*frame_rate_fps*/ 0},
128 {/*rtp_stream_index*/ 1,
129 /*spatial_id*/ 1,
130 /*target_bitrate_per_temporal_layer*/ {DataRate::KilobitsPerSec(200)},
131 /*width*/ 0,
132 /*height*/ 0,
133 /*frame_rate_fps*/ 0},
134 };
135 rtc::Buffer buffer(
136 RtpVideoLayersAllocationExtension::ValueSize(written_allocation));
137 EXPECT_TRUE(
138 RtpVideoLayersAllocationExtension::Write(buffer, written_allocation));
139 VideoLayersAllocation parsed_allocation;
140 EXPECT_TRUE(
141 RtpVideoLayersAllocationExtension::Parse(buffer, &parsed_allocation));
142 EXPECT_EQ(written_allocation, parsed_allocation);
143 }
144
TEST(RtpVideoLayersAllocationExtension,CanWriteAndParseAllocationWithSkippedRtpStreamIds)145 TEST(RtpVideoLayersAllocationExtension,
146 CanWriteAndParseAllocationWithSkippedRtpStreamIds) {
147 VideoLayersAllocation written_allocation;
148 written_allocation.rtp_stream_index = 2;
149 written_allocation.active_spatial_layers = {
150 {/*rtp_stream_index*/ 0,
151 /*spatial_id*/ 0,
152 /*target_bitrate_per_temporal_layer*/ {DataRate::KilobitsPerSec(50)},
153 /*width*/ 0,
154 /*height*/ 0,
155 /*frame_rate_fps*/ 0},
156 {/*rtp_stream_index*/ 2,
157 /*spatial_id*/ 0,
158 /*target_bitrate_per_temporal_layer*/ {DataRate::KilobitsPerSec(200)},
159 /*width*/ 0,
160 /*height*/ 0,
161 /*frame_rate_fps*/ 0},
162 };
163 rtc::Buffer buffer(
164 RtpVideoLayersAllocationExtension::ValueSize(written_allocation));
165 EXPECT_TRUE(
166 RtpVideoLayersAllocationExtension::Write(buffer, written_allocation));
167 VideoLayersAllocation parsed_allocation;
168 EXPECT_TRUE(
169 RtpVideoLayersAllocationExtension::Parse(buffer, &parsed_allocation));
170 EXPECT_EQ(written_allocation, parsed_allocation);
171 }
172
TEST(RtpVideoLayersAllocationExtension,CanWriteAndParseAllocationWithDifferentNumerOfTemporalLayers)173 TEST(RtpVideoLayersAllocationExtension,
174 CanWriteAndParseAllocationWithDifferentNumerOfTemporalLayers) {
175 VideoLayersAllocation written_allocation;
176 written_allocation.rtp_stream_index = 1;
177 written_allocation.active_spatial_layers = {
178 {
179 /*rtp_stream_index*/ 0,
180 /*spatial_id*/ 0,
181 /*target_bitrate_per_temporal_layer*/
182 {DataRate::KilobitsPerSec(25), DataRate::KilobitsPerSec(50)},
183 /*width*/ 0,
184 /*height*/ 0,
185 /*frame_rate_fps*/ 0,
186 },
187 {
188 /*rtp_stream_index*/ 1,
189 /*spatial_id*/ 0,
190 /*target_bitrate_per_temporal_layer*/ {DataRate::KilobitsPerSec(100)},
191 /*width*/ 0,
192 /*height*/ 0,
193 /*frame_rate_fps*/ 0,
194 },
195 };
196 rtc::Buffer buffer(
197 RtpVideoLayersAllocationExtension::ValueSize(written_allocation));
198 EXPECT_TRUE(
199 RtpVideoLayersAllocationExtension::Write(buffer, written_allocation));
200 VideoLayersAllocation parsed_allocation;
201 EXPECT_TRUE(
202 RtpVideoLayersAllocationExtension::Parse(buffer, &parsed_allocation));
203 EXPECT_EQ(written_allocation, parsed_allocation);
204 }
205
TEST(RtpVideoLayersAllocationExtension,CanWriteAndParseAllocationWithResolution)206 TEST(RtpVideoLayersAllocationExtension,
207 CanWriteAndParseAllocationWithResolution) {
208 VideoLayersAllocation written_allocation;
209 written_allocation.rtp_stream_index = 1;
210 written_allocation.resolution_and_frame_rate_is_valid = true;
211 written_allocation.active_spatial_layers = {
212 {
213 /*rtp_stream_index*/ 0,
214 /*spatial_id*/ 0,
215 /*target_bitrate_per_temporal_layer*/
216 {DataRate::KilobitsPerSec(25), DataRate::KilobitsPerSec(50)},
217 /*width*/ 320,
218 /*height*/ 240,
219 /*frame_rate_fps*/ 8,
220 },
221 {
222 /*rtp_stream_index*/ 1,
223 /*spatial_id*/ 1,
224 /*target_bitrate_per_temporal_layer*/
225 {DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200)},
226 /*width*/ 640,
227 /*height*/ 320,
228 /*frame_rate_fps*/ 30,
229 },
230 };
231
232 rtc::Buffer buffer(
233 RtpVideoLayersAllocationExtension::ValueSize(written_allocation));
234 EXPECT_TRUE(
235 RtpVideoLayersAllocationExtension::Write(buffer, written_allocation));
236 VideoLayersAllocation parsed_allocation;
237 EXPECT_TRUE(
238 RtpVideoLayersAllocationExtension::Parse(buffer, &parsed_allocation));
239 EXPECT_EQ(written_allocation, parsed_allocation);
240 }
241
TEST(RtpVideoLayersAllocationExtension,WriteEmptyAllocationCanHaveAnyRtpStreamIndex)242 TEST(RtpVideoLayersAllocationExtension,
243 WriteEmptyAllocationCanHaveAnyRtpStreamIndex) {
244 VideoLayersAllocation written_allocation;
245 written_allocation.rtp_stream_index = 1;
246 rtc::Buffer buffer(
247 RtpVideoLayersAllocationExtension::ValueSize(written_allocation));
248 EXPECT_TRUE(
249 RtpVideoLayersAllocationExtension::Write(buffer, written_allocation));
250 }
251
TEST(RtpVideoLayersAllocationExtension,DiscardsOverLargeDataRate)252 TEST(RtpVideoLayersAllocationExtension, DiscardsOverLargeDataRate) {
253 constexpr uint8_t buffer[] = {0x4b, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff,
254 0xff, 0xcb, 0x78, 0xeb, 0x8d, 0xb5, 0x31};
255 VideoLayersAllocation allocation;
256 EXPECT_FALSE(RtpVideoLayersAllocationExtension::Parse(buffer, &allocation));
257 }
258
TEST(RtpVideoLayersAllocationExtension,DiscardsInvalidHeight)259 TEST(RtpVideoLayersAllocationExtension, DiscardsInvalidHeight) {
260 VideoLayersAllocation written_allocation;
261 written_allocation.rtp_stream_index = 0;
262 written_allocation.resolution_and_frame_rate_is_valid = true;
263 written_allocation.active_spatial_layers = {
264 {
265 /*rtp_stream_index*/ 0,
266 /*spatial_id*/ 0,
267 /*target_bitrate_per_temporal_layer*/
268 {DataRate::KilobitsPerSec(25), DataRate::KilobitsPerSec(50)},
269 /*width*/ 320,
270 /*height*/ 240,
271 /*frame_rate_fps*/ 8,
272 },
273 };
274 rtc::Buffer buffer(
275 RtpVideoLayersAllocationExtension::ValueSize(written_allocation));
276 ASSERT_TRUE(
277 RtpVideoLayersAllocationExtension::Write(buffer, written_allocation));
278
279 // Modify the height to be invalid.
280 buffer[buffer.size() - 3] = 0xff;
281 buffer[buffer.size() - 2] = 0xff;
282 VideoLayersAllocation allocation;
283 EXPECT_FALSE(RtpVideoLayersAllocationExtension::Parse(buffer, &allocation));
284 }
285
286 } // namespace
287 } // namespace webrtc
288