blob: 1ad58d165c0c4be0bab397df91dbc214f4cffc9e [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
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000013#include <string>
14#include <vector>
15
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000016#include "webrtc/base/gunit.h"
17#include "webrtc/base/logging.h"
kjellandera96e2d72016-02-04 23:52:28 -080018#include "webrtc/media/base/fakevideocapturer.h"
19#include "webrtc/media/base/mediachannel.h"
20#include "webrtc/media/base/testutils.h"
21#include "webrtc/media/base/videoadapter.h"
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000022
23namespace cricket {
24
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000025class VideoAdapterTest : public testing::Test {
26 public:
27 virtual void SetUp() {
Magnus Jedvert01840572015-04-10 11:18:39 +020028 capturer_.reset(new FakeVideoCapturer);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000029 capture_format_ = capturer_->GetSupportedFormats()->at(0);
30 capture_format_.interval = VideoFormat::FpsToInterval(50);
Per766ad3b2016-04-05 15:23:49 +020031 adapter_.SetExpectedInputFrameInterval(capture_format_.interval);
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
52 int adapted_width;
53 int adapted_height;
54 };
55
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000056 explicit VideoCapturerListener(VideoAdapter* adapter)
57 : video_adapter_(adapter),
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000058 captured_frames_(0),
59 dropped_frames_(0),
60 last_adapt_was_no_op_(false) {
61 }
62
63 void OnFrameCaptured(VideoCapturer* capturer,
64 const CapturedFrame* captured_frame) {
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000065 rtc::CritScope lock(&crit_);
Magnus Jedvertac27e202015-03-24 15:18:39 +010066 const int in_width = captured_frame->width;
67 const int in_height = abs(captured_frame->height);
68 const VideoFormat adapted_format =
69 video_adapter_->AdaptFrameResolution(in_width, in_height);
70 if (!adapted_format.IsSize0x0()) {
71 adapted_format_ = adapted_format;
72 last_adapt_was_no_op_ = (in_width == adapted_format.width &&
73 in_height == adapted_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000074 } else {
75 ++dropped_frames_;
76 }
77 ++captured_frames_;
78 }
79
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000080 Stats GetStats() {
81 rtc::CritScope lock(&crit_);
82 Stats stats;
83 stats.captured_frames = captured_frames_;
84 stats.dropped_frames = dropped_frames_;
85 stats.last_adapt_was_no_op = last_adapt_was_no_op_;
Magnus Jedvertac27e202015-03-24 15:18:39 +010086 if (!adapted_format_.IsSize0x0()) {
87 stats.adapted_width = adapted_format_.width;
88 stats.adapted_height = adapted_format_.height;
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000089 } else {
90 stats.adapted_width = stats.adapted_height = -1;
91 }
92
93 return stats;
94 }
95
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000096 private:
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000097 rtc::CriticalSection crit_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000098 VideoAdapter* video_adapter_;
Magnus Jedvertac27e202015-03-24 15:18:39 +010099 VideoFormat adapted_format_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000100 int captured_frames_;
101 int dropped_frames_;
102 bool last_adapt_was_no_op_;
103 };
104
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000105
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000106 void VerifyAdaptedResolution(const VideoCapturerListener::Stats& stats,
107 int width,
108 int height) {
109 EXPECT_EQ(width, stats.adapted_width);
110 EXPECT_EQ(height, stats.adapted_height);
111 }
112
kwiberg686a8ef2016-02-26 03:00:35 -0800113 std::unique_ptr<FakeVideoCapturer> capturer_;
Per766ad3b2016-04-05 15:23:49 +0200114 VideoAdapter adapter_;
kwiberg686a8ef2016-02-26 03:00:35 -0800115 std::unique_ptr<VideoCapturerListener> listener_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000116 VideoFormat capture_format_;
117};
118
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000119// Do not adapt the frame rate or the resolution. Expect no frame drop and no
120// resolution change.
121TEST_F(VideoAdapterTest, AdaptNothing) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000122 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200123 for (int i = 0; i < 10; ++i)
124 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000125
126 // Verify no frame drop and no resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000127 VideoCapturerListener::Stats stats = listener_->GetStats();
128 EXPECT_GE(stats.captured_frames, 10);
129 EXPECT_EQ(0, stats.dropped_frames);
130 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height);
131 EXPECT_TRUE(stats.last_adapt_was_no_op);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000132}
133
134TEST_F(VideoAdapterTest, AdaptZeroInterval) {
135 VideoFormat format = capturer_->GetSupportedFormats()->at(0);
136 format.interval = 0;
Per766ad3b2016-04-05 15:23:49 +0200137 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000138 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200139 for (int i = 0; i < 10; ++i)
140 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000141
142 // Verify no crash and that frames aren't dropped.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000143 VideoCapturerListener::Stats stats = listener_->GetStats();
144 EXPECT_GE(stats.captured_frames, 10);
145 EXPECT_EQ(0, stats.dropped_frames);
146 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000147}
148
149// Adapt the frame rate to be half of the capture rate at the beginning. Expect
150// the number of dropped frames to be half of the number the captured frames.
151TEST_F(VideoAdapterTest, AdaptFramerate) {
152 VideoFormat request_format = capture_format_;
153 request_format.interval *= 2;
Per766ad3b2016-04-05 15:23:49 +0200154 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000155 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200156 for (int i = 0; i < 10; ++i)
157 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000158
159 // Verify frame drop and no resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000160 VideoCapturerListener::Stats stats = listener_->GetStats();
161 EXPECT_GE(stats.captured_frames, 10);
162 EXPECT_EQ(stats.captured_frames / 2, stats.dropped_frames);
163 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000164}
165
166// Adapt the frame rate to be half of the capture rate at the beginning. Expect
167// the number of dropped frames to be half of the number the captured frames.
168TEST_F(VideoAdapterTest, AdaptFramerateVariable) {
169 VideoFormat request_format = capture_format_;
170 request_format.interval = request_format.interval * 3 / 2;
Per766ad3b2016-04-05 15:23:49 +0200171 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000172 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200173 for (int i = 0; i < 30; ++i)
174 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000175
176 // Verify frame drop and no resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000177 VideoCapturerListener::Stats stats = listener_->GetStats();
178 EXPECT_GE(stats.captured_frames, 30);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000179 // Verify 2 / 3 kept (20) and 1 / 3 dropped (10).
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000180 EXPECT_EQ(stats.captured_frames * 1 / 3, stats.dropped_frames);
181 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000182}
183
184// Adapt the frame rate to be half of the capture rate after capturing no less
185// than 10 frames. Expect no frame dropped before adaptation and frame dropped
186// after adaptation.
187TEST_F(VideoAdapterTest, AdaptFramerateOntheFly) {
188 VideoFormat request_format = capture_format_;
Per766ad3b2016-04-05 15:23:49 +0200189 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000190 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200191 for (int i = 0; i < 10; ++i)
192 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000193
194 // Verify no frame drop before adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000195 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000196
197 // Adapat the frame rate.
198 request_format.interval *= 2;
Per766ad3b2016-04-05 15:23:49 +0200199 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000200
Magnus Jedvert01840572015-04-10 11:18:39 +0200201 for (int i = 0; i < 20; ++i)
202 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000203
204 // Verify frame drop after adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000205 EXPECT_GT(listener_->GetStats().dropped_frames, 0);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000206}
207
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000208// Set a very high output pixel resolution. Expect no resolution change.
209TEST_F(VideoAdapterTest, AdaptFrameResolutionHighLimit) {
Per766ad3b2016-04-05 15:23:49 +0200210 VideoFormat output_format = capture_format_;
211 output_format.width = 2560;
212 output_format.height = 2560;
213 adapter_.OnOutputFormatRequest(output_format);
214 VideoFormat adapted_format = adapter_.AdaptFrameResolution(
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000215 capture_format_.width, capture_format_.height);
216 EXPECT_EQ(capture_format_.width, adapted_format.width);
217 EXPECT_EQ(capture_format_.height, adapted_format.height);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000218}
219
220// Adapt the frame resolution to be the same as capture resolution. Expect no
221// resolution change.
222TEST_F(VideoAdapterTest, AdaptFrameResolutionIdentical) {
Per766ad3b2016-04-05 15:23:49 +0200223 adapter_.OnOutputFormatRequest(capture_format_);
224 const VideoFormat adapted_format = adapter_.AdaptFrameResolution(
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000225 capture_format_.width, capture_format_.height);
226 EXPECT_EQ(capture_format_.width, adapted_format.width);
227 EXPECT_EQ(capture_format_.height, adapted_format.height);
228}
229
230// Adapt the frame resolution to be a quarter of the capture resolution. Expect
231// resolution change.
232TEST_F(VideoAdapterTest, AdaptFrameResolutionQuarter) {
233 VideoFormat request_format = capture_format_;
234 request_format.width /= 2;
235 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200236 adapter_.OnOutputFormatRequest(request_format);
237 const VideoFormat adapted_format = adapter_.AdaptFrameResolution(
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000238 request_format.width, request_format.height);
239 EXPECT_EQ(request_format.width, adapted_format.width);
240 EXPECT_EQ(request_format.height, adapted_format.height);
241}
242
243// Adapt the pixel resolution to 0. Expect frame drop.
244TEST_F(VideoAdapterTest, AdaptFrameResolutionDrop) {
Per766ad3b2016-04-05 15:23:49 +0200245 VideoFormat output_format = capture_format_;
246 output_format.width = 0;
247 output_format.height = 0;
248 adapter_.OnOutputFormatRequest(output_format);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000249 EXPECT_TRUE(
Per766ad3b2016-04-05 15:23:49 +0200250 adapter_
251 .AdaptFrameResolution(capture_format_.width, capture_format_.height)
252 .IsSize0x0());
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000253}
254
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000255// Adapt the frame resolution to be a quarter of the capture resolution at the
256// beginning. Expect resolution change.
257TEST_F(VideoAdapterTest, AdaptResolution) {
258 VideoFormat request_format = capture_format_;
259 request_format.width /= 2;
260 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200261 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000262 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200263 for (int i = 0; i < 10; ++i)
264 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000265
266 // Verify no frame drop and resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000267 VideoCapturerListener::Stats stats = listener_->GetStats();
268 EXPECT_EQ(0, stats.dropped_frames);
269 VerifyAdaptedResolution(stats, request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000270}
271
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000272// Adapt the frame resolution to be a quarter of the capture resolution after
273// capturing no less than 10 frames. Expect no resolution change before
274// adaptation and resolution change after adaptation.
275TEST_F(VideoAdapterTest, AdaptResolutionOnTheFly) {
276 VideoFormat request_format = capture_format_;
Per766ad3b2016-04-05 15:23:49 +0200277 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000278 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200279 for (int i = 0; i < 10; ++i)
280 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000281
282 // Verify no resolution change before adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000283 VerifyAdaptedResolution(
284 listener_->GetStats(), request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000285
286 // Adapt the frame resolution.
287 request_format.width /= 2;
288 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200289 adapter_.OnOutputFormatRequest(request_format);
Magnus Jedvert01840572015-04-10 11:18:39 +0200290 for (int i = 0; i < 10; ++i)
291 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000292
293 // Verify resolution change after adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000294 VerifyAdaptedResolution(
295 listener_->GetStats(), request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000296}
297
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000298// Drop all frames.
299TEST_F(VideoAdapterTest, DropAllFrames) {
300 VideoFormat format; // with resolution 0x0.
Per766ad3b2016-04-05 15:23:49 +0200301 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000302 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200303 for (int i = 0; i < 10; ++i)
304 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000305
306 // Verify all frames are dropped.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000307 VideoCapturerListener::Stats stats = listener_->GetStats();
308 EXPECT_GE(stats.captured_frames, 10);
309 EXPECT_EQ(stats.captured_frames, stats.dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000310}
311
Per766ad3b2016-04-05 15:23:49 +0200312TEST_F(VideoAdapterTest, TestOnOutputFormatRequest) {
313 VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), 0);
314 adapter_.SetExpectedInputFrameInterval(VideoFormat::FpsToInterval(30));
315 VideoFormat out_format =
316 adapter_.AdaptFrameResolution(format.width, format.height);
317 EXPECT_EQ(format, adapter_.input_format());
318 EXPECT_EQ(format, out_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000319
Per766ad3b2016-04-05 15:23:49 +0200320 // Format request 640x400.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000321 format.height = 400;
Per766ad3b2016-04-05 15:23:49 +0200322 adapter_.OnOutputFormatRequest(format);
323 out_format = adapter_.AdaptFrameResolution(640, 400);
324 EXPECT_EQ(640, out_format.width);
325 EXPECT_EQ(400, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000326
Per766ad3b2016-04-05 15:23:49 +0200327 // Request 1280x720, higher than input. Adapt nothing.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000328 format.width = 1280;
329 format.height = 720;
Per766ad3b2016-04-05 15:23:49 +0200330 adapter_.OnOutputFormatRequest(format);
331 out_format = adapter_.AdaptFrameResolution(640, 400);
332 EXPECT_EQ(640, out_format.width);
333 EXPECT_EQ(400, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000334
Per766ad3b2016-04-05 15:23:49 +0200335 // Request 0x0.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000336 format.width = 0;
337 format.height = 0;
Per766ad3b2016-04-05 15:23:49 +0200338 adapter_.OnOutputFormatRequest(format);
339 out_format = adapter_.AdaptFrameResolution(640, 400);
340 EXPECT_TRUE(out_format.IsSize0x0());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000341
Per766ad3b2016-04-05 15:23:49 +0200342 // Request 320x200.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000343 format.width = 320;
344 format.height = 200;
Per766ad3b2016-04-05 15:23:49 +0200345 adapter_.OnOutputFormatRequest(format);
346 out_format = adapter_.AdaptFrameResolution(640, 400);
347 EXPECT_EQ(320, out_format.width);
348 EXPECT_EQ(200, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000349
Per766ad3b2016-04-05 15:23:49 +0200350 // Request resolution of 2 / 3. Expect adapt down. Scaling to 1/3 is not
351 // optimized and not allowed.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000352 format.width = (640 * 2 + 1) / 3;
353 format.height = (400 * 2 + 1) / 3;
Per766ad3b2016-04-05 15:23:49 +0200354 adapter_.OnOutputFormatRequest(format);
355 out_format = adapter_.AdaptFrameResolution(640, 400);
356 EXPECT_EQ(320, out_format.width);
357 EXPECT_EQ(200, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000358
Per766ad3b2016-04-05 15:23:49 +0200359 // Request resolution of 3 / 8. Expect adapt down.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000360 format.width = 640 * 3 / 8;
361 format.height = 400 * 3 / 8;
Per766ad3b2016-04-05 15:23:49 +0200362 adapter_.OnOutputFormatRequest(format);
363 out_format = adapter_.AdaptFrameResolution(640, 400);
364 EXPECT_EQ(640 * 3 / 8, out_format.width);
365 EXPECT_EQ(400 * 3 / 8, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000366
Per766ad3b2016-04-05 15:23:49 +0200367 // Switch back up. Expect adapt.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000368 format.width = 320;
369 format.height = 200;
Per766ad3b2016-04-05 15:23:49 +0200370 adapter_.OnOutputFormatRequest(format);
371 out_format = adapter_.AdaptFrameResolution(640, 400);
372 EXPECT_EQ(320, out_format.width);
373 EXPECT_EQ(200, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000374
Per766ad3b2016-04-05 15:23:49 +0200375 // Format request 480x300.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000376 format.width = 480;
377 format.height = 300;
Per766ad3b2016-04-05 15:23:49 +0200378 adapter_.OnOutputFormatRequest(format);
379 out_format = adapter_.AdaptFrameResolution(640, 400);
380 EXPECT_EQ(480, out_format.width);
381 EXPECT_EQ(300, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000382}
383
Per766ad3b2016-04-05 15:23:49 +0200384TEST_F(VideoAdapterTest, TestViewRequestPlusCameraSwitch) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000385 // Start at HD.
Per766ad3b2016-04-05 15:23:49 +0200386 VideoFormat format(1280, 720, VideoFormat::FpsToInterval(30), 0);
387 adapter_.SetExpectedInputFrameInterval(VideoFormat::FpsToInterval(30));
388 VideoFormat out_format =
389 adapter_.AdaptFrameResolution(format.width, format.height);
390 EXPECT_EQ(format, adapter_.input_format());
391 EXPECT_EQ(out_format, adapter_.input_format());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000392
Per766ad3b2016-04-05 15:23:49 +0200393 // Format request for VGA.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000394 format.width = 640;
395 format.height = 360;
Per766ad3b2016-04-05 15:23:49 +0200396 adapter_.OnOutputFormatRequest(format);
397 out_format = adapter_.AdaptFrameResolution(1280, 720);
398 EXPECT_EQ(640, out_format.width);
399 EXPECT_EQ(360, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000400
401 // Now, the camera reopens at VGA.
402 // Both the frame and the output format should be 640x360.
Per766ad3b2016-04-05 15:23:49 +0200403 out_format = adapter_.AdaptFrameResolution(640, 360);
Magnus Jedvertac27e202015-03-24 15:18:39 +0100404 EXPECT_EQ(640, out_format.width);
405 EXPECT_EQ(360, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000406
407 // And another view request comes in for 640x360, which should have no
408 // real impact.
Per766ad3b2016-04-05 15:23:49 +0200409 adapter_.OnOutputFormatRequest(format);
410 out_format = adapter_.AdaptFrameResolution(640, 360);
411 EXPECT_EQ(640, out_format.width);
412 EXPECT_EQ(360, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000413}
414
Per766ad3b2016-04-05 15:23:49 +0200415TEST_F(VideoAdapterTest, TestVGAWidth) {
416 // Reqeuested Output format is 640x360.
417 VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420);
418 adapter_.SetExpectedInputFrameInterval(VideoFormat::FpsToInterval(30));
419 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000420
Per766ad3b2016-04-05 15:23:49 +0200421 VideoFormat out_format = adapter_.AdaptFrameResolution(640, 480);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000422 // At this point, we have to adapt down to something lower.
Per766ad3b2016-04-05 15:23:49 +0200423 EXPECT_EQ(480, out_format.width);
424 EXPECT_EQ(360, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000425
426 // But if frames come in at 640x360, we shouldn't adapt them down.
Per766ad3b2016-04-05 15:23:49 +0200427 out_format = adapter_.AdaptFrameResolution(640, 360);
Magnus Jedvertac27e202015-03-24 15:18:39 +0100428 EXPECT_EQ(640, out_format.width);
429 EXPECT_EQ(360, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000430
Per766ad3b2016-04-05 15:23:49 +0200431 out_format = adapter_.AdaptFrameResolution(640, 480);
432 EXPECT_EQ(480, out_format.width);
433 EXPECT_EQ(360, out_format.height);
434}
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000435
Per766ad3b2016-04-05 15:23:49 +0200436TEST_F(VideoAdapterTest, TestOnResolutionRequestInSmallSteps) {
437 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720);
438 EXPECT_EQ(1280, out_format.width);
439 EXPECT_EQ(720, out_format.height);
440
441 // Adapt down one step.
442 adapter_.OnResolutionRequest(rtc::Optional<int>(1280 * 720 - 1),
443 rtc::Optional<int>());
444 out_format = adapter_.AdaptFrameResolution(1280, 720);
445 EXPECT_EQ(960, out_format.width);
446 EXPECT_EQ(540, out_format.height);
447
448 // Adapt down one step more.
449 adapter_.OnResolutionRequest(rtc::Optional<int>(960 * 540 - 1),
450 rtc::Optional<int>());
451 out_format = adapter_.AdaptFrameResolution(1280, 720);
452 EXPECT_EQ(640, out_format.width);
453 EXPECT_EQ(360, out_format.height);
454
455 // Adapt down one step more.
456 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
457 rtc::Optional<int>());
458 out_format = adapter_.AdaptFrameResolution(1280, 720);
459 EXPECT_EQ(480, out_format.width);
460 EXPECT_EQ(270, out_format.height);
461
462 // Adapt up one step.
463 adapter_.OnResolutionRequest(rtc::Optional<int>(),
464 rtc::Optional<int>(480 * 270));
465 out_format = adapter_.AdaptFrameResolution(1280, 720);
466 EXPECT_EQ(640, out_format.width);
467 EXPECT_EQ(360, out_format.height);
468
469 // Adapt up one step more.
470 adapter_.OnResolutionRequest(rtc::Optional<int>(),
471 rtc::Optional<int>(640 * 360));
472 out_format = adapter_.AdaptFrameResolution(1280, 720);
473 EXPECT_EQ(960, out_format.width);
474 EXPECT_EQ(540, out_format.height);
475
476 // Adapt up one step more.
477 adapter_.OnResolutionRequest(rtc::Optional<int>(),
478 rtc::Optional<int>(960 * 720));
479 out_format = adapter_.AdaptFrameResolution(1280, 720);
480 EXPECT_EQ(1280, out_format.width);
481 EXPECT_EQ(720, out_format.height);
482}
483
484TEST_F(VideoAdapterTest, TestOnResolutionRequestMaxZero) {
485 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720);
486 EXPECT_EQ(1280, out_format.width);
487 EXPECT_EQ(720, out_format.height);
488
489 adapter_.OnResolutionRequest(rtc::Optional<int>(0), rtc::Optional<int>());
490 out_format = adapter_.AdaptFrameResolution(1280, 720);
491 EXPECT_EQ(0, out_format.width);
492 EXPECT_EQ(0, out_format.height);
493}
494
495TEST_F(VideoAdapterTest, TestOnResolutionRequestInLargeSteps) {
496 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
497 rtc::Optional<int>());
498 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720);
499 EXPECT_EQ(480, out_format.width);
500 EXPECT_EQ(270, out_format.height);
501
502 adapter_.OnResolutionRequest(rtc::Optional<int>(),
503 rtc::Optional<int>(960 * 720));
504 out_format = adapter_.AdaptFrameResolution(1280, 720);
505 EXPECT_EQ(1280, out_format.width);
506 EXPECT_EQ(720, out_format.height);
507}
508
509TEST_F(VideoAdapterTest, TestOnOutputFormatRequestCapsMaxResolution) {
510 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
511 rtc::Optional<int>());
512 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720);
513 EXPECT_EQ(480, out_format.width);
514 EXPECT_EQ(270, out_format.height);
515
516 VideoFormat new_format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420);
517 adapter_.SetExpectedInputFrameInterval(VideoFormat::FpsToInterval(30));
518 adapter_.OnOutputFormatRequest(new_format);
519 out_format = adapter_.AdaptFrameResolution(1280, 720);
520 EXPECT_EQ(480, out_format.width);
521 EXPECT_EQ(270, out_format.height);
522
523 adapter_.OnResolutionRequest(rtc::Optional<int>(),
524 rtc::Optional<int>(960 * 720));
525 out_format = adapter_.AdaptFrameResolution(1280, 720);
Magnus Jedvertac27e202015-03-24 15:18:39 +0100526 EXPECT_EQ(640, out_format.width);
527 EXPECT_EQ(360, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000528}
529
Per766ad3b2016-04-05 15:23:49 +0200530TEST_F(VideoAdapterTest, TestOnResolutionRequestReset) {
531 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720);
532 EXPECT_EQ(1280, out_format.width);
533 EXPECT_EQ(720, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000534
Per766ad3b2016-04-05 15:23:49 +0200535 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
536 rtc::Optional<int>());
537 out_format = adapter_.AdaptFrameResolution(1280, 720);
538 EXPECT_EQ(480, out_format.width);
539 EXPECT_EQ(270, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000540
Per766ad3b2016-04-05 15:23:49 +0200541 adapter_.OnResolutionRequest(rtc::Optional<int>(), rtc::Optional<int>());
542 out_format = adapter_.AdaptFrameResolution(1280, 720);
543 EXPECT_EQ(1280, out_format.width);
544 EXPECT_EQ(720, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000545}
546
547} // namespace cricket