1 /*
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
28 #include <string>
29 #include <vector>
30
31 #include "talk/app/webrtc/remotevideocapturer.h"
32 #include "talk/app/webrtc/test/fakeconstraints.h"
33 #include "talk/app/webrtc/videosource.h"
34 #include "talk/media/base/fakemediaengine.h"
35 #include "talk/media/base/fakevideocapturer.h"
36 #include "talk/media/base/fakevideorenderer.h"
37 #include "talk/media/webrtc/webrtcvideoframe.h"
38 #include "talk/session/media/channelmanager.h"
39 #include "webrtc/base/gunit.h"
40
41 using webrtc::FakeConstraints;
42 using webrtc::VideoSource;
43 using webrtc::MediaConstraintsInterface;
44 using webrtc::MediaSourceInterface;
45 using webrtc::ObserverInterface;
46 using webrtc::VideoSourceInterface;
47
48 namespace {
49
50 // Max wait time for a test.
51 const 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.
60 class TestVideoCapturer : public cricket::FakeVideoCapturer {
61 public:
TestVideoCapturer()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.
TestWithoutCameraFormats()81 void TestWithoutCameraFormats() {
82 test_without_formats_ = true;
83 std::vector<cricket::VideoFormat> formats;
84 ResetSupportedFormats(formats);
85 }
86
Start(const cricket::VideoFormat & capture_format)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
GetBestCaptureFormat(const cricket::VideoFormat & desired,cricket::VideoFormat * best_format)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
111 class StateObserver : public ObserverInterface {
112 public:
StateObserver(VideoSourceInterface * source)113 explicit StateObserver(VideoSourceInterface* source)
114 : state_(source->state()),
115 source_(source) {
116 }
OnChanged()117 virtual void OnChanged() {
118 state_ = source_->state();
119 }
state() const120 MediaSourceInterface::SourceState state() const { return state_; }
121
122 private:
123 MediaSourceInterface::SourceState state_;
124 rtc::scoped_refptr<VideoSourceInterface> source_;
125 };
126
127 class VideoSourceTest : public testing::Test {
128 protected:
VideoSourceTest()129 VideoSourceTest()
130 : capturer_cleanup_(new TestVideoCapturer()),
131 capturer_(capturer_cleanup_.get()),
132 channel_manager_(new cricket::ChannelManager(
133 new cricket::FakeMediaEngine(), rtc::Thread::Current())) {
134 }
135
SetUp()136 void SetUp() {
137 ASSERT_TRUE(channel_manager_->Init());
138 }
139
CreateVideoSource()140 void CreateVideoSource() {
141 CreateVideoSource(NULL);
142 }
143
CreateVideoSource(const webrtc::MediaConstraintsInterface * constraints)144 void CreateVideoSource(
145 const webrtc::MediaConstraintsInterface* constraints) {
146 // VideoSource take ownership of |capturer_|
147 source_ =
148 VideoSource::Create(channel_manager_.get(), capturer_cleanup_.release(),
149 constraints, false);
150
151 ASSERT_TRUE(source_.get() != NULL);
152 EXPECT_EQ(capturer_, source_->GetVideoCapturer());
153
154 state_observer_.reset(new StateObserver(source_));
155 source_->RegisterObserver(state_observer_.get());
156 source_->AddSink(&renderer_);
157 }
158
159 rtc::scoped_ptr<TestVideoCapturer> capturer_cleanup_;
160 TestVideoCapturer* capturer_;
161 cricket::FakeVideoRenderer renderer_;
162 rtc::scoped_ptr<cricket::ChannelManager> channel_manager_;
163 rtc::scoped_ptr<StateObserver> state_observer_;
164 rtc::scoped_refptr<VideoSource> source_;
165 };
166
167
168 // Test that a VideoSource transition to kLive state when the capture
169 // device have started and kEnded if it is stopped.
170 // It also test that an output can receive video frames.
TEST_F(VideoSourceTest,CapturerStartStop)171 TEST_F(VideoSourceTest, CapturerStartStop) {
172 // Initialize without constraints.
173 CreateVideoSource();
174 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
185 // Test that a VideoSource can be stopped and restarted.
TEST_F(VideoSourceTest,StopRestart)186 TEST_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
209 // Test start stop with a remote VideoSource - the video source that has a
210 // RemoteVideoCapturer and takes video frames from FrameInput.
TEST_F(VideoSourceTest,StartStopRemote)211 TEST_F(VideoSourceTest, StartStopRemote) {
212 source_ = VideoSource::Create(channel_manager_.get(),
213 new webrtc::RemoteVideoCapturer(), NULL, true);
214
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;
227 frameinput->SetSize(1280, 720, 0);
228 frameinput->RenderFrame(&test_frame);
229 EXPECT_EQ(1, renderer_.num_rendered_frames());
230
231 source_->GetVideoCapturer()->Stop();
232 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
233 kMaxWaitMs);
234 }
235
236 // Test that a VideoSource transition to kEnded if the capture device
237 // fails.
TEST_F(VideoSourceTest,CameraFailed)238 TEST_F(VideoSourceTest, CameraFailed) {
239 CreateVideoSource();
240 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
241 kMaxWaitMs);
242
243 capturer_->SignalStateChange(capturer_, cricket::CS_FAILED);
244 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
245 kMaxWaitMs);
246 }
247
248 // Test that the capture output is CIF if we set max constraints to CIF.
249 // and the capture device support CIF.
TEST_F(VideoSourceTest,MandatoryConstraintCif5Fps)250 TEST_F(VideoSourceTest, MandatoryConstraintCif5Fps) {
251 FakeConstraints constraints;
252 constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 352);
253 constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 288);
254 constraints.AddMandatory(MediaConstraintsInterface::kMaxFrameRate, 5);
255
256 CreateVideoSource(&constraints);
257 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
258 kMaxWaitMs);
259 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
260 ASSERT_TRUE(format != NULL);
261 EXPECT_EQ(352, format->width);
262 EXPECT_EQ(288, format->height);
263 EXPECT_EQ(30, format->framerate());
264 }
265
266 // Test that the capture output is 720P if the camera support it and the
267 // optional constraint is set to 720P.
TEST_F(VideoSourceTest,MandatoryMinVgaOptional720P)268 TEST_F(VideoSourceTest, MandatoryMinVgaOptional720P) {
269 FakeConstraints constraints;
270 constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
271 constraints.AddMandatory(MediaConstraintsInterface::kMinHeight, 480);
272 constraints.AddOptional(MediaConstraintsInterface::kMinWidth, 1280);
273 constraints.AddOptional(MediaConstraintsInterface::kMinAspectRatio,
274 1280.0 / 720);
275
276 CreateVideoSource(&constraints);
277 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(1280, format->width);
282 EXPECT_EQ(720, format->height);
283 EXPECT_EQ(30, format->framerate());
284 }
285
286 // Test that the capture output have aspect ratio 4:3 if a mandatory constraint
287 // require it even if an optional constraint request a higher resolution
288 // that don't have this aspect ratio.
TEST_F(VideoSourceTest,MandatoryAspectRatio4To3)289 TEST_F(VideoSourceTest, MandatoryAspectRatio4To3) {
290 FakeConstraints constraints;
291 constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
292 constraints.AddMandatory(MediaConstraintsInterface::kMinHeight, 480);
293 constraints.AddMandatory(MediaConstraintsInterface::kMaxAspectRatio,
294 640.0 / 480);
295 constraints.AddOptional(MediaConstraintsInterface::kMinWidth, 1280);
296
297 CreateVideoSource(&constraints);
298 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
299 kMaxWaitMs);
300 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
301 ASSERT_TRUE(format != NULL);
302 EXPECT_EQ(640, format->width);
303 EXPECT_EQ(480, format->height);
304 EXPECT_EQ(30, format->framerate());
305 }
306
307
308 // Test that the source state transition to kEnded if the mandatory aspect ratio
309 // is set higher than supported.
TEST_F(VideoSourceTest,MandatoryAspectRatioTooHigh)310 TEST_F(VideoSourceTest, MandatoryAspectRatioTooHigh) {
311 FakeConstraints constraints;
312 constraints.AddMandatory(MediaConstraintsInterface::kMinAspectRatio, 2);
313 CreateVideoSource(&constraints);
314 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
315 kMaxWaitMs);
316 }
317
318 // Test that the source ignores an optional aspect ratio that is higher than
319 // supported.
TEST_F(VideoSourceTest,OptionalAspectRatioTooHigh)320 TEST_F(VideoSourceTest, OptionalAspectRatioTooHigh) {
321 FakeConstraints constraints;
322 constraints.AddOptional(MediaConstraintsInterface::kMinAspectRatio, 2);
323 CreateVideoSource(&constraints);
324 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
325 kMaxWaitMs);
326 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
327 ASSERT_TRUE(format != NULL);
328 double aspect_ratio = static_cast<double>(format->width) / format->height;
329 EXPECT_LT(aspect_ratio, 2);
330 }
331
332 // Test that the source starts video with the default resolution if the
333 // camera doesn't support capability enumeration and there are no constraints.
TEST_F(VideoSourceTest,NoCameraCapability)334 TEST_F(VideoSourceTest, NoCameraCapability) {
335 capturer_->TestWithoutCameraFormats();
336
337 CreateVideoSource();
338 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
339 kMaxWaitMs);
340 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
341 ASSERT_TRUE(format != NULL);
342 EXPECT_EQ(640, format->width);
343 EXPECT_EQ(480, format->height);
344 EXPECT_EQ(30, format->framerate());
345 }
346
347 // Test that the source can start the video and get the requested aspect ratio
348 // if the camera doesn't support capability enumeration and the aspect ratio is
349 // set.
TEST_F(VideoSourceTest,NoCameraCapability16To9Ratio)350 TEST_F(VideoSourceTest, NoCameraCapability16To9Ratio) {
351 capturer_->TestWithoutCameraFormats();
352
353 FakeConstraints constraints;
354 double requested_aspect_ratio = 640.0 / 360;
355 constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
356 constraints.AddMandatory(MediaConstraintsInterface::kMinAspectRatio,
357 requested_aspect_ratio);
358
359 CreateVideoSource(&constraints);
360 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
361 kMaxWaitMs);
362 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
363 double aspect_ratio = static_cast<double>(format->width) / format->height;
364 EXPECT_LE(requested_aspect_ratio, aspect_ratio);
365 }
366
367 // Test that the source state transitions to kEnded if an unknown mandatory
368 // constraint is found.
TEST_F(VideoSourceTest,InvalidMandatoryConstraint)369 TEST_F(VideoSourceTest, InvalidMandatoryConstraint) {
370 FakeConstraints constraints;
371 constraints.AddMandatory("weird key", 640);
372
373 CreateVideoSource(&constraints);
374 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
375 kMaxWaitMs);
376 }
377
378 // Test that the source ignores an unknown optional constraint.
TEST_F(VideoSourceTest,InvalidOptionalConstraint)379 TEST_F(VideoSourceTest, InvalidOptionalConstraint) {
380 FakeConstraints constraints;
381 constraints.AddOptional("weird key", 640);
382
383 CreateVideoSource(&constraints);
384 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
385 kMaxWaitMs);
386 }
387
TEST_F(VideoSourceTest,SetValidOptionValues)388 TEST_F(VideoSourceTest, SetValidOptionValues) {
389 FakeConstraints constraints;
390 constraints.AddMandatory(MediaConstraintsInterface::kNoiseReduction, "false");
391
392 CreateVideoSource(&constraints);
393
394 EXPECT_EQ(rtc::Optional<bool>(false),
395 source_->options()->video_noise_reduction);
396 }
397
TEST_F(VideoSourceTest,OptionNotSet)398 TEST_F(VideoSourceTest, OptionNotSet) {
399 FakeConstraints constraints;
400 CreateVideoSource(&constraints);
401 EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction);
402 }
403
TEST_F(VideoSourceTest,MandatoryOptionOverridesOptional)404 TEST_F(VideoSourceTest, MandatoryOptionOverridesOptional) {
405 FakeConstraints constraints;
406 constraints.AddMandatory(
407 MediaConstraintsInterface::kNoiseReduction, true);
408 constraints.AddOptional(
409 MediaConstraintsInterface::kNoiseReduction, false);
410
411 CreateVideoSource(&constraints);
412
413 EXPECT_EQ(rtc::Optional<bool>(true),
414 source_->options()->video_noise_reduction);
415 }
416
TEST_F(VideoSourceTest,InvalidOptionKeyOptional)417 TEST_F(VideoSourceTest, InvalidOptionKeyOptional) {
418 FakeConstraints constraints;
419 constraints.AddOptional(
420 MediaConstraintsInterface::kNoiseReduction, false);
421 constraints.AddOptional("invalidKey", false);
422
423 CreateVideoSource(&constraints);
424
425 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
426 kMaxWaitMs);
427 EXPECT_EQ(rtc::Optional<bool>(false),
428 source_->options()->video_noise_reduction);
429 }
430
TEST_F(VideoSourceTest,InvalidOptionKeyMandatory)431 TEST_F(VideoSourceTest, InvalidOptionKeyMandatory) {
432 FakeConstraints constraints;
433 constraints.AddMandatory(
434 MediaConstraintsInterface::kNoiseReduction, false);
435 constraints.AddMandatory("invalidKey", false);
436
437 CreateVideoSource(&constraints);
438
439 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
440 kMaxWaitMs);
441 EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction);
442 }
443
TEST_F(VideoSourceTest,InvalidOptionValueOptional)444 TEST_F(VideoSourceTest, InvalidOptionValueOptional) {
445 FakeConstraints constraints;
446 constraints.AddOptional(
447 MediaConstraintsInterface::kNoiseReduction, "not a boolean");
448
449 CreateVideoSource(&constraints);
450
451 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
452 kMaxWaitMs);
453 EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction);
454 }
455
TEST_F(VideoSourceTest,InvalidOptionValueMandatory)456 TEST_F(VideoSourceTest, InvalidOptionValueMandatory) {
457 FakeConstraints constraints;
458 // Optional constraints should be ignored if the mandatory constraints fail.
459 constraints.AddOptional(
460 MediaConstraintsInterface::kNoiseReduction, "false");
461 // Values are case-sensitive and must be all lower-case.
462 constraints.AddMandatory(
463 MediaConstraintsInterface::kNoiseReduction, "True");
464
465 CreateVideoSource(&constraints);
466
467 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
468 kMaxWaitMs);
469 EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction);
470 }
471
TEST_F(VideoSourceTest,MixedOptionsAndConstraints)472 TEST_F(VideoSourceTest, MixedOptionsAndConstraints) {
473 FakeConstraints constraints;
474 constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 352);
475 constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 288);
476 constraints.AddOptional(MediaConstraintsInterface::kMaxFrameRate, 5);
477
478 constraints.AddMandatory(
479 MediaConstraintsInterface::kNoiseReduction, false);
480 constraints.AddOptional(
481 MediaConstraintsInterface::kNoiseReduction, true);
482
483 CreateVideoSource(&constraints);
484 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
485 kMaxWaitMs);
486 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
487 ASSERT_TRUE(format != NULL);
488 EXPECT_EQ(352, format->width);
489 EXPECT_EQ(288, format->height);
490 EXPECT_EQ(30, format->framerate());
491
492 EXPECT_EQ(rtc::Optional<bool>(false),
493 source_->options()->video_noise_reduction);
494 }
495
496 // Tests that the source starts video with the default resolution for
497 // screencast if no constraint is set.
TEST_F(VideoSourceTest,ScreencastResolutionNoConstraint)498 TEST_F(VideoSourceTest, ScreencastResolutionNoConstraint) {
499 capturer_->TestWithoutCameraFormats();
500 capturer_->SetScreencast(true);
501
502 CreateVideoSource();
503 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
504 kMaxWaitMs);
505 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
506 ASSERT_TRUE(format != NULL);
507 EXPECT_EQ(640, format->width);
508 EXPECT_EQ(480, format->height);
509 EXPECT_EQ(30, format->framerate());
510 }
511
512 // Tests that the source starts video with the max width and height set by
513 // constraints for screencast.
TEST_F(VideoSourceTest,ScreencastResolutionWithConstraint)514 TEST_F(VideoSourceTest, ScreencastResolutionWithConstraint) {
515 FakeConstraints constraints;
516 constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 480);
517 constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 270);
518
519 capturer_->TestWithoutCameraFormats();
520 capturer_->SetScreencast(true);
521
522 CreateVideoSource(&constraints);
523 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
524 kMaxWaitMs);
525 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
526 ASSERT_TRUE(format != NULL);
527 EXPECT_EQ(480, format->width);
528 EXPECT_EQ(270, format->height);
529 EXPECT_EQ(30, format->framerate());
530 }
531
TEST_F(VideoSourceTest,MandatorySubOneFpsConstraints)532 TEST_F(VideoSourceTest, MandatorySubOneFpsConstraints) {
533 FakeConstraints constraints;
534 constraints.AddMandatory(MediaConstraintsInterface::kMaxFrameRate, 0.5);
535
536 CreateVideoSource(&constraints);
537 EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
538 kMaxWaitMs);
539 ASSERT_TRUE(capturer_->GetCaptureFormat() == NULL);
540 }
541
TEST_F(VideoSourceTest,OptionalSubOneFpsConstraints)542 TEST_F(VideoSourceTest, OptionalSubOneFpsConstraints) {
543 FakeConstraints constraints;
544 constraints.AddOptional(MediaConstraintsInterface::kMaxFrameRate, 0.5);
545
546 CreateVideoSource(&constraints);
547 EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
548 kMaxWaitMs);
549 const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
550 ASSERT_TRUE(format != NULL);
551 EXPECT_EQ(30, format->framerate());
552 }
553
554