blob: 34d11b58a96a6a19be825fe7aeaa9aa53a846575 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -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.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
kwibergd1fe2812016-04-27 06:47:29 -070011#include <memory>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000012#include <string>
Steve Anton36b29d12017-10-30 09:57:42 -070013#include <utility>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000014#include <vector>
15
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "api/test/fakeconstraints.h"
17#include "media/base/fakemediaengine.h"
18#include "media/base/fakevideocapturer.h"
19#include "media/base/fakevideorenderer.h"
20#include "pc/videocapturertracksource.h"
Tommi1f432e02018-02-05 23:01:43 +010021#include "rtc_base/arraysize.h"
22#include "rtc_base/event.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "rtc_base/gunit.h"
Tommi1f432e02018-02-05 23:01:43 +010024#include "rtc_base/task_queue.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000025
Tommi1f432e02018-02-05 23:01:43 +010026using cricket::FOURCC_I420;
27using cricket::VideoFormat;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000028using webrtc::FakeConstraints;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000029using webrtc::MediaConstraintsInterface;
30using webrtc::MediaSourceInterface;
31using webrtc::ObserverInterface;
Tommi1f432e02018-02-05 23:01:43 +010032using webrtc::VideoCapturerTrackSource;
perkja3ede6c2016-03-08 01:27:48 +010033using webrtc::VideoTrackSourceInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034
35namespace {
36
37// Max wait time for a test.
38const int kMaxWaitMs = 100;
39
40} // anonymous namespace
41
henrike@webrtc.org28e20752013-07-10 00:45:36 +000042// TestVideoCapturer extends cricket::FakeVideoCapturer so it can be used for
43// testing without known camera formats.
44// It keeps its own lists of cricket::VideoFormats for the unit tests in this
45// file.
46class TestVideoCapturer : public cricket::FakeVideoCapturer {
47 public:
perkja3ede6c2016-03-08 01:27:48 +010048 explicit TestVideoCapturer(bool is_screencast)
49 : FakeVideoCapturer(is_screencast), test_without_formats_(false) {
Tommi1f432e02018-02-05 23:01:43 +010050 static const auto fps = VideoFormat::FpsToInterval(30);
51 static const VideoFormat formats[] = {
52 {1280, 720, fps, FOURCC_I420}, {640, 480, fps, FOURCC_I420},
53 {640, 400, fps, FOURCC_I420}, {320, 240, fps, FOURCC_I420},
54 {352, 288, fps, FOURCC_I420},
55 };
56 ResetSupportedFormats({&formats[0], &formats[arraysize(formats)]});
henrike@webrtc.org28e20752013-07-10 00:45:36 +000057 }
58
59 // This function is used for resetting the supported capture formats and
60 // simulating a cricket::VideoCapturer implementation that don't support
61 // capture format enumeration. This is used to simulate the current
62 // Chrome implementation.
63 void TestWithoutCameraFormats() {
64 test_without_formats_ = true;
Tommi1f432e02018-02-05 23:01:43 +010065 std::vector<VideoFormat> formats;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066 ResetSupportedFormats(formats);
67 }
68
Tommi1f432e02018-02-05 23:01:43 +010069 virtual cricket::CaptureState Start(const VideoFormat& capture_format) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000070 if (test_without_formats_) {
Tommi1f432e02018-02-05 23:01:43 +010071 std::vector<VideoFormat> formats;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000072 formats.push_back(capture_format);
73 ResetSupportedFormats(formats);
74 }
75 return FakeVideoCapturer::Start(capture_format);
76 }
77
Tommi1f432e02018-02-05 23:01:43 +010078 virtual bool GetBestCaptureFormat(const VideoFormat& desired,
79 VideoFormat* best_format) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000080 if (test_without_formats_) {
81 *best_format = desired;
82 return true;
83 }
perkja3ede6c2016-03-08 01:27:48 +010084 return FakeVideoCapturer::GetBestCaptureFormat(desired, best_format);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000085 }
86
87 private:
88 bool test_without_formats_;
89};
90
91class StateObserver : public ObserverInterface {
92 public:
perkja3ede6c2016-03-08 01:27:48 +010093 explicit StateObserver(VideoTrackSourceInterface* source)
94 : state_(source->state()), source_(source) {}
95 virtual void OnChanged() { state_ = source_->state(); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000096 MediaSourceInterface::SourceState state() const { return state_; }
97
98 private:
99 MediaSourceInterface::SourceState state_;
perkja3ede6c2016-03-08 01:27:48 +0100100 rtc::scoped_refptr<VideoTrackSourceInterface> source_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000101};
102
perkja3ede6c2016-03-08 01:27:48 +0100103class VideoCapturerTrackSourceTest : public testing::Test {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000104 protected:
perkja3ede6c2016-03-08 01:27:48 +0100105 VideoCapturerTrackSourceTest() { InitCapturer(false); }
Niels Möller60653ba2016-03-02 11:41:36 +0100106 void InitCapturer(bool is_screencast) {
deadbeef112b2e92017-02-10 20:13:37 -0800107 capturer_ = new TestVideoCapturer(is_screencast);
108 capturer_cleanup_.reset(capturer_);
Niels Möller60653ba2016-03-02 11:41:36 +0100109 }
110
111 void InitScreencast() { InitCapturer(true); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000112
perkja3ede6c2016-03-08 01:27:48 +0100113 void CreateVideoCapturerSource() { CreateVideoCapturerSource(NULL); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000114
perkja3ede6c2016-03-08 01:27:48 +0100115 void CreateVideoCapturerSource(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000116 const webrtc::MediaConstraintsInterface* constraints) {
perkja3ede6c2016-03-08 01:27:48 +0100117 source_ = VideoCapturerTrackSource::Create(rtc::Thread::Current(),
deadbeef112b2e92017-02-10 20:13:37 -0800118 std::move(capturer_cleanup_),
perkja3ede6c2016-03-08 01:27:48 +0100119 constraints, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000120
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000121 ASSERT_TRUE(source_.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000122
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000123 state_observer_.reset(new StateObserver(source_));
124 source_->RegisterObserver(state_observer_.get());
perkjf2880a02016-03-03 01:51:52 -0800125 source_->AddOrUpdateSink(&renderer_, rtc::VideoSinkWants());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000126 }
127
Tommi1f432e02018-02-05 23:01:43 +0100128 void CaptureSingleFrame() {
129 rtc::Event event(false, false);
130 task_queue_.PostTask([this, &event]() {
131 ASSERT_TRUE(capturer_->CaptureFrame());
132 event.Set();
133 });
134 event.Wait(rtc::Event::kForever);
135 }
136
137 rtc::TaskQueue task_queue_{"VideoCapturerTrackSourceTest"};
deadbeef112b2e92017-02-10 20:13:37 -0800138 std::unique_ptr<cricket::VideoCapturer> capturer_cleanup_;
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000139 TestVideoCapturer* capturer_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000140 cricket::FakeVideoRenderer renderer_;
kwibergd1fe2812016-04-27 06:47:29 -0700141 std::unique_ptr<StateObserver> state_observer_;
perkja3ede6c2016-03-08 01:27:48 +0100142 rtc::scoped_refptr<VideoTrackSourceInterface> source_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000143};
144
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000145// Test that a VideoSource transition to kLive state when the capture
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000146// device have started and kEnded if it is stopped.
147// It also test that an output can receive video frames.
perkja3ede6c2016-03-08 01:27:48 +0100148TEST_F(VideoCapturerTrackSourceTest, CapturerStartStop) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000149 // Initialize without constraints.
perkja3ede6c2016-03-08 01:27:48 +0100150 CreateVideoCapturerSource();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000151 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
152 kMaxWaitMs);
153
Tommi1f432e02018-02-05 23:01:43 +0100154 CaptureSingleFrame();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000155 EXPECT_EQ(1, renderer_.num_rendered_frames());
156
157 capturer_->Stop();
158 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
159 kMaxWaitMs);
160}
161
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000162// Test that a VideoSource transition to kEnded if the capture device
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000163// fails.
perkja3ede6c2016-03-08 01:27:48 +0100164TEST_F(VideoCapturerTrackSourceTest, CameraFailed) {
165 CreateVideoCapturerSource();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
167 kMaxWaitMs);
168
169 capturer_->SignalStateChange(capturer_, cricket::CS_FAILED);
170 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
171 kMaxWaitMs);
172}
173
174// Test that the capture output is CIF if we set max constraints to CIF.
175// and the capture device support CIF.
perkja3ede6c2016-03-08 01:27:48 +0100176TEST_F(VideoCapturerTrackSourceTest, MandatoryConstraintCif5Fps) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000177 FakeConstraints constraints;
178 constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 352);
179 constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 288);
180 constraints.AddMandatory(MediaConstraintsInterface::kMaxFrameRate, 5);
181
perkja3ede6c2016-03-08 01:27:48 +0100182 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000183 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
184 kMaxWaitMs);
Tommi1f432e02018-02-05 23:01:43 +0100185 const VideoFormat* format = capturer_->GetCaptureFormat();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000186 ASSERT_TRUE(format != NULL);
187 EXPECT_EQ(352, format->width);
188 EXPECT_EQ(288, format->height);
perkjfa10b552016-10-02 23:45:26 -0700189 EXPECT_EQ(5, format->framerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000190}
191
192// Test that the capture output is 720P if the camera support it and the
193// optional constraint is set to 720P.
perkja3ede6c2016-03-08 01:27:48 +0100194TEST_F(VideoCapturerTrackSourceTest, MandatoryMinVgaOptional720P) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000195 FakeConstraints constraints;
196 constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
197 constraints.AddMandatory(MediaConstraintsInterface::kMinHeight, 480);
198 constraints.AddOptional(MediaConstraintsInterface::kMinWidth, 1280);
199 constraints.AddOptional(MediaConstraintsInterface::kMinAspectRatio,
200 1280.0 / 720);
201
perkja3ede6c2016-03-08 01:27:48 +0100202 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000203 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
204 kMaxWaitMs);
Tommi1f432e02018-02-05 23:01:43 +0100205 const VideoFormat* format = capturer_->GetCaptureFormat();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000206 ASSERT_TRUE(format != NULL);
207 EXPECT_EQ(1280, format->width);
208 EXPECT_EQ(720, format->height);
209 EXPECT_EQ(30, format->framerate());
210}
211
212// Test that the capture output have aspect ratio 4:3 if a mandatory constraint
213// require it even if an optional constraint request a higher resolution
214// that don't have this aspect ratio.
perkja3ede6c2016-03-08 01:27:48 +0100215TEST_F(VideoCapturerTrackSourceTest, MandatoryAspectRatio4To3) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000216 FakeConstraints constraints;
217 constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
218 constraints.AddMandatory(MediaConstraintsInterface::kMinHeight, 480);
219 constraints.AddMandatory(MediaConstraintsInterface::kMaxAspectRatio,
220 640.0 / 480);
221 constraints.AddOptional(MediaConstraintsInterface::kMinWidth, 1280);
222
perkja3ede6c2016-03-08 01:27:48 +0100223 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000224 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
225 kMaxWaitMs);
Tommi1f432e02018-02-05 23:01:43 +0100226 const VideoFormat* format = capturer_->GetCaptureFormat();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000227 ASSERT_TRUE(format != NULL);
228 EXPECT_EQ(640, format->width);
229 EXPECT_EQ(480, format->height);
230 EXPECT_EQ(30, format->framerate());
231}
232
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233// Test that the source state transition to kEnded if the mandatory aspect ratio
234// is set higher than supported.
perkja3ede6c2016-03-08 01:27:48 +0100235TEST_F(VideoCapturerTrackSourceTest, MandatoryAspectRatioTooHigh) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 FakeConstraints constraints;
237 constraints.AddMandatory(MediaConstraintsInterface::kMinAspectRatio, 2);
perkja3ede6c2016-03-08 01:27:48 +0100238 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000239 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
240 kMaxWaitMs);
241}
242
243// Test that the source ignores an optional aspect ratio that is higher than
244// supported.
perkja3ede6c2016-03-08 01:27:48 +0100245TEST_F(VideoCapturerTrackSourceTest, OptionalAspectRatioTooHigh) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000246 FakeConstraints constraints;
247 constraints.AddOptional(MediaConstraintsInterface::kMinAspectRatio, 2);
perkja3ede6c2016-03-08 01:27:48 +0100248 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000249 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
250 kMaxWaitMs);
Tommi1f432e02018-02-05 23:01:43 +0100251 const VideoFormat* format = capturer_->GetCaptureFormat();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 ASSERT_TRUE(format != NULL);
253 double aspect_ratio = static_cast<double>(format->width) / format->height;
254 EXPECT_LT(aspect_ratio, 2);
255}
256
257// Test that the source starts video with the default resolution if the
258// camera doesn't support capability enumeration and there are no constraints.
perkja3ede6c2016-03-08 01:27:48 +0100259TEST_F(VideoCapturerTrackSourceTest, NoCameraCapability) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000260 capturer_->TestWithoutCameraFormats();
261
perkja3ede6c2016-03-08 01:27:48 +0100262 CreateVideoCapturerSource();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000263 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
264 kMaxWaitMs);
Tommi1f432e02018-02-05 23:01:43 +0100265 const VideoFormat* format = capturer_->GetCaptureFormat();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000266 ASSERT_TRUE(format != NULL);
267 EXPECT_EQ(640, format->width);
268 EXPECT_EQ(480, format->height);
269 EXPECT_EQ(30, format->framerate());
270}
271
272// Test that the source can start the video and get the requested aspect ratio
273// if the camera doesn't support capability enumeration and the aspect ratio is
274// set.
perkja3ede6c2016-03-08 01:27:48 +0100275TEST_F(VideoCapturerTrackSourceTest, NoCameraCapability16To9Ratio) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000276 capturer_->TestWithoutCameraFormats();
277
278 FakeConstraints constraints;
279 double requested_aspect_ratio = 640.0 / 360;
280 constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
281 constraints.AddMandatory(MediaConstraintsInterface::kMinAspectRatio,
282 requested_aspect_ratio);
283
perkja3ede6c2016-03-08 01:27:48 +0100284 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000285 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
286 kMaxWaitMs);
Tommi1f432e02018-02-05 23:01:43 +0100287 const VideoFormat* format = capturer_->GetCaptureFormat();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000288 double aspect_ratio = static_cast<double>(format->width) / format->height;
289 EXPECT_LE(requested_aspect_ratio, aspect_ratio);
290}
291
292// Test that the source state transitions to kEnded if an unknown mandatory
293// constraint is found.
perkja3ede6c2016-03-08 01:27:48 +0100294TEST_F(VideoCapturerTrackSourceTest, InvalidMandatoryConstraint) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000295 FakeConstraints constraints;
296 constraints.AddMandatory("weird key", 640);
297
perkja3ede6c2016-03-08 01:27:48 +0100298 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000299 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
300 kMaxWaitMs);
301}
302
303// Test that the source ignores an unknown optional constraint.
perkja3ede6c2016-03-08 01:27:48 +0100304TEST_F(VideoCapturerTrackSourceTest, InvalidOptionalConstraint) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000305 FakeConstraints constraints;
306 constraints.AddOptional("weird key", 640);
307
perkja3ede6c2016-03-08 01:27:48 +0100308 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000309 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
310 kMaxWaitMs);
311}
312
perkj0d3eef22016-03-09 02:39:17 +0100313TEST_F(VideoCapturerTrackSourceTest, SetValidDenoisingConstraint) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000314 FakeConstraints constraints;
Perc0d31e92016-03-31 17:23:39 +0200315 constraints.AddMandatory(MediaConstraintsInterface::kNoiseReduction, "false");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000316
perkja3ede6c2016-03-08 01:27:48 +0100317 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000318
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100319 EXPECT_EQ(false, source_->needs_denoising());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000320}
321
perkj0d3eef22016-03-09 02:39:17 +0100322TEST_F(VideoCapturerTrackSourceTest, NoiseReductionConstraintNotSet) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323 FakeConstraints constraints;
perkja3ede6c2016-03-08 01:27:48 +0100324 CreateVideoCapturerSource(&constraints);
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100325 EXPECT_EQ(rtc::nullopt, source_->needs_denoising());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000326}
327
perkj0d3eef22016-03-09 02:39:17 +0100328TEST_F(VideoCapturerTrackSourceTest,
329 MandatoryDenoisingConstraintOverridesOptional) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 FakeConstraints constraints;
perkj0d3eef22016-03-09 02:39:17 +0100331 constraints.AddMandatory(MediaConstraintsInterface::kNoiseReduction, false);
332 constraints.AddOptional(MediaConstraintsInterface::kNoiseReduction, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333
perkja3ede6c2016-03-08 01:27:48 +0100334 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100336 EXPECT_EQ(false, source_->needs_denoising());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000337}
338
perkj0d3eef22016-03-09 02:39:17 +0100339TEST_F(VideoCapturerTrackSourceTest, NoiseReductionAndInvalidKeyOptional) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000340 FakeConstraints constraints;
perkj0d3eef22016-03-09 02:39:17 +0100341 constraints.AddOptional(MediaConstraintsInterface::kNoiseReduction, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000342 constraints.AddOptional("invalidKey", false);
343
perkja3ede6c2016-03-08 01:27:48 +0100344 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000345
346 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
perkja3ede6c2016-03-08 01:27:48 +0100347 kMaxWaitMs);
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100348 EXPECT_EQ(true, source_->needs_denoising());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000349}
350
perkj0d3eef22016-03-09 02:39:17 +0100351TEST_F(VideoCapturerTrackSourceTest, NoiseReductionAndInvalidKeyMandatory) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000352 FakeConstraints constraints;
perkja3ede6c2016-03-08 01:27:48 +0100353 constraints.AddMandatory(MediaConstraintsInterface::kNoiseReduction, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000354 constraints.AddMandatory("invalidKey", false);
355
perkja3ede6c2016-03-08 01:27:48 +0100356 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000357
358 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
perkja3ede6c2016-03-08 01:27:48 +0100359 kMaxWaitMs);
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100360 EXPECT_EQ(rtc::nullopt, source_->needs_denoising());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000361}
362
perkj0d3eef22016-03-09 02:39:17 +0100363TEST_F(VideoCapturerTrackSourceTest, InvalidDenoisingValueOptional) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000364 FakeConstraints constraints;
perkja3ede6c2016-03-08 01:27:48 +0100365 constraints.AddOptional(MediaConstraintsInterface::kNoiseReduction,
366 "not a boolean");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000367
perkja3ede6c2016-03-08 01:27:48 +0100368 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000369
370 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
perkja3ede6c2016-03-08 01:27:48 +0100371 kMaxWaitMs);
Perc0d31e92016-03-31 17:23:39 +0200372
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100373 EXPECT_EQ(rtc::nullopt, source_->needs_denoising());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000374}
375
perkj0d3eef22016-03-09 02:39:17 +0100376TEST_F(VideoCapturerTrackSourceTest, InvalidDenoisingValueMandatory) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000377 FakeConstraints constraints;
378 // Optional constraints should be ignored if the mandatory constraints fail.
perkja3ede6c2016-03-08 01:27:48 +0100379 constraints.AddOptional(MediaConstraintsInterface::kNoiseReduction, "false");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000380 // Values are case-sensitive and must be all lower-case.
perkja3ede6c2016-03-08 01:27:48 +0100381 constraints.AddMandatory(MediaConstraintsInterface::kNoiseReduction, "True");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000382
perkja3ede6c2016-03-08 01:27:48 +0100383 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000384
385 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
perkja3ede6c2016-03-08 01:27:48 +0100386 kMaxWaitMs);
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100387 EXPECT_EQ(rtc::nullopt, source_->needs_denoising());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000388}
389
perkja3ede6c2016-03-08 01:27:48 +0100390TEST_F(VideoCapturerTrackSourceTest, MixedOptionsAndConstraints) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000391 FakeConstraints constraints;
392 constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 352);
393 constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 288);
394 constraints.AddOptional(MediaConstraintsInterface::kMaxFrameRate, 5);
395
perkja3ede6c2016-03-08 01:27:48 +0100396 constraints.AddMandatory(MediaConstraintsInterface::kNoiseReduction, false);
397 constraints.AddOptional(MediaConstraintsInterface::kNoiseReduction, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000398
perkja3ede6c2016-03-08 01:27:48 +0100399 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000400 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
401 kMaxWaitMs);
Tommi1f432e02018-02-05 23:01:43 +0100402 const VideoFormat* format = capturer_->GetCaptureFormat();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000403 ASSERT_TRUE(format != NULL);
404 EXPECT_EQ(352, format->width);
405 EXPECT_EQ(288, format->height);
perkjfa10b552016-10-02 23:45:26 -0700406 EXPECT_EQ(5, format->framerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000407
Oskar Sundbom36f8f3e2017-11-16 10:54:27 +0100408 EXPECT_EQ(false, source_->needs_denoising());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000409}
410
411// Tests that the source starts video with the default resolution for
412// screencast if no constraint is set.
perkja3ede6c2016-03-08 01:27:48 +0100413TEST_F(VideoCapturerTrackSourceTest, ScreencastResolutionNoConstraint) {
Niels Möller60653ba2016-03-02 11:41:36 +0100414 InitScreencast();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000415 capturer_->TestWithoutCameraFormats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000416
perkja3ede6c2016-03-08 01:27:48 +0100417 CreateVideoCapturerSource();
perkj0d3eef22016-03-09 02:39:17 +0100418 ASSERT_TRUE(source_->is_screencast());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000419 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
420 kMaxWaitMs);
Tommi1f432e02018-02-05 23:01:43 +0100421 const VideoFormat* format = capturer_->GetCaptureFormat();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000422 ASSERT_TRUE(format != NULL);
423 EXPECT_EQ(640, format->width);
424 EXPECT_EQ(480, format->height);
425 EXPECT_EQ(30, format->framerate());
426}
427
428// Tests that the source starts video with the max width and height set by
429// constraints for screencast.
perkja3ede6c2016-03-08 01:27:48 +0100430TEST_F(VideoCapturerTrackSourceTest, ScreencastResolutionWithConstraint) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000431 FakeConstraints constraints;
432 constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 480);
433 constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 270);
434
Niels Möller60653ba2016-03-02 11:41:36 +0100435 InitScreencast();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000436 capturer_->TestWithoutCameraFormats();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000437
perkja3ede6c2016-03-08 01:27:48 +0100438 CreateVideoCapturerSource(&constraints);
perkj0d3eef22016-03-09 02:39:17 +0100439 ASSERT_TRUE(source_->is_screencast());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000440 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
441 kMaxWaitMs);
Tommi1f432e02018-02-05 23:01:43 +0100442 const VideoFormat* format = capturer_->GetCaptureFormat();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000443 ASSERT_TRUE(format != NULL);
444 EXPECT_EQ(480, format->width);
445 EXPECT_EQ(270, format->height);
446 EXPECT_EQ(30, format->framerate());
447}
448
perkja3ede6c2016-03-08 01:27:48 +0100449TEST_F(VideoCapturerTrackSourceTest, MandatorySubOneFpsConstraints) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000450 FakeConstraints constraints;
451 constraints.AddMandatory(MediaConstraintsInterface::kMaxFrameRate, 0.5);
452
perkja3ede6c2016-03-08 01:27:48 +0100453 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000454 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
455 kMaxWaitMs);
456 ASSERT_TRUE(capturer_->GetCaptureFormat() == NULL);
457}
458
perkja3ede6c2016-03-08 01:27:48 +0100459TEST_F(VideoCapturerTrackSourceTest, OptionalSubOneFpsConstraints) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000460 FakeConstraints constraints;
461 constraints.AddOptional(MediaConstraintsInterface::kMaxFrameRate, 0.5);
462
perkja3ede6c2016-03-08 01:27:48 +0100463 CreateVideoCapturerSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000464 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
465 kMaxWaitMs);
Tommi1f432e02018-02-05 23:01:43 +0100466 const VideoFormat* format = capturer_->GetCaptureFormat();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000467 ASSERT_TRUE(format != NULL);
perkjfa10b552016-10-02 23:45:26 -0700468 EXPECT_EQ(1, format->framerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000469}