blob: 0e6f992934962c6d981670f41a13d842f884437b [file] [log] [blame]
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2008 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 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
11#include <stdio.h>
kwibergbfefb032016-05-01 14:53:46 -070012
13#include <memory>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000014#include <vector>
15
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000016#include "webrtc/base/gunit.h"
17#include "webrtc/base/logging.h"
18#include "webrtc/base/thread.h"
kjellandera96e2d72016-02-04 23:52:28 -080019#include "webrtc/media/base/fakevideocapturer.h"
20#include "webrtc/media/base/fakevideorenderer.h"
21#include "webrtc/media/base/testutils.h"
22#include "webrtc/media/base/videocapturer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000023
henrike@webrtc.org28e20752013-07-10 00:45:36 +000024using cricket::FakeVideoCapturer;
25
26namespace {
27
28const int kMsCallbackWait = 500;
29// For HD only the height matters.
30const int kMinHdHeight = 720;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000031
32} // namespace
33
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034class VideoCapturerTest
35 : public sigslot::has_slots<>,
36 public testing::Test {
37 public:
38 VideoCapturerTest()
Pera5092412016-02-12 13:30:57 +010039 : capture_state_(cricket::CS_STOPPED), num_state_changes_(0) {
Niels Möller60653ba2016-03-02 11:41:36 +010040 InitCapturer(false);
guoweis@webrtc.org1226e922015-02-11 18:37:54 +000041 }
42
henrike@webrtc.org28e20752013-07-10 00:45:36 +000043 protected:
Niels Möller60653ba2016-03-02 11:41:36 +010044 void InitCapturer(bool is_screencast) {
kwibergbfefb032016-05-01 14:53:46 -070045 capturer_ = std::unique_ptr<FakeVideoCapturer>(
Niels Möller60653ba2016-03-02 11:41:36 +010046 new FakeVideoCapturer(is_screencast));
47 capturer_->SignalStateChange.connect(this,
48 &VideoCapturerTest::OnStateChange);
49 capturer_->AddOrUpdateSink(&renderer_, rtc::VideoSinkWants());
50 }
51 void InitScreencast() { InitCapturer(true); }
52
henrike@webrtc.org28e20752013-07-10 00:45:36 +000053 void OnStateChange(cricket::VideoCapturer*,
54 cricket::CaptureState capture_state) {
55 capture_state_ = capture_state;
56 ++num_state_changes_;
57 }
58 cricket::CaptureState capture_state() { return capture_state_; }
59 int num_state_changes() { return num_state_changes_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060
kwibergbfefb032016-05-01 14:53:46 -070061 std::unique_ptr<cricket::FakeVideoCapturer> capturer_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000062 cricket::CaptureState capture_state_;
63 int num_state_changes_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064 cricket::FakeVideoRenderer renderer_;
guoweis@webrtc.org1226e922015-02-11 18:37:54 +000065 bool expects_rotation_applied_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066};
67
68TEST_F(VideoCapturerTest, CaptureState) {
Niels Möller60653ba2016-03-02 11:41:36 +010069 EXPECT_TRUE(capturer_->enable_video_adapter());
70 EXPECT_EQ(cricket::CS_RUNNING, capturer_->Start(cricket::VideoFormat(
henrike@webrtc.org28e20752013-07-10 00:45:36 +000071 640,
72 480,
73 cricket::VideoFormat::FpsToInterval(30),
74 cricket::FOURCC_I420)));
Niels Möller60653ba2016-03-02 11:41:36 +010075 EXPECT_TRUE(capturer_->IsRunning());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000076 EXPECT_EQ_WAIT(cricket::CS_RUNNING, capture_state(), kMsCallbackWait);
77 EXPECT_EQ(1, num_state_changes());
Niels Möller60653ba2016-03-02 11:41:36 +010078 capturer_->Stop();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000079 EXPECT_EQ_WAIT(cricket::CS_STOPPED, capture_state(), kMsCallbackWait);
80 EXPECT_EQ(2, num_state_changes());
Niels Möller60653ba2016-03-02 11:41:36 +010081 capturer_->Stop();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000082 rtc::Thread::Current()->ProcessMessages(100);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000083 EXPECT_EQ(2, num_state_changes());
84}
85
buildbot@webrtc.org53f57932014-06-16 21:08:51 +000086TEST_F(VideoCapturerTest, ScreencastScaledOddWidth) {
Niels Möller60653ba2016-03-02 11:41:36 +010087 InitScreencast();
buildbot@webrtc.org53f57932014-06-16 21:08:51 +000088
89 int kWidth = 1281;
90 int kHeight = 720;
91
92 std::vector<cricket::VideoFormat> formats;
93 formats.push_back(cricket::VideoFormat(kWidth, kHeight,
nissef5297a02016-09-30 01:34:27 -070094 cricket::VideoFormat::FpsToInterval(5),
95 cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +010096 capturer_->ResetSupportedFormats(formats);
buildbot@webrtc.org53f57932014-06-16 21:08:51 +000097
nissef5297a02016-09-30 01:34:27 -070098 EXPECT_EQ(cricket::CS_RUNNING,
99 capturer_->Start(cricket::VideoFormat(
100 kWidth, kHeight, cricket::VideoFormat::FpsToInterval(30),
perkjfa10b552016-10-02 23:45:26 -0700101 cricket::FOURCC_I420)));
Niels Möller60653ba2016-03-02 11:41:36 +0100102 EXPECT_TRUE(capturer_->IsRunning());
buildbot@webrtc.org53f57932014-06-16 21:08:51 +0000103 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller60653ba2016-03-02 11:41:36 +0100104 EXPECT_TRUE(capturer_->CaptureFrame());
buildbot@webrtc.org53f57932014-06-16 21:08:51 +0000105 EXPECT_EQ(1, renderer_.num_rendered_frames());
nissec4c84852016-01-19 00:52:47 -0800106 EXPECT_EQ(kWidth, renderer_.width());
107 EXPECT_EQ(kHeight, renderer_.height());
buildbot@webrtc.org53f57932014-06-16 21:08:51 +0000108}
109
Pera5092412016-02-12 13:30:57 +0100110TEST_F(VideoCapturerTest, TestRotationAppliedBySource) {
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000111 int kWidth = 800;
112 int kHeight = 400;
113 int frame_count = 0;
114
115 std::vector<cricket::VideoFormat> formats;
116 formats.push_back(cricket::VideoFormat(kWidth, kHeight,
117 cricket::VideoFormat::FpsToInterval(5),
118 cricket::FOURCC_I420));
119
Niels Möller60653ba2016-03-02 11:41:36 +0100120 capturer_->ResetSupportedFormats(formats);
deadbeeff5629ad2016-03-18 11:38:26 -0700121 rtc::VideoSinkWants wants;
122 // |capturer_| should compensate rotation.
123 wants.rotation_applied = true;
124 capturer_->AddOrUpdateSink(&renderer_, wants);
Pera5092412016-02-12 13:30:57 +0100125
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000126 // capturer_ should compensate rotation as default.
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000127 EXPECT_EQ(cricket::CS_RUNNING,
Niels Möller60653ba2016-03-02 11:41:36 +0100128 capturer_->Start(cricket::VideoFormat(
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000129 kWidth, kHeight, cricket::VideoFormat::FpsToInterval(30),
130 cricket::FOURCC_I420)));
Niels Möller60653ba2016-03-02 11:41:36 +0100131 EXPECT_TRUE(capturer_->IsRunning());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000132 EXPECT_EQ(0, renderer_.num_rendered_frames());
133
134 // If the frame's rotation is compensated anywhere in the pipeline based on
135 // the rotation information, the renderer should be given the right dimension
136 // such that the frame could be rendered.
137
Niels Möller60653ba2016-03-02 11:41:36 +0100138 capturer_->SetRotation(webrtc::kVideoRotation_90);
139 EXPECT_TRUE(capturer_->CaptureFrame());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000140 EXPECT_EQ(++frame_count, renderer_.num_rendered_frames());
nissec4c84852016-01-19 00:52:47 -0800141 // Swapped width and height
142 EXPECT_EQ(kWidth, renderer_.height());
143 EXPECT_EQ(kHeight, renderer_.width());
Pera5092412016-02-12 13:30:57 +0100144 EXPECT_EQ(webrtc::kVideoRotation_0, renderer_.rotation());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000145
Niels Möller60653ba2016-03-02 11:41:36 +0100146 capturer_->SetRotation(webrtc::kVideoRotation_270);
147 EXPECT_TRUE(capturer_->CaptureFrame());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000148 EXPECT_EQ(++frame_count, renderer_.num_rendered_frames());
nissec4c84852016-01-19 00:52:47 -0800149 // Swapped width and height
150 EXPECT_EQ(kWidth, renderer_.height());
151 EXPECT_EQ(kHeight, renderer_.width());
Pera5092412016-02-12 13:30:57 +0100152 EXPECT_EQ(webrtc::kVideoRotation_0, renderer_.rotation());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000153
Niels Möller60653ba2016-03-02 11:41:36 +0100154 capturer_->SetRotation(webrtc::kVideoRotation_180);
155 EXPECT_TRUE(capturer_->CaptureFrame());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000156 EXPECT_EQ(++frame_count, renderer_.num_rendered_frames());
nissec4c84852016-01-19 00:52:47 -0800157 // Back to normal width and height
158 EXPECT_EQ(kWidth, renderer_.width());
159 EXPECT_EQ(kHeight, renderer_.height());
Pera5092412016-02-12 13:30:57 +0100160 EXPECT_EQ(webrtc::kVideoRotation_0, renderer_.rotation());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000161}
162
deadbeeff5629ad2016-03-18 11:38:26 -0700163TEST_F(VideoCapturerTest, TestRotationAppliedBySinkByDefault) {
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000164 int kWidth = 800;
165 int kHeight = 400;
166
167 std::vector<cricket::VideoFormat> formats;
168 formats.push_back(cricket::VideoFormat(kWidth, kHeight,
169 cricket::VideoFormat::FpsToInterval(5),
170 cricket::FOURCC_I420));
171
Niels Möller60653ba2016-03-02 11:41:36 +0100172 capturer_->ResetSupportedFormats(formats);
Pera5092412016-02-12 13:30:57 +0100173
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000174 EXPECT_EQ(cricket::CS_RUNNING,
Niels Möller60653ba2016-03-02 11:41:36 +0100175 capturer_->Start(cricket::VideoFormat(
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000176 kWidth, kHeight, cricket::VideoFormat::FpsToInterval(30),
177 cricket::FOURCC_I420)));
Niels Möller60653ba2016-03-02 11:41:36 +0100178 EXPECT_TRUE(capturer_->IsRunning());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000179 EXPECT_EQ(0, renderer_.num_rendered_frames());
180
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000181 // If the frame's rotation is compensated anywhere in the pipeline, the frame
182 // won't have its original dimension out from capturer. Since the renderer
183 // here has the same dimension as the capturer, it will skip that frame as the
184 // resolution won't match anymore.
185
186 int frame_count = 0;
Niels Möller60653ba2016-03-02 11:41:36 +0100187 capturer_->SetRotation(webrtc::kVideoRotation_0);
188 EXPECT_TRUE(capturer_->CaptureFrame());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000189 EXPECT_EQ(++frame_count, renderer_.num_rendered_frames());
Niels Möller60653ba2016-03-02 11:41:36 +0100190 EXPECT_EQ(capturer_->GetRotation(), renderer_.rotation());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000191
Niels Möller60653ba2016-03-02 11:41:36 +0100192 capturer_->SetRotation(webrtc::kVideoRotation_90);
193 EXPECT_TRUE(capturer_->CaptureFrame());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000194 EXPECT_EQ(++frame_count, renderer_.num_rendered_frames());
Niels Möller60653ba2016-03-02 11:41:36 +0100195 EXPECT_EQ(capturer_->GetRotation(), renderer_.rotation());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000196
Niels Möller60653ba2016-03-02 11:41:36 +0100197 capturer_->SetRotation(webrtc::kVideoRotation_180);
198 EXPECT_TRUE(capturer_->CaptureFrame());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000199 EXPECT_EQ(++frame_count, renderer_.num_rendered_frames());
Niels Möller60653ba2016-03-02 11:41:36 +0100200 EXPECT_EQ(capturer_->GetRotation(), renderer_.rotation());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000201
Niels Möller60653ba2016-03-02 11:41:36 +0100202 capturer_->SetRotation(webrtc::kVideoRotation_270);
203 EXPECT_TRUE(capturer_->CaptureFrame());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000204 EXPECT_EQ(++frame_count, renderer_.num_rendered_frames());
Niels Möller60653ba2016-03-02 11:41:36 +0100205 EXPECT_EQ(capturer_->GetRotation(), renderer_.rotation());
Pera5092412016-02-12 13:30:57 +0100206}
207
208TEST_F(VideoCapturerTest, TestRotationAppliedBySourceWhenDifferentWants) {
209 int kWidth = 800;
210 int kHeight = 400;
211
212 std::vector<cricket::VideoFormat> formats;
213 formats.push_back(cricket::VideoFormat(kWidth, kHeight,
214 cricket::VideoFormat::FpsToInterval(5),
215 cricket::FOURCC_I420));
216
Niels Möller60653ba2016-03-02 11:41:36 +0100217 capturer_->ResetSupportedFormats(formats);
Pera5092412016-02-12 13:30:57 +0100218 rtc::VideoSinkWants wants;
219 // capturer_ should not compensate rotation.
220 wants.rotation_applied = false;
Niels Möller60653ba2016-03-02 11:41:36 +0100221 capturer_->AddOrUpdateSink(&renderer_, wants);
Pera5092412016-02-12 13:30:57 +0100222
Pera5092412016-02-12 13:30:57 +0100223 EXPECT_EQ(cricket::CS_RUNNING,
Niels Möller60653ba2016-03-02 11:41:36 +0100224 capturer_->Start(cricket::VideoFormat(
Pera5092412016-02-12 13:30:57 +0100225 kWidth, kHeight, cricket::VideoFormat::FpsToInterval(30),
226 cricket::FOURCC_I420)));
Niels Möller60653ba2016-03-02 11:41:36 +0100227 EXPECT_TRUE(capturer_->IsRunning());
Pera5092412016-02-12 13:30:57 +0100228 EXPECT_EQ(0, renderer_.num_rendered_frames());
229
230 int frame_count = 0;
Niels Möller60653ba2016-03-02 11:41:36 +0100231 capturer_->SetRotation(webrtc::kVideoRotation_90);
232 EXPECT_TRUE(capturer_->CaptureFrame());
Pera5092412016-02-12 13:30:57 +0100233 EXPECT_EQ(++frame_count, renderer_.num_rendered_frames());
Niels Möller60653ba2016-03-02 11:41:36 +0100234 EXPECT_EQ(capturer_->GetRotation(), renderer_.rotation());
Pera5092412016-02-12 13:30:57 +0100235
236 // Add another sink that wants frames to be rotated.
237 cricket::FakeVideoRenderer renderer2;
238 wants.rotation_applied = true;
Niels Möller60653ba2016-03-02 11:41:36 +0100239 capturer_->AddOrUpdateSink(&renderer2, wants);
Pera5092412016-02-12 13:30:57 +0100240
Niels Möller60653ba2016-03-02 11:41:36 +0100241 EXPECT_TRUE(capturer_->CaptureFrame());
Pera5092412016-02-12 13:30:57 +0100242 EXPECT_EQ(++frame_count, renderer_.num_rendered_frames());
243 EXPECT_EQ(1, renderer2.num_rendered_frames());
244 EXPECT_EQ(webrtc::kVideoRotation_0, renderer_.rotation());
245 EXPECT_EQ(webrtc::kVideoRotation_0, renderer2.rotation());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000246}
247
nissef5297a02016-09-30 01:34:27 -0700248// TODO(nisse): This test doesn't quite fit here. It tests two things:
249// Aggregation of VideoSinkWants, which is the responsibility of
250// VideoBroadcaster, and translation of VideoSinkWants to actual
251// resolution, which is the responsibility of the VideoAdapter.
perkj2d5f0912016-02-29 00:04:41 -0800252TEST_F(VideoCapturerTest, SinkWantsMaxPixelAndMaxPixelCountStepUp) {
253 EXPECT_EQ(cricket::CS_RUNNING,
Niels Möller60653ba2016-03-02 11:41:36 +0100254 capturer_->Start(cricket::VideoFormat(
perkj2d5f0912016-02-29 00:04:41 -0800255 1280, 720, cricket::VideoFormat::FpsToInterval(30),
256 cricket::FOURCC_I420)));
Niels Möller60653ba2016-03-02 11:41:36 +0100257 EXPECT_TRUE(capturer_->IsRunning());
perkj2d5f0912016-02-29 00:04:41 -0800258
259 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller60653ba2016-03-02 11:41:36 +0100260 EXPECT_TRUE(capturer_->CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -0800261 EXPECT_EQ(1, renderer_.num_rendered_frames());
262 EXPECT_EQ(1280, renderer_.width());
263 EXPECT_EQ(720, renderer_.height());
264
Per766ad3b2016-04-05 15:23:49 +0200265 // Request a lower resolution. The output resolution will have a resolution
266 // with less than or equal to |wants.max_pixel_count| depending on how the
267 // capturer can scale the input frame size.
perkj2d5f0912016-02-29 00:04:41 -0800268 rtc::VideoSinkWants wants;
lliuuf9ed2352017-03-30 10:44:38 -0700269 wants.max_pixel_count = rtc::Optional<int>(1280 * 720 * 3 / 5);
Niels Möller60653ba2016-03-02 11:41:36 +0100270 capturer_->AddOrUpdateSink(&renderer_, wants);
271 EXPECT_TRUE(capturer_->CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -0800272 EXPECT_EQ(2, renderer_.num_rendered_frames());
273 EXPECT_EQ(960, renderer_.width());
274 EXPECT_EQ(540, renderer_.height());
275
276 // Request a lower resolution.
lliuuf9ed2352017-03-30 10:44:38 -0700277 wants.max_pixel_count =
278 rtc::Optional<int>((renderer_.width() * renderer_.height() * 3) / 5);
Niels Möller60653ba2016-03-02 11:41:36 +0100279 capturer_->AddOrUpdateSink(&renderer_, wants);
280 EXPECT_TRUE(capturer_->CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -0800281 EXPECT_EQ(3, renderer_.num_rendered_frames());
282 EXPECT_EQ(640, renderer_.width());
283 EXPECT_EQ(360, renderer_.height());
284
285 // Adding a new renderer should not affect resolution.
286 cricket::FakeVideoRenderer renderer2;
Niels Möller60653ba2016-03-02 11:41:36 +0100287 capturer_->AddOrUpdateSink(&renderer2, rtc::VideoSinkWants());
288 EXPECT_TRUE(capturer_->CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -0800289 EXPECT_EQ(4, renderer_.num_rendered_frames());
290 EXPECT_EQ(640, renderer_.width());
291 EXPECT_EQ(360, renderer_.height());
292 EXPECT_EQ(1, renderer2.num_rendered_frames());
293 EXPECT_EQ(640, renderer2.width());
294 EXPECT_EQ(360, renderer2.height());
295
296 // Request higher resolution.
lliuuf9ed2352017-03-30 10:44:38 -0700297 wants.target_pixel_count.emplace((*wants.max_pixel_count * 5) / 3);
298 wants.max_pixel_count.emplace(*wants.max_pixel_count * 4);
Niels Möller60653ba2016-03-02 11:41:36 +0100299 capturer_->AddOrUpdateSink(&renderer_, wants);
300 EXPECT_TRUE(capturer_->CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -0800301 EXPECT_EQ(5, renderer_.num_rendered_frames());
302 EXPECT_EQ(960, renderer_.width());
303 EXPECT_EQ(540, renderer_.height());
304 EXPECT_EQ(2, renderer2.num_rendered_frames());
305 EXPECT_EQ(960, renderer2.width());
306 EXPECT_EQ(540, renderer2.height());
307
308 // Updating with no wants should not affect resolution.
Niels Möller60653ba2016-03-02 11:41:36 +0100309 capturer_->AddOrUpdateSink(&renderer2, rtc::VideoSinkWants());
310 EXPECT_TRUE(capturer_->CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -0800311 EXPECT_EQ(6, renderer_.num_rendered_frames());
312 EXPECT_EQ(960, renderer_.width());
313 EXPECT_EQ(540, renderer_.height());
314 EXPECT_EQ(3, renderer2.num_rendered_frames());
315 EXPECT_EQ(960, renderer2.width());
316 EXPECT_EQ(540, renderer2.height());
Per766ad3b2016-04-05 15:23:49 +0200317
318 // But resetting the wants should reset the resolution to what the camera is
319 // opened with.
320 capturer_->AddOrUpdateSink(&renderer_, rtc::VideoSinkWants());
321 EXPECT_TRUE(capturer_->CaptureFrame());
322 EXPECT_EQ(7, renderer_.num_rendered_frames());
323 EXPECT_EQ(1280, renderer_.width());
324 EXPECT_EQ(720, renderer_.height());
325 EXPECT_EQ(4, renderer2.num_rendered_frames());
326 EXPECT_EQ(1280, renderer2.width());
327 EXPECT_EQ(720, renderer2.height());
perkj2d5f0912016-02-29 00:04:41 -0800328}
329
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330TEST_F(VideoCapturerTest, TestFourccMatch) {
331 cricket::VideoFormat desired(640, 480,
332 cricket::VideoFormat::FpsToInterval(30),
333 cricket::FOURCC_ANY);
334 cricket::VideoFormat best;
Niels Möller60653ba2016-03-02 11:41:36 +0100335 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000336 EXPECT_EQ(640, best.width);
337 EXPECT_EQ(480, best.height);
338 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
339
340 desired.fourcc = cricket::FOURCC_MJPG;
Niels Möller60653ba2016-03-02 11:41:36 +0100341 EXPECT_FALSE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000342
343 desired.fourcc = cricket::FOURCC_I420;
Niels Möller60653ba2016-03-02 11:41:36 +0100344 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000345}
346
347TEST_F(VideoCapturerTest, TestResolutionMatch) {
348 cricket::VideoFormat desired(1920, 1080,
349 cricket::VideoFormat::FpsToInterval(30),
350 cricket::FOURCC_ANY);
351 cricket::VideoFormat best;
352 // Ask for 1920x1080. Get HD 1280x720 which is the highest.
Niels Möller60653ba2016-03-02 11:41:36 +0100353 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000354 EXPECT_EQ(1280, best.width);
355 EXPECT_EQ(720, best.height);
356 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
357
358 desired.width = 360;
359 desired.height = 250;
360 // Ask for a little higher than QVGA. Get QVGA.
Niels Möller60653ba2016-03-02 11:41:36 +0100361 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000362 EXPECT_EQ(320, best.width);
363 EXPECT_EQ(240, best.height);
364 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
365
366 desired.width = 480;
magjed@webrtc.org35c1ace2014-11-13 16:21:49 +0000367 desired.height = 270;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000368 // Ask for HVGA. Get VGA.
Niels Möller60653ba2016-03-02 11:41:36 +0100369 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000370 EXPECT_EQ(640, best.width);
371 EXPECT_EQ(480, best.height);
372 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
373
374 desired.width = 320;
375 desired.height = 240;
376 // Ask for QVGA. Get QVGA.
Niels Möller60653ba2016-03-02 11:41:36 +0100377 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000378 EXPECT_EQ(320, best.width);
379 EXPECT_EQ(240, best.height);
380 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
381
382 desired.width = 80;
383 desired.height = 60;
384 // Ask for lower than QQVGA. Get QQVGA, which is the lowest.
Niels Möller60653ba2016-03-02 11:41:36 +0100385 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000386 EXPECT_EQ(160, best.width);
387 EXPECT_EQ(120, best.height);
388 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
389}
390
391TEST_F(VideoCapturerTest, TestHDResolutionMatch) {
392 // Add some HD formats typical of a mediocre HD webcam.
393 std::vector<cricket::VideoFormat> formats;
394 formats.push_back(cricket::VideoFormat(320, 240,
395 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
396 formats.push_back(cricket::VideoFormat(640, 480,
397 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
398 formats.push_back(cricket::VideoFormat(960, 544,
399 cricket::VideoFormat::FpsToInterval(24), cricket::FOURCC_I420));
400 formats.push_back(cricket::VideoFormat(1280, 720,
401 cricket::VideoFormat::FpsToInterval(15), cricket::FOURCC_I420));
402 formats.push_back(cricket::VideoFormat(2592, 1944,
403 cricket::VideoFormat::FpsToInterval(7), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100404 capturer_->ResetSupportedFormats(formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000405
406 cricket::VideoFormat desired(960, 720,
407 cricket::VideoFormat::FpsToInterval(30),
408 cricket::FOURCC_ANY);
409 cricket::VideoFormat best;
410 // Ask for 960x720 30 fps. Get qHD 24 fps
Niels Möller60653ba2016-03-02 11:41:36 +0100411 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000412 EXPECT_EQ(960, best.width);
413 EXPECT_EQ(544, best.height);
414 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(24), best.interval);
415
416 desired.width = 960;
417 desired.height = 544;
418 desired.interval = cricket::VideoFormat::FpsToInterval(30);
419 // Ask for qHD 30 fps. Get qHD 24 fps
Niels Möller60653ba2016-03-02 11:41:36 +0100420 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000421 EXPECT_EQ(960, best.width);
422 EXPECT_EQ(544, best.height);
423 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(24), best.interval);
424
425 desired.width = 360;
426 desired.height = 250;
427 desired.interval = cricket::VideoFormat::FpsToInterval(30);
428 // Ask for a little higher than QVGA. Get QVGA.
Niels Möller60653ba2016-03-02 11:41:36 +0100429 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000430 EXPECT_EQ(320, best.width);
431 EXPECT_EQ(240, best.height);
432 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
433
434 desired.width = 480;
435 desired.height = 270;
436 // Ask for HVGA. Get VGA.
Niels Möller60653ba2016-03-02 11:41:36 +0100437 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000438 EXPECT_EQ(640, best.width);
439 EXPECT_EQ(480, best.height);
440 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
441
442 desired.width = 320;
443 desired.height = 240;
444 // Ask for QVGA. Get QVGA.
Niels Möller60653ba2016-03-02 11:41:36 +0100445 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000446 EXPECT_EQ(320, best.width);
447 EXPECT_EQ(240, best.height);
448 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
449
450 desired.width = 160;
451 desired.height = 120;
452 // Ask for lower than QVGA. Get QVGA, which is the lowest.
Niels Möller60653ba2016-03-02 11:41:36 +0100453 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000454 EXPECT_EQ(320, best.width);
455 EXPECT_EQ(240, best.height);
456 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
457
458 desired.width = 1280;
459 desired.height = 720;
460 // Ask for HD. 720p fps is too low. Get VGA which has 30 fps.
Niels Möller60653ba2016-03-02 11:41:36 +0100461 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000462 EXPECT_EQ(640, best.width);
463 EXPECT_EQ(480, best.height);
464 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
465
466 desired.width = 1280;
467 desired.height = 720;
468 desired.interval = cricket::VideoFormat::FpsToInterval(15);
469 // Ask for HD 15 fps. Fps matches. Get HD
Niels Möller60653ba2016-03-02 11:41:36 +0100470 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000471 EXPECT_EQ(1280, best.width);
472 EXPECT_EQ(720, best.height);
473 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(15), best.interval);
474
475 desired.width = 1920;
476 desired.height = 1080;
477 desired.interval = cricket::VideoFormat::FpsToInterval(30);
478 // Ask for 1080p. Fps of HD formats is too low. Get VGA which can do 30 fps.
Niels Möller60653ba2016-03-02 11:41:36 +0100479 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000480 EXPECT_EQ(640, best.width);
481 EXPECT_EQ(480, best.height);
482 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
483}
484
485// Some cameras support 320x240 and 320x640. Verify we choose 320x240.
486TEST_F(VideoCapturerTest, TestStrangeFormats) {
487 std::vector<cricket::VideoFormat> supported_formats;
488 supported_formats.push_back(cricket::VideoFormat(320, 240,
489 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
490 supported_formats.push_back(cricket::VideoFormat(320, 640,
491 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100492 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000493
494 std::vector<cricket::VideoFormat> required_formats;
495 required_formats.push_back(cricket::VideoFormat(320, 240,
496 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
497 required_formats.push_back(cricket::VideoFormat(320, 200,
498 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
499 required_formats.push_back(cricket::VideoFormat(320, 180,
500 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
501 cricket::VideoFormat best;
502 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100503 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000504 EXPECT_EQ(320, best.width);
505 EXPECT_EQ(240, best.height);
506 }
507
508 supported_formats.clear();
509 supported_formats.push_back(cricket::VideoFormat(320, 640,
510 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
511 supported_formats.push_back(cricket::VideoFormat(320, 240,
512 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100513 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000514
515 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100516 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000517 EXPECT_EQ(320, best.width);
518 EXPECT_EQ(240, best.height);
519 }
520}
521
522// Some cameras only have very low fps. Verify we choose something sensible.
523TEST_F(VideoCapturerTest, TestPoorFpsFormats) {
524 // all formats are low framerate
525 std::vector<cricket::VideoFormat> supported_formats;
526 supported_formats.push_back(cricket::VideoFormat(320, 240,
527 cricket::VideoFormat::FpsToInterval(10), cricket::FOURCC_I420));
528 supported_formats.push_back(cricket::VideoFormat(640, 480,
529 cricket::VideoFormat::FpsToInterval(7), cricket::FOURCC_I420));
530 supported_formats.push_back(cricket::VideoFormat(1280, 720,
531 cricket::VideoFormat::FpsToInterval(2), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100532 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000533
534 std::vector<cricket::VideoFormat> required_formats;
535 required_formats.push_back(cricket::VideoFormat(320, 240,
536 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
537 required_formats.push_back(cricket::VideoFormat(640, 480,
538 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
539 cricket::VideoFormat best;
540 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100541 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000542 EXPECT_EQ(required_formats[i].width, best.width);
543 EXPECT_EQ(required_formats[i].height, best.height);
544 }
545
546 // Increase framerate of 320x240. Expect low fps VGA avoided.
547 supported_formats.clear();
548 supported_formats.push_back(cricket::VideoFormat(320, 240,
549 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
550 supported_formats.push_back(cricket::VideoFormat(640, 480,
551 cricket::VideoFormat::FpsToInterval(7), cricket::FOURCC_I420));
552 supported_formats.push_back(cricket::VideoFormat(1280, 720,
553 cricket::VideoFormat::FpsToInterval(2), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100554 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000555
556 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100557 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000558 EXPECT_EQ(320, best.width);
559 EXPECT_EQ(240, best.height);
560 }
561}
562
563// Some cameras support same size with different frame rates. Verify we choose
564// the frame rate properly.
565TEST_F(VideoCapturerTest, TestSameSizeDifferentFpsFormats) {
566 std::vector<cricket::VideoFormat> supported_formats;
567 supported_formats.push_back(cricket::VideoFormat(320, 240,
568 cricket::VideoFormat::FpsToInterval(10), cricket::FOURCC_I420));
569 supported_formats.push_back(cricket::VideoFormat(320, 240,
570 cricket::VideoFormat::FpsToInterval(20), cricket::FOURCC_I420));
571 supported_formats.push_back(cricket::VideoFormat(320, 240,
572 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100573 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000574
575 std::vector<cricket::VideoFormat> required_formats = supported_formats;
576 cricket::VideoFormat best;
577 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100578 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000579 EXPECT_EQ(320, best.width);
580 EXPECT_EQ(240, best.height);
581 EXPECT_EQ(required_formats[i].interval, best.interval);
582 }
583}
584
585// Some cameras support the correct resolution but at a lower fps than
586// we'd like. This tests we get the expected resolution and fps.
587TEST_F(VideoCapturerTest, TestFpsFormats) {
588 // We have VGA but low fps. Choose VGA, not HD
589 std::vector<cricket::VideoFormat> supported_formats;
590 supported_formats.push_back(cricket::VideoFormat(1280, 720,
591 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
592 supported_formats.push_back(cricket::VideoFormat(640, 480,
593 cricket::VideoFormat::FpsToInterval(15), cricket::FOURCC_I420));
594 supported_formats.push_back(cricket::VideoFormat(640, 400,
595 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
596 supported_formats.push_back(cricket::VideoFormat(640, 360,
597 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100598 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000599
600 std::vector<cricket::VideoFormat> required_formats;
601 required_formats.push_back(cricket::VideoFormat(640, 480,
602 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_ANY));
603 required_formats.push_back(cricket::VideoFormat(640, 480,
604 cricket::VideoFormat::FpsToInterval(20), cricket::FOURCC_ANY));
605 required_formats.push_back(cricket::VideoFormat(640, 480,
606 cricket::VideoFormat::FpsToInterval(10), cricket::FOURCC_ANY));
607 cricket::VideoFormat best;
608
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000609 // Expect 30 fps to choose 30 fps format.
Niels Möller60653ba2016-03-02 11:41:36 +0100610 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[0], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000611 EXPECT_EQ(640, best.width);
612 EXPECT_EQ(400, best.height);
613 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
614
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000615 // Expect 20 fps to choose 30 fps format.
Niels Möller60653ba2016-03-02 11:41:36 +0100616 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[1], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000617 EXPECT_EQ(640, best.width);
618 EXPECT_EQ(400, best.height);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000619 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000620
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000621 // Expect 10 fps to choose 15 fps format and set fps to 15.
Niels Möller60653ba2016-03-02 11:41:36 +0100622 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[2], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000623 EXPECT_EQ(640, best.width);
624 EXPECT_EQ(480, best.height);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000625 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(15), best.interval);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000626
627 // We have VGA 60 fps and 15 fps. Choose best fps.
628 supported_formats.clear();
629 supported_formats.push_back(cricket::VideoFormat(1280, 720,
630 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
631 supported_formats.push_back(cricket::VideoFormat(640, 480,
632 cricket::VideoFormat::FpsToInterval(60), cricket::FOURCC_MJPG));
633 supported_formats.push_back(cricket::VideoFormat(640, 480,
634 cricket::VideoFormat::FpsToInterval(15), cricket::FOURCC_I420));
635 supported_formats.push_back(cricket::VideoFormat(640, 400,
636 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
637 supported_formats.push_back(cricket::VideoFormat(640, 360,
638 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100639 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000640
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000641 // Expect 30 fps to choose 60 fps format and will set best fps to 60.
Niels Möller60653ba2016-03-02 11:41:36 +0100642 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[0], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000643 EXPECT_EQ(640, best.width);
644 EXPECT_EQ(480, best.height);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000645 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(60), best.interval);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000646
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000647 // Expect 20 fps to choose 60 fps format, and will set best fps to 60.
Niels Möller60653ba2016-03-02 11:41:36 +0100648 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[1], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000649 EXPECT_EQ(640, best.width);
650 EXPECT_EQ(480, best.height);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000651 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(60), best.interval);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000652
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000653 // Expect 10 fps to choose 15 fps.
Niels Möller60653ba2016-03-02 11:41:36 +0100654 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[2], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000655 EXPECT_EQ(640, best.width);
656 EXPECT_EQ(480, best.height);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000657 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(15), best.interval);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000658}
659
660TEST_F(VideoCapturerTest, TestRequest16x10_9) {
661 std::vector<cricket::VideoFormat> supported_formats;
662 // We do not support HD, expect 4x3 for 4x3, 16x10, and 16x9 requests.
663 supported_formats.push_back(cricket::VideoFormat(640, 480,
664 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
665 supported_formats.push_back(cricket::VideoFormat(640, 400,
666 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
667 supported_formats.push_back(cricket::VideoFormat(640, 360,
668 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100669 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000670
671 std::vector<cricket::VideoFormat> required_formats = supported_formats;
672 cricket::VideoFormat best;
673 // Expect 4x3, 16x10, and 16x9 requests are respected.
674 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100675 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000676 EXPECT_EQ(required_formats[i].width, best.width);
677 EXPECT_EQ(required_formats[i].height, best.height);
678 }
679
680 // We do not support 16x9 HD, expect 4x3 for 4x3, 16x10, and 16x9 requests.
681 supported_formats.clear();
682 supported_formats.push_back(cricket::VideoFormat(960, 720,
683 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
684 supported_formats.push_back(cricket::VideoFormat(640, 480,
685 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
686 supported_formats.push_back(cricket::VideoFormat(640, 400,
687 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
688 supported_formats.push_back(cricket::VideoFormat(640, 360,
689 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100690 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000691
692 // Expect 4x3, 16x10, and 16x9 requests are respected.
693 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100694 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000695 EXPECT_EQ(required_formats[i].width, best.width);
696 EXPECT_EQ(required_formats[i].height, best.height);
697 }
698
699 // We support 16x9HD, Expect 4x3, 16x10, and 16x9 requests are respected.
700 supported_formats.clear();
701 supported_formats.push_back(cricket::VideoFormat(1280, 720,
702 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
703 supported_formats.push_back(cricket::VideoFormat(640, 480,
704 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
705 supported_formats.push_back(cricket::VideoFormat(640, 400,
706 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
707 supported_formats.push_back(cricket::VideoFormat(640, 360,
708 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100709 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000710
711 // Expect 4x3 for 4x3 and 16x10 requests.
712 for (size_t i = 0; i < required_formats.size() - 1; ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100713 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000714 EXPECT_EQ(required_formats[i].width, best.width);
715 EXPECT_EQ(required_formats[i].height, best.height);
716 }
717
718 // Expect 16x9 for 16x9 request.
Niels Möller60653ba2016-03-02 11:41:36 +0100719 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[2], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000720 EXPECT_EQ(640, best.width);
721 EXPECT_EQ(360, best.height);
722}
723
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724bool HdFormatInList(const std::vector<cricket::VideoFormat>& formats) {
725 for (std::vector<cricket::VideoFormat>::const_iterator found =
726 formats.begin(); found != formats.end(); ++found) {
727 if (found->height >= kMinHdHeight) {
728 return true;
729 }
730 }
731 return false;
732}
733
734TEST_F(VideoCapturerTest, Whitelist) {
735 // The definition of HD only applies to the height. Set the HD width to the
736 // smallest legal number to document this fact in this test.
737 const int kMinHdWidth = 1;
738 cricket::VideoFormat hd_format(kMinHdWidth,
739 kMinHdHeight,
740 cricket::VideoFormat::FpsToInterval(30),
741 cricket::FOURCC_I420);
742 cricket::VideoFormat vga_format(640, 480,
743 cricket::VideoFormat::FpsToInterval(30),
744 cricket::FOURCC_I420);
Niels Möller60653ba2016-03-02 11:41:36 +0100745 std::vector<cricket::VideoFormat> formats = *capturer_->GetSupportedFormats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000746 formats.push_back(hd_format);
747
748 // Enable whitelist. Expect HD not in list.
Niels Möller60653ba2016-03-02 11:41:36 +0100749 capturer_->set_enable_camera_list(true);
750 capturer_->ResetSupportedFormats(formats);
751 EXPECT_TRUE(HdFormatInList(*capturer_->GetSupportedFormats()));
752 capturer_->ConstrainSupportedFormats(vga_format);
753 EXPECT_FALSE(HdFormatInList(*capturer_->GetSupportedFormats()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000754
755 // Disable whitelist. Expect HD in list.
Niels Möller60653ba2016-03-02 11:41:36 +0100756 capturer_->set_enable_camera_list(false);
757 capturer_->ResetSupportedFormats(formats);
758 EXPECT_TRUE(HdFormatInList(*capturer_->GetSupportedFormats()));
759 capturer_->ConstrainSupportedFormats(vga_format);
760 EXPECT_TRUE(HdFormatInList(*capturer_->GetSupportedFormats()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000761}
sergeyu@chromium.org0be6aa02013-08-23 23:21:25 +0000762
763TEST_F(VideoCapturerTest, BlacklistAllFormats) {
764 cricket::VideoFormat vga_format(640, 480,
765 cricket::VideoFormat::FpsToInterval(30),
766 cricket::FOURCC_I420);
767 std::vector<cricket::VideoFormat> supported_formats;
768 // Mock a device that only supports HD formats.
769 supported_formats.push_back(cricket::VideoFormat(1280, 720,
770 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
771 supported_formats.push_back(cricket::VideoFormat(1920, 1080,
772 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100773 capturer_->ResetSupportedFormats(supported_formats);
774 EXPECT_EQ(2u, capturer_->GetSupportedFormats()->size());
sergeyu@chromium.org0be6aa02013-08-23 23:21:25 +0000775 // Now, enable the list, which would exclude both formats. However, since
776 // only HD formats are available, we refuse to filter at all, so we don't
777 // break this camera.
Niels Möller60653ba2016-03-02 11:41:36 +0100778 capturer_->set_enable_camera_list(true);
779 capturer_->ConstrainSupportedFormats(vga_format);
780 EXPECT_EQ(2u, capturer_->GetSupportedFormats()->size());
sergeyu@chromium.org0be6aa02013-08-23 23:21:25 +0000781 // To make sure it's not just the camera list being broken, add in VGA and
782 // try again. This time, only the VGA format should be there.
783 supported_formats.push_back(vga_format);
Niels Möller60653ba2016-03-02 11:41:36 +0100784 capturer_->ResetSupportedFormats(supported_formats);
785 ASSERT_EQ(1u, capturer_->GetSupportedFormats()->size());
786 EXPECT_EQ(vga_format.height, capturer_->GetSupportedFormats()->at(0).height);
sergeyu@chromium.org0be6aa02013-08-23 23:21:25 +0000787}