blob: e8056798907f36dc8afae9e9e77d7032f2a3b8bc [file] [log] [blame]
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2010 The WebRTC project authors. All Rights Reserved.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * 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.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +00009 */
10
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000011#include <limits.h> // For INT_MAX
kwiberg686a8ef2016-02-26 03:00:35 -080012
kwibergbfefb032016-05-01 14:53:46 -070013#include <memory>
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000014#include <string>
15#include <vector>
16
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000017#include "webrtc/base/gunit.h"
18#include "webrtc/base/logging.h"
kjellandera96e2d72016-02-04 23:52:28 -080019#include "webrtc/media/base/fakevideocapturer.h"
20#include "webrtc/media/base/mediachannel.h"
21#include "webrtc/media/base/testutils.h"
22#include "webrtc/media/base/videoadapter.h"
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000023
24namespace cricket {
25
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000026class VideoAdapterTest : public testing::Test {
27 public:
28 virtual void SetUp() {
Magnus Jedvert01840572015-04-10 11:18:39 +020029 capturer_.reset(new FakeVideoCapturer);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000030 capture_format_ = capturer_->GetSupportedFormats()->at(0);
magjed604abe02016-05-19 06:05:40 -070031 capture_format_.interval = VideoFormat::FpsToInterval(30);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000032
Per766ad3b2016-04-05 15:23:49 +020033 listener_.reset(new VideoCapturerListener(&adapter_));
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000034 capturer_->SignalFrameCaptured.connect(
35 listener_.get(), &VideoCapturerListener::OnFrameCaptured);
36 }
37
pbos@webrtc.org75c3ec12014-08-27 18:16:13 +000038 virtual void TearDown() {
39 // Explicitly disconnect the VideoCapturer before to avoid data races
40 // (frames delivered to VideoCapturerListener while it's being destructed).
41 capturer_->SignalFrameCaptured.disconnect_all();
42 }
43
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000044 protected:
45 class VideoCapturerListener: public sigslot::has_slots<> {
46 public:
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000047 struct Stats {
48 int captured_frames;
49 int dropped_frames;
50 bool last_adapt_was_no_op;
51
magjed709f73c2016-05-13 10:26:00 -070052 int cropped_width;
53 int cropped_height;
54 int out_width;
55 int out_height;
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000056 };
57
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000058 explicit VideoCapturerListener(VideoAdapter* adapter)
59 : video_adapter_(adapter),
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000060 captured_frames_(0),
61 dropped_frames_(0),
62 last_adapt_was_no_op_(false) {
63 }
64
65 void OnFrameCaptured(VideoCapturer* capturer,
66 const CapturedFrame* captured_frame) {
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000067 rtc::CritScope lock(&crit_);
Magnus Jedvertac27e202015-03-24 15:18:39 +010068 const int in_width = captured_frame->width;
69 const int in_height = abs(captured_frame->height);
magjed709f73c2016-05-13 10:26:00 -070070 int cropped_width;
71 int cropped_height;
72 int out_width;
73 int out_height;
nisse47ac4622016-05-25 08:47:01 -070074 if (video_adapter_->AdaptFrameResolution(in_width, in_height,
75 captured_frame->time_stamp,
76 &cropped_width, &cropped_height,
77 &out_width, &out_height)) {
magjed709f73c2016-05-13 10:26:00 -070078 cropped_width_ = cropped_width;
79 cropped_height_ = cropped_height;
80 out_width_ = out_width;
81 out_height_ = out_height;
82 last_adapt_was_no_op_ =
83 (in_width == cropped_width && in_height == cropped_height &&
84 in_width == out_width && in_height == out_height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000085 } else {
86 ++dropped_frames_;
87 }
88 ++captured_frames_;
89 }
90
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000091 Stats GetStats() {
92 rtc::CritScope lock(&crit_);
93 Stats stats;
94 stats.captured_frames = captured_frames_;
95 stats.dropped_frames = dropped_frames_;
96 stats.last_adapt_was_no_op = last_adapt_was_no_op_;
magjed709f73c2016-05-13 10:26:00 -070097 stats.cropped_width = cropped_width_;
98 stats.cropped_height = cropped_height_;
99 stats.out_width = out_width_;
100 stats.out_height = out_height_;
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000101 return stats;
102 }
103
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000104 private:
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000105 rtc::CriticalSection crit_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000106 VideoAdapter* video_adapter_;
magjed709f73c2016-05-13 10:26:00 -0700107 int cropped_width_;
108 int cropped_height_;
109 int out_width_;
110 int out_height_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000111 int captured_frames_;
112 int dropped_frames_;
113 bool last_adapt_was_no_op_;
114 };
115
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000116
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000117 void VerifyAdaptedResolution(const VideoCapturerListener::Stats& stats,
magjed709f73c2016-05-13 10:26:00 -0700118 int cropped_width,
119 int cropped_height,
120 int out_width,
121 int out_height) {
122 EXPECT_EQ(cropped_width, stats.cropped_width);
123 EXPECT_EQ(cropped_height, stats.cropped_height);
124 EXPECT_EQ(out_width, stats.out_width);
125 EXPECT_EQ(out_height, stats.out_height);
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000126 }
127
kwiberg686a8ef2016-02-26 03:00:35 -0800128 std::unique_ptr<FakeVideoCapturer> capturer_;
Per766ad3b2016-04-05 15:23:49 +0200129 VideoAdapter adapter_;
magjed709f73c2016-05-13 10:26:00 -0700130 int cropped_width_;
131 int cropped_height_;
132 int out_width_;
133 int out_height_;
kwiberg686a8ef2016-02-26 03:00:35 -0800134 std::unique_ptr<VideoCapturerListener> listener_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000135 VideoFormat capture_format_;
136};
137
magjed709f73c2016-05-13 10:26:00 -0700138// Do not adapt the frame rate or the resolution. Expect no frame drop, no
139// cropping, and no resolution change.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000140TEST_F(VideoAdapterTest, AdaptNothing) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000141 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200142 for (int i = 0; i < 10; ++i)
143 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000144
145 // Verify no frame drop and no resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000146 VideoCapturerListener::Stats stats = listener_->GetStats();
147 EXPECT_GE(stats.captured_frames, 10);
148 EXPECT_EQ(0, stats.dropped_frames);
magjed709f73c2016-05-13 10:26:00 -0700149 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height,
150 capture_format_.width, capture_format_.height);
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000151 EXPECT_TRUE(stats.last_adapt_was_no_op);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000152}
153
154TEST_F(VideoAdapterTest, AdaptZeroInterval) {
155 VideoFormat format = capturer_->GetSupportedFormats()->at(0);
156 format.interval = 0;
Per766ad3b2016-04-05 15:23:49 +0200157 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000158 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200159 for (int i = 0; i < 10; ++i)
160 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000161
162 // Verify no crash and that frames aren't dropped.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000163 VideoCapturerListener::Stats stats = listener_->GetStats();
164 EXPECT_GE(stats.captured_frames, 10);
165 EXPECT_EQ(0, stats.dropped_frames);
magjed709f73c2016-05-13 10:26:00 -0700166 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height,
167 capture_format_.width, capture_format_.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000168}
169
170// Adapt the frame rate to be half of the capture rate at the beginning. Expect
171// the number of dropped frames to be half of the number the captured frames.
magjed604abe02016-05-19 06:05:40 -0700172TEST_F(VideoAdapterTest, AdaptFramerateToHalf) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000173 VideoFormat request_format = capture_format_;
174 request_format.interval *= 2;
Per766ad3b2016-04-05 15:23:49 +0200175 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000176 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
magjed604abe02016-05-19 06:05:40 -0700177
178 // Capture 10 frames and verify that every other frame is dropped. The first
179 // frame should not be dropped.
180 capturer_->CaptureFrame();
181 EXPECT_GE(listener_->GetStats().captured_frames, 1);
182 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
183
184 capturer_->CaptureFrame();
185 EXPECT_GE(listener_->GetStats().captured_frames, 2);
186 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
187
188 capturer_->CaptureFrame();
189 EXPECT_GE(listener_->GetStats().captured_frames, 3);
190 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
191
192 capturer_->CaptureFrame();
193 EXPECT_GE(listener_->GetStats().captured_frames, 4);
194 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
195
196 capturer_->CaptureFrame();
197 EXPECT_GE(listener_->GetStats().captured_frames, 5);
198 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
199
200 capturer_->CaptureFrame();
201 EXPECT_GE(listener_->GetStats().captured_frames, 6);
202 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
203
204 capturer_->CaptureFrame();
205 EXPECT_GE(listener_->GetStats().captured_frames, 7);
206 EXPECT_EQ(3, listener_->GetStats().dropped_frames);
207
208 capturer_->CaptureFrame();
209 EXPECT_GE(listener_->GetStats().captured_frames, 8);
210 EXPECT_EQ(3, listener_->GetStats().dropped_frames);
211
212 capturer_->CaptureFrame();
213 EXPECT_GE(listener_->GetStats().captured_frames, 9);
214 EXPECT_EQ(4, listener_->GetStats().dropped_frames);
215
216 capturer_->CaptureFrame();
217 EXPECT_GE(listener_->GetStats().captured_frames, 10);
218 EXPECT_EQ(4, listener_->GetStats().dropped_frames);
219}
220
221// Adapt the frame rate to be two thirds of the capture rate at the beginning.
222// Expect the number of dropped frames to be one thirds of the number the
223// captured frames.
224TEST_F(VideoAdapterTest, AdaptFramerateToTwoThirds) {
225 VideoFormat request_format = capture_format_;
226 request_format.interval = request_format.interval * 3 / 2;
227 adapter_.OnOutputFormatRequest(request_format);
228 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
229
230 // Capture 10 frames and verify that every third frame is dropped. The first
231 // frame should not be dropped.
232 capturer_->CaptureFrame();
233 EXPECT_GE(listener_->GetStats().captured_frames, 1);
234 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
235
236 capturer_->CaptureFrame();
237 EXPECT_GE(listener_->GetStats().captured_frames, 2);
238 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
239
240 capturer_->CaptureFrame();
241 EXPECT_GE(listener_->GetStats().captured_frames, 3);
242 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
243
244 capturer_->CaptureFrame();
245 EXPECT_GE(listener_->GetStats().captured_frames, 4);
246 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
247
248 capturer_->CaptureFrame();
249 EXPECT_GE(listener_->GetStats().captured_frames, 5);
250 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
251
252 capturer_->CaptureFrame();
253 EXPECT_GE(listener_->GetStats().captured_frames, 6);
254 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
255
256 capturer_->CaptureFrame();
257 EXPECT_GE(listener_->GetStats().captured_frames, 7);
258 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
259
260 capturer_->CaptureFrame();
261 EXPECT_GE(listener_->GetStats().captured_frames, 8);
262 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
263
264 capturer_->CaptureFrame();
265 EXPECT_GE(listener_->GetStats().captured_frames, 9);
266 EXPECT_EQ(3, listener_->GetStats().dropped_frames);
267
268 capturer_->CaptureFrame();
269 EXPECT_GE(listener_->GetStats().captured_frames, 10);
270 EXPECT_EQ(3, listener_->GetStats().dropped_frames);
271}
272
273// Request frame rate twice as high as captured frame rate. Expect no frame
274// drop.
275TEST_F(VideoAdapterTest, AdaptFramerateHighLimit) {
276 VideoFormat request_format = capture_format_;
277 request_format.interval /= 2;
278 adapter_.OnOutputFormatRequest(request_format);
279 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200280 for (int i = 0; i < 10; ++i)
281 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000282
magjed604abe02016-05-19 06:05:40 -0700283 // Verify no frame drop.
284 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000285}
286
magjed604abe02016-05-19 06:05:40 -0700287// After the first timestamp, add a big offset to the timestamps. Expect that
288// the adapter is conservative and resets to the new offset and does not drop
289// any frame.
290TEST_F(VideoAdapterTest, AdaptFramerateTimestampOffset) {
291 const int64_t capture_interval = VideoFormat::FpsToInterval(30);
292 adapter_.OnOutputFormatRequest(
293 VideoFormat(640, 480, capture_interval, cricket::FOURCC_ANY));
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000294
magjed604abe02016-05-19 06:05:40 -0700295 const int64_t first_timestamp = 0;
296 adapter_.AdaptFrameResolution(640, 480, first_timestamp,
297 &cropped_width_, &cropped_height_,
298 &out_width_, &out_height_);
299 EXPECT_GT(out_width_, 0);
300 EXPECT_GT(out_height_, 0);
301
302 const int64_t big_offset = -987654321LL * 1000;
303 const int64_t second_timestamp = big_offset;
304 adapter_.AdaptFrameResolution(640, 480, second_timestamp,
305 &cropped_width_, &cropped_height_,
306 &out_width_, &out_height_);
307 EXPECT_GT(out_width_, 0);
308 EXPECT_GT(out_height_, 0);
309
310 const int64_t third_timestamp = big_offset + capture_interval;
311 adapter_.AdaptFrameResolution(640, 480, third_timestamp,
312 &cropped_width_, &cropped_height_,
313 &out_width_, &out_height_);
314 EXPECT_GT(out_width_, 0);
315 EXPECT_GT(out_height_, 0);
316}
317
318// Request 30 fps and send 30 fps with jitter. Expect that no frame is dropped.
319TEST_F(VideoAdapterTest, AdaptFramerateTimestampJitter) {
320 const int64_t capture_interval = VideoFormat::FpsToInterval(30);
321 adapter_.OnOutputFormatRequest(
322 VideoFormat(640, 480, capture_interval, cricket::FOURCC_ANY));
323
324 adapter_.AdaptFrameResolution(640, 480, capture_interval * 0 / 10,
325 &cropped_width_, &cropped_height_,
326 &out_width_, &out_height_);
327 EXPECT_GT(out_width_, 0);
328 EXPECT_GT(out_height_, 0);
329
330 adapter_.AdaptFrameResolution(640, 480, capture_interval * 10 / 10 - 1,
331 &cropped_width_, &cropped_height_,
332 &out_width_, &out_height_);
333 EXPECT_GT(out_width_, 0);
334 EXPECT_GT(out_height_, 0);
335
336 adapter_.AdaptFrameResolution(640, 480, capture_interval * 25 / 10,
337 &cropped_width_, &cropped_height_,
338 &out_width_, &out_height_);
339 EXPECT_GT(out_width_, 0);
340 EXPECT_GT(out_height_, 0);
341
342 adapter_.AdaptFrameResolution(640, 480, capture_interval * 30 / 10,
343 &cropped_width_, &cropped_height_,
344 &out_width_, &out_height_);
345 EXPECT_GT(out_width_, 0);
346 EXPECT_GT(out_height_, 0);
347
348 adapter_.AdaptFrameResolution(640, 480, capture_interval * 35 / 10,
349 &cropped_width_, &cropped_height_,
350 &out_width_, &out_height_);
351 EXPECT_GT(out_width_, 0);
352 EXPECT_GT(out_height_, 0);
353
354 adapter_.AdaptFrameResolution(640, 480, capture_interval * 50 / 10,
355 &cropped_width_, &cropped_height_,
356 &out_width_, &out_height_);
357 EXPECT_GT(out_width_, 0);
358 EXPECT_GT(out_height_, 0);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000359}
360
361// Adapt the frame rate to be half of the capture rate after capturing no less
362// than 10 frames. Expect no frame dropped before adaptation and frame dropped
363// after adaptation.
364TEST_F(VideoAdapterTest, AdaptFramerateOntheFly) {
365 VideoFormat request_format = capture_format_;
Per766ad3b2016-04-05 15:23:49 +0200366 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000367 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200368 for (int i = 0; i < 10; ++i)
369 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000370
371 // Verify no frame drop before adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000372 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000373
374 // Adapat the frame rate.
375 request_format.interval *= 2;
Per766ad3b2016-04-05 15:23:49 +0200376 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000377
Magnus Jedvert01840572015-04-10 11:18:39 +0200378 for (int i = 0; i < 20; ++i)
379 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000380
381 // Verify frame drop after adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000382 EXPECT_GT(listener_->GetStats().dropped_frames, 0);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000383}
384
magjed709f73c2016-05-13 10:26:00 -0700385// Set a very high output pixel resolution. Expect no cropping or resolution
386// change.
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000387TEST_F(VideoAdapterTest, AdaptFrameResolutionHighLimit) {
Per766ad3b2016-04-05 15:23:49 +0200388 VideoFormat output_format = capture_format_;
magjed709f73c2016-05-13 10:26:00 -0700389 output_format.width *= 10;
390 output_format.height *= 10;
Per766ad3b2016-04-05 15:23:49 +0200391 adapter_.OnOutputFormatRequest(output_format);
nisse47ac4622016-05-25 08:47:01 -0700392 EXPECT_TRUE(adapter_.AdaptFrameResolution(
393 capture_format_.width, capture_format_.height, 0,
394 &cropped_width_, &cropped_height_,
395 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700396 EXPECT_EQ(capture_format_.width, cropped_width_);
397 EXPECT_EQ(capture_format_.height, cropped_height_);
398 EXPECT_EQ(capture_format_.width, out_width_);
399 EXPECT_EQ(capture_format_.height, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000400}
401
402// Adapt the frame resolution to be the same as capture resolution. Expect no
magjed709f73c2016-05-13 10:26:00 -0700403// cropping or resolution change.
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000404TEST_F(VideoAdapterTest, AdaptFrameResolutionIdentical) {
Per766ad3b2016-04-05 15:23:49 +0200405 adapter_.OnOutputFormatRequest(capture_format_);
nisse47ac4622016-05-25 08:47:01 -0700406 EXPECT_TRUE(adapter_.AdaptFrameResolution(
407 capture_format_.width, capture_format_.height, 0,
408 &cropped_width_, &cropped_height_,
409 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700410 EXPECT_EQ(capture_format_.width, cropped_width_);
411 EXPECT_EQ(capture_format_.height, cropped_height_);
412 EXPECT_EQ(capture_format_.width, out_width_);
413 EXPECT_EQ(capture_format_.height, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000414}
415
416// Adapt the frame resolution to be a quarter of the capture resolution. Expect
magjed709f73c2016-05-13 10:26:00 -0700417// no cropping, but a resolution change.
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000418TEST_F(VideoAdapterTest, AdaptFrameResolutionQuarter) {
419 VideoFormat request_format = capture_format_;
420 request_format.width /= 2;
421 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200422 adapter_.OnOutputFormatRequest(request_format);
nisse47ac4622016-05-25 08:47:01 -0700423 EXPECT_TRUE(adapter_.AdaptFrameResolution(
424 capture_format_.width, capture_format_.height, 0,
425 &cropped_width_, &cropped_height_,
426 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700427 EXPECT_EQ(capture_format_.width, cropped_width_);
428 EXPECT_EQ(capture_format_.height, cropped_height_);
429 EXPECT_EQ(request_format.width, out_width_);
430 EXPECT_EQ(request_format.height, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000431}
432
433// Adapt the pixel resolution to 0. Expect frame drop.
434TEST_F(VideoAdapterTest, AdaptFrameResolutionDrop) {
Per766ad3b2016-04-05 15:23:49 +0200435 VideoFormat output_format = capture_format_;
436 output_format.width = 0;
437 output_format.height = 0;
438 adapter_.OnOutputFormatRequest(output_format);
nisse47ac4622016-05-25 08:47:01 -0700439 EXPECT_FALSE(adapter_.AdaptFrameResolution(
440 capture_format_.width, capture_format_.height, 0,
441 &cropped_width_, &cropped_height_,
442 &out_width_, &out_height_));
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000443}
444
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000445// Adapt the frame resolution to be a quarter of the capture resolution at the
magjed709f73c2016-05-13 10:26:00 -0700446// beginning. Expect no cropping but a resolution change.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000447TEST_F(VideoAdapterTest, AdaptResolution) {
448 VideoFormat request_format = capture_format_;
449 request_format.width /= 2;
450 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200451 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000452 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200453 for (int i = 0; i < 10; ++i)
454 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000455
magjed709f73c2016-05-13 10:26:00 -0700456 // Verify no frame drop, no cropping, and resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000457 VideoCapturerListener::Stats stats = listener_->GetStats();
458 EXPECT_EQ(0, stats.dropped_frames);
magjed709f73c2016-05-13 10:26:00 -0700459 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height,
460 request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000461}
462
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000463// Adapt the frame resolution to be a quarter of the capture resolution after
464// capturing no less than 10 frames. Expect no resolution change before
465// adaptation and resolution change after adaptation.
466TEST_F(VideoAdapterTest, AdaptResolutionOnTheFly) {
467 VideoFormat request_format = capture_format_;
Per766ad3b2016-04-05 15:23:49 +0200468 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000469 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200470 for (int i = 0; i < 10; ++i)
471 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000472
473 // Verify no resolution change before adaptation.
magjed709f73c2016-05-13 10:26:00 -0700474 VerifyAdaptedResolution(listener_->GetStats(),
475 capture_format_.width, capture_format_.height,
476 request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000477
478 // Adapt the frame resolution.
479 request_format.width /= 2;
480 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200481 adapter_.OnOutputFormatRequest(request_format);
Magnus Jedvert01840572015-04-10 11:18:39 +0200482 for (int i = 0; i < 10; ++i)
483 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000484
485 // Verify resolution change after adaptation.
magjed709f73c2016-05-13 10:26:00 -0700486 VerifyAdaptedResolution(listener_->GetStats(),
487 capture_format_.width, capture_format_.height,
488 request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000489}
490
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000491// Drop all frames.
492TEST_F(VideoAdapterTest, DropAllFrames) {
493 VideoFormat format; // with resolution 0x0.
Per766ad3b2016-04-05 15:23:49 +0200494 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000495 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200496 for (int i = 0; i < 10; ++i)
497 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000498
499 // Verify all frames are dropped.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000500 VideoCapturerListener::Stats stats = listener_->GetStats();
501 EXPECT_GE(stats.captured_frames, 10);
502 EXPECT_EQ(stats.captured_frames, stats.dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000503}
504
Per766ad3b2016-04-05 15:23:49 +0200505TEST_F(VideoAdapterTest, TestOnOutputFormatRequest) {
magjed604abe02016-05-19 06:05:40 -0700506 VideoFormat format(640, 400, 0, 0);
nisse47ac4622016-05-25 08:47:01 -0700507 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
508 &cropped_width_, &cropped_height_,
509 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700510 EXPECT_EQ(640, cropped_width_);
511 EXPECT_EQ(400, cropped_height_);
512 EXPECT_EQ(640, out_width_);
513 EXPECT_EQ(400, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000514
Per766ad3b2016-04-05 15:23:49 +0200515 // Format request 640x400.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000516 format.height = 400;
Per766ad3b2016-04-05 15:23:49 +0200517 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700518 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
519 &cropped_width_, &cropped_height_,
520 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700521 EXPECT_EQ(640, cropped_width_);
522 EXPECT_EQ(400, cropped_height_);
523 EXPECT_EQ(640, out_width_);
524 EXPECT_EQ(400, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000525
magjed709f73c2016-05-13 10:26:00 -0700526 // Request 1280x720, higher than input, but aspect 16:9. Expect cropping but
527 // no scaling.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000528 format.width = 1280;
529 format.height = 720;
Per766ad3b2016-04-05 15:23:49 +0200530 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700531 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
532 &cropped_width_, &cropped_height_,
533 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700534 EXPECT_EQ(640, cropped_width_);
535 EXPECT_EQ(360, cropped_height_);
536 EXPECT_EQ(640, out_width_);
537 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000538
Per766ad3b2016-04-05 15:23:49 +0200539 // Request 0x0.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000540 format.width = 0;
541 format.height = 0;
Per766ad3b2016-04-05 15:23:49 +0200542 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700543 EXPECT_FALSE(adapter_.AdaptFrameResolution(640, 400, 0,
544 &cropped_width_, &cropped_height_,
545 &out_width_, &out_height_));
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000546
magjed709f73c2016-05-13 10:26:00 -0700547 // Request 320x200. Expect scaling, but no cropping.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000548 format.width = 320;
549 format.height = 200;
Per766ad3b2016-04-05 15:23:49 +0200550 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700551 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
552 &cropped_width_, &cropped_height_,
553 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700554 EXPECT_EQ(640, cropped_width_);
555 EXPECT_EQ(400, cropped_height_);
556 EXPECT_EQ(320, out_width_);
557 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000558
magjed709f73c2016-05-13 10:26:00 -0700559 // Request resolution close to 2/3 scale. Expect adapt down. Scaling to 2/3
560 // is not optimized and not allowed, therefore 1/2 scaling will be used
561 // instead.
562 format.width = 424;
563 format.height = 265;
Per766ad3b2016-04-05 15:23:49 +0200564 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700565 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
566 &cropped_width_, &cropped_height_,
567 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700568 EXPECT_EQ(640, cropped_width_);
569 EXPECT_EQ(400, cropped_height_);
570 EXPECT_EQ(320, out_width_);
571 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000572
Per766ad3b2016-04-05 15:23:49 +0200573 // Request resolution of 3 / 8. Expect adapt down.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000574 format.width = 640 * 3 / 8;
575 format.height = 400 * 3 / 8;
Per766ad3b2016-04-05 15:23:49 +0200576 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700577 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
578 &cropped_width_, &cropped_height_,
579 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700580 EXPECT_EQ(640, cropped_width_);
581 EXPECT_EQ(400, cropped_height_);
582 EXPECT_EQ(640 * 3 / 8, out_width_);
583 EXPECT_EQ(400 * 3 / 8, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000584
Per766ad3b2016-04-05 15:23:49 +0200585 // Switch back up. Expect adapt.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000586 format.width = 320;
587 format.height = 200;
Per766ad3b2016-04-05 15:23:49 +0200588 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700589 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
590 &cropped_width_, &cropped_height_,
591 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700592 EXPECT_EQ(640, cropped_width_);
593 EXPECT_EQ(400, cropped_height_);
594 EXPECT_EQ(320, out_width_);
595 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000596
Per766ad3b2016-04-05 15:23:49 +0200597 // Format request 480x300.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000598 format.width = 480;
599 format.height = 300;
Per766ad3b2016-04-05 15:23:49 +0200600 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700601 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0,
602 &cropped_width_, &cropped_height_,
603 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700604 EXPECT_EQ(640, cropped_width_);
605 EXPECT_EQ(400, cropped_height_);
606 EXPECT_EQ(480, out_width_);
607 EXPECT_EQ(300, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000608}
609
Per766ad3b2016-04-05 15:23:49 +0200610TEST_F(VideoAdapterTest, TestViewRequestPlusCameraSwitch) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000611 // Start at HD.
magjed604abe02016-05-19 06:05:40 -0700612 VideoFormat format(1280, 720, 0, 0);
nisse47ac4622016-05-25 08:47:01 -0700613 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
614 &cropped_width_, &cropped_height_,
615 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700616 EXPECT_EQ(1280, cropped_width_);
617 EXPECT_EQ(720, cropped_height_);
618 EXPECT_EQ(1280, out_width_);
619 EXPECT_EQ(720, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000620
Per766ad3b2016-04-05 15:23:49 +0200621 // Format request for VGA.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000622 format.width = 640;
623 format.height = 360;
Per766ad3b2016-04-05 15:23:49 +0200624 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700625 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
626 &cropped_width_, &cropped_height_,
627 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700628 EXPECT_EQ(1280, cropped_width_);
629 EXPECT_EQ(720, cropped_height_);
630 EXPECT_EQ(640, out_width_);
631 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000632
633 // Now, the camera reopens at VGA.
634 // Both the frame and the output format should be 640x360.
nisse47ac4622016-05-25 08:47:01 -0700635 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0,
636 &cropped_width_, &cropped_height_,
637 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700638 EXPECT_EQ(640, cropped_width_);
639 EXPECT_EQ(360, cropped_height_);
640 EXPECT_EQ(640, out_width_);
641 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000642
643 // And another view request comes in for 640x360, which should have no
644 // real impact.
Per766ad3b2016-04-05 15:23:49 +0200645 adapter_.OnOutputFormatRequest(format);
nisse47ac4622016-05-25 08:47:01 -0700646 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0,
647 &cropped_width_, &cropped_height_,
648 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700649 EXPECT_EQ(640, cropped_width_);
650 EXPECT_EQ(360, cropped_height_);
651 EXPECT_EQ(640, out_width_);
652 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000653}
654
Per766ad3b2016-04-05 15:23:49 +0200655TEST_F(VideoAdapterTest, TestVGAWidth) {
656 // Reqeuested Output format is 640x360.
magjed604abe02016-05-19 06:05:40 -0700657 VideoFormat format(640, 360, 0, FOURCC_I420);
Per766ad3b2016-04-05 15:23:49 +0200658 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000659
nisse47ac4622016-05-25 08:47:01 -0700660 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
661 &cropped_width_, &cropped_height_,
662 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700663 // Expect cropping.
664 EXPECT_EQ(640, cropped_width_);
665 EXPECT_EQ(360, cropped_height_);
666 EXPECT_EQ(640, out_width_);
667 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000668
669 // But if frames come in at 640x360, we shouldn't adapt them down.
nisse47ac4622016-05-25 08:47:01 -0700670 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0,
671 &cropped_width_, &cropped_height_,
672 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700673 EXPECT_EQ(640, cropped_width_);
674 EXPECT_EQ(360, cropped_height_);
675 EXPECT_EQ(640, out_width_);
676 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000677
nisse47ac4622016-05-25 08:47:01 -0700678 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
679 &cropped_width_, &cropped_height_,
680 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700681 EXPECT_EQ(640, cropped_width_);
682 EXPECT_EQ(360, cropped_height_);
683 EXPECT_EQ(640, out_width_);
684 EXPECT_EQ(360, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200685}
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000686
Per766ad3b2016-04-05 15:23:49 +0200687TEST_F(VideoAdapterTest, TestOnResolutionRequestInSmallSteps) {
nisse47ac4622016-05-25 08:47:01 -0700688 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
689 &cropped_width_, &cropped_height_,
690 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700691 EXPECT_EQ(1280, cropped_width_);
692 EXPECT_EQ(720, cropped_height_);
693 EXPECT_EQ(1280, out_width_);
694 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200695
696 // Adapt down one step.
697 adapter_.OnResolutionRequest(rtc::Optional<int>(1280 * 720 - 1),
698 rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700699 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
700 &cropped_width_, &cropped_height_,
701 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700702 EXPECT_EQ(1280, cropped_width_);
703 EXPECT_EQ(720, cropped_height_);
704 EXPECT_EQ(960, out_width_);
705 EXPECT_EQ(540, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200706
707 // Adapt down one step more.
708 adapter_.OnResolutionRequest(rtc::Optional<int>(960 * 540 - 1),
709 rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700710 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
711 &cropped_width_, &cropped_height_,
712 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700713 EXPECT_EQ(1280, cropped_width_);
714 EXPECT_EQ(720, cropped_height_);
715 EXPECT_EQ(640, out_width_);
716 EXPECT_EQ(360, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200717
718 // Adapt down one step more.
719 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
720 rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700721 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
722 &cropped_width_, &cropped_height_,
723 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700724 EXPECT_EQ(1280, cropped_width_);
725 EXPECT_EQ(720, cropped_height_);
726 EXPECT_EQ(480, out_width_);
727 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200728
729 // Adapt up one step.
730 adapter_.OnResolutionRequest(rtc::Optional<int>(),
731 rtc::Optional<int>(480 * 270));
nisse47ac4622016-05-25 08:47:01 -0700732 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
733 &cropped_width_, &cropped_height_,
734 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700735 EXPECT_EQ(1280, cropped_width_);
736 EXPECT_EQ(720, cropped_height_);
737 EXPECT_EQ(640, out_width_);
738 EXPECT_EQ(360, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200739
740 // Adapt up one step more.
741 adapter_.OnResolutionRequest(rtc::Optional<int>(),
742 rtc::Optional<int>(640 * 360));
nisse47ac4622016-05-25 08:47:01 -0700743 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
744 &cropped_width_, &cropped_height_,
745 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700746 EXPECT_EQ(1280, cropped_width_);
747 EXPECT_EQ(720, cropped_height_);
748 EXPECT_EQ(960, out_width_);
749 EXPECT_EQ(540, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200750
751 // Adapt up one step more.
752 adapter_.OnResolutionRequest(rtc::Optional<int>(),
753 rtc::Optional<int>(960 * 720));
nisse47ac4622016-05-25 08:47:01 -0700754 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
755 &cropped_width_, &cropped_height_,
756 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700757 EXPECT_EQ(1280, cropped_width_);
758 EXPECT_EQ(720, cropped_height_);
759 EXPECT_EQ(1280, out_width_);
760 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200761}
762
763TEST_F(VideoAdapterTest, TestOnResolutionRequestMaxZero) {
nisse47ac4622016-05-25 08:47:01 -0700764 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
765 &cropped_width_, &cropped_height_,
766 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700767 EXPECT_EQ(1280, cropped_width_);
768 EXPECT_EQ(720, cropped_height_);
769 EXPECT_EQ(1280, out_width_);
770 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200771
772 adapter_.OnResolutionRequest(rtc::Optional<int>(0), rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700773 EXPECT_FALSE(adapter_.AdaptFrameResolution(1280, 720, 0,
774 &cropped_width_, &cropped_height_,
775 &out_width_, &out_height_));
Per766ad3b2016-04-05 15:23:49 +0200776}
777
778TEST_F(VideoAdapterTest, TestOnResolutionRequestInLargeSteps) {
779 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
780 rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700781 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
782 &cropped_width_, &cropped_height_,
783 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700784 EXPECT_EQ(1280, cropped_width_);
785 EXPECT_EQ(720, cropped_height_);
786 EXPECT_EQ(480, out_width_);
787 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200788
789 adapter_.OnResolutionRequest(rtc::Optional<int>(),
790 rtc::Optional<int>(960 * 720));
nisse47ac4622016-05-25 08:47:01 -0700791 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
792 &cropped_width_, &cropped_height_,
793 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700794 EXPECT_EQ(1280, cropped_width_);
795 EXPECT_EQ(720, cropped_height_);
796 EXPECT_EQ(1280, out_width_);
797 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200798}
799
800TEST_F(VideoAdapterTest, TestOnOutputFormatRequestCapsMaxResolution) {
801 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
802 rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700803 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
804 &cropped_width_, &cropped_height_,
805 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700806 EXPECT_EQ(1280, cropped_width_);
807 EXPECT_EQ(720, cropped_height_);
808 EXPECT_EQ(480, out_width_);
809 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200810
magjed604abe02016-05-19 06:05:40 -0700811 VideoFormat new_format(640, 360, 0, FOURCC_I420);
Per766ad3b2016-04-05 15:23:49 +0200812 adapter_.OnOutputFormatRequest(new_format);
nisse47ac4622016-05-25 08:47:01 -0700813 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
814 &cropped_width_, &cropped_height_,
815 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700816 EXPECT_EQ(1280, cropped_width_);
817 EXPECT_EQ(720, cropped_height_);
818 EXPECT_EQ(480, out_width_);
819 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200820
821 adapter_.OnResolutionRequest(rtc::Optional<int>(),
822 rtc::Optional<int>(960 * 720));
nisse47ac4622016-05-25 08:47:01 -0700823 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
824 &cropped_width_, &cropped_height_,
825 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700826 EXPECT_EQ(1280, cropped_width_);
827 EXPECT_EQ(720, cropped_height_);
828 EXPECT_EQ(640, out_width_);
829 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000830}
831
Per766ad3b2016-04-05 15:23:49 +0200832TEST_F(VideoAdapterTest, TestOnResolutionRequestReset) {
nisse47ac4622016-05-25 08:47:01 -0700833 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
834 &cropped_width_, &cropped_height_,
835 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700836 EXPECT_EQ(1280, cropped_width_);
837 EXPECT_EQ(720, cropped_height_);
838 EXPECT_EQ(1280, out_width_);
839 EXPECT_EQ(720, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000840
Per766ad3b2016-04-05 15:23:49 +0200841 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
842 rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700843 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
844 &cropped_width_, &cropped_height_,
845 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700846 EXPECT_EQ(1280, cropped_width_);
847 EXPECT_EQ(720, cropped_height_);
848 EXPECT_EQ(480, out_width_);
849 EXPECT_EQ(270, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000850
Per766ad3b2016-04-05 15:23:49 +0200851 adapter_.OnResolutionRequest(rtc::Optional<int>(), rtc::Optional<int>());
nisse47ac4622016-05-25 08:47:01 -0700852 EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0,
853 &cropped_width_, &cropped_height_,
854 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700855 EXPECT_EQ(1280, cropped_width_);
856 EXPECT_EQ(720, cropped_height_);
857 EXPECT_EQ(1280, out_width_);
858 EXPECT_EQ(720, out_height_);
859}
860
861TEST_F(VideoAdapterTest, TestCroppingWithResolutionRequest) {
862 // Ask for 640x360 (16:9 aspect).
magjed604abe02016-05-19 06:05:40 -0700863 adapter_.OnOutputFormatRequest(VideoFormat(640, 360, 0, FOURCC_I420));
magjed709f73c2016-05-13 10:26:00 -0700864 // Send 640x480 (4:3 aspect).
nisse47ac4622016-05-25 08:47:01 -0700865 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
866 &cropped_width_, &cropped_height_,
867 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700868 // Expect cropping to 16:9 format and no scaling.
869 EXPECT_EQ(640, cropped_width_);
870 EXPECT_EQ(360, cropped_height_);
871 EXPECT_EQ(640, out_width_);
872 EXPECT_EQ(360, out_height_);
873
874 // Adapt down one step.
875 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
876 rtc::Optional<int>());
877 // Expect cropping to 16:9 format and 3/4 scaling.
nisse47ac4622016-05-25 08:47:01 -0700878 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
879 &cropped_width_, &cropped_height_,
880 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700881 EXPECT_EQ(640, cropped_width_);
882 EXPECT_EQ(360, cropped_height_);
883 EXPECT_EQ(480, out_width_);
884 EXPECT_EQ(270, out_height_);
885
886 // Adapt down one step more.
887 adapter_.OnResolutionRequest(rtc::Optional<int>(480 * 270 - 1),
888 rtc::Optional<int>());
889 // Expect cropping to 16:9 format and 1/2 scaling.
nisse47ac4622016-05-25 08:47:01 -0700890 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
891 &cropped_width_, &cropped_height_,
892 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700893 EXPECT_EQ(640, cropped_width_);
894 EXPECT_EQ(360, cropped_height_);
895 EXPECT_EQ(320, out_width_);
896 EXPECT_EQ(180, out_height_);
897
898 // Adapt up one step.
899 adapter_.OnResolutionRequest(rtc::Optional<int>(),
900 rtc::Optional<int>(320 * 180));
901 // Expect cropping to 16:9 format and 3/4 scaling.
nisse47ac4622016-05-25 08:47:01 -0700902 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
903 &cropped_width_, &cropped_height_,
904 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700905 EXPECT_EQ(640, cropped_width_);
906 EXPECT_EQ(360, cropped_height_);
907 EXPECT_EQ(480, out_width_);
908 EXPECT_EQ(270, out_height_);
909
910 // Adapt up one step more.
911 adapter_.OnResolutionRequest(rtc::Optional<int>(),
912 rtc::Optional<int>(480 * 270));
913 // Expect cropping to 16:9 format and no scaling.
nisse47ac4622016-05-25 08:47:01 -0700914 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
915 &cropped_width_, &cropped_height_,
916 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700917 EXPECT_EQ(640, cropped_width_);
918 EXPECT_EQ(360, cropped_height_);
919 EXPECT_EQ(640, out_width_);
920 EXPECT_EQ(360, out_height_);
921
922 // Try to adapt up one step more.
923 adapter_.OnResolutionRequest(rtc::Optional<int>(),
924 rtc::Optional<int>(640 * 360));
925 // Expect cropping to 16:9 format and no scaling.
nisse47ac4622016-05-25 08:47:01 -0700926 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
927 &cropped_width_, &cropped_height_,
928 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700929 EXPECT_EQ(640, cropped_width_);
930 EXPECT_EQ(360, cropped_height_);
931 EXPECT_EQ(640, out_width_);
932 EXPECT_EQ(360, out_height_);
933}
934
935TEST_F(VideoAdapterTest, TestCroppingOddResolution) {
936 // Ask for 640x360 (16:9 aspect), with 3/16 scaling.
magjed709f73c2016-05-13 10:26:00 -0700937 adapter_.OnOutputFormatRequest(
magjed604abe02016-05-19 06:05:40 -0700938 VideoFormat(640, 360, 0, FOURCC_I420));
magjed709f73c2016-05-13 10:26:00 -0700939 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 * 3 / 16 * 3 / 16),
940 rtc::Optional<int>());
941
942 // Send 640x480 (4:3 aspect).
nisse47ac4622016-05-25 08:47:01 -0700943 EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0,
944 &cropped_width_, &cropped_height_,
945 &out_width_, &out_height_));
magjed709f73c2016-05-13 10:26:00 -0700946
947 // Instead of getting the exact aspect ratio with cropped resolution 640x360,
948 // the resolution should be adjusted to get a perfect scale factor instead.
949 EXPECT_EQ(640, cropped_width_);
950 EXPECT_EQ(368, cropped_height_);
951 EXPECT_EQ(120, out_width_);
952 EXPECT_EQ(69, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000953}
954
955} // namespace cricket