blob: 402682e511ccee4c3ba1f7d52587c834b9371c85 [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
kjellandera96e2d72016-02-04 23:52:28 -080016#include "webrtc/media/base/fakevideocapturer.h"
17#include "webrtc/media/base/fakevideorenderer.h"
18#include "webrtc/media/base/testutils.h"
19#include "webrtc/media/base/videocapturer.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020020#include "webrtc/rtc_base/gunit.h"
21#include "webrtc/rtc_base/logging.h"
22#include "webrtc/rtc_base/thread.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;
sprangc5d62e22017-04-02 23:53:04 -0700269 wants.max_pixel_count = 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.
sprangc5d62e22017-04-02 23:53:04 -0700277 wants.max_pixel_count = (renderer_.width() * renderer_.height() * 3) / 5;
Niels Möller60653ba2016-03-02 11:41:36 +0100278 capturer_->AddOrUpdateSink(&renderer_, wants);
279 EXPECT_TRUE(capturer_->CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -0800280 EXPECT_EQ(3, renderer_.num_rendered_frames());
281 EXPECT_EQ(640, renderer_.width());
282 EXPECT_EQ(360, renderer_.height());
283
284 // Adding a new renderer should not affect resolution.
285 cricket::FakeVideoRenderer renderer2;
Niels Möller60653ba2016-03-02 11:41:36 +0100286 capturer_->AddOrUpdateSink(&renderer2, rtc::VideoSinkWants());
287 EXPECT_TRUE(capturer_->CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -0800288 EXPECT_EQ(4, renderer_.num_rendered_frames());
289 EXPECT_EQ(640, renderer_.width());
290 EXPECT_EQ(360, renderer_.height());
291 EXPECT_EQ(1, renderer2.num_rendered_frames());
292 EXPECT_EQ(640, renderer2.width());
293 EXPECT_EQ(360, renderer2.height());
294
295 // Request higher resolution.
sprangc5d62e22017-04-02 23:53:04 -0700296 wants.target_pixel_count.emplace((wants.max_pixel_count * 5) / 3);
297 wants.max_pixel_count = wants.max_pixel_count * 4;
Niels Möller60653ba2016-03-02 11:41:36 +0100298 capturer_->AddOrUpdateSink(&renderer_, wants);
299 EXPECT_TRUE(capturer_->CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -0800300 EXPECT_EQ(5, renderer_.num_rendered_frames());
301 EXPECT_EQ(960, renderer_.width());
302 EXPECT_EQ(540, renderer_.height());
303 EXPECT_EQ(2, renderer2.num_rendered_frames());
304 EXPECT_EQ(960, renderer2.width());
305 EXPECT_EQ(540, renderer2.height());
306
307 // Updating with no wants should not affect resolution.
Niels Möller60653ba2016-03-02 11:41:36 +0100308 capturer_->AddOrUpdateSink(&renderer2, rtc::VideoSinkWants());
309 EXPECT_TRUE(capturer_->CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -0800310 EXPECT_EQ(6, renderer_.num_rendered_frames());
311 EXPECT_EQ(960, renderer_.width());
312 EXPECT_EQ(540, renderer_.height());
313 EXPECT_EQ(3, renderer2.num_rendered_frames());
314 EXPECT_EQ(960, renderer2.width());
315 EXPECT_EQ(540, renderer2.height());
Per766ad3b2016-04-05 15:23:49 +0200316
317 // But resetting the wants should reset the resolution to what the camera is
318 // opened with.
319 capturer_->AddOrUpdateSink(&renderer_, rtc::VideoSinkWants());
320 EXPECT_TRUE(capturer_->CaptureFrame());
321 EXPECT_EQ(7, renderer_.num_rendered_frames());
322 EXPECT_EQ(1280, renderer_.width());
323 EXPECT_EQ(720, renderer_.height());
324 EXPECT_EQ(4, renderer2.num_rendered_frames());
325 EXPECT_EQ(1280, renderer2.width());
326 EXPECT_EQ(720, renderer2.height());
perkj2d5f0912016-02-29 00:04:41 -0800327}
328
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000329TEST_F(VideoCapturerTest, TestFourccMatch) {
330 cricket::VideoFormat desired(640, 480,
331 cricket::VideoFormat::FpsToInterval(30),
332 cricket::FOURCC_ANY);
333 cricket::VideoFormat best;
Niels Möller60653ba2016-03-02 11:41:36 +0100334 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335 EXPECT_EQ(640, best.width);
336 EXPECT_EQ(480, best.height);
337 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
338
339 desired.fourcc = cricket::FOURCC_MJPG;
Niels Möller60653ba2016-03-02 11:41:36 +0100340 EXPECT_FALSE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000341
342 desired.fourcc = cricket::FOURCC_I420;
Niels Möller60653ba2016-03-02 11:41:36 +0100343 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000344}
345
346TEST_F(VideoCapturerTest, TestResolutionMatch) {
347 cricket::VideoFormat desired(1920, 1080,
348 cricket::VideoFormat::FpsToInterval(30),
349 cricket::FOURCC_ANY);
350 cricket::VideoFormat best;
351 // Ask for 1920x1080. Get HD 1280x720 which is the highest.
Niels Möller60653ba2016-03-02 11:41:36 +0100352 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000353 EXPECT_EQ(1280, best.width);
354 EXPECT_EQ(720, best.height);
355 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
356
357 desired.width = 360;
358 desired.height = 250;
359 // Ask for a little higher than QVGA. Get QVGA.
Niels Möller60653ba2016-03-02 11:41:36 +0100360 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000361 EXPECT_EQ(320, best.width);
362 EXPECT_EQ(240, best.height);
363 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
364
365 desired.width = 480;
magjed@webrtc.org35c1ace2014-11-13 16:21:49 +0000366 desired.height = 270;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000367 // Ask for HVGA. Get VGA.
Niels Möller60653ba2016-03-02 11:41:36 +0100368 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000369 EXPECT_EQ(640, best.width);
370 EXPECT_EQ(480, best.height);
371 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
372
373 desired.width = 320;
374 desired.height = 240;
375 // Ask for QVGA. Get QVGA.
Niels Möller60653ba2016-03-02 11:41:36 +0100376 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000377 EXPECT_EQ(320, best.width);
378 EXPECT_EQ(240, best.height);
379 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
380
381 desired.width = 80;
382 desired.height = 60;
383 // Ask for lower than QQVGA. Get QQVGA, which is the lowest.
Niels Möller60653ba2016-03-02 11:41:36 +0100384 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000385 EXPECT_EQ(160, best.width);
386 EXPECT_EQ(120, best.height);
387 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
388}
389
390TEST_F(VideoCapturerTest, TestHDResolutionMatch) {
391 // Add some HD formats typical of a mediocre HD webcam.
392 std::vector<cricket::VideoFormat> formats;
393 formats.push_back(cricket::VideoFormat(320, 240,
394 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
395 formats.push_back(cricket::VideoFormat(640, 480,
396 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
397 formats.push_back(cricket::VideoFormat(960, 544,
398 cricket::VideoFormat::FpsToInterval(24), cricket::FOURCC_I420));
399 formats.push_back(cricket::VideoFormat(1280, 720,
400 cricket::VideoFormat::FpsToInterval(15), cricket::FOURCC_I420));
401 formats.push_back(cricket::VideoFormat(2592, 1944,
402 cricket::VideoFormat::FpsToInterval(7), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100403 capturer_->ResetSupportedFormats(formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000404
405 cricket::VideoFormat desired(960, 720,
406 cricket::VideoFormat::FpsToInterval(30),
407 cricket::FOURCC_ANY);
408 cricket::VideoFormat best;
409 // Ask for 960x720 30 fps. Get qHD 24 fps
Niels Möller60653ba2016-03-02 11:41:36 +0100410 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000411 EXPECT_EQ(960, best.width);
412 EXPECT_EQ(544, best.height);
413 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(24), best.interval);
414
415 desired.width = 960;
416 desired.height = 544;
417 desired.interval = cricket::VideoFormat::FpsToInterval(30);
418 // Ask for qHD 30 fps. Get qHD 24 fps
Niels Möller60653ba2016-03-02 11:41:36 +0100419 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000420 EXPECT_EQ(960, best.width);
421 EXPECT_EQ(544, best.height);
422 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(24), best.interval);
423
424 desired.width = 360;
425 desired.height = 250;
426 desired.interval = cricket::VideoFormat::FpsToInterval(30);
427 // Ask for a little higher than QVGA. Get QVGA.
Niels Möller60653ba2016-03-02 11:41:36 +0100428 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000429 EXPECT_EQ(320, best.width);
430 EXPECT_EQ(240, best.height);
431 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
432
433 desired.width = 480;
434 desired.height = 270;
435 // Ask for HVGA. Get VGA.
Niels Möller60653ba2016-03-02 11:41:36 +0100436 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000437 EXPECT_EQ(640, best.width);
438 EXPECT_EQ(480, best.height);
439 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
440
441 desired.width = 320;
442 desired.height = 240;
443 // Ask for QVGA. Get QVGA.
Niels Möller60653ba2016-03-02 11:41:36 +0100444 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000445 EXPECT_EQ(320, best.width);
446 EXPECT_EQ(240, best.height);
447 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
448
449 desired.width = 160;
450 desired.height = 120;
451 // Ask for lower than QVGA. Get QVGA, which is the lowest.
Niels Möller60653ba2016-03-02 11:41:36 +0100452 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000453 EXPECT_EQ(320, best.width);
454 EXPECT_EQ(240, best.height);
455 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
456
457 desired.width = 1280;
458 desired.height = 720;
459 // Ask for HD. 720p fps is too low. Get VGA which has 30 fps.
Niels Möller60653ba2016-03-02 11:41:36 +0100460 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000461 EXPECT_EQ(640, best.width);
462 EXPECT_EQ(480, best.height);
463 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
464
465 desired.width = 1280;
466 desired.height = 720;
467 desired.interval = cricket::VideoFormat::FpsToInterval(15);
468 // Ask for HD 15 fps. Fps matches. Get HD
Niels Möller60653ba2016-03-02 11:41:36 +0100469 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000470 EXPECT_EQ(1280, best.width);
471 EXPECT_EQ(720, best.height);
472 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(15), best.interval);
473
474 desired.width = 1920;
475 desired.height = 1080;
476 desired.interval = cricket::VideoFormat::FpsToInterval(30);
477 // 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 +0100478 EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000479 EXPECT_EQ(640, best.width);
480 EXPECT_EQ(480, best.height);
481 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
482}
483
484// Some cameras support 320x240 and 320x640. Verify we choose 320x240.
485TEST_F(VideoCapturerTest, TestStrangeFormats) {
486 std::vector<cricket::VideoFormat> supported_formats;
487 supported_formats.push_back(cricket::VideoFormat(320, 240,
488 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
489 supported_formats.push_back(cricket::VideoFormat(320, 640,
490 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100491 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000492
493 std::vector<cricket::VideoFormat> required_formats;
494 required_formats.push_back(cricket::VideoFormat(320, 240,
495 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
496 required_formats.push_back(cricket::VideoFormat(320, 200,
497 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
498 required_formats.push_back(cricket::VideoFormat(320, 180,
499 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
500 cricket::VideoFormat best;
501 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100502 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000503 EXPECT_EQ(320, best.width);
504 EXPECT_EQ(240, best.height);
505 }
506
507 supported_formats.clear();
508 supported_formats.push_back(cricket::VideoFormat(320, 640,
509 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
510 supported_formats.push_back(cricket::VideoFormat(320, 240,
511 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100512 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000513
514 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100515 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000516 EXPECT_EQ(320, best.width);
517 EXPECT_EQ(240, best.height);
518 }
519}
520
521// Some cameras only have very low fps. Verify we choose something sensible.
522TEST_F(VideoCapturerTest, TestPoorFpsFormats) {
523 // all formats are low framerate
524 std::vector<cricket::VideoFormat> supported_formats;
525 supported_formats.push_back(cricket::VideoFormat(320, 240,
526 cricket::VideoFormat::FpsToInterval(10), cricket::FOURCC_I420));
527 supported_formats.push_back(cricket::VideoFormat(640, 480,
528 cricket::VideoFormat::FpsToInterval(7), cricket::FOURCC_I420));
529 supported_formats.push_back(cricket::VideoFormat(1280, 720,
530 cricket::VideoFormat::FpsToInterval(2), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100531 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000532
533 std::vector<cricket::VideoFormat> required_formats;
534 required_formats.push_back(cricket::VideoFormat(320, 240,
535 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
536 required_formats.push_back(cricket::VideoFormat(640, 480,
537 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
538 cricket::VideoFormat best;
539 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100540 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000541 EXPECT_EQ(required_formats[i].width, best.width);
542 EXPECT_EQ(required_formats[i].height, best.height);
543 }
544
545 // Increase framerate of 320x240. Expect low fps VGA avoided.
546 supported_formats.clear();
547 supported_formats.push_back(cricket::VideoFormat(320, 240,
548 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
549 supported_formats.push_back(cricket::VideoFormat(640, 480,
550 cricket::VideoFormat::FpsToInterval(7), cricket::FOURCC_I420));
551 supported_formats.push_back(cricket::VideoFormat(1280, 720,
552 cricket::VideoFormat::FpsToInterval(2), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100553 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000554
555 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100556 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000557 EXPECT_EQ(320, best.width);
558 EXPECT_EQ(240, best.height);
559 }
560}
561
562// Some cameras support same size with different frame rates. Verify we choose
563// the frame rate properly.
564TEST_F(VideoCapturerTest, TestSameSizeDifferentFpsFormats) {
565 std::vector<cricket::VideoFormat> supported_formats;
566 supported_formats.push_back(cricket::VideoFormat(320, 240,
567 cricket::VideoFormat::FpsToInterval(10), cricket::FOURCC_I420));
568 supported_formats.push_back(cricket::VideoFormat(320, 240,
569 cricket::VideoFormat::FpsToInterval(20), cricket::FOURCC_I420));
570 supported_formats.push_back(cricket::VideoFormat(320, 240,
571 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100572 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000573
574 std::vector<cricket::VideoFormat> required_formats = supported_formats;
575 cricket::VideoFormat best;
576 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100577 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000578 EXPECT_EQ(320, best.width);
579 EXPECT_EQ(240, best.height);
580 EXPECT_EQ(required_formats[i].interval, best.interval);
581 }
582}
583
584// Some cameras support the correct resolution but at a lower fps than
585// we'd like. This tests we get the expected resolution and fps.
586TEST_F(VideoCapturerTest, TestFpsFormats) {
587 // We have VGA but low fps. Choose VGA, not HD
588 std::vector<cricket::VideoFormat> supported_formats;
589 supported_formats.push_back(cricket::VideoFormat(1280, 720,
590 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
591 supported_formats.push_back(cricket::VideoFormat(640, 480,
592 cricket::VideoFormat::FpsToInterval(15), cricket::FOURCC_I420));
593 supported_formats.push_back(cricket::VideoFormat(640, 400,
594 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
595 supported_formats.push_back(cricket::VideoFormat(640, 360,
596 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100597 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000598
599 std::vector<cricket::VideoFormat> required_formats;
600 required_formats.push_back(cricket::VideoFormat(640, 480,
601 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_ANY));
602 required_formats.push_back(cricket::VideoFormat(640, 480,
603 cricket::VideoFormat::FpsToInterval(20), cricket::FOURCC_ANY));
604 required_formats.push_back(cricket::VideoFormat(640, 480,
605 cricket::VideoFormat::FpsToInterval(10), cricket::FOURCC_ANY));
606 cricket::VideoFormat best;
607
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000608 // Expect 30 fps to choose 30 fps format.
Niels Möller60653ba2016-03-02 11:41:36 +0100609 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[0], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000610 EXPECT_EQ(640, best.width);
611 EXPECT_EQ(400, best.height);
612 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
613
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000614 // Expect 20 fps to choose 30 fps format.
Niels Möller60653ba2016-03-02 11:41:36 +0100615 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[1], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000616 EXPECT_EQ(640, best.width);
617 EXPECT_EQ(400, best.height);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000618 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000619
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000620 // Expect 10 fps to choose 15 fps format and set fps to 15.
Niels Möller60653ba2016-03-02 11:41:36 +0100621 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[2], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000622 EXPECT_EQ(640, best.width);
623 EXPECT_EQ(480, best.height);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000624 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(15), best.interval);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000625
626 // We have VGA 60 fps and 15 fps. Choose best fps.
627 supported_formats.clear();
628 supported_formats.push_back(cricket::VideoFormat(1280, 720,
629 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
630 supported_formats.push_back(cricket::VideoFormat(640, 480,
631 cricket::VideoFormat::FpsToInterval(60), cricket::FOURCC_MJPG));
632 supported_formats.push_back(cricket::VideoFormat(640, 480,
633 cricket::VideoFormat::FpsToInterval(15), cricket::FOURCC_I420));
634 supported_formats.push_back(cricket::VideoFormat(640, 400,
635 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
636 supported_formats.push_back(cricket::VideoFormat(640, 360,
637 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100638 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000639
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000640 // Expect 30 fps to choose 60 fps format and will set best fps to 60.
Niels Möller60653ba2016-03-02 11:41:36 +0100641 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[0], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000642 EXPECT_EQ(640, best.width);
643 EXPECT_EQ(480, best.height);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000644 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(60), best.interval);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000645
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000646 // Expect 20 fps to choose 60 fps format, and will set best fps to 60.
Niels Möller60653ba2016-03-02 11:41:36 +0100647 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[1], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000648 EXPECT_EQ(640, best.width);
649 EXPECT_EQ(480, best.height);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000650 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(60), best.interval);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000651
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000652 // Expect 10 fps to choose 15 fps.
Niels Möller60653ba2016-03-02 11:41:36 +0100653 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[2], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000654 EXPECT_EQ(640, best.width);
655 EXPECT_EQ(480, best.height);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000656 EXPECT_EQ(cricket::VideoFormat::FpsToInterval(15), best.interval);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000657}
658
659TEST_F(VideoCapturerTest, TestRequest16x10_9) {
660 std::vector<cricket::VideoFormat> supported_formats;
661 // We do not support HD, expect 4x3 for 4x3, 16x10, and 16x9 requests.
662 supported_formats.push_back(cricket::VideoFormat(640, 480,
663 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
664 supported_formats.push_back(cricket::VideoFormat(640, 400,
665 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
666 supported_formats.push_back(cricket::VideoFormat(640, 360,
667 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100668 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000669
670 std::vector<cricket::VideoFormat> required_formats = supported_formats;
671 cricket::VideoFormat best;
672 // Expect 4x3, 16x10, and 16x9 requests are respected.
673 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100674 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000675 EXPECT_EQ(required_formats[i].width, best.width);
676 EXPECT_EQ(required_formats[i].height, best.height);
677 }
678
679 // We do not support 16x9 HD, expect 4x3 for 4x3, 16x10, and 16x9 requests.
680 supported_formats.clear();
681 supported_formats.push_back(cricket::VideoFormat(960, 720,
682 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
683 supported_formats.push_back(cricket::VideoFormat(640, 480,
684 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
685 supported_formats.push_back(cricket::VideoFormat(640, 400,
686 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
687 supported_formats.push_back(cricket::VideoFormat(640, 360,
688 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100689 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000690
691 // Expect 4x3, 16x10, and 16x9 requests are respected.
692 for (size_t i = 0; i < required_formats.size(); ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100693 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000694 EXPECT_EQ(required_formats[i].width, best.width);
695 EXPECT_EQ(required_formats[i].height, best.height);
696 }
697
698 // We support 16x9HD, Expect 4x3, 16x10, and 16x9 requests are respected.
699 supported_formats.clear();
700 supported_formats.push_back(cricket::VideoFormat(1280, 720,
701 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
702 supported_formats.push_back(cricket::VideoFormat(640, 480,
703 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
704 supported_formats.push_back(cricket::VideoFormat(640, 400,
705 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
706 supported_formats.push_back(cricket::VideoFormat(640, 360,
707 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100708 capturer_->ResetSupportedFormats(supported_formats);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000709
710 // Expect 4x3 for 4x3 and 16x10 requests.
711 for (size_t i = 0; i < required_formats.size() - 1; ++i) {
Niels Möller60653ba2016-03-02 11:41:36 +0100712 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[i], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000713 EXPECT_EQ(required_formats[i].width, best.width);
714 EXPECT_EQ(required_formats[i].height, best.height);
715 }
716
717 // Expect 16x9 for 16x9 request.
Niels Möller60653ba2016-03-02 11:41:36 +0100718 EXPECT_TRUE(capturer_->GetBestCaptureFormat(required_formats[2], &best));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000719 EXPECT_EQ(640, best.width);
720 EXPECT_EQ(360, best.height);
721}
722
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000723bool HdFormatInList(const std::vector<cricket::VideoFormat>& formats) {
724 for (std::vector<cricket::VideoFormat>::const_iterator found =
725 formats.begin(); found != formats.end(); ++found) {
726 if (found->height >= kMinHdHeight) {
727 return true;
728 }
729 }
730 return false;
731}
732
733TEST_F(VideoCapturerTest, Whitelist) {
734 // The definition of HD only applies to the height. Set the HD width to the
735 // smallest legal number to document this fact in this test.
736 const int kMinHdWidth = 1;
737 cricket::VideoFormat hd_format(kMinHdWidth,
738 kMinHdHeight,
739 cricket::VideoFormat::FpsToInterval(30),
740 cricket::FOURCC_I420);
741 cricket::VideoFormat vga_format(640, 480,
742 cricket::VideoFormat::FpsToInterval(30),
743 cricket::FOURCC_I420);
Niels Möller60653ba2016-03-02 11:41:36 +0100744 std::vector<cricket::VideoFormat> formats = *capturer_->GetSupportedFormats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000745 formats.push_back(hd_format);
746
747 // Enable whitelist. Expect HD not in list.
Niels Möller60653ba2016-03-02 11:41:36 +0100748 capturer_->set_enable_camera_list(true);
749 capturer_->ResetSupportedFormats(formats);
750 EXPECT_TRUE(HdFormatInList(*capturer_->GetSupportedFormats()));
751 capturer_->ConstrainSupportedFormats(vga_format);
752 EXPECT_FALSE(HdFormatInList(*capturer_->GetSupportedFormats()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000753
754 // Disable whitelist. Expect HD in list.
Niels Möller60653ba2016-03-02 11:41:36 +0100755 capturer_->set_enable_camera_list(false);
756 capturer_->ResetSupportedFormats(formats);
757 EXPECT_TRUE(HdFormatInList(*capturer_->GetSupportedFormats()));
758 capturer_->ConstrainSupportedFormats(vga_format);
759 EXPECT_TRUE(HdFormatInList(*capturer_->GetSupportedFormats()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000760}
sergeyu@chromium.org0be6aa02013-08-23 23:21:25 +0000761
762TEST_F(VideoCapturerTest, BlacklistAllFormats) {
763 cricket::VideoFormat vga_format(640, 480,
764 cricket::VideoFormat::FpsToInterval(30),
765 cricket::FOURCC_I420);
766 std::vector<cricket::VideoFormat> supported_formats;
767 // Mock a device that only supports HD formats.
768 supported_formats.push_back(cricket::VideoFormat(1280, 720,
769 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
770 supported_formats.push_back(cricket::VideoFormat(1920, 1080,
771 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
Niels Möller60653ba2016-03-02 11:41:36 +0100772 capturer_->ResetSupportedFormats(supported_formats);
773 EXPECT_EQ(2u, capturer_->GetSupportedFormats()->size());
sergeyu@chromium.org0be6aa02013-08-23 23:21:25 +0000774 // Now, enable the list, which would exclude both formats. However, since
775 // only HD formats are available, we refuse to filter at all, so we don't
776 // break this camera.
Niels Möller60653ba2016-03-02 11:41:36 +0100777 capturer_->set_enable_camera_list(true);
778 capturer_->ConstrainSupportedFormats(vga_format);
779 EXPECT_EQ(2u, capturer_->GetSupportedFormats()->size());
sergeyu@chromium.org0be6aa02013-08-23 23:21:25 +0000780 // To make sure it's not just the camera list being broken, add in VGA and
781 // try again. This time, only the VGA format should be there.
782 supported_formats.push_back(vga_format);
Niels Möller60653ba2016-03-02 11:41:36 +0100783 capturer_->ResetSupportedFormats(supported_formats);
784 ASSERT_EQ(1u, capturer_->GetSupportedFormats()->size());
785 EXPECT_EQ(vga_format.height, capturer_->GetSupportedFormats()->at(0).height);
sergeyu@chromium.org0be6aa02013-08-23 23:21:25 +0000786}