blob: d76bbd6ac8a53d5ef02b54ce2e37905edaed9a76 [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;
74 video_adapter_->AdaptFrameResolution(in_width, in_height,
magjed604abe02016-05-19 06:05:40 -070075 captured_frame->time_stamp,
magjed709f73c2016-05-13 10:26:00 -070076 &cropped_width, &cropped_height,
77 &out_width, &out_height);
78 if (out_width != 0 && out_height != 0) {
79 cropped_width_ = cropped_width;
80 cropped_height_ = cropped_height;
81 out_width_ = out_width;
82 out_height_ = out_height;
83 last_adapt_was_no_op_ =
84 (in_width == cropped_width && in_height == cropped_height &&
85 in_width == out_width && in_height == out_height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000086 } else {
87 ++dropped_frames_;
88 }
89 ++captured_frames_;
90 }
91
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000092 Stats GetStats() {
93 rtc::CritScope lock(&crit_);
94 Stats stats;
95 stats.captured_frames = captured_frames_;
96 stats.dropped_frames = dropped_frames_;
97 stats.last_adapt_was_no_op = last_adapt_was_no_op_;
magjed709f73c2016-05-13 10:26:00 -070098 stats.cropped_width = cropped_width_;
99 stats.cropped_height = cropped_height_;
100 stats.out_width = out_width_;
101 stats.out_height = out_height_;
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000102 return stats;
103 }
104
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000105 private:
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000106 rtc::CriticalSection crit_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000107 VideoAdapter* video_adapter_;
magjed709f73c2016-05-13 10:26:00 -0700108 int cropped_width_;
109 int cropped_height_;
110 int out_width_;
111 int out_height_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000112 int captured_frames_;
113 int dropped_frames_;
114 bool last_adapt_was_no_op_;
115 };
116
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000117
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000118 void VerifyAdaptedResolution(const VideoCapturerListener::Stats& stats,
magjed709f73c2016-05-13 10:26:00 -0700119 int cropped_width,
120 int cropped_height,
121 int out_width,
122 int out_height) {
123 EXPECT_EQ(cropped_width, stats.cropped_width);
124 EXPECT_EQ(cropped_height, stats.cropped_height);
125 EXPECT_EQ(out_width, stats.out_width);
126 EXPECT_EQ(out_height, stats.out_height);
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000127 }
128
kwiberg686a8ef2016-02-26 03:00:35 -0800129 std::unique_ptr<FakeVideoCapturer> capturer_;
Per766ad3b2016-04-05 15:23:49 +0200130 VideoAdapter adapter_;
magjed709f73c2016-05-13 10:26:00 -0700131 int cropped_width_;
132 int cropped_height_;
133 int out_width_;
134 int out_height_;
kwiberg686a8ef2016-02-26 03:00:35 -0800135 std::unique_ptr<VideoCapturerListener> listener_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000136 VideoFormat capture_format_;
137};
138
magjed709f73c2016-05-13 10:26:00 -0700139// Do not adapt the frame rate or the resolution. Expect no frame drop, no
140// cropping, and no resolution change.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000141TEST_F(VideoAdapterTest, AdaptNothing) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000142 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200143 for (int i = 0; i < 10; ++i)
144 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000145
146 // Verify no frame drop and no resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000147 VideoCapturerListener::Stats stats = listener_->GetStats();
148 EXPECT_GE(stats.captured_frames, 10);
149 EXPECT_EQ(0, stats.dropped_frames);
magjed709f73c2016-05-13 10:26:00 -0700150 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height,
151 capture_format_.width, capture_format_.height);
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000152 EXPECT_TRUE(stats.last_adapt_was_no_op);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000153}
154
155TEST_F(VideoAdapterTest, AdaptZeroInterval) {
156 VideoFormat format = capturer_->GetSupportedFormats()->at(0);
157 format.interval = 0;
Per766ad3b2016-04-05 15:23:49 +0200158 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000159 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200160 for (int i = 0; i < 10; ++i)
161 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000162
163 // Verify no crash and that frames aren't dropped.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000164 VideoCapturerListener::Stats stats = listener_->GetStats();
165 EXPECT_GE(stats.captured_frames, 10);
166 EXPECT_EQ(0, stats.dropped_frames);
magjed709f73c2016-05-13 10:26:00 -0700167 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height,
168 capture_format_.width, capture_format_.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000169}
170
171// Adapt the frame rate to be half of the capture rate at the beginning. Expect
172// the number of dropped frames to be half of the number the captured frames.
magjed604abe02016-05-19 06:05:40 -0700173TEST_F(VideoAdapterTest, AdaptFramerateToHalf) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000174 VideoFormat request_format = capture_format_;
175 request_format.interval *= 2;
Per766ad3b2016-04-05 15:23:49 +0200176 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000177 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
magjed604abe02016-05-19 06:05:40 -0700178
179 // Capture 10 frames and verify that every other frame is dropped. The first
180 // frame should not be dropped.
181 capturer_->CaptureFrame();
182 EXPECT_GE(listener_->GetStats().captured_frames, 1);
183 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
184
185 capturer_->CaptureFrame();
186 EXPECT_GE(listener_->GetStats().captured_frames, 2);
187 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
188
189 capturer_->CaptureFrame();
190 EXPECT_GE(listener_->GetStats().captured_frames, 3);
191 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
192
193 capturer_->CaptureFrame();
194 EXPECT_GE(listener_->GetStats().captured_frames, 4);
195 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
196
197 capturer_->CaptureFrame();
198 EXPECT_GE(listener_->GetStats().captured_frames, 5);
199 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
200
201 capturer_->CaptureFrame();
202 EXPECT_GE(listener_->GetStats().captured_frames, 6);
203 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
204
205 capturer_->CaptureFrame();
206 EXPECT_GE(listener_->GetStats().captured_frames, 7);
207 EXPECT_EQ(3, listener_->GetStats().dropped_frames);
208
209 capturer_->CaptureFrame();
210 EXPECT_GE(listener_->GetStats().captured_frames, 8);
211 EXPECT_EQ(3, listener_->GetStats().dropped_frames);
212
213 capturer_->CaptureFrame();
214 EXPECT_GE(listener_->GetStats().captured_frames, 9);
215 EXPECT_EQ(4, listener_->GetStats().dropped_frames);
216
217 capturer_->CaptureFrame();
218 EXPECT_GE(listener_->GetStats().captured_frames, 10);
219 EXPECT_EQ(4, listener_->GetStats().dropped_frames);
220}
221
222// Adapt the frame rate to be two thirds of the capture rate at the beginning.
223// Expect the number of dropped frames to be one thirds of the number the
224// captured frames.
225TEST_F(VideoAdapterTest, AdaptFramerateToTwoThirds) {
226 VideoFormat request_format = capture_format_;
227 request_format.interval = request_format.interval * 3 / 2;
228 adapter_.OnOutputFormatRequest(request_format);
229 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
230
231 // Capture 10 frames and verify that every third frame is dropped. The first
232 // frame should not be dropped.
233 capturer_->CaptureFrame();
234 EXPECT_GE(listener_->GetStats().captured_frames, 1);
235 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
236
237 capturer_->CaptureFrame();
238 EXPECT_GE(listener_->GetStats().captured_frames, 2);
239 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
240
241 capturer_->CaptureFrame();
242 EXPECT_GE(listener_->GetStats().captured_frames, 3);
243 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
244
245 capturer_->CaptureFrame();
246 EXPECT_GE(listener_->GetStats().captured_frames, 4);
247 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
248
249 capturer_->CaptureFrame();
250 EXPECT_GE(listener_->GetStats().captured_frames, 5);
251 EXPECT_EQ(1, listener_->GetStats().dropped_frames);
252
253 capturer_->CaptureFrame();
254 EXPECT_GE(listener_->GetStats().captured_frames, 6);
255 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
256
257 capturer_->CaptureFrame();
258 EXPECT_GE(listener_->GetStats().captured_frames, 7);
259 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
260
261 capturer_->CaptureFrame();
262 EXPECT_GE(listener_->GetStats().captured_frames, 8);
263 EXPECT_EQ(2, listener_->GetStats().dropped_frames);
264
265 capturer_->CaptureFrame();
266 EXPECT_GE(listener_->GetStats().captured_frames, 9);
267 EXPECT_EQ(3, listener_->GetStats().dropped_frames);
268
269 capturer_->CaptureFrame();
270 EXPECT_GE(listener_->GetStats().captured_frames, 10);
271 EXPECT_EQ(3, listener_->GetStats().dropped_frames);
272}
273
274// Request frame rate twice as high as captured frame rate. Expect no frame
275// drop.
276TEST_F(VideoAdapterTest, AdaptFramerateHighLimit) {
277 VideoFormat request_format = capture_format_;
278 request_format.interval /= 2;
279 adapter_.OnOutputFormatRequest(request_format);
280 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200281 for (int i = 0; i < 10; ++i)
282 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000283
magjed604abe02016-05-19 06:05:40 -0700284 // Verify no frame drop.
285 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000286}
287
magjed604abe02016-05-19 06:05:40 -0700288// After the first timestamp, add a big offset to the timestamps. Expect that
289// the adapter is conservative and resets to the new offset and does not drop
290// any frame.
291TEST_F(VideoAdapterTest, AdaptFramerateTimestampOffset) {
292 const int64_t capture_interval = VideoFormat::FpsToInterval(30);
293 adapter_.OnOutputFormatRequest(
294 VideoFormat(640, 480, capture_interval, cricket::FOURCC_ANY));
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000295
magjed604abe02016-05-19 06:05:40 -0700296 const int64_t first_timestamp = 0;
297 adapter_.AdaptFrameResolution(640, 480, first_timestamp,
298 &cropped_width_, &cropped_height_,
299 &out_width_, &out_height_);
300 EXPECT_GT(out_width_, 0);
301 EXPECT_GT(out_height_, 0);
302
303 const int64_t big_offset = -987654321LL * 1000;
304 const int64_t second_timestamp = big_offset;
305 adapter_.AdaptFrameResolution(640, 480, second_timestamp,
306 &cropped_width_, &cropped_height_,
307 &out_width_, &out_height_);
308 EXPECT_GT(out_width_, 0);
309 EXPECT_GT(out_height_, 0);
310
311 const int64_t third_timestamp = big_offset + capture_interval;
312 adapter_.AdaptFrameResolution(640, 480, third_timestamp,
313 &cropped_width_, &cropped_height_,
314 &out_width_, &out_height_);
315 EXPECT_GT(out_width_, 0);
316 EXPECT_GT(out_height_, 0);
317}
318
319// Request 30 fps and send 30 fps with jitter. Expect that no frame is dropped.
320TEST_F(VideoAdapterTest, AdaptFramerateTimestampJitter) {
321 const int64_t capture_interval = VideoFormat::FpsToInterval(30);
322 adapter_.OnOutputFormatRequest(
323 VideoFormat(640, 480, capture_interval, cricket::FOURCC_ANY));
324
325 adapter_.AdaptFrameResolution(640, 480, capture_interval * 0 / 10,
326 &cropped_width_, &cropped_height_,
327 &out_width_, &out_height_);
328 EXPECT_GT(out_width_, 0);
329 EXPECT_GT(out_height_, 0);
330
331 adapter_.AdaptFrameResolution(640, 480, capture_interval * 10 / 10 - 1,
332 &cropped_width_, &cropped_height_,
333 &out_width_, &out_height_);
334 EXPECT_GT(out_width_, 0);
335 EXPECT_GT(out_height_, 0);
336
337 adapter_.AdaptFrameResolution(640, 480, capture_interval * 25 / 10,
338 &cropped_width_, &cropped_height_,
339 &out_width_, &out_height_);
340 EXPECT_GT(out_width_, 0);
341 EXPECT_GT(out_height_, 0);
342
343 adapter_.AdaptFrameResolution(640, 480, capture_interval * 30 / 10,
344 &cropped_width_, &cropped_height_,
345 &out_width_, &out_height_);
346 EXPECT_GT(out_width_, 0);
347 EXPECT_GT(out_height_, 0);
348
349 adapter_.AdaptFrameResolution(640, 480, capture_interval * 35 / 10,
350 &cropped_width_, &cropped_height_,
351 &out_width_, &out_height_);
352 EXPECT_GT(out_width_, 0);
353 EXPECT_GT(out_height_, 0);
354
355 adapter_.AdaptFrameResolution(640, 480, capture_interval * 50 / 10,
356 &cropped_width_, &cropped_height_,
357 &out_width_, &out_height_);
358 EXPECT_GT(out_width_, 0);
359 EXPECT_GT(out_height_, 0);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000360}
361
362// Adapt the frame rate to be half of the capture rate after capturing no less
363// than 10 frames. Expect no frame dropped before adaptation and frame dropped
364// after adaptation.
365TEST_F(VideoAdapterTest, AdaptFramerateOntheFly) {
366 VideoFormat request_format = capture_format_;
Per766ad3b2016-04-05 15:23:49 +0200367 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000368 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200369 for (int i = 0; i < 10; ++i)
370 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000371
372 // Verify no frame drop before adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000373 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000374
375 // Adapat the frame rate.
376 request_format.interval *= 2;
Per766ad3b2016-04-05 15:23:49 +0200377 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000378
Magnus Jedvert01840572015-04-10 11:18:39 +0200379 for (int i = 0; i < 20; ++i)
380 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000381
382 // Verify frame drop after adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000383 EXPECT_GT(listener_->GetStats().dropped_frames, 0);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000384}
385
magjed709f73c2016-05-13 10:26:00 -0700386// Set a very high output pixel resolution. Expect no cropping or resolution
387// change.
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000388TEST_F(VideoAdapterTest, AdaptFrameResolutionHighLimit) {
Per766ad3b2016-04-05 15:23:49 +0200389 VideoFormat output_format = capture_format_;
magjed709f73c2016-05-13 10:26:00 -0700390 output_format.width *= 10;
391 output_format.height *= 10;
Per766ad3b2016-04-05 15:23:49 +0200392 adapter_.OnOutputFormatRequest(output_format);
magjed709f73c2016-05-13 10:26:00 -0700393 adapter_.AdaptFrameResolution(capture_format_.width, capture_format_.height,
magjed604abe02016-05-19 06:05:40 -0700394 0, &cropped_width_, &cropped_height_,
magjed709f73c2016-05-13 10:26:00 -0700395 &out_width_, &out_height_);
396 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_);
magjed709f73c2016-05-13 10:26:00 -0700406 adapter_.AdaptFrameResolution(capture_format_.width, capture_format_.height,
magjed604abe02016-05-19 06:05:40 -0700407 0, &cropped_width_, &cropped_height_,
magjed709f73c2016-05-13 10:26:00 -0700408 &out_width_, &out_height_);
409 EXPECT_EQ(capture_format_.width, cropped_width_);
410 EXPECT_EQ(capture_format_.height, cropped_height_);
411 EXPECT_EQ(capture_format_.width, out_width_);
412 EXPECT_EQ(capture_format_.height, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000413}
414
415// Adapt the frame resolution to be a quarter of the capture resolution. Expect
magjed709f73c2016-05-13 10:26:00 -0700416// no cropping, but a resolution change.
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000417TEST_F(VideoAdapterTest, AdaptFrameResolutionQuarter) {
418 VideoFormat request_format = capture_format_;
419 request_format.width /= 2;
420 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200421 adapter_.OnOutputFormatRequest(request_format);
magjed709f73c2016-05-13 10:26:00 -0700422 adapter_.AdaptFrameResolution(capture_format_.width, capture_format_.height,
magjed604abe02016-05-19 06:05:40 -0700423 0, &cropped_width_, &cropped_height_,
magjed709f73c2016-05-13 10:26:00 -0700424 &out_width_, &out_height_);
425 EXPECT_EQ(capture_format_.width, cropped_width_);
426 EXPECT_EQ(capture_format_.height, cropped_height_);
427 EXPECT_EQ(request_format.width, out_width_);
428 EXPECT_EQ(request_format.height, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000429}
430
431// Adapt the pixel resolution to 0. Expect frame drop.
432TEST_F(VideoAdapterTest, AdaptFrameResolutionDrop) {
Per766ad3b2016-04-05 15:23:49 +0200433 VideoFormat output_format = capture_format_;
434 output_format.width = 0;
435 output_format.height = 0;
436 adapter_.OnOutputFormatRequest(output_format);
magjed709f73c2016-05-13 10:26:00 -0700437 adapter_.AdaptFrameResolution(capture_format_.width, capture_format_.height,
magjed604abe02016-05-19 06:05:40 -0700438 0, &cropped_width_, &cropped_height_,
magjed709f73c2016-05-13 10:26:00 -0700439 &out_width_, &out_height_);
440 EXPECT_EQ(0, out_width_);
441 EXPECT_EQ(0, out_height_);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000442}
443
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000444// Adapt the frame resolution to be a quarter of the capture resolution at the
magjed709f73c2016-05-13 10:26:00 -0700445// beginning. Expect no cropping but a resolution change.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000446TEST_F(VideoAdapterTest, AdaptResolution) {
447 VideoFormat request_format = capture_format_;
448 request_format.width /= 2;
449 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200450 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000451 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200452 for (int i = 0; i < 10; ++i)
453 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000454
magjed709f73c2016-05-13 10:26:00 -0700455 // Verify no frame drop, no cropping, and resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000456 VideoCapturerListener::Stats stats = listener_->GetStats();
457 EXPECT_EQ(0, stats.dropped_frames);
magjed709f73c2016-05-13 10:26:00 -0700458 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height,
459 request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000460}
461
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000462// Adapt the frame resolution to be a quarter of the capture resolution after
463// capturing no less than 10 frames. Expect no resolution change before
464// adaptation and resolution change after adaptation.
465TEST_F(VideoAdapterTest, AdaptResolutionOnTheFly) {
466 VideoFormat request_format = capture_format_;
Per766ad3b2016-04-05 15:23:49 +0200467 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000468 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200469 for (int i = 0; i < 10; ++i)
470 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000471
472 // Verify no resolution change before adaptation.
magjed709f73c2016-05-13 10:26:00 -0700473 VerifyAdaptedResolution(listener_->GetStats(),
474 capture_format_.width, capture_format_.height,
475 request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000476
477 // Adapt the frame resolution.
478 request_format.width /= 2;
479 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200480 adapter_.OnOutputFormatRequest(request_format);
Magnus Jedvert01840572015-04-10 11:18:39 +0200481 for (int i = 0; i < 10; ++i)
482 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000483
484 // Verify resolution change after adaptation.
magjed709f73c2016-05-13 10:26:00 -0700485 VerifyAdaptedResolution(listener_->GetStats(),
486 capture_format_.width, capture_format_.height,
487 request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000488}
489
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000490// Drop all frames.
491TEST_F(VideoAdapterTest, DropAllFrames) {
492 VideoFormat format; // with resolution 0x0.
Per766ad3b2016-04-05 15:23:49 +0200493 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000494 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200495 for (int i = 0; i < 10; ++i)
496 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000497
498 // Verify all frames are dropped.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000499 VideoCapturerListener::Stats stats = listener_->GetStats();
500 EXPECT_GE(stats.captured_frames, 10);
501 EXPECT_EQ(stats.captured_frames, stats.dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000502}
503
Per766ad3b2016-04-05 15:23:49 +0200504TEST_F(VideoAdapterTest, TestOnOutputFormatRequest) {
magjed604abe02016-05-19 06:05:40 -0700505 VideoFormat format(640, 400, 0, 0);
506 adapter_.AdaptFrameResolution(640, 400, 0,
magjed709f73c2016-05-13 10:26:00 -0700507 &cropped_width_, &cropped_height_,
508 &out_width_, &out_height_);
509 EXPECT_EQ(640, cropped_width_);
510 EXPECT_EQ(400, cropped_height_);
511 EXPECT_EQ(640, out_width_);
512 EXPECT_EQ(400, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000513
Per766ad3b2016-04-05 15:23:49 +0200514 // Format request 640x400.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000515 format.height = 400;
Per766ad3b2016-04-05 15:23:49 +0200516 adapter_.OnOutputFormatRequest(format);
magjed604abe02016-05-19 06:05:40 -0700517 adapter_.AdaptFrameResolution(640, 400, 0,
magjed709f73c2016-05-13 10:26:00 -0700518 &cropped_width_, &cropped_height_,
519 &out_width_, &out_height_);
520 EXPECT_EQ(640, cropped_width_);
521 EXPECT_EQ(400, cropped_height_);
522 EXPECT_EQ(640, out_width_);
523 EXPECT_EQ(400, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000524
magjed709f73c2016-05-13 10:26:00 -0700525 // Request 1280x720, higher than input, but aspect 16:9. Expect cropping but
526 // no scaling.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000527 format.width = 1280;
528 format.height = 720;
Per766ad3b2016-04-05 15:23:49 +0200529 adapter_.OnOutputFormatRequest(format);
magjed604abe02016-05-19 06:05:40 -0700530 adapter_.AdaptFrameResolution(640, 400, 0,
magjed709f73c2016-05-13 10:26:00 -0700531 &cropped_width_, &cropped_height_,
532 &out_width_, &out_height_);
533 EXPECT_EQ(640, cropped_width_);
534 EXPECT_EQ(360, cropped_height_);
535 EXPECT_EQ(640, out_width_);
536 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000537
Per766ad3b2016-04-05 15:23:49 +0200538 // Request 0x0.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000539 format.width = 0;
540 format.height = 0;
Per766ad3b2016-04-05 15:23:49 +0200541 adapter_.OnOutputFormatRequest(format);
magjed604abe02016-05-19 06:05:40 -0700542 adapter_.AdaptFrameResolution(640, 400, 0,
magjed709f73c2016-05-13 10:26:00 -0700543 &cropped_width_, &cropped_height_,
544 &out_width_, &out_height_);
545 EXPECT_EQ(0, out_width_);
546 EXPECT_EQ(0, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000547
magjed709f73c2016-05-13 10:26:00 -0700548 // Request 320x200. Expect scaling, but no cropping.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000549 format.width = 320;
550 format.height = 200;
Per766ad3b2016-04-05 15:23:49 +0200551 adapter_.OnOutputFormatRequest(format);
magjed604abe02016-05-19 06:05:40 -0700552 adapter_.AdaptFrameResolution(640, 400, 0,
magjed709f73c2016-05-13 10:26:00 -0700553 &cropped_width_, &cropped_height_,
554 &out_width_, &out_height_);
555 EXPECT_EQ(640, cropped_width_);
556 EXPECT_EQ(400, cropped_height_);
557 EXPECT_EQ(320, out_width_);
558 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000559
magjed709f73c2016-05-13 10:26:00 -0700560 // Request resolution close to 2/3 scale. Expect adapt down. Scaling to 2/3
561 // is not optimized and not allowed, therefore 1/2 scaling will be used
562 // instead.
563 format.width = 424;
564 format.height = 265;
Per766ad3b2016-04-05 15:23:49 +0200565 adapter_.OnOutputFormatRequest(format);
magjed604abe02016-05-19 06:05:40 -0700566 adapter_.AdaptFrameResolution(640, 400, 0,
magjed709f73c2016-05-13 10:26:00 -0700567 &cropped_width_, &cropped_height_,
568 &out_width_, &out_height_);
569 EXPECT_EQ(640, cropped_width_);
570 EXPECT_EQ(400, cropped_height_);
571 EXPECT_EQ(320, out_width_);
572 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000573
Per766ad3b2016-04-05 15:23:49 +0200574 // Request resolution of 3 / 8. Expect adapt down.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000575 format.width = 640 * 3 / 8;
576 format.height = 400 * 3 / 8;
Per766ad3b2016-04-05 15:23:49 +0200577 adapter_.OnOutputFormatRequest(format);
magjed604abe02016-05-19 06:05:40 -0700578 adapter_.AdaptFrameResolution(640, 400, 0,
magjed709f73c2016-05-13 10:26:00 -0700579 &cropped_width_, &cropped_height_,
580 &out_width_, &out_height_);
581 EXPECT_EQ(640, cropped_width_);
582 EXPECT_EQ(400, cropped_height_);
583 EXPECT_EQ(640 * 3 / 8, out_width_);
584 EXPECT_EQ(400 * 3 / 8, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000585
Per766ad3b2016-04-05 15:23:49 +0200586 // Switch back up. Expect adapt.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000587 format.width = 320;
588 format.height = 200;
Per766ad3b2016-04-05 15:23:49 +0200589 adapter_.OnOutputFormatRequest(format);
magjed604abe02016-05-19 06:05:40 -0700590 adapter_.AdaptFrameResolution(640, 400, 0,
magjed709f73c2016-05-13 10:26:00 -0700591 &cropped_width_, &cropped_height_,
592 &out_width_, &out_height_);
593 EXPECT_EQ(640, cropped_width_);
594 EXPECT_EQ(400, cropped_height_);
595 EXPECT_EQ(320, out_width_);
596 EXPECT_EQ(200, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000597
Per766ad3b2016-04-05 15:23:49 +0200598 // Format request 480x300.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000599 format.width = 480;
600 format.height = 300;
Per766ad3b2016-04-05 15:23:49 +0200601 adapter_.OnOutputFormatRequest(format);
magjed604abe02016-05-19 06:05:40 -0700602 adapter_.AdaptFrameResolution(640, 400, 0,
magjed709f73c2016-05-13 10:26:00 -0700603 &cropped_width_, &cropped_height_,
604 &out_width_, &out_height_);
605 EXPECT_EQ(640, cropped_width_);
606 EXPECT_EQ(400, cropped_height_);
607 EXPECT_EQ(480, out_width_);
608 EXPECT_EQ(300, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000609}
610
Per766ad3b2016-04-05 15:23:49 +0200611TEST_F(VideoAdapterTest, TestViewRequestPlusCameraSwitch) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000612 // Start at HD.
magjed604abe02016-05-19 06:05:40 -0700613 VideoFormat format(1280, 720, 0, 0);
614 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700615 &cropped_width_, &cropped_height_,
616 &out_width_, &out_height_);
617 EXPECT_EQ(1280, cropped_width_);
618 EXPECT_EQ(720, cropped_height_);
619 EXPECT_EQ(1280, out_width_);
620 EXPECT_EQ(720, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000621
Per766ad3b2016-04-05 15:23:49 +0200622 // Format request for VGA.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000623 format.width = 640;
624 format.height = 360;
Per766ad3b2016-04-05 15:23:49 +0200625 adapter_.OnOutputFormatRequest(format);
magjed604abe02016-05-19 06:05:40 -0700626 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700627 &cropped_width_, &cropped_height_,
628 &out_width_, &out_height_);
629 EXPECT_EQ(1280, cropped_width_);
630 EXPECT_EQ(720, cropped_height_);
631 EXPECT_EQ(640, out_width_);
632 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000633
634 // Now, the camera reopens at VGA.
635 // Both the frame and the output format should be 640x360.
magjed604abe02016-05-19 06:05:40 -0700636 adapter_.AdaptFrameResolution(640, 360, 0,
magjed709f73c2016-05-13 10:26:00 -0700637 &cropped_width_, &cropped_height_,
638 &out_width_, &out_height_);
639 EXPECT_EQ(640, cropped_width_);
640 EXPECT_EQ(360, cropped_height_);
641 EXPECT_EQ(640, out_width_);
642 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000643
644 // And another view request comes in for 640x360, which should have no
645 // real impact.
Per766ad3b2016-04-05 15:23:49 +0200646 adapter_.OnOutputFormatRequest(format);
magjed604abe02016-05-19 06:05:40 -0700647 adapter_.AdaptFrameResolution(640, 360, 0,
magjed709f73c2016-05-13 10:26:00 -0700648 &cropped_width_, &cropped_height_,
649 &out_width_, &out_height_);
650 EXPECT_EQ(640, cropped_width_);
651 EXPECT_EQ(360, cropped_height_);
652 EXPECT_EQ(640, out_width_);
653 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000654}
655
Per766ad3b2016-04-05 15:23:49 +0200656TEST_F(VideoAdapterTest, TestVGAWidth) {
657 // Reqeuested Output format is 640x360.
magjed604abe02016-05-19 06:05:40 -0700658 VideoFormat format(640, 360, 0, FOURCC_I420);
Per766ad3b2016-04-05 15:23:49 +0200659 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000660
magjed604abe02016-05-19 06:05:40 -0700661 adapter_.AdaptFrameResolution(640, 480, 0,
magjed709f73c2016-05-13 10:26:00 -0700662 &cropped_width_, &cropped_height_,
663 &out_width_, &out_height_);
664 // Expect cropping.
665 EXPECT_EQ(640, cropped_width_);
666 EXPECT_EQ(360, cropped_height_);
667 EXPECT_EQ(640, out_width_);
668 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000669
670 // But if frames come in at 640x360, we shouldn't adapt them down.
magjed604abe02016-05-19 06:05:40 -0700671 adapter_.AdaptFrameResolution(640, 360, 0,
magjed709f73c2016-05-13 10:26:00 -0700672 &cropped_width_, &cropped_height_,
673 &out_width_, &out_height_);
674 EXPECT_EQ(640, cropped_width_);
675 EXPECT_EQ(360, cropped_height_);
676 EXPECT_EQ(640, out_width_);
677 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000678
magjed604abe02016-05-19 06:05:40 -0700679 adapter_.AdaptFrameResolution(640, 480, 0,
magjed709f73c2016-05-13 10:26:00 -0700680 &cropped_width_, &cropped_height_,
681 &out_width_, &out_height_);
682 EXPECT_EQ(640, cropped_width_);
683 EXPECT_EQ(360, cropped_height_);
684 EXPECT_EQ(640, out_width_);
685 EXPECT_EQ(360, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200686}
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000687
Per766ad3b2016-04-05 15:23:49 +0200688TEST_F(VideoAdapterTest, TestOnResolutionRequestInSmallSteps) {
magjed604abe02016-05-19 06:05:40 -0700689 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700690 &cropped_width_, &cropped_height_,
691 &out_width_, &out_height_);
692 EXPECT_EQ(1280, cropped_width_);
693 EXPECT_EQ(720, cropped_height_);
694 EXPECT_EQ(1280, out_width_);
695 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200696
697 // Adapt down one step.
698 adapter_.OnResolutionRequest(rtc::Optional<int>(1280 * 720 - 1),
699 rtc::Optional<int>());
magjed604abe02016-05-19 06:05:40 -0700700 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700701 &cropped_width_, &cropped_height_,
702 &out_width_, &out_height_);
703 EXPECT_EQ(1280, cropped_width_);
704 EXPECT_EQ(720, cropped_height_);
705 EXPECT_EQ(960, out_width_);
706 EXPECT_EQ(540, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200707
708 // Adapt down one step more.
709 adapter_.OnResolutionRequest(rtc::Optional<int>(960 * 540 - 1),
710 rtc::Optional<int>());
magjed604abe02016-05-19 06:05:40 -0700711 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700712 &cropped_width_, &cropped_height_,
713 &out_width_, &out_height_);
714 EXPECT_EQ(1280, cropped_width_);
715 EXPECT_EQ(720, cropped_height_);
716 EXPECT_EQ(640, out_width_);
717 EXPECT_EQ(360, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200718
719 // Adapt down one step more.
720 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
721 rtc::Optional<int>());
magjed604abe02016-05-19 06:05:40 -0700722 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700723 &cropped_width_, &cropped_height_,
724 &out_width_, &out_height_);
725 EXPECT_EQ(1280, cropped_width_);
726 EXPECT_EQ(720, cropped_height_);
727 EXPECT_EQ(480, out_width_);
728 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200729
730 // Adapt up one step.
731 adapter_.OnResolutionRequest(rtc::Optional<int>(),
732 rtc::Optional<int>(480 * 270));
magjed604abe02016-05-19 06:05:40 -0700733 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700734 &cropped_width_, &cropped_height_,
735 &out_width_, &out_height_);
736 EXPECT_EQ(1280, cropped_width_);
737 EXPECT_EQ(720, cropped_height_);
738 EXPECT_EQ(640, out_width_);
739 EXPECT_EQ(360, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200740
741 // Adapt up one step more.
742 adapter_.OnResolutionRequest(rtc::Optional<int>(),
743 rtc::Optional<int>(640 * 360));
magjed604abe02016-05-19 06:05:40 -0700744 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700745 &cropped_width_, &cropped_height_,
746 &out_width_, &out_height_);
747 EXPECT_EQ(1280, cropped_width_);
748 EXPECT_EQ(720, cropped_height_);
749 EXPECT_EQ(960, out_width_);
750 EXPECT_EQ(540, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200751
752 // Adapt up one step more.
753 adapter_.OnResolutionRequest(rtc::Optional<int>(),
754 rtc::Optional<int>(960 * 720));
magjed604abe02016-05-19 06:05:40 -0700755 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700756 &cropped_width_, &cropped_height_,
757 &out_width_, &out_height_);
758 EXPECT_EQ(1280, cropped_width_);
759 EXPECT_EQ(720, cropped_height_);
760 EXPECT_EQ(1280, out_width_);
761 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200762}
763
764TEST_F(VideoAdapterTest, TestOnResolutionRequestMaxZero) {
magjed604abe02016-05-19 06:05:40 -0700765 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700766 &cropped_width_, &cropped_height_,
767 &out_width_, &out_height_);
768 EXPECT_EQ(1280, cropped_width_);
769 EXPECT_EQ(720, cropped_height_);
770 EXPECT_EQ(1280, out_width_);
771 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200772
773 adapter_.OnResolutionRequest(rtc::Optional<int>(0), rtc::Optional<int>());
magjed604abe02016-05-19 06:05:40 -0700774 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700775 &cropped_width_, &cropped_height_,
776 &out_width_, &out_height_);
777 EXPECT_EQ(0, out_width_);
778 EXPECT_EQ(0, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200779}
780
781TEST_F(VideoAdapterTest, TestOnResolutionRequestInLargeSteps) {
782 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
783 rtc::Optional<int>());
magjed604abe02016-05-19 06:05:40 -0700784 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700785 &cropped_width_, &cropped_height_,
786 &out_width_, &out_height_);
787 EXPECT_EQ(1280, cropped_width_);
788 EXPECT_EQ(720, cropped_height_);
789 EXPECT_EQ(480, out_width_);
790 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200791
792 adapter_.OnResolutionRequest(rtc::Optional<int>(),
793 rtc::Optional<int>(960 * 720));
magjed604abe02016-05-19 06:05:40 -0700794 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700795 &cropped_width_, &cropped_height_,
796 &out_width_, &out_height_);
797 EXPECT_EQ(1280, cropped_width_);
798 EXPECT_EQ(720, cropped_height_);
799 EXPECT_EQ(1280, out_width_);
800 EXPECT_EQ(720, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200801}
802
803TEST_F(VideoAdapterTest, TestOnOutputFormatRequestCapsMaxResolution) {
804 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
805 rtc::Optional<int>());
magjed604abe02016-05-19 06:05:40 -0700806 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700807 &cropped_width_, &cropped_height_,
808 &out_width_, &out_height_);
809 EXPECT_EQ(1280, cropped_width_);
810 EXPECT_EQ(720, cropped_height_);
811 EXPECT_EQ(480, out_width_);
812 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200813
magjed604abe02016-05-19 06:05:40 -0700814 VideoFormat new_format(640, 360, 0, FOURCC_I420);
Per766ad3b2016-04-05 15:23:49 +0200815 adapter_.OnOutputFormatRequest(new_format);
magjed604abe02016-05-19 06:05:40 -0700816 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700817 &cropped_width_, &cropped_height_,
818 &out_width_, &out_height_);
819 EXPECT_EQ(1280, cropped_width_);
820 EXPECT_EQ(720, cropped_height_);
821 EXPECT_EQ(480, out_width_);
822 EXPECT_EQ(270, out_height_);
Per766ad3b2016-04-05 15:23:49 +0200823
824 adapter_.OnResolutionRequest(rtc::Optional<int>(),
825 rtc::Optional<int>(960 * 720));
magjed604abe02016-05-19 06:05:40 -0700826 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700827 &cropped_width_, &cropped_height_,
828 &out_width_, &out_height_);
829 EXPECT_EQ(1280, cropped_width_);
830 EXPECT_EQ(720, cropped_height_);
831 EXPECT_EQ(640, out_width_);
832 EXPECT_EQ(360, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000833}
834
Per766ad3b2016-04-05 15:23:49 +0200835TEST_F(VideoAdapterTest, TestOnResolutionRequestReset) {
magjed604abe02016-05-19 06:05:40 -0700836 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700837 &cropped_width_, &cropped_height_,
838 &out_width_, &out_height_);
839 EXPECT_EQ(1280, cropped_width_);
840 EXPECT_EQ(720, cropped_height_);
841 EXPECT_EQ(1280, out_width_);
842 EXPECT_EQ(720, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000843
Per766ad3b2016-04-05 15:23:49 +0200844 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
845 rtc::Optional<int>());
magjed604abe02016-05-19 06:05:40 -0700846 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700847 &cropped_width_, &cropped_height_,
848 &out_width_, &out_height_);
849 EXPECT_EQ(1280, cropped_width_);
850 EXPECT_EQ(720, cropped_height_);
851 EXPECT_EQ(480, out_width_);
852 EXPECT_EQ(270, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000853
Per766ad3b2016-04-05 15:23:49 +0200854 adapter_.OnResolutionRequest(rtc::Optional<int>(), rtc::Optional<int>());
magjed604abe02016-05-19 06:05:40 -0700855 adapter_.AdaptFrameResolution(1280, 720, 0,
magjed709f73c2016-05-13 10:26:00 -0700856 &cropped_width_, &cropped_height_,
857 &out_width_, &out_height_);
858 EXPECT_EQ(1280, cropped_width_);
859 EXPECT_EQ(720, cropped_height_);
860 EXPECT_EQ(1280, out_width_);
861 EXPECT_EQ(720, out_height_);
862}
863
864TEST_F(VideoAdapterTest, TestCroppingWithResolutionRequest) {
865 // Ask for 640x360 (16:9 aspect).
magjed604abe02016-05-19 06:05:40 -0700866 adapter_.OnOutputFormatRequest(VideoFormat(640, 360, 0, FOURCC_I420));
magjed709f73c2016-05-13 10:26:00 -0700867 // Send 640x480 (4:3 aspect).
magjed604abe02016-05-19 06:05:40 -0700868 adapter_.AdaptFrameResolution(640, 480, 0,
magjed709f73c2016-05-13 10:26:00 -0700869 &cropped_width_, &cropped_height_,
870 &out_width_, &out_height_);
871 // Expect cropping to 16:9 format and no scaling.
872 EXPECT_EQ(640, cropped_width_);
873 EXPECT_EQ(360, cropped_height_);
874 EXPECT_EQ(640, out_width_);
875 EXPECT_EQ(360, out_height_);
876
877 // Adapt down one step.
878 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
879 rtc::Optional<int>());
880 // Expect cropping to 16:9 format and 3/4 scaling.
magjed604abe02016-05-19 06:05:40 -0700881 adapter_.AdaptFrameResolution(640, 480, 0,
magjed709f73c2016-05-13 10:26:00 -0700882 &cropped_width_, &cropped_height_,
883 &out_width_, &out_height_);
884 EXPECT_EQ(640, cropped_width_);
885 EXPECT_EQ(360, cropped_height_);
886 EXPECT_EQ(480, out_width_);
887 EXPECT_EQ(270, out_height_);
888
889 // Adapt down one step more.
890 adapter_.OnResolutionRequest(rtc::Optional<int>(480 * 270 - 1),
891 rtc::Optional<int>());
892 // Expect cropping to 16:9 format and 1/2 scaling.
magjed604abe02016-05-19 06:05:40 -0700893 adapter_.AdaptFrameResolution(640, 480, 0,
magjed709f73c2016-05-13 10:26:00 -0700894 &cropped_width_, &cropped_height_,
895 &out_width_, &out_height_);
896 EXPECT_EQ(640, cropped_width_);
897 EXPECT_EQ(360, cropped_height_);
898 EXPECT_EQ(320, out_width_);
899 EXPECT_EQ(180, out_height_);
900
901 // Adapt up one step.
902 adapter_.OnResolutionRequest(rtc::Optional<int>(),
903 rtc::Optional<int>(320 * 180));
904 // Expect cropping to 16:9 format and 3/4 scaling.
magjed604abe02016-05-19 06:05:40 -0700905 adapter_.AdaptFrameResolution(640, 480, 0,
magjed709f73c2016-05-13 10:26:00 -0700906 &cropped_width_, &cropped_height_,
907 &out_width_, &out_height_);
908 EXPECT_EQ(640, cropped_width_);
909 EXPECT_EQ(360, cropped_height_);
910 EXPECT_EQ(480, out_width_);
911 EXPECT_EQ(270, out_height_);
912
913 // Adapt up one step more.
914 adapter_.OnResolutionRequest(rtc::Optional<int>(),
915 rtc::Optional<int>(480 * 270));
916 // Expect cropping to 16:9 format and no scaling.
magjed604abe02016-05-19 06:05:40 -0700917 adapter_.AdaptFrameResolution(640, 480, 0,
magjed709f73c2016-05-13 10:26:00 -0700918 &cropped_width_, &cropped_height_,
919 &out_width_, &out_height_);
920 EXPECT_EQ(640, cropped_width_);
921 EXPECT_EQ(360, cropped_height_);
922 EXPECT_EQ(640, out_width_);
923 EXPECT_EQ(360, out_height_);
924
925 // Try to adapt up one step more.
926 adapter_.OnResolutionRequest(rtc::Optional<int>(),
927 rtc::Optional<int>(640 * 360));
928 // Expect cropping to 16:9 format and no scaling.
magjed604abe02016-05-19 06:05:40 -0700929 adapter_.AdaptFrameResolution(640, 480, 0,
magjed709f73c2016-05-13 10:26:00 -0700930 &cropped_width_, &cropped_height_,
931 &out_width_, &out_height_);
932 EXPECT_EQ(640, cropped_width_);
933 EXPECT_EQ(360, cropped_height_);
934 EXPECT_EQ(640, out_width_);
935 EXPECT_EQ(360, out_height_);
936}
937
938TEST_F(VideoAdapterTest, TestCroppingOddResolution) {
939 // Ask for 640x360 (16:9 aspect), with 3/16 scaling.
magjed709f73c2016-05-13 10:26:00 -0700940 adapter_.OnOutputFormatRequest(
magjed604abe02016-05-19 06:05:40 -0700941 VideoFormat(640, 360, 0, FOURCC_I420));
magjed709f73c2016-05-13 10:26:00 -0700942 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 * 3 / 16 * 3 / 16),
943 rtc::Optional<int>());
944
945 // Send 640x480 (4:3 aspect).
magjed604abe02016-05-19 06:05:40 -0700946 adapter_.AdaptFrameResolution(640, 480, 0,
magjed709f73c2016-05-13 10:26:00 -0700947 &cropped_width_, &cropped_height_,
948 &out_width_, &out_height_);
949
950 // Instead of getting the exact aspect ratio with cropped resolution 640x360,
951 // the resolution should be adjusted to get a perfect scale factor instead.
952 EXPECT_EQ(640, cropped_width_);
953 EXPECT_EQ(368, cropped_height_);
954 EXPECT_EQ(120, out_width_);
955 EXPECT_EQ(69, out_height_);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000956}
957
958} // namespace cricket