blob: d793d566dd8ac47b88cd212d139be7e0e6cddeb6 [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);
31 capture_format_.interval = VideoFormat::FpsToInterval(50);
Per766ad3b2016-04-05 15:23:49 +020032 adapter_.SetExpectedInputFrameInterval(capture_format_.interval);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000033
Per766ad3b2016-04-05 15:23:49 +020034 listener_.reset(new VideoCapturerListener(&adapter_));
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000035 capturer_->SignalFrameCaptured.connect(
36 listener_.get(), &VideoCapturerListener::OnFrameCaptured);
37 }
38
pbos@webrtc.org75c3ec12014-08-27 18:16:13 +000039 virtual void TearDown() {
40 // Explicitly disconnect the VideoCapturer before to avoid data races
41 // (frames delivered to VideoCapturerListener while it's being destructed).
42 capturer_->SignalFrameCaptured.disconnect_all();
43 }
44
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000045 protected:
46 class VideoCapturerListener: public sigslot::has_slots<> {
47 public:
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000048 struct Stats {
49 int captured_frames;
50 int dropped_frames;
51 bool last_adapt_was_no_op;
52
53 int adapted_width;
54 int adapted_height;
55 };
56
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000057 explicit VideoCapturerListener(VideoAdapter* adapter)
58 : video_adapter_(adapter),
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000059 captured_frames_(0),
60 dropped_frames_(0),
61 last_adapt_was_no_op_(false) {
62 }
63
64 void OnFrameCaptured(VideoCapturer* capturer,
65 const CapturedFrame* captured_frame) {
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000066 rtc::CritScope lock(&crit_);
Magnus Jedvertac27e202015-03-24 15:18:39 +010067 const int in_width = captured_frame->width;
68 const int in_height = abs(captured_frame->height);
69 const VideoFormat adapted_format =
70 video_adapter_->AdaptFrameResolution(in_width, in_height);
71 if (!adapted_format.IsSize0x0()) {
72 adapted_format_ = adapted_format;
73 last_adapt_was_no_op_ = (in_width == adapted_format.width &&
74 in_height == adapted_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000075 } else {
76 ++dropped_frames_;
77 }
78 ++captured_frames_;
79 }
80
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000081 Stats GetStats() {
82 rtc::CritScope lock(&crit_);
83 Stats stats;
84 stats.captured_frames = captured_frames_;
85 stats.dropped_frames = dropped_frames_;
86 stats.last_adapt_was_no_op = last_adapt_was_no_op_;
Magnus Jedvertac27e202015-03-24 15:18:39 +010087 if (!adapted_format_.IsSize0x0()) {
88 stats.adapted_width = adapted_format_.width;
89 stats.adapted_height = adapted_format_.height;
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000090 } else {
91 stats.adapted_width = stats.adapted_height = -1;
92 }
93
94 return stats;
95 }
96
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000097 private:
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +000098 rtc::CriticalSection crit_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +000099 VideoAdapter* video_adapter_;
Magnus Jedvertac27e202015-03-24 15:18:39 +0100100 VideoFormat adapted_format_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000101 int captured_frames_;
102 int dropped_frames_;
103 bool last_adapt_was_no_op_;
104 };
105
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000106
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000107 void VerifyAdaptedResolution(const VideoCapturerListener::Stats& stats,
108 int width,
109 int height) {
110 EXPECT_EQ(width, stats.adapted_width);
111 EXPECT_EQ(height, stats.adapted_height);
112 }
113
kwiberg686a8ef2016-02-26 03:00:35 -0800114 std::unique_ptr<FakeVideoCapturer> capturer_;
Per766ad3b2016-04-05 15:23:49 +0200115 VideoAdapter adapter_;
kwiberg686a8ef2016-02-26 03:00:35 -0800116 std::unique_ptr<VideoCapturerListener> listener_;
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000117 VideoFormat capture_format_;
118};
119
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000120// Do not adapt the frame rate or the resolution. Expect no frame drop and no
121// resolution change.
122TEST_F(VideoAdapterTest, AdaptNothing) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000123 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200124 for (int i = 0; i < 10; ++i)
125 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000126
127 // Verify no frame drop and no resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000128 VideoCapturerListener::Stats stats = listener_->GetStats();
129 EXPECT_GE(stats.captured_frames, 10);
130 EXPECT_EQ(0, stats.dropped_frames);
131 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height);
132 EXPECT_TRUE(stats.last_adapt_was_no_op);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000133}
134
135TEST_F(VideoAdapterTest, AdaptZeroInterval) {
136 VideoFormat format = capturer_->GetSupportedFormats()->at(0);
137 format.interval = 0;
Per766ad3b2016-04-05 15:23:49 +0200138 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000139 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200140 for (int i = 0; i < 10; ++i)
141 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000142
143 // Verify no crash and that frames aren't dropped.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000144 VideoCapturerListener::Stats stats = listener_->GetStats();
145 EXPECT_GE(stats.captured_frames, 10);
146 EXPECT_EQ(0, stats.dropped_frames);
147 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000148}
149
150// Adapt the frame rate to be half of the capture rate at the beginning. Expect
151// the number of dropped frames to be half of the number the captured frames.
152TEST_F(VideoAdapterTest, AdaptFramerate) {
153 VideoFormat request_format = capture_format_;
154 request_format.interval *= 2;
Per766ad3b2016-04-05 15:23:49 +0200155 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000156 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200157 for (int i = 0; i < 10; ++i)
158 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000159
160 // Verify frame drop and no resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000161 VideoCapturerListener::Stats stats = listener_->GetStats();
162 EXPECT_GE(stats.captured_frames, 10);
163 EXPECT_EQ(stats.captured_frames / 2, stats.dropped_frames);
164 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000165}
166
167// Adapt the frame rate to be half of the capture rate at the beginning. Expect
168// the number of dropped frames to be half of the number the captured frames.
169TEST_F(VideoAdapterTest, AdaptFramerateVariable) {
170 VideoFormat request_format = capture_format_;
171 request_format.interval = request_format.interval * 3 / 2;
Per766ad3b2016-04-05 15:23:49 +0200172 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000173 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200174 for (int i = 0; i < 30; ++i)
175 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000176
177 // Verify frame drop and no resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000178 VideoCapturerListener::Stats stats = listener_->GetStats();
179 EXPECT_GE(stats.captured_frames, 30);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000180 // Verify 2 / 3 kept (20) and 1 / 3 dropped (10).
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000181 EXPECT_EQ(stats.captured_frames * 1 / 3, stats.dropped_frames);
182 VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000183}
184
185// Adapt the frame rate to be half of the capture rate after capturing no less
186// than 10 frames. Expect no frame dropped before adaptation and frame dropped
187// after adaptation.
188TEST_F(VideoAdapterTest, AdaptFramerateOntheFly) {
189 VideoFormat request_format = capture_format_;
Per766ad3b2016-04-05 15:23:49 +0200190 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000191 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200192 for (int i = 0; i < 10; ++i)
193 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000194
195 // Verify no frame drop before adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000196 EXPECT_EQ(0, listener_->GetStats().dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000197
198 // Adapat the frame rate.
199 request_format.interval *= 2;
Per766ad3b2016-04-05 15:23:49 +0200200 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000201
Magnus Jedvert01840572015-04-10 11:18:39 +0200202 for (int i = 0; i < 20; ++i)
203 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000204
205 // Verify frame drop after adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000206 EXPECT_GT(listener_->GetStats().dropped_frames, 0);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000207}
208
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000209// Set a very high output pixel resolution. Expect no resolution change.
210TEST_F(VideoAdapterTest, AdaptFrameResolutionHighLimit) {
Per766ad3b2016-04-05 15:23:49 +0200211 VideoFormat output_format = capture_format_;
212 output_format.width = 2560;
213 output_format.height = 2560;
214 adapter_.OnOutputFormatRequest(output_format);
215 VideoFormat adapted_format = adapter_.AdaptFrameResolution(
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000216 capture_format_.width, capture_format_.height);
217 EXPECT_EQ(capture_format_.width, adapted_format.width);
218 EXPECT_EQ(capture_format_.height, adapted_format.height);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000219}
220
221// Adapt the frame resolution to be the same as capture resolution. Expect no
222// resolution change.
223TEST_F(VideoAdapterTest, AdaptFrameResolutionIdentical) {
Per766ad3b2016-04-05 15:23:49 +0200224 adapter_.OnOutputFormatRequest(capture_format_);
225 const VideoFormat adapted_format = adapter_.AdaptFrameResolution(
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000226 capture_format_.width, capture_format_.height);
227 EXPECT_EQ(capture_format_.width, adapted_format.width);
228 EXPECT_EQ(capture_format_.height, adapted_format.height);
229}
230
231// Adapt the frame resolution to be a quarter of the capture resolution. Expect
232// resolution change.
233TEST_F(VideoAdapterTest, AdaptFrameResolutionQuarter) {
234 VideoFormat request_format = capture_format_;
235 request_format.width /= 2;
236 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200237 adapter_.OnOutputFormatRequest(request_format);
238 const VideoFormat adapted_format = adapter_.AdaptFrameResolution(
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000239 request_format.width, request_format.height);
240 EXPECT_EQ(request_format.width, adapted_format.width);
241 EXPECT_EQ(request_format.height, adapted_format.height);
242}
243
244// Adapt the pixel resolution to 0. Expect frame drop.
245TEST_F(VideoAdapterTest, AdaptFrameResolutionDrop) {
Per766ad3b2016-04-05 15:23:49 +0200246 VideoFormat output_format = capture_format_;
247 output_format.width = 0;
248 output_format.height = 0;
249 adapter_.OnOutputFormatRequest(output_format);
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000250 EXPECT_TRUE(
Per766ad3b2016-04-05 15:23:49 +0200251 adapter_
252 .AdaptFrameResolution(capture_format_.width, capture_format_.height)
253 .IsSize0x0());
magjed@webrtc.orgf58b4552014-11-19 18:09:14 +0000254}
255
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000256// Adapt the frame resolution to be a quarter of the capture resolution at the
257// beginning. Expect resolution change.
258TEST_F(VideoAdapterTest, AdaptResolution) {
259 VideoFormat request_format = capture_format_;
260 request_format.width /= 2;
261 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200262 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000263 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200264 for (int i = 0; i < 10; ++i)
265 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000266
267 // Verify no frame drop and resolution change.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000268 VideoCapturerListener::Stats stats = listener_->GetStats();
269 EXPECT_EQ(0, stats.dropped_frames);
270 VerifyAdaptedResolution(stats, request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000271}
272
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000273// Adapt the frame resolution to be a quarter of the capture resolution after
274// capturing no less than 10 frames. Expect no resolution change before
275// adaptation and resolution change after adaptation.
276TEST_F(VideoAdapterTest, AdaptResolutionOnTheFly) {
277 VideoFormat request_format = capture_format_;
Per766ad3b2016-04-05 15:23:49 +0200278 adapter_.OnOutputFormatRequest(request_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000279 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
283 // Verify no resolution change before adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000284 VerifyAdaptedResolution(
285 listener_->GetStats(), request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000286
287 // Adapt the frame resolution.
288 request_format.width /= 2;
289 request_format.height /= 2;
Per766ad3b2016-04-05 15:23:49 +0200290 adapter_.OnOutputFormatRequest(request_format);
Magnus Jedvert01840572015-04-10 11:18:39 +0200291 for (int i = 0; i < 10; ++i)
292 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000293
294 // Verify resolution change after adaptation.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000295 VerifyAdaptedResolution(
296 listener_->GetStats(), request_format.width, request_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000297}
298
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000299// Drop all frames.
300TEST_F(VideoAdapterTest, DropAllFrames) {
301 VideoFormat format; // with resolution 0x0.
Per766ad3b2016-04-05 15:23:49 +0200302 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000303 EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
Magnus Jedvert01840572015-04-10 11:18:39 +0200304 for (int i = 0; i < 10; ++i)
305 capturer_->CaptureFrame();
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000306
307 // Verify all frames are dropped.
pbos@webrtc.orgc9b3f772014-08-26 12:33:18 +0000308 VideoCapturerListener::Stats stats = listener_->GetStats();
309 EXPECT_GE(stats.captured_frames, 10);
310 EXPECT_EQ(stats.captured_frames, stats.dropped_frames);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000311}
312
Per766ad3b2016-04-05 15:23:49 +0200313TEST_F(VideoAdapterTest, TestOnOutputFormatRequest) {
314 VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), 0);
315 adapter_.SetExpectedInputFrameInterval(VideoFormat::FpsToInterval(30));
316 VideoFormat out_format =
317 adapter_.AdaptFrameResolution(format.width, format.height);
318 EXPECT_EQ(format, adapter_.input_format());
319 EXPECT_EQ(format, out_format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000320
Per766ad3b2016-04-05 15:23:49 +0200321 // Format request 640x400.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000322 format.height = 400;
Per766ad3b2016-04-05 15:23:49 +0200323 adapter_.OnOutputFormatRequest(format);
324 out_format = adapter_.AdaptFrameResolution(640, 400);
325 EXPECT_EQ(640, out_format.width);
326 EXPECT_EQ(400, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000327
Per766ad3b2016-04-05 15:23:49 +0200328 // Request 1280x720, higher than input. Adapt nothing.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000329 format.width = 1280;
330 format.height = 720;
Per766ad3b2016-04-05 15:23:49 +0200331 adapter_.OnOutputFormatRequest(format);
332 out_format = adapter_.AdaptFrameResolution(640, 400);
333 EXPECT_EQ(640, out_format.width);
334 EXPECT_EQ(400, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000335
Per766ad3b2016-04-05 15:23:49 +0200336 // Request 0x0.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000337 format.width = 0;
338 format.height = 0;
Per766ad3b2016-04-05 15:23:49 +0200339 adapter_.OnOutputFormatRequest(format);
340 out_format = adapter_.AdaptFrameResolution(640, 400);
341 EXPECT_TRUE(out_format.IsSize0x0());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000342
Per766ad3b2016-04-05 15:23:49 +0200343 // Request 320x200.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000344 format.width = 320;
345 format.height = 200;
Per766ad3b2016-04-05 15:23:49 +0200346 adapter_.OnOutputFormatRequest(format);
347 out_format = adapter_.AdaptFrameResolution(640, 400);
348 EXPECT_EQ(320, out_format.width);
349 EXPECT_EQ(200, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000350
Per766ad3b2016-04-05 15:23:49 +0200351 // Request resolution of 2 / 3. Expect adapt down. Scaling to 1/3 is not
352 // optimized and not allowed.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000353 format.width = (640 * 2 + 1) / 3;
354 format.height = (400 * 2 + 1) / 3;
Per766ad3b2016-04-05 15:23:49 +0200355 adapter_.OnOutputFormatRequest(format);
356 out_format = adapter_.AdaptFrameResolution(640, 400);
357 EXPECT_EQ(320, out_format.width);
358 EXPECT_EQ(200, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000359
Per766ad3b2016-04-05 15:23:49 +0200360 // Request resolution of 3 / 8. Expect adapt down.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000361 format.width = 640 * 3 / 8;
362 format.height = 400 * 3 / 8;
Per766ad3b2016-04-05 15:23:49 +0200363 adapter_.OnOutputFormatRequest(format);
364 out_format = adapter_.AdaptFrameResolution(640, 400);
365 EXPECT_EQ(640 * 3 / 8, out_format.width);
366 EXPECT_EQ(400 * 3 / 8, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000367
Per766ad3b2016-04-05 15:23:49 +0200368 // Switch back up. Expect adapt.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000369 format.width = 320;
370 format.height = 200;
Per766ad3b2016-04-05 15:23:49 +0200371 adapter_.OnOutputFormatRequest(format);
372 out_format = adapter_.AdaptFrameResolution(640, 400);
373 EXPECT_EQ(320, out_format.width);
374 EXPECT_EQ(200, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000375
Per766ad3b2016-04-05 15:23:49 +0200376 // Format request 480x300.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000377 format.width = 480;
378 format.height = 300;
Per766ad3b2016-04-05 15:23:49 +0200379 adapter_.OnOutputFormatRequest(format);
380 out_format = adapter_.AdaptFrameResolution(640, 400);
381 EXPECT_EQ(480, out_format.width);
382 EXPECT_EQ(300, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000383}
384
Per766ad3b2016-04-05 15:23:49 +0200385TEST_F(VideoAdapterTest, TestViewRequestPlusCameraSwitch) {
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000386 // Start at HD.
Per766ad3b2016-04-05 15:23:49 +0200387 VideoFormat format(1280, 720, VideoFormat::FpsToInterval(30), 0);
388 adapter_.SetExpectedInputFrameInterval(VideoFormat::FpsToInterval(30));
389 VideoFormat out_format =
390 adapter_.AdaptFrameResolution(format.width, format.height);
391 EXPECT_EQ(format, adapter_.input_format());
392 EXPECT_EQ(out_format, adapter_.input_format());
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000393
Per766ad3b2016-04-05 15:23:49 +0200394 // Format request for VGA.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000395 format.width = 640;
396 format.height = 360;
Per766ad3b2016-04-05 15:23:49 +0200397 adapter_.OnOutputFormatRequest(format);
398 out_format = adapter_.AdaptFrameResolution(1280, 720);
399 EXPECT_EQ(640, out_format.width);
400 EXPECT_EQ(360, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000401
402 // Now, the camera reopens at VGA.
403 // Both the frame and the output format should be 640x360.
Per766ad3b2016-04-05 15:23:49 +0200404 out_format = adapter_.AdaptFrameResolution(640, 360);
Magnus Jedvertac27e202015-03-24 15:18:39 +0100405 EXPECT_EQ(640, out_format.width);
406 EXPECT_EQ(360, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000407
408 // And another view request comes in for 640x360, which should have no
409 // real impact.
Per766ad3b2016-04-05 15:23:49 +0200410 adapter_.OnOutputFormatRequest(format);
411 out_format = adapter_.AdaptFrameResolution(640, 360);
412 EXPECT_EQ(640, out_format.width);
413 EXPECT_EQ(360, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000414}
415
Per766ad3b2016-04-05 15:23:49 +0200416TEST_F(VideoAdapterTest, TestVGAWidth) {
417 // Reqeuested Output format is 640x360.
418 VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420);
419 adapter_.SetExpectedInputFrameInterval(VideoFormat::FpsToInterval(30));
420 adapter_.OnOutputFormatRequest(format);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000421
Per766ad3b2016-04-05 15:23:49 +0200422 VideoFormat out_format = adapter_.AdaptFrameResolution(640, 480);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000423 // At this point, we have to adapt down to something lower.
Per766ad3b2016-04-05 15:23:49 +0200424 EXPECT_EQ(480, out_format.width);
425 EXPECT_EQ(360, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000426
427 // But if frames come in at 640x360, we shouldn't adapt them down.
Per766ad3b2016-04-05 15:23:49 +0200428 out_format = adapter_.AdaptFrameResolution(640, 360);
Magnus Jedvertac27e202015-03-24 15:18:39 +0100429 EXPECT_EQ(640, out_format.width);
430 EXPECT_EQ(360, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000431
Per766ad3b2016-04-05 15:23:49 +0200432 out_format = adapter_.AdaptFrameResolution(640, 480);
433 EXPECT_EQ(480, out_format.width);
434 EXPECT_EQ(360, out_format.height);
435}
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000436
Per766ad3b2016-04-05 15:23:49 +0200437TEST_F(VideoAdapterTest, TestOnResolutionRequestInSmallSteps) {
438 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720);
439 EXPECT_EQ(1280, out_format.width);
440 EXPECT_EQ(720, out_format.height);
441
442 // Adapt down one step.
443 adapter_.OnResolutionRequest(rtc::Optional<int>(1280 * 720 - 1),
444 rtc::Optional<int>());
445 out_format = adapter_.AdaptFrameResolution(1280, 720);
446 EXPECT_EQ(960, out_format.width);
447 EXPECT_EQ(540, out_format.height);
448
449 // Adapt down one step more.
450 adapter_.OnResolutionRequest(rtc::Optional<int>(960 * 540 - 1),
451 rtc::Optional<int>());
452 out_format = adapter_.AdaptFrameResolution(1280, 720);
453 EXPECT_EQ(640, out_format.width);
454 EXPECT_EQ(360, out_format.height);
455
456 // Adapt down one step more.
457 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
458 rtc::Optional<int>());
459 out_format = adapter_.AdaptFrameResolution(1280, 720);
460 EXPECT_EQ(480, out_format.width);
461 EXPECT_EQ(270, out_format.height);
462
463 // Adapt up one step.
464 adapter_.OnResolutionRequest(rtc::Optional<int>(),
465 rtc::Optional<int>(480 * 270));
466 out_format = adapter_.AdaptFrameResolution(1280, 720);
467 EXPECT_EQ(640, out_format.width);
468 EXPECT_EQ(360, out_format.height);
469
470 // Adapt up one step more.
471 adapter_.OnResolutionRequest(rtc::Optional<int>(),
472 rtc::Optional<int>(640 * 360));
473 out_format = adapter_.AdaptFrameResolution(1280, 720);
474 EXPECT_EQ(960, out_format.width);
475 EXPECT_EQ(540, out_format.height);
476
477 // Adapt up one step more.
478 adapter_.OnResolutionRequest(rtc::Optional<int>(),
479 rtc::Optional<int>(960 * 720));
480 out_format = adapter_.AdaptFrameResolution(1280, 720);
481 EXPECT_EQ(1280, out_format.width);
482 EXPECT_EQ(720, out_format.height);
483}
484
485TEST_F(VideoAdapterTest, TestOnResolutionRequestMaxZero) {
486 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720);
487 EXPECT_EQ(1280, out_format.width);
488 EXPECT_EQ(720, out_format.height);
489
490 adapter_.OnResolutionRequest(rtc::Optional<int>(0), rtc::Optional<int>());
491 out_format = adapter_.AdaptFrameResolution(1280, 720);
492 EXPECT_EQ(0, out_format.width);
493 EXPECT_EQ(0, out_format.height);
494}
495
496TEST_F(VideoAdapterTest, TestOnResolutionRequestInLargeSteps) {
497 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
498 rtc::Optional<int>());
499 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720);
500 EXPECT_EQ(480, out_format.width);
501 EXPECT_EQ(270, out_format.height);
502
503 adapter_.OnResolutionRequest(rtc::Optional<int>(),
504 rtc::Optional<int>(960 * 720));
505 out_format = adapter_.AdaptFrameResolution(1280, 720);
506 EXPECT_EQ(1280, out_format.width);
507 EXPECT_EQ(720, out_format.height);
508}
509
510TEST_F(VideoAdapterTest, TestOnOutputFormatRequestCapsMaxResolution) {
511 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
512 rtc::Optional<int>());
513 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720);
514 EXPECT_EQ(480, out_format.width);
515 EXPECT_EQ(270, out_format.height);
516
517 VideoFormat new_format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420);
518 adapter_.SetExpectedInputFrameInterval(VideoFormat::FpsToInterval(30));
519 adapter_.OnOutputFormatRequest(new_format);
520 out_format = adapter_.AdaptFrameResolution(1280, 720);
521 EXPECT_EQ(480, out_format.width);
522 EXPECT_EQ(270, out_format.height);
523
524 adapter_.OnResolutionRequest(rtc::Optional<int>(),
525 rtc::Optional<int>(960 * 720));
526 out_format = adapter_.AdaptFrameResolution(1280, 720);
Magnus Jedvertac27e202015-03-24 15:18:39 +0100527 EXPECT_EQ(640, out_format.width);
528 EXPECT_EQ(360, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000529}
530
Per766ad3b2016-04-05 15:23:49 +0200531TEST_F(VideoAdapterTest, TestOnResolutionRequestReset) {
532 VideoFormat out_format = adapter_.AdaptFrameResolution(1280, 720);
533 EXPECT_EQ(1280, out_format.width);
534 EXPECT_EQ(720, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000535
Per766ad3b2016-04-05 15:23:49 +0200536 adapter_.OnResolutionRequest(rtc::Optional<int>(640 * 360 - 1),
537 rtc::Optional<int>());
538 out_format = adapter_.AdaptFrameResolution(1280, 720);
539 EXPECT_EQ(480, out_format.width);
540 EXPECT_EQ(270, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000541
Per766ad3b2016-04-05 15:23:49 +0200542 adapter_.OnResolutionRequest(rtc::Optional<int>(), rtc::Optional<int>());
543 out_format = adapter_.AdaptFrameResolution(1280, 720);
544 EXPECT_EQ(1280, out_format.width);
545 EXPECT_EQ(720, out_format.height);
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000546}
547
548} // namespace cricket