blob: dddbdeeb4fd98261c6fa64140457b54347a9fd0d [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2012, Google Inc.
4 *
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
31#include "talk/app/webrtc/test/fakeconstraints.h"
wu@webrtc.org967bfff2013-09-19 05:49:50 +000032#include "talk/app/webrtc/remotevideocapturer.h"
33#include "talk/app/webrtc/videosource.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034#include "talk/base/gunit.h"
35#include "talk/media/base/fakemediaengine.h"
36#include "talk/media/base/fakevideorenderer.h"
37#include "talk/media/devices/fakedevicemanager.h"
wu@webrtc.org967bfff2013-09-19 05:49:50 +000038#include "talk/media/webrtc/webrtcvideoframe.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039#include "talk/session/media/channelmanager.h"
40
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_;
124 talk_base::scoped_refptr<VideoSourceInterface> source_;
125};
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()
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000130 : channel_manager_(new cricket::ChannelManager(
131 new cricket::FakeMediaEngine(),
132 new cricket::FakeDeviceManager(), talk_base::Thread::Current())) {
133 }
134
135 void SetUp() {
136 ASSERT_TRUE(channel_manager_->Init());
137 capturer_ = new TestVideoCapturer();
138 }
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_|
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000147 source_ = VideoSource::Create(channel_manager_.get(),
148 capturer_,
149 constraints);
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
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000159 TestVideoCapturer* capturer_; // Raw pointer. Owned by source_.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000160 cricket::FakeVideoRenderer renderer_;
161 talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
162 talk_base::scoped_ptr<StateObserver> state_observer_;
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000163 talk_base::scoped_refptr<VideoSource> source_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000164};
165
166
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000167// Test that a VideoSource transition to kLive state when the capture
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000168// device have started and kEnded if it is stopped.
169// It also test that an output can receive video frames.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000170TEST_F(VideoSourceTest, StartStop) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000171 // Initialize without constraints.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000172 CreateVideoSource();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000173 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
174 kMaxWaitMs);
175
176 ASSERT_TRUE(capturer_->CaptureFrame());
177 EXPECT_EQ(1, renderer_.num_rendered_frames());
178
179 capturer_->Stop();
180 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
181 kMaxWaitMs);
182}
183
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000184// Test start stop with a remote VideoSource - the video source that has a
185// RemoteVideoCapturer and takes video frames from FrameInput.
186TEST_F(VideoSourceTest, StartStopRemote) {
187 // Will use RemoteVideoCapturer.
188 delete capturer_;
189
190 source_ = VideoSource::Create(channel_manager_.get(),
191 new webrtc::RemoteVideoCapturer(),
192 NULL);
193
194 ASSERT_TRUE(source_.get() != NULL);
195 EXPECT_TRUE(NULL != source_->GetVideoCapturer());
196
197 state_observer_.reset(new StateObserver(source_));
198 source_->RegisterObserver(state_observer_.get());
199 source_->AddSink(&renderer_);
200
201 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
202 kMaxWaitMs);
203
204 cricket::VideoRenderer* frameinput = source_->FrameInput();
205 cricket::WebRtcVideoFrame test_frame;
206 frameinput->SetSize(1280, 720, 0);
207 frameinput->RenderFrame(&test_frame);
208 EXPECT_EQ(1, renderer_.num_rendered_frames());
209
210 source_->GetVideoCapturer()->Stop();
211 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
212 kMaxWaitMs);
213}
214
215// Test that a VideoSource transition to kEnded if the capture device
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000216// fails.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000217TEST_F(VideoSourceTest, CameraFailed) {
218 CreateVideoSource();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000219 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
220 kMaxWaitMs);
221
222 capturer_->SignalStateChange(capturer_, cricket::CS_FAILED);
223 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
224 kMaxWaitMs);
225}
226
227// Test that the capture output is CIF if we set max constraints to CIF.
228// and the capture device support CIF.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000229TEST_F(VideoSourceTest, MandatoryConstraintCif5Fps) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000230 FakeConstraints constraints;
231 constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 352);
232 constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 288);
233 constraints.AddMandatory(MediaConstraintsInterface::kMaxFrameRate, 5);
234
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000235 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
237 kMaxWaitMs);
238 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
239 ASSERT_TRUE(format != NULL);
240 EXPECT_EQ(352, format->width);
241 EXPECT_EQ(288, format->height);
242 EXPECT_EQ(5, format->framerate());
243}
244
245// Test that the capture output is 720P if the camera support it and the
246// optional constraint is set to 720P.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000247TEST_F(VideoSourceTest, MandatoryMinVgaOptional720P) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248 FakeConstraints constraints;
249 constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
250 constraints.AddMandatory(MediaConstraintsInterface::kMinHeight, 480);
251 constraints.AddOptional(MediaConstraintsInterface::kMinWidth, 1280);
252 constraints.AddOptional(MediaConstraintsInterface::kMinAspectRatio,
253 1280.0 / 720);
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(1280, format->width);
261 EXPECT_EQ(720, format->height);
262 EXPECT_EQ(30, format->framerate());
263}
264
265// Test that the capture output have aspect ratio 4:3 if a mandatory constraint
266// require it even if an optional constraint request a higher resolution
267// that don't have this aspect ratio.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000268TEST_F(VideoSourceTest, MandatoryAspectRatio4To3) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000269 FakeConstraints constraints;
270 constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
271 constraints.AddMandatory(MediaConstraintsInterface::kMinHeight, 480);
272 constraints.AddMandatory(MediaConstraintsInterface::kMaxAspectRatio,
273 640.0 / 480);
274 constraints.AddOptional(MediaConstraintsInterface::kMinWidth, 1280);
275
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000276 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000277 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
278 kMaxWaitMs);
279 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
280 ASSERT_TRUE(format != NULL);
281 EXPECT_EQ(640, format->width);
282 EXPECT_EQ(480, format->height);
283 EXPECT_EQ(30, format->framerate());
284}
285
286
287// Test that the source state transition to kEnded if the mandatory aspect ratio
288// is set higher than supported.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000289TEST_F(VideoSourceTest, MandatoryAspectRatioTooHigh) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000290 FakeConstraints constraints;
291 constraints.AddMandatory(MediaConstraintsInterface::kMinAspectRatio, 2);
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000292 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000293 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
294 kMaxWaitMs);
295}
296
297// Test that the source ignores an optional aspect ratio that is higher than
298// supported.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000299TEST_F(VideoSourceTest, OptionalAspectRatioTooHigh) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000300 FakeConstraints constraints;
301 constraints.AddOptional(MediaConstraintsInterface::kMinAspectRatio, 2);
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000302 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000303 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
304 kMaxWaitMs);
305 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
306 ASSERT_TRUE(format != NULL);
307 double aspect_ratio = static_cast<double>(format->width) / format->height;
308 EXPECT_LT(aspect_ratio, 2);
309}
310
311// Test that the source starts video with the default resolution if the
312// camera doesn't support capability enumeration and there are no constraints.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000313TEST_F(VideoSourceTest, NoCameraCapability) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000314 capturer_->TestWithoutCameraFormats();
315
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000316 CreateVideoSource();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
318 kMaxWaitMs);
319 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
320 ASSERT_TRUE(format != NULL);
321 EXPECT_EQ(640, format->width);
322 EXPECT_EQ(480, format->height);
323 EXPECT_EQ(30, format->framerate());
324}
325
326// Test that the source can start the video and get the requested aspect ratio
327// if the camera doesn't support capability enumeration and the aspect ratio is
328// set.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000329TEST_F(VideoSourceTest, NoCameraCapability16To9Ratio) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 capturer_->TestWithoutCameraFormats();
331
332 FakeConstraints constraints;
333 double requested_aspect_ratio = 640.0 / 360;
334 constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
335 constraints.AddMandatory(MediaConstraintsInterface::kMinAspectRatio,
336 requested_aspect_ratio);
337
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000338 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000339 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
340 kMaxWaitMs);
341 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
342 double aspect_ratio = static_cast<double>(format->width) / format->height;
343 EXPECT_LE(requested_aspect_ratio, aspect_ratio);
344}
345
346// Test that the source state transitions to kEnded if an unknown mandatory
347// constraint is found.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000348TEST_F(VideoSourceTest, InvalidMandatoryConstraint) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000349 FakeConstraints constraints;
350 constraints.AddMandatory("weird key", 640);
351
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000352 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000353 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
354 kMaxWaitMs);
355}
356
357// Test that the source ignores an unknown optional constraint.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000358TEST_F(VideoSourceTest, InvalidOptionalConstraint) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000359 FakeConstraints constraints;
360 constraints.AddOptional("weird key", 640);
361
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000362 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000363 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
364 kMaxWaitMs);
365}
366
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000367TEST_F(VideoSourceTest, SetValidOptionValues) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000368 FakeConstraints constraints;
369 constraints.AddMandatory(MediaConstraintsInterface::kNoiseReduction, "false");
370 constraints.AddMandatory(
371 MediaConstraintsInterface::kTemporalLayeredScreencast, "false");
372 constraints.AddOptional(
373 MediaConstraintsInterface::kLeakyBucket, "true");
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000374 constraints.AddOptional(
375 MediaConstraintsInterface::kCpuOveruseDetection, "true");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000376
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000377 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000378
379 bool value = true;
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000380 EXPECT_TRUE(source_->options()->video_noise_reduction.Get(&value));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000381 EXPECT_FALSE(value);
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000382 EXPECT_TRUE(source_->options()->
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000383 video_temporal_layer_screencast.Get(&value));
384 EXPECT_FALSE(value);
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000385 EXPECT_TRUE(source_->options()->video_leaky_bucket.Get(&value));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000386 EXPECT_TRUE(value);
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000387 EXPECT_TRUE(source_->options()->
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000388 cpu_overuse_detection.GetWithDefaultIfUnset(false));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000389}
390
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000391TEST_F(VideoSourceTest, OptionNotSet) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000392 FakeConstraints constraints;
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000393 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000394 bool value;
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000395 EXPECT_FALSE(source_->options()->video_noise_reduction.Get(&value));
396 EXPECT_FALSE(source_->options()->cpu_overuse_detection.Get(&value));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000397}
398
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000399TEST_F(VideoSourceTest, MandatoryOptionOverridesOptional) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000400 FakeConstraints constraints;
401 constraints.AddMandatory(
402 MediaConstraintsInterface::kNoiseReduction, true);
403 constraints.AddOptional(
404 MediaConstraintsInterface::kNoiseReduction, false);
405
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000406 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000407
408 bool value = false;
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000409 EXPECT_TRUE(source_->options()->video_noise_reduction.Get(&value));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000410 EXPECT_TRUE(value);
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000411 EXPECT_FALSE(source_->options()->video_leaky_bucket.Get(&value));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000412}
413
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000414TEST_F(VideoSourceTest, InvalidOptionKeyOptional) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000415 FakeConstraints constraints;
416 constraints.AddOptional(
417 MediaConstraintsInterface::kNoiseReduction, false);
418 constraints.AddOptional("invalidKey", false);
419
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000420 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000421
422 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
423 kMaxWaitMs);
424 bool value = true;
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000425 EXPECT_TRUE(source_->options()->video_noise_reduction.Get(&value));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000426 EXPECT_FALSE(value);
427}
428
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000429TEST_F(VideoSourceTest, InvalidOptionKeyMandatory) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000430 FakeConstraints constraints;
431 constraints.AddMandatory(
432 MediaConstraintsInterface::kNoiseReduction, false);
433 constraints.AddMandatory("invalidKey", false);
434
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000435 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000436
437 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
438 kMaxWaitMs);
439 bool value;
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000440 EXPECT_FALSE(source_->options()->video_noise_reduction.Get(&value));
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(
446 MediaConstraintsInterface::kNoiseReduction, "true");
447 constraints.AddOptional(
448 MediaConstraintsInterface::kLeakyBucket, "not boolean");
449
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000450 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000451
452 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
453 kMaxWaitMs);
454 bool value = false;
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000455 EXPECT_TRUE(source_->options()->video_noise_reduction.Get(&value));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000456 EXPECT_TRUE(value);
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000457 EXPECT_FALSE(source_->options()->video_leaky_bucket.Get(&value));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000458}
459
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000460TEST_F(VideoSourceTest, InvalidOptionValueMandatory) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000461 FakeConstraints constraints;
462 // Optional constraints should be ignored if the mandatory constraints fail.
463 constraints.AddOptional(
464 MediaConstraintsInterface::kNoiseReduction, "false");
465 // Values are case-sensitive and must be all lower-case.
466 constraints.AddMandatory(
467 MediaConstraintsInterface::kLeakyBucket, "True");
468
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000469 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000470
471 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
472 kMaxWaitMs);
473 bool value;
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000474 EXPECT_FALSE(source_->options()->video_noise_reduction.Get(&value));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000475}
476
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000477TEST_F(VideoSourceTest, MixedOptionsAndConstraints) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000478 FakeConstraints constraints;
479 constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 352);
480 constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 288);
481 constraints.AddOptional(MediaConstraintsInterface::kMaxFrameRate, 5);
482
483 constraints.AddMandatory(
484 MediaConstraintsInterface::kNoiseReduction, false);
485 constraints.AddOptional(
486 MediaConstraintsInterface::kNoiseReduction, true);
487
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000488 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000489 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
490 kMaxWaitMs);
491 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
492 ASSERT_TRUE(format != NULL);
493 EXPECT_EQ(352, format->width);
494 EXPECT_EQ(288, format->height);
495 EXPECT_EQ(5, format->framerate());
496
497 bool value = true;
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000498 EXPECT_TRUE(source_->options()->video_noise_reduction.Get(&value));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000499 EXPECT_FALSE(value);
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000500 EXPECT_FALSE(source_->options()->video_leaky_bucket.Get(&value));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000501}
502
503// Tests that the source starts video with the default resolution for
504// screencast if no constraint is set.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000505TEST_F(VideoSourceTest, ScreencastResolutionNoConstraint) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000506 capturer_->TestWithoutCameraFormats();
507 capturer_->SetScreencast(true);
508
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000509 CreateVideoSource();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000510 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
511 kMaxWaitMs);
512 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
513 ASSERT_TRUE(format != NULL);
514 EXPECT_EQ(640, format->width);
515 EXPECT_EQ(480, format->height);
516 EXPECT_EQ(30, format->framerate());
517}
518
519// Tests that the source starts video with the max width and height set by
520// constraints for screencast.
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000521TEST_F(VideoSourceTest, ScreencastResolutionWithConstraint) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000522 FakeConstraints constraints;
523 constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 480);
524 constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 270);
525
526 capturer_->TestWithoutCameraFormats();
527 capturer_->SetScreencast(true);
528
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000529 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000530 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
531 kMaxWaitMs);
532 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
533 ASSERT_TRUE(format != NULL);
534 EXPECT_EQ(480, format->width);
535 EXPECT_EQ(270, format->height);
536 EXPECT_EQ(30, format->framerate());
537}
538
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000539TEST_F(VideoSourceTest, MandatorySubOneFpsConstraints) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000540 FakeConstraints constraints;
541 constraints.AddMandatory(MediaConstraintsInterface::kMaxFrameRate, 0.5);
542
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000543 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000544 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
545 kMaxWaitMs);
546 ASSERT_TRUE(capturer_->GetCaptureFormat() == NULL);
547}
548
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000549TEST_F(VideoSourceTest, OptionalSubOneFpsConstraints) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000550 FakeConstraints constraints;
551 constraints.AddOptional(MediaConstraintsInterface::kMaxFrameRate, 0.5);
552
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000553 CreateVideoSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000554 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
555 kMaxWaitMs);
556 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
557 ASSERT_TRUE(format != NULL);
558 EXPECT_EQ(1, format->framerate());
559}
560