blob: 7d8a731d2695f8236c9c58ebb9937833da37970f [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 * Copyright 2012 Google Inc.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00004 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
henrike@webrtc.org28e20752013-07-10 00:45:36 +000028#include <string>
29#include <vector>
30
wu@webrtc.org967bfff2013-09-19 05:49:50 +000031#include "talk/app/webrtc/remotevideocapturer.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000032#include "talk/app/webrtc/test/fakeconstraints.h"
wu@webrtc.org967bfff2013-09-19 05:49:50 +000033#include "talk/app/webrtc/videosource.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034#include "talk/session/media/channelmanager.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000035#include "webrtc/base/gunit.h"
kjellandera96e2d72016-02-04 23:52:28 -080036#include "webrtc/media/base/fakemediaengine.h"
37#include "webrtc/media/base/fakevideocapturer.h"
38#include "webrtc/media/base/fakevideorenderer.h"
39#include "webrtc/media/webrtc/webrtcvideoframe.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040
41using webrtc::FakeConstraints;
wu@webrtc.org967bfff2013-09-19 05:49:50 +000042using webrtc::VideoSource;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000043using webrtc::MediaConstraintsInterface;
44using webrtc::MediaSourceInterface;
45using webrtc::ObserverInterface;
46using webrtc::VideoSourceInterface;
47
48namespace {
49
50// Max wait time for a test.
51const int kMaxWaitMs = 100;
52
53} // anonymous namespace
54
55
56// TestVideoCapturer extends cricket::FakeVideoCapturer so it can be used for
57// testing without known camera formats.
58// It keeps its own lists of cricket::VideoFormats for the unit tests in this
59// file.
60class TestVideoCapturer : public cricket::FakeVideoCapturer {
61 public:
62 TestVideoCapturer() : test_without_formats_(false) {
63 std::vector<cricket::VideoFormat> formats;
64 formats.push_back(cricket::VideoFormat(1280, 720,
65 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
66 formats.push_back(cricket::VideoFormat(640, 480,
67 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
68 formats.push_back(cricket::VideoFormat(640, 400,
69 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
70 formats.push_back(cricket::VideoFormat(320, 240,
71 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
72 formats.push_back(cricket::VideoFormat(352, 288,
73 cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
74 ResetSupportedFormats(formats);
75 }
76
77 // This function is used for resetting the supported capture formats and
78 // simulating a cricket::VideoCapturer implementation that don't support
79 // capture format enumeration. This is used to simulate the current
80 // Chrome implementation.
81 void TestWithoutCameraFormats() {
82 test_without_formats_ = true;
83 std::vector<cricket::VideoFormat> formats;
84 ResetSupportedFormats(formats);
85 }
86
87 virtual cricket::CaptureState Start(
88 const cricket::VideoFormat& capture_format) {
89 if (test_without_formats_) {
90 std::vector<cricket::VideoFormat> formats;
91 formats.push_back(capture_format);
92 ResetSupportedFormats(formats);
93 }
94 return FakeVideoCapturer::Start(capture_format);
95 }
96
97 virtual bool GetBestCaptureFormat(const cricket::VideoFormat& desired,
98 cricket::VideoFormat* best_format) {
99 if (test_without_formats_) {
100 *best_format = desired;
101 return true;
102 }
103 return FakeVideoCapturer::GetBestCaptureFormat(desired,
104 best_format);
105 }
106
107 private:
108 bool test_without_formats_;
109};
110
111class StateObserver : public ObserverInterface {
112 public:
113 explicit StateObserver(VideoSourceInterface* source)
114 : state_(source->state()),
115 source_(source) {
116 }
117 virtual void OnChanged() {
118 state_ = source_->state();
119 }
120 MediaSourceInterface::SourceState state() const { return state_; }
121
122 private:
123 MediaSourceInterface::SourceState state_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000124 rtc::scoped_refptr<VideoSourceInterface> source_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000125};
126
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000127class VideoSourceTest : public testing::Test {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000128 protected:
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000129 VideoSourceTest()
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000130 : capturer_cleanup_(new TestVideoCapturer()),
131 capturer_(capturer_cleanup_.get()),
132 channel_manager_(new cricket::ChannelManager(
solenbergfacbbec2015-09-24 00:41:50 -0700133 new cricket::FakeMediaEngine(), rtc::Thread::Current())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000134 }
135
136 void SetUp() {
137 ASSERT_TRUE(channel_manager_->Init());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000138 }
139
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000140 void CreateVideoSource() {
141 CreateVideoSource(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000142 }
143
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000144 void CreateVideoSource(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000145 const webrtc::MediaConstraintsInterface* constraints) {
146 // VideoSource take ownership of |capturer_|
tommi6eca7e32015-12-15 04:27:11 -0800147 source_ =
148 VideoSource::Create(channel_manager_.get(), capturer_cleanup_.release(),
149 constraints, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000150
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000151 ASSERT_TRUE(source_.get() != NULL);
152 EXPECT_EQ(capturer_, source_->GetVideoCapturer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000153
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000154 state_observer_.reset(new StateObserver(source_));
155 source_->RegisterObserver(state_observer_.get());
156 source_->AddSink(&renderer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000157 }
158
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000159 rtc::scoped_ptr<TestVideoCapturer> capturer_cleanup_;
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000160 TestVideoCapturer* capturer_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000161 cricket::FakeVideoRenderer renderer_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000162 rtc::scoped_ptr<cricket::ChannelManager> channel_manager_;
163 rtc::scoped_ptr<StateObserver> state_observer_;
164 rtc::scoped_refptr<VideoSource> source_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000165};
166
167
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000168// Test that a VideoSource transition to kLive state when the capture
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000169// device have started and kEnded if it is stopped.
170// It also test that an output can receive video frames.
perkj@webrtc.org8f605e82015-02-17 13:53:56 +0000171TEST_F(VideoSourceTest, CapturerStartStop) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000172 // Initialize without constraints.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000173 CreateVideoSource();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
175 kMaxWaitMs);
176
177 ASSERT_TRUE(capturer_->CaptureFrame());
178 EXPECT_EQ(1, renderer_.num_rendered_frames());
179
180 capturer_->Stop();
181 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
182 kMaxWaitMs);
183}
184
perkj@webrtc.org8f605e82015-02-17 13:53:56 +0000185// Test that a VideoSource can be stopped and restarted.
186TEST_F(VideoSourceTest, StopRestart) {
187 // Initialize without constraints.
188 CreateVideoSource();
189 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
190 kMaxWaitMs);
191
192 ASSERT_TRUE(capturer_->CaptureFrame());
193 EXPECT_EQ(1, renderer_.num_rendered_frames());
194
195 source_->Stop();
196 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
197 kMaxWaitMs);
198
199 source_->Restart();
200 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
201 kMaxWaitMs);
202
203 ASSERT_TRUE(capturer_->CaptureFrame());
204 EXPECT_EQ(2, renderer_.num_rendered_frames());
205
206 source_->Stop();
207}
208
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000209// Test start stop with a remote VideoSource - the video source that has a
210// RemoteVideoCapturer and takes video frames from FrameInput.
211TEST_F(VideoSourceTest, StartStopRemote) {
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000212 source_ = VideoSource::Create(channel_manager_.get(),
tommi6eca7e32015-12-15 04:27:11 -0800213 new webrtc::RemoteVideoCapturer(), NULL, true);
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000214
215 ASSERT_TRUE(source_.get() != NULL);
216 EXPECT_TRUE(NULL != source_->GetVideoCapturer());
217
218 state_observer_.reset(new StateObserver(source_));
219 source_->RegisterObserver(state_observer_.get());
220 source_->AddSink(&renderer_);
221
222 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
223 kMaxWaitMs);
224
225 cricket::VideoRenderer* frameinput = source_->FrameInput();
226 cricket::WebRtcVideoFrame test_frame;
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000227 frameinput->RenderFrame(&test_frame);
228 EXPECT_EQ(1, renderer_.num_rendered_frames());
229
230 source_->GetVideoCapturer()->Stop();
231 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
232 kMaxWaitMs);
233}
234
235// Test that a VideoSource transition to kEnded if the capture device
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236// fails.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000237TEST_F(VideoSourceTest, CameraFailed) {
238 CreateVideoSource();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000239 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
240 kMaxWaitMs);
241
242 capturer_->SignalStateChange(capturer_, cricket::CS_FAILED);
243 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
244 kMaxWaitMs);
245}
246
247// Test that the capture output is CIF if we set max constraints to CIF.
248// and the capture device support CIF.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000249TEST_F(VideoSourceTest, MandatoryConstraintCif5Fps) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000250 FakeConstraints constraints;
251 constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 352);
252 constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 288);
253 constraints.AddMandatory(MediaConstraintsInterface::kMaxFrameRate, 5);
254
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000255 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
257 kMaxWaitMs);
258 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
259 ASSERT_TRUE(format != NULL);
260 EXPECT_EQ(352, format->width);
261 EXPECT_EQ(288, format->height);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000262 EXPECT_EQ(30, format->framerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000263}
264
265// Test that the capture output is 720P if the camera support it and the
266// optional constraint is set to 720P.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000267TEST_F(VideoSourceTest, MandatoryMinVgaOptional720P) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268 FakeConstraints constraints;
269 constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
270 constraints.AddMandatory(MediaConstraintsInterface::kMinHeight, 480);
271 constraints.AddOptional(MediaConstraintsInterface::kMinWidth, 1280);
272 constraints.AddOptional(MediaConstraintsInterface::kMinAspectRatio,
273 1280.0 / 720);
274
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000275 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000276 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
277 kMaxWaitMs);
278 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
279 ASSERT_TRUE(format != NULL);
280 EXPECT_EQ(1280, format->width);
281 EXPECT_EQ(720, format->height);
282 EXPECT_EQ(30, format->framerate());
283}
284
285// Test that the capture output have aspect ratio 4:3 if a mandatory constraint
286// require it even if an optional constraint request a higher resolution
287// that don't have this aspect ratio.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000288TEST_F(VideoSourceTest, MandatoryAspectRatio4To3) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000289 FakeConstraints constraints;
290 constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
291 constraints.AddMandatory(MediaConstraintsInterface::kMinHeight, 480);
292 constraints.AddMandatory(MediaConstraintsInterface::kMaxAspectRatio,
293 640.0 / 480);
294 constraints.AddOptional(MediaConstraintsInterface::kMinWidth, 1280);
295
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000296 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000297 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
298 kMaxWaitMs);
299 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
300 ASSERT_TRUE(format != NULL);
301 EXPECT_EQ(640, format->width);
302 EXPECT_EQ(480, format->height);
303 EXPECT_EQ(30, format->framerate());
304}
305
306
307// Test that the source state transition to kEnded if the mandatory aspect ratio
308// is set higher than supported.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000309TEST_F(VideoSourceTest, MandatoryAspectRatioTooHigh) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000310 FakeConstraints constraints;
311 constraints.AddMandatory(MediaConstraintsInterface::kMinAspectRatio, 2);
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000312 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000313 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
314 kMaxWaitMs);
315}
316
317// Test that the source ignores an optional aspect ratio that is higher than
318// supported.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000319TEST_F(VideoSourceTest, OptionalAspectRatioTooHigh) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000320 FakeConstraints constraints;
321 constraints.AddOptional(MediaConstraintsInterface::kMinAspectRatio, 2);
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000322 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
324 kMaxWaitMs);
325 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
326 ASSERT_TRUE(format != NULL);
327 double aspect_ratio = static_cast<double>(format->width) / format->height;
328 EXPECT_LT(aspect_ratio, 2);
329}
330
331// Test that the source starts video with the default resolution if the
332// camera doesn't support capability enumeration and there are no constraints.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000333TEST_F(VideoSourceTest, NoCameraCapability) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000334 capturer_->TestWithoutCameraFormats();
335
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000336 CreateVideoSource();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000337 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
338 kMaxWaitMs);
339 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
340 ASSERT_TRUE(format != NULL);
341 EXPECT_EQ(640, format->width);
342 EXPECT_EQ(480, format->height);
343 EXPECT_EQ(30, format->framerate());
344}
345
346// Test that the source can start the video and get the requested aspect ratio
347// if the camera doesn't support capability enumeration and the aspect ratio is
348// set.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000349TEST_F(VideoSourceTest, NoCameraCapability16To9Ratio) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000350 capturer_->TestWithoutCameraFormats();
351
352 FakeConstraints constraints;
353 double requested_aspect_ratio = 640.0 / 360;
354 constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
355 constraints.AddMandatory(MediaConstraintsInterface::kMinAspectRatio,
356 requested_aspect_ratio);
357
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000358 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000359 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
360 kMaxWaitMs);
361 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
362 double aspect_ratio = static_cast<double>(format->width) / format->height;
363 EXPECT_LE(requested_aspect_ratio, aspect_ratio);
364}
365
366// Test that the source state transitions to kEnded if an unknown mandatory
367// constraint is found.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000368TEST_F(VideoSourceTest, InvalidMandatoryConstraint) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000369 FakeConstraints constraints;
370 constraints.AddMandatory("weird key", 640);
371
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000372 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000373 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
374 kMaxWaitMs);
375}
376
377// Test that the source ignores an unknown optional constraint.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000378TEST_F(VideoSourceTest, InvalidOptionalConstraint) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000379 FakeConstraints constraints;
380 constraints.AddOptional("weird key", 640);
381
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000382 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000383 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
384 kMaxWaitMs);
385}
386
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000387TEST_F(VideoSourceTest, SetValidOptionValues) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000388 FakeConstraints constraints;
389 constraints.AddMandatory(MediaConstraintsInterface::kNoiseReduction, "false");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000390
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000391 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000392
Karl Wibergbe579832015-11-10 22:34:18 +0100393 EXPECT_EQ(rtc::Optional<bool>(false),
394 source_->options()->video_noise_reduction);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000395}
396
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000397TEST_F(VideoSourceTest, OptionNotSet) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000398 FakeConstraints constraints;
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000399 CreateVideoSource(&constraints);
Karl Wibergbe579832015-11-10 22:34:18 +0100400 EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000401}
402
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000403TEST_F(VideoSourceTest, MandatoryOptionOverridesOptional) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000404 FakeConstraints constraints;
405 constraints.AddMandatory(
406 MediaConstraintsInterface::kNoiseReduction, true);
407 constraints.AddOptional(
408 MediaConstraintsInterface::kNoiseReduction, false);
409
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000410 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000411
Karl Wibergbe579832015-11-10 22:34:18 +0100412 EXPECT_EQ(rtc::Optional<bool>(true),
413 source_->options()->video_noise_reduction);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000414}
415
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000416TEST_F(VideoSourceTest, InvalidOptionKeyOptional) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000417 FakeConstraints constraints;
418 constraints.AddOptional(
419 MediaConstraintsInterface::kNoiseReduction, false);
420 constraints.AddOptional("invalidKey", false);
421
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000422 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000423
424 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
425 kMaxWaitMs);
Karl Wibergbe579832015-11-10 22:34:18 +0100426 EXPECT_EQ(rtc::Optional<bool>(false),
427 source_->options()->video_noise_reduction);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000428}
429
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000430TEST_F(VideoSourceTest, InvalidOptionKeyMandatory) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000431 FakeConstraints constraints;
432 constraints.AddMandatory(
433 MediaConstraintsInterface::kNoiseReduction, false);
434 constraints.AddMandatory("invalidKey", false);
435
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000436 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000437
438 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
439 kMaxWaitMs);
Karl Wibergbe579832015-11-10 22:34:18 +0100440 EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000441}
442
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000443TEST_F(VideoSourceTest, InvalidOptionValueOptional) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000444 FakeConstraints constraints;
445 constraints.AddOptional(
buildbot@webrtc.org81ddc782014-10-14 22:39:24 +0000446 MediaConstraintsInterface::kNoiseReduction, "not a boolean");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000447
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000448 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000449
450 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
451 kMaxWaitMs);
Karl Wibergbe579832015-11-10 22:34:18 +0100452 EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000453}
454
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000455TEST_F(VideoSourceTest, InvalidOptionValueMandatory) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000456 FakeConstraints constraints;
457 // Optional constraints should be ignored if the mandatory constraints fail.
458 constraints.AddOptional(
459 MediaConstraintsInterface::kNoiseReduction, "false");
460 // Values are case-sensitive and must be all lower-case.
461 constraints.AddMandatory(
buildbot@webrtc.org81ddc782014-10-14 22:39:24 +0000462 MediaConstraintsInterface::kNoiseReduction, "True");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000463
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000464 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000465
466 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
467 kMaxWaitMs);
Karl Wibergbe579832015-11-10 22:34:18 +0100468 EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000469}
470
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000471TEST_F(VideoSourceTest, MixedOptionsAndConstraints) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000472 FakeConstraints constraints;
473 constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 352);
474 constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 288);
475 constraints.AddOptional(MediaConstraintsInterface::kMaxFrameRate, 5);
476
477 constraints.AddMandatory(
478 MediaConstraintsInterface::kNoiseReduction, false);
479 constraints.AddOptional(
480 MediaConstraintsInterface::kNoiseReduction, true);
481
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000482 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000483 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
484 kMaxWaitMs);
485 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
486 ASSERT_TRUE(format != NULL);
487 EXPECT_EQ(352, format->width);
488 EXPECT_EQ(288, format->height);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000489 EXPECT_EQ(30, format->framerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000490
Karl Wibergbe579832015-11-10 22:34:18 +0100491 EXPECT_EQ(rtc::Optional<bool>(false),
492 source_->options()->video_noise_reduction);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000493}
494
495// Tests that the source starts video with the default resolution for
496// screencast if no constraint is set.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000497TEST_F(VideoSourceTest, ScreencastResolutionNoConstraint) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000498 capturer_->TestWithoutCameraFormats();
499 capturer_->SetScreencast(true);
500
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000501 CreateVideoSource();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000502 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
503 kMaxWaitMs);
504 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
505 ASSERT_TRUE(format != NULL);
506 EXPECT_EQ(640, format->width);
507 EXPECT_EQ(480, format->height);
508 EXPECT_EQ(30, format->framerate());
509}
510
511// Tests that the source starts video with the max width and height set by
512// constraints for screencast.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000513TEST_F(VideoSourceTest, ScreencastResolutionWithConstraint) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000514 FakeConstraints constraints;
515 constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 480);
516 constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 270);
517
518 capturer_->TestWithoutCameraFormats();
519 capturer_->SetScreencast(true);
520
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000521 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000522 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
523 kMaxWaitMs);
524 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
525 ASSERT_TRUE(format != NULL);
526 EXPECT_EQ(480, format->width);
527 EXPECT_EQ(270, format->height);
528 EXPECT_EQ(30, format->framerate());
529}
530
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000531TEST_F(VideoSourceTest, MandatorySubOneFpsConstraints) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000532 FakeConstraints constraints;
533 constraints.AddMandatory(MediaConstraintsInterface::kMaxFrameRate, 0.5);
534
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000535 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000536 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
537 kMaxWaitMs);
538 ASSERT_TRUE(capturer_->GetCaptureFormat() == NULL);
539}
540
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000541TEST_F(VideoSourceTest, OptionalSubOneFpsConstraints) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000542 FakeConstraints constraints;
543 constraints.AddOptional(MediaConstraintsInterface::kMaxFrameRate, 0.5);
544
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000545 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000546 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
547 kMaxWaitMs);
548 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
549 ASSERT_TRUE(format != NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000550 EXPECT_EQ(30, format->framerate());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000551}