Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / renderer / media / media_stream_video_source_unittest.cc
blob28816f1641edff2a89bcd63bbd764a98a85e9a9f
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <string>
6 #include <vector>
8 #include "base/bind.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "content/child/child_process.h"
14 #include "content/renderer/media/media_stream_video_source.h"
15 #include "content/renderer/media/media_stream_video_track.h"
16 #include "content/renderer/media/mock_media_constraint_factory.h"
17 #include "content/renderer/media/mock_media_stream_video_sink.h"
18 #include "content/renderer/media/mock_media_stream_video_source.h"
19 #include "media/base/video_frame.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 using ::testing::_;
23 using ::testing::DoAll;
24 using ::testing::SaveArg;
26 namespace content {
28 ACTION_P(RunClosure, closure) {
29 closure.Run();
32 class MediaStreamVideoSourceTest
33 : public ::testing::Test {
34 public:
35 MediaStreamVideoSourceTest()
36 : child_process_(new ChildProcess()),
37 number_of_successful_constraints_applied_(0),
38 number_of_failed_constraints_applied_(0),
39 result_(MEDIA_DEVICE_OK),
40 result_name_(""),
41 mock_source_(new MockMediaStreamVideoSource(true)) {
42 media::VideoCaptureFormats formats;
43 formats.push_back(media::VideoCaptureFormat(
44 gfx::Size(1280, 720), 30, media::PIXEL_FORMAT_I420));
45 formats.push_back(media::VideoCaptureFormat(
46 gfx::Size(640, 480), 30, media::PIXEL_FORMAT_I420));
47 formats.push_back(media::VideoCaptureFormat(
48 gfx::Size(352, 288), 30, media::PIXEL_FORMAT_I420));
49 formats.push_back(media::VideoCaptureFormat(
50 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420));
51 mock_source_->SetSupportedFormats(formats);
52 webkit_source_.initialize(base::UTF8ToUTF16("dummy_source_id"),
53 blink::WebMediaStreamSource::TypeVideo,
54 base::UTF8ToUTF16("dummy_source_name"));
55 webkit_source_.setExtraData(mock_source_);
58 protected:
59 // Create a track that's associated with |webkit_source_|.
60 blink::WebMediaStreamTrack CreateTrack(
61 const std::string& id,
62 const blink::WebMediaConstraints& constraints) {
63 bool enabled = true;
64 return MediaStreamVideoTrack::CreateVideoTrack(
65 mock_source_, constraints,
66 base::Bind(
67 &MediaStreamVideoSourceTest::OnConstraintsApplied,
68 base::Unretained(this)),
69 enabled);
72 blink::WebMediaStreamTrack CreateTrackAndStartSource(
73 const blink::WebMediaConstraints& constraints,
74 int expected_width,
75 int expected_height,
76 int expected_frame_rate) {
77 blink::WebMediaStreamTrack track = CreateTrack("123", constraints);
79 mock_source_->CompleteGetSupportedFormats();
80 const media::VideoCaptureParams& format = mock_source()->start_params();
81 EXPECT_EQ(expected_width, format.requested_format.frame_size.width());
82 EXPECT_EQ(expected_height, format.requested_format.frame_size.height());
83 EXPECT_EQ(expected_frame_rate, format.requested_format.frame_rate);
85 EXPECT_EQ(0, NumberOfSuccessConstraintsCallbacks());
86 mock_source_->StartMockedSource();
87 // Once the source has started successfully we expect that the
88 // ConstraintsCallback in MediaStreamSource::AddTrack completes.
89 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
90 return track;
93 int NumberOfSuccessConstraintsCallbacks() const {
94 return number_of_successful_constraints_applied_;
97 int NumberOfFailedConstraintsCallbacks() const {
98 return number_of_failed_constraints_applied_;
101 content::MediaStreamRequestResult error_type() const { return result_; }
102 blink::WebString error_name() const { return result_name_; }
104 MockMediaStreamVideoSource* mock_source() { return mock_source_; }
106 // Test that the source crops/scales to the requested width and
107 // height even though the camera delivers a larger frame.
108 void TestSourceCropFrame(int capture_width,
109 int capture_height,
110 const blink::WebMediaConstraints& constraints,
111 int expected_width,
112 int expected_height) {
113 // Expect the source to start capture with the supported resolution.
114 blink::WebMediaStreamTrack track =
115 CreateTrackAndStartSource(constraints, capture_width, capture_height,
116 30);
118 MockMediaStreamVideoSink sink;
119 MediaStreamVideoSink::AddToVideoTrack(
120 &sink, sink.GetDeliverFrameCB(), track);
121 DeliverVideoFrameAndWaitForRenderer(capture_width, capture_height, &sink);
122 EXPECT_EQ(1, sink.number_of_frames());
124 // Expect the delivered frame to be cropped.
125 EXPECT_EQ(expected_height, sink.frame_size().height());
126 EXPECT_EQ(expected_width, sink.frame_size().width());
127 MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
130 void DeliverVideoFrameAndWaitForRenderer(int width, int height,
131 MockMediaStreamVideoSink* sink) {
132 base::RunLoop run_loop;
133 base::Closure quit_closure = run_loop.QuitClosure();
134 EXPECT_CALL(*sink, OnVideoFrame()).WillOnce(
135 RunClosure(quit_closure));
136 scoped_refptr<media::VideoFrame> frame =
137 media::VideoFrame::CreateBlackFrame(gfx::Size(width, height));
138 mock_source()->DeliverVideoFrame(frame);
139 run_loop.Run();
142 void DeliverVideoFrameAndWaitForTwoRenderers(
143 int width,
144 int height,
145 MockMediaStreamVideoSink* sink1,
146 MockMediaStreamVideoSink* sink2) {
147 base::RunLoop run_loop;
148 base::Closure quit_closure = run_loop.QuitClosure();
149 EXPECT_CALL(*sink1, OnVideoFrame());
150 EXPECT_CALL(*sink2, OnVideoFrame()).WillOnce(
151 RunClosure(quit_closure));
152 scoped_refptr<media::VideoFrame> frame =
153 media::VideoFrame::CreateBlackFrame(gfx::Size(width, height));
154 mock_source()->DeliverVideoFrame(frame);
155 run_loop.Run();
158 void TestTwoTracksWithDifferentConstraints(
159 const blink::WebMediaConstraints& constraints1,
160 const blink::WebMediaConstraints& constraints2,
161 int capture_width,
162 int capture_height,
163 int expected_width1,
164 int expected_height1,
165 int expected_width2,
166 int expected_height2) {
167 blink::WebMediaStreamTrack track1 =
168 CreateTrackAndStartSource(constraints1, capture_width, capture_height,
169 MediaStreamVideoSource::kDefaultFrameRate);
171 blink::WebMediaStreamTrack track2 =
172 CreateTrack("dummy", constraints2);
174 MockMediaStreamVideoSink sink1;
175 MediaStreamVideoSink::AddToVideoTrack(&sink1, sink1.GetDeliverFrameCB(),
176 track1);
177 EXPECT_EQ(0, sink1.number_of_frames());
179 MockMediaStreamVideoSink sink2;
180 MediaStreamVideoSink::AddToVideoTrack(&sink2, sink2.GetDeliverFrameCB(),
181 track2);
182 EXPECT_EQ(0, sink2.number_of_frames());
184 DeliverVideoFrameAndWaitForTwoRenderers(capture_width,
185 capture_height,
186 &sink1,
187 &sink2);
189 EXPECT_EQ(1, sink1.number_of_frames());
190 EXPECT_EQ(expected_width1, sink1.frame_size().width());
191 EXPECT_EQ(expected_height1, sink1.frame_size().height());
193 EXPECT_EQ(1, sink2.number_of_frames());
194 EXPECT_EQ(expected_width2, sink2.frame_size().width());
195 EXPECT_EQ(expected_height2, sink2.frame_size().height());
197 MediaStreamVideoSink::RemoveFromVideoTrack(&sink1, track1);
198 MediaStreamVideoSink::RemoveFromVideoTrack(&sink2, track2);
201 void ReleaseTrackAndSourceOnAddTrackCallback(
202 const blink::WebMediaStreamTrack& track_to_release) {
203 track_to_release_ = track_to_release;
206 private:
207 void OnConstraintsApplied(MediaStreamSource* source,
208 MediaStreamRequestResult result,
209 const blink::WebString& result_name) {
210 ASSERT_EQ(source, webkit_source_.extraData());
212 if (result == MEDIA_DEVICE_OK) {
213 ++number_of_successful_constraints_applied_;
214 } else {
215 result_ = result;
216 result_name_ = result_name;
217 ++number_of_failed_constraints_applied_;
220 if (!track_to_release_.isNull()) {
221 mock_source_ = NULL;
222 webkit_source_.reset();
223 track_to_release_.reset();
226 base::MessageLoopForUI message_loop_;
227 scoped_ptr<ChildProcess> child_process_;
228 blink::WebMediaStreamTrack track_to_release_;
229 int number_of_successful_constraints_applied_;
230 int number_of_failed_constraints_applied_;
231 content::MediaStreamRequestResult result_;
232 blink::WebString result_name_;
233 blink::WebMediaStreamSource webkit_source_;
234 // |mock_source_| is owned by |webkit_source_|.
235 MockMediaStreamVideoSource* mock_source_;
238 TEST_F(MediaStreamVideoSourceTest, AddTrackAndStartSource) {
239 blink::WebMediaConstraints constraints;
240 constraints.initialize();
241 blink::WebMediaStreamTrack track = CreateTrack("123", constraints);
242 mock_source()->CompleteGetSupportedFormats();
243 mock_source()->StartMockedSource();
244 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
247 TEST_F(MediaStreamVideoSourceTest, AddTwoTracksBeforeSourceStarts) {
248 blink::WebMediaConstraints constraints;
249 constraints.initialize();
250 blink::WebMediaStreamTrack track1 = CreateTrack("123", constraints);
251 mock_source()->CompleteGetSupportedFormats();
252 blink::WebMediaStreamTrack track2 = CreateTrack("123", constraints);
253 EXPECT_EQ(0, NumberOfSuccessConstraintsCallbacks());
254 mock_source()->StartMockedSource();
255 EXPECT_EQ(2, NumberOfSuccessConstraintsCallbacks());
258 TEST_F(MediaStreamVideoSourceTest, AddTrackAfterSourceStarts) {
259 blink::WebMediaConstraints constraints;
260 constraints.initialize();
261 blink::WebMediaStreamTrack track1 = CreateTrack("123", constraints);
262 mock_source()->CompleteGetSupportedFormats();
263 mock_source()->StartMockedSource();
264 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
265 blink::WebMediaStreamTrack track2 = CreateTrack("123", constraints);
266 EXPECT_EQ(2, NumberOfSuccessConstraintsCallbacks());
269 TEST_F(MediaStreamVideoSourceTest, AddTrackAndFailToStartSource) {
270 blink::WebMediaConstraints constraints;
271 constraints.initialize();
272 blink::WebMediaStreamTrack track = CreateTrack("123", constraints);
273 mock_source()->CompleteGetSupportedFormats();
274 mock_source()->FailToStartMockedSource();
275 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
278 TEST_F(MediaStreamVideoSourceTest, AddTwoTracksBeforeGetSupportedFormats) {
279 blink::WebMediaConstraints constraints;
280 constraints.initialize();
281 blink::WebMediaStreamTrack track1 = CreateTrack("123", constraints);
282 blink::WebMediaStreamTrack track2 = CreateTrack("123", constraints);
283 mock_source()->CompleteGetSupportedFormats();
284 mock_source()->StartMockedSource();
285 EXPECT_EQ(2, NumberOfSuccessConstraintsCallbacks());
288 // Test that the capture output is CIF if we set max constraints to CIF.
289 // and the capture device support CIF.
290 TEST_F(MediaStreamVideoSourceTest, MandatoryConstraintCif5Fps) {
291 MockMediaConstraintFactory factory;
292 factory.AddMandatory(MediaStreamVideoSource::kMaxWidth, 352);
293 factory.AddMandatory(MediaStreamVideoSource::kMaxHeight, 288);
294 factory.AddMandatory(MediaStreamVideoSource::kMaxFrameRate, 5);
296 CreateTrackAndStartSource(factory.CreateWebMediaConstraints(), 352, 288, 5);
299 // Test that the capture output is 720P if the camera support it and the
300 // optional constraint is set to 720P.
301 TEST_F(MediaStreamVideoSourceTest, MandatoryMinVgaOptional720P) {
302 MockMediaConstraintFactory factory;
303 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 640);
304 factory.AddMandatory(MediaStreamVideoSource::kMinHeight, 480);
305 factory.AddOptional(MediaStreamVideoSource::kMinWidth, 1280);
306 factory.AddOptional(MediaStreamVideoSource::kMinAspectRatio,
307 1280.0 / 720);
309 CreateTrackAndStartSource(factory.CreateWebMediaConstraints(), 1280, 720, 30);
312 // Test that the capture output have aspect ratio 4:3 if a mandatory constraint
313 // require it even if an optional constraint request a higher resolution
314 // that don't have this aspect ratio.
315 TEST_F(MediaStreamVideoSourceTest, MandatoryAspectRatio4To3) {
316 MockMediaConstraintFactory factory;
317 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 640);
318 factory.AddMandatory(MediaStreamVideoSource::kMinHeight, 480);
319 factory.AddMandatory(MediaStreamVideoSource::kMaxAspectRatio,
320 640.0 / 480);
321 factory.AddOptional(MediaStreamVideoSource::kMinWidth, 1280);
323 TestSourceCropFrame(1280, 720,
324 factory.CreateWebMediaConstraints(), 960, 720);
327 // Test that AddTrack succeeds if the mandatory min aspect ratio it set to 2.
328 TEST_F(MediaStreamVideoSourceTest, MandatoryAspectRatio2) {
329 MockMediaConstraintFactory factory;
330 factory.AddMandatory(MediaStreamVideoSource::kMinAspectRatio, 2);
332 TestSourceCropFrame(MediaStreamVideoSource::kDefaultWidth,
333 MediaStreamVideoSource::kDefaultHeight,
334 factory.CreateWebMediaConstraints(), 640, 320);
337 TEST_F(MediaStreamVideoSourceTest, MinAspectRatioLargerThanMaxAspectRatio) {
338 MockMediaConstraintFactory factory;
339 factory.AddMandatory(MediaStreamVideoSource::kMinAspectRatio, 2);
340 factory.AddMandatory(MediaStreamVideoSource::kMaxAspectRatio, 1);
341 blink::WebMediaStreamTrack track = CreateTrack(
342 "123", factory.CreateWebMediaConstraints());
343 mock_source()->CompleteGetSupportedFormats();
344 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
347 TEST_F(MediaStreamVideoSourceTest, MaxAspectRatioZero) {
348 MockMediaConstraintFactory factory;
349 factory.AddOptional(MediaStreamVideoSource::kMaxAspectRatio, 0);
350 blink::WebMediaStreamTrack track = CreateTrack(
351 "123", factory.CreateWebMediaConstraints());
352 mock_source()->CompleteGetSupportedFormats();
353 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
356 TEST_F(MediaStreamVideoSourceTest, MinWidthLargerThanMaxWidth) {
357 MockMediaConstraintFactory factory;
358 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 640);
359 factory.AddMandatory(MediaStreamVideoSource::kMaxWidth, 320);
360 blink::WebMediaStreamTrack track = CreateTrack(
361 "123", factory.CreateWebMediaConstraints());
362 mock_source()->CompleteGetSupportedFormats();
363 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
366 TEST_F(MediaStreamVideoSourceTest, MinHeightLargerThanMaxHeight) {
367 MockMediaConstraintFactory factory;
368 factory.AddMandatory(MediaStreamVideoSource::kMinHeight, 480);
369 factory.AddMandatory(MediaStreamVideoSource::kMaxHeight, 360);
370 blink::WebMediaStreamTrack track = CreateTrack(
371 "123", factory.CreateWebMediaConstraints());
372 mock_source()->CompleteGetSupportedFormats();
373 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
376 TEST_F(MediaStreamVideoSourceTest, MinFrameRateLargerThanMaxFrameRate) {
377 MockMediaConstraintFactory factory;
378 factory.AddMandatory(MediaStreamVideoSource::kMinFrameRate, 25);
379 factory.AddMandatory(MediaStreamVideoSource::kMaxFrameRate, 15);
380 blink::WebMediaStreamTrack track = CreateTrack(
381 "123", factory.CreateWebMediaConstraints());
382 mock_source()->CompleteGetSupportedFormats();
383 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
386 // Test that its safe to release the last reference of a blink track and the
387 // source during the callback if adding a track succeeds.
388 TEST_F(MediaStreamVideoSourceTest, ReleaseTrackAndSourceOnSuccessCallBack) {
389 MockMediaConstraintFactory factory;
391 blink::WebMediaStreamTrack track =
392 CreateTrack("123", factory.CreateWebMediaConstraints());
393 ReleaseTrackAndSourceOnAddTrackCallback(track);
395 mock_source()->CompleteGetSupportedFormats();
396 mock_source()->StartMockedSource();
397 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
400 // Test that its safe to release the last reference of a blink track and the
401 // source during the callback if adding a track fails.
402 TEST_F(MediaStreamVideoSourceTest, ReleaseTrackAndSourceOnFailureCallBack) {
403 MockMediaConstraintFactory factory;
404 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 99999);
406 blink::WebMediaStreamTrack track =
407 CreateTrack("123", factory.CreateWebMediaConstraints());
408 ReleaseTrackAndSourceOnAddTrackCallback(track);
410 mock_source()->CompleteGetSupportedFormats();
411 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
414 // Test that the source ignores an optional aspect ratio that is higher than
415 // supported.
416 TEST_F(MediaStreamVideoSourceTest, OptionalAspectRatioTooHigh) {
417 MockMediaConstraintFactory factory;
418 factory.AddOptional(MediaStreamVideoSource::kMinAspectRatio, 2);
419 blink::WebMediaStreamTrack track = CreateTrack(
420 "123", factory.CreateWebMediaConstraints());
421 mock_source()->CompleteGetSupportedFormats();
423 const media::VideoCaptureParams& params = mock_source()->start_params();
424 double aspect_ratio =
425 static_cast<double>(params.requested_format.frame_size.width()) /
426 params.requested_format.frame_size.height();
427 EXPECT_LT(aspect_ratio, 2);
430 // Test that the source starts video with the default resolution if the
431 // that is the only supported.
432 TEST_F(MediaStreamVideoSourceTest, DefaultCapability) {
433 media::VideoCaptureFormats formats;
434 formats.push_back(media::VideoCaptureFormat(
435 gfx::Size(MediaStreamVideoSource::kDefaultWidth,
436 MediaStreamVideoSource::kDefaultHeight),
437 MediaStreamVideoSource::kDefaultFrameRate,
438 media::PIXEL_FORMAT_I420));
439 mock_source()->SetSupportedFormats(formats);
441 blink::WebMediaConstraints constraints;
442 constraints.initialize();
443 CreateTrackAndStartSource(constraints,
444 MediaStreamVideoSource::kDefaultWidth,
445 MediaStreamVideoSource::kDefaultHeight,
446 30);
449 TEST_F(MediaStreamVideoSourceTest, InvalidMandatoryConstraint) {
450 MockMediaConstraintFactory factory;
451 factory.AddMandatory("weird key", 640);
452 blink::WebMediaStreamTrack track = CreateTrack(
453 "123", factory.CreateWebMediaConstraints());
454 mock_source()->CompleteGetSupportedFormats();
455 EXPECT_EQ(MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, error_type());
456 EXPECT_EQ("weird key", error_name());
457 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
460 // Test that the source ignores an unknown optional constraint.
461 TEST_F(MediaStreamVideoSourceTest, InvalidOptionalConstraint) {
462 MockMediaConstraintFactory factory;
463 factory.AddOptional("weird key", 640);
465 CreateTrackAndStartSource(factory.CreateWebMediaConstraints(),
466 MediaStreamVideoSource::kDefaultWidth,
467 MediaStreamVideoSource::kDefaultHeight,
468 30);
471 // Tests that the source starts video with the max width and height set by
472 // constraints for screencast.
473 TEST_F(MediaStreamVideoSourceTest, ScreencastResolutionWithConstraint) {
474 media::VideoCaptureFormats formats;
475 formats.push_back(media::VideoCaptureFormat(
476 gfx::Size(480, 270), 30, media::PIXEL_FORMAT_I420));
477 mock_source()->SetSupportedFormats(formats);
478 MockMediaConstraintFactory factory;
479 factory.AddMandatory(MediaStreamVideoSource::kMaxWidth, 480);
480 factory.AddMandatory(MediaStreamVideoSource::kMaxHeight, 270);
482 blink::WebMediaStreamTrack track = CreateTrackAndStartSource(
483 factory.CreateWebMediaConstraints(), 480, 270, 30);
484 EXPECT_EQ(480, mock_source()->max_requested_height());
485 EXPECT_EQ(270, mock_source()->max_requested_width());
488 // Test that optional constraints are applied in order.
489 TEST_F(MediaStreamVideoSourceTest, OptionalConstraints) {
490 MockMediaConstraintFactory factory;
491 // Min width of 2056 pixels can not be fulfilled.
492 factory.AddOptional(MediaStreamVideoSource::kMinWidth, 2056);
493 factory.AddOptional(MediaStreamVideoSource::kMinWidth, 641);
494 // Since min width is set to 641 pixels, max width 640 can not be fulfilled.
495 factory.AddOptional(MediaStreamVideoSource::kMaxWidth, 640);
496 CreateTrackAndStartSource(factory.CreateWebMediaConstraints(), 1280, 720, 30);
499 // Test that the source crops to the requested max width and
500 // height even though the camera delivers a larger frame.
501 TEST_F(MediaStreamVideoSourceTest, DeliverCroppedVideoFrameOptional640360) {
502 MockMediaConstraintFactory factory;
503 factory.AddOptional(MediaStreamVideoSource::kMaxWidth, 640);
504 factory.AddOptional(MediaStreamVideoSource::kMaxHeight, 360);
505 TestSourceCropFrame(640, 480, factory.CreateWebMediaConstraints(), 640, 360);
508 TEST_F(MediaStreamVideoSourceTest, DeliverCroppedVideoFrameMandatory640360) {
509 MockMediaConstraintFactory factory;
510 factory.AddMandatory(MediaStreamVideoSource::kMaxWidth, 640);
511 factory.AddMandatory(MediaStreamVideoSource::kMaxHeight, 360);
512 TestSourceCropFrame(640, 480, factory.CreateWebMediaConstraints(), 640, 360);
515 TEST_F(MediaStreamVideoSourceTest, DeliverCroppedVideoFrameMandatory732489) {
516 MockMediaConstraintFactory factory;
517 factory.AddMandatory(MediaStreamVideoSource::kMaxWidth, 732);
518 factory.AddMandatory(MediaStreamVideoSource::kMaxHeight, 489);
519 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 732);
520 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 489);
521 TestSourceCropFrame(1280, 720, factory.CreateWebMediaConstraints(), 732, 489);
524 // Test that the source crops to the requested max width and
525 // height even though the requested frame has odd size.
526 TEST_F(MediaStreamVideoSourceTest, DeliverCroppedVideoFrame637359) {
527 MockMediaConstraintFactory factory;
528 factory.AddOptional(MediaStreamVideoSource::kMaxWidth, 637);
529 factory.AddOptional(MediaStreamVideoSource::kMaxHeight, 359);
530 TestSourceCropFrame(640, 480, factory.CreateWebMediaConstraints(), 637, 359);
533 TEST_F(MediaStreamVideoSourceTest, DeliverCroppedVideoFrame320320) {
534 MockMediaConstraintFactory factory;
535 factory.AddMandatory(MediaStreamVideoSource::kMaxWidth, 320);
536 factory.AddMandatory(MediaStreamVideoSource::kMaxHeight, 320);
537 factory.AddMandatory(MediaStreamVideoSource::kMinHeight, 320);
538 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 320);
539 TestSourceCropFrame(640, 480, factory.CreateWebMediaConstraints(), 320, 320);
542 TEST_F(MediaStreamVideoSourceTest, DeliverSmallerSizeWhenTooLargeMax) {
543 MockMediaConstraintFactory factory;
544 factory.AddOptional(MediaStreamVideoSource::kMaxWidth, 1920);
545 factory.AddOptional(MediaStreamVideoSource::kMaxHeight, 1080);
546 factory.AddOptional(MediaStreamVideoSource::kMinWidth, 1280);
547 factory.AddOptional(MediaStreamVideoSource::kMinHeight, 720);
548 TestSourceCropFrame(1280, 720, factory.CreateWebMediaConstraints(),
549 1280, 720);
552 TEST_F(MediaStreamVideoSourceTest, TwoTracksWithVGAAndWVGA) {
553 MockMediaConstraintFactory factory1;
554 factory1.AddOptional(MediaStreamVideoSource::kMaxWidth, 640);
555 factory1.AddOptional(MediaStreamVideoSource::kMaxHeight, 480);
557 MockMediaConstraintFactory factory2;
558 factory2.AddOptional(MediaStreamVideoSource::kMaxHeight, 360);
560 TestTwoTracksWithDifferentConstraints(factory1.CreateWebMediaConstraints(),
561 factory2.CreateWebMediaConstraints(),
562 640, 480,
563 640, 480,
564 640, 360);
567 TEST_F(MediaStreamVideoSourceTest, TwoTracksWith720AndWVGA) {
568 MockMediaConstraintFactory factory1;
569 factory1.AddOptional(MediaStreamVideoSource::kMinWidth, 1280);
570 factory1.AddOptional(MediaStreamVideoSource::kMinHeight, 720);
573 MockMediaConstraintFactory factory2;
574 factory2.AddMandatory(MediaStreamVideoSource::kMaxWidth, 640);
575 factory2.AddMandatory(MediaStreamVideoSource::kMaxHeight, 360);
577 TestTwoTracksWithDifferentConstraints(factory1.CreateWebMediaConstraints(),
578 factory2.CreateWebMediaConstraints(),
579 1280, 720,
580 1280, 720,
581 640, 360);
584 TEST_F(MediaStreamVideoSourceTest, TwoTracksWith720AndW700H700) {
585 MockMediaConstraintFactory factory1;
586 factory1.AddOptional(MediaStreamVideoSource::kMinWidth, 1280);
587 factory1.AddOptional(MediaStreamVideoSource::kMinHeight, 720);
589 MockMediaConstraintFactory factory2;
590 factory2.AddMandatory(MediaStreamVideoSource::kMaxWidth, 700);
591 factory2.AddMandatory(MediaStreamVideoSource::kMaxHeight, 700);
593 TestTwoTracksWithDifferentConstraints(factory1.CreateWebMediaConstraints(),
594 factory2.CreateWebMediaConstraints(),
595 1280, 720,
596 1280, 720,
597 700, 700);
600 TEST_F(MediaStreamVideoSourceTest, TwoTracksWith720AndMaxAspectRatio4To3) {
601 MockMediaConstraintFactory factory1;
602 factory1.AddOptional(MediaStreamVideoSource::kMinWidth, 1280);
603 factory1.AddOptional(MediaStreamVideoSource::kMinHeight, 720);
605 MockMediaConstraintFactory factory2;
606 factory2.AddMandatory(MediaStreamVideoSource::kMaxAspectRatio, 640.0 / 480);
608 TestTwoTracksWithDifferentConstraints(factory1.CreateWebMediaConstraints(),
609 factory2.CreateWebMediaConstraints(),
610 1280, 720,
611 1280, 720,
612 960, 720);
615 TEST_F(MediaStreamVideoSourceTest, TwoTracksWithVgaAndMinAspectRatio) {
616 MockMediaConstraintFactory factory1;
617 factory1.AddOptional(MediaStreamVideoSource::kMaxWidth, 640);
618 factory1.AddOptional(MediaStreamVideoSource::kMaxHeight, 480);
620 MockMediaConstraintFactory factory2;
621 factory2.AddMandatory(MediaStreamVideoSource::kMinAspectRatio, 640.0 / 360);
623 TestTwoTracksWithDifferentConstraints(factory1.CreateWebMediaConstraints(),
624 factory2.CreateWebMediaConstraints(),
625 640, 480,
626 640, 480,
627 640, 360);
630 TEST_F(MediaStreamVideoSourceTest,
631 TwoTracksWithSecondTrackFrameRateHigherThanFirst) {
632 MockMediaConstraintFactory factory1;
633 factory1.AddMandatory(MediaStreamVideoSource::kMinFrameRate, 15);
634 factory1.AddMandatory(MediaStreamVideoSource::kMaxFrameRate, 15);
636 blink::WebMediaStreamTrack track1 =
637 CreateTrackAndStartSource(factory1.CreateWebMediaConstraints(),
638 MediaStreamVideoSource::kDefaultWidth,
639 MediaStreamVideoSource::kDefaultHeight,
640 15);
642 MockMediaConstraintFactory factory2;
643 factory2.AddMandatory(MediaStreamVideoSource::kMinFrameRate, 30);
644 blink::WebMediaStreamTrack track2 = CreateTrack(
645 "123", factory2.CreateWebMediaConstraints());
646 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
649 // Test that a source can change the frame resolution on the fly and that
650 // tracks sinks get the new frame size unless constraints force the frame to be
651 // cropped.
652 TEST_F(MediaStreamVideoSourceTest, SourceChangeFrameSize) {
653 MockMediaConstraintFactory factory;
654 factory.AddOptional(MediaStreamVideoSource::kMaxWidth, 800);
655 factory.AddOptional(MediaStreamVideoSource::kMaxHeight, 700);
657 // Expect the source to start capture with the supported resolution.
658 blink::WebMediaStreamTrack track =
659 CreateTrackAndStartSource(factory.CreateWebMediaConstraints(),
660 640, 480, 30);
662 MockMediaStreamVideoSink sink;
663 MediaStreamVideoSink::AddToVideoTrack(
664 &sink, sink.GetDeliverFrameCB(), track);
665 EXPECT_EQ(0, sink.number_of_frames());
666 DeliverVideoFrameAndWaitForRenderer(320, 240, &sink);
667 EXPECT_EQ(1, sink.number_of_frames());
668 // Expect the delivered frame to be passed unchanged since its smaller than
669 // max requested.
670 EXPECT_EQ(320, sink.frame_size().width());
671 EXPECT_EQ(240, sink.frame_size().height());
673 DeliverVideoFrameAndWaitForRenderer(640, 480, &sink);
674 EXPECT_EQ(2, sink.number_of_frames());
675 // Expect the delivered frame to be passed unchanged since its smaller than
676 // max requested.
677 EXPECT_EQ(640, sink.frame_size().width());
678 EXPECT_EQ(480, sink.frame_size().height());
680 DeliverVideoFrameAndWaitForRenderer(1280, 720, &sink);
682 EXPECT_EQ(3, sink.number_of_frames());
683 // Expect a frame to be cropped since its larger than max requested.
684 EXPECT_EQ(800, sink.frame_size().width());
685 EXPECT_EQ(700, sink.frame_size().height());
687 MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
690 TEST_F(MediaStreamVideoSourceTest, IsConstraintSupported) {
691 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
692 MediaStreamVideoSource::kMaxFrameRate));
693 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
694 MediaStreamVideoSource::kMinFrameRate));
695 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
696 MediaStreamVideoSource::kMaxWidth));
697 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
698 MediaStreamVideoSource::kMinWidth));
699 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
700 MediaStreamVideoSource::kMaxHeight));
701 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
702 MediaStreamVideoSource::kMinHeight));
703 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
704 MediaStreamVideoSource::kMaxAspectRatio));
705 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
706 MediaStreamVideoSource::kMinAspectRatio));
708 EXPECT_FALSE(MediaStreamVideoSource::IsConstraintSupported(
709 "something unsupported"));
712 // Test that the constraint negotiation can handle 0.0 fps as frame rate.
713 TEST_F(MediaStreamVideoSourceTest, Use0FpsSupportedFormat) {
714 media::VideoCaptureFormats formats;
715 formats.push_back(media::VideoCaptureFormat(
716 gfx::Size(640, 480), 0.0f, media::PIXEL_FORMAT_I420));
717 formats.push_back(media::VideoCaptureFormat(
718 gfx::Size(320, 240), 0.0f, media::PIXEL_FORMAT_I420));
719 mock_source()->SetSupportedFormats(formats);
721 blink::WebMediaConstraints constraints;
722 constraints.initialize();
723 blink::WebMediaStreamTrack track = CreateTrack("123", constraints);
724 mock_source()->CompleteGetSupportedFormats();
725 mock_source()->StartMockedSource();
726 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
728 MockMediaStreamVideoSink sink;
729 MediaStreamVideoSink::AddToVideoTrack(
730 &sink, sink.GetDeliverFrameCB(), track);
731 EXPECT_EQ(0, sink.number_of_frames());
732 DeliverVideoFrameAndWaitForRenderer(320, 240, &sink);
733 EXPECT_EQ(1, sink.number_of_frames());
734 // Expect the delivered frame to be passed unchanged since its smaller than
735 // max requested.
736 EXPECT_EQ(320, sink.frame_size().width());
737 EXPECT_EQ(240, sink.frame_size().height());
738 MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
741 // Test that a source producing no frames calls back the MSVCS to tell so, and
742 // this in turn tells the Track attached. Then start passing frames, and check
743 // that in a reasonable time frame the muted state turns to false.
744 TEST_F(MediaStreamVideoSourceTest, MutedSource) {
745 MockMediaConstraintFactory factory;
746 blink::WebMediaStreamTrack track =
747 CreateTrackAndStartSource(factory.CreateWebMediaConstraints(),
748 640, 480, 30);
750 MockMediaStreamVideoSink sink;
751 MediaStreamVideoSink::AddToVideoTrack(&sink, sink.GetDeliverFrameCB(), track);
752 EXPECT_EQ(MediaStreamTrack::GetTrack(track)->GetMutedState(), false);
754 base::RunLoop run_loop;
755 base::Closure quit_closure = run_loop.QuitClosure();
756 bool muted_state = false;
757 EXPECT_CALL(*mock_source(), DoSetMutedState(_))
758 .WillOnce(DoAll(SaveArg<0>(&muted_state), RunClosure(quit_closure)));
759 run_loop.Run();
760 EXPECT_EQ(muted_state, true);
761 // TODO(mcasas): When added, check |track|'s (WebMediaStreamTrack) Muted
762 // attribute, should be true. In the meantime, check the MediaStreamTrack's.
763 EXPECT_EQ(MediaStreamTrack::GetTrack(track)->GetMutedState(), true);
765 EXPECT_CALL(*mock_source(), DoSetMutedState(_))
766 .WillOnce(DoAll(SaveArg<0>(&muted_state), RunClosure(quit_closure)));
767 // Mock frame delivery happens asynchronously, not according to the configured
768 // frame rate, potentially many frames can pass before the muted state is
769 // flipped. |kMaxFrameCount| is used as a reasonable high bound of this value.
770 const int kMaxFrameCount = 10000;
771 int i = 0;
772 while (muted_state != false || ++i > kMaxFrameCount)
773 DeliverVideoFrameAndWaitForRenderer(640, 480, &sink);
774 EXPECT_EQ(muted_state, false);
775 EXPECT_LT(i, kMaxFrameCount);
776 EXPECT_EQ(MediaStreamTrack::GetTrack(track)->GetMutedState(), false);
778 MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
781 // Test that a source producing no frames calls back the MSVCS to tell so, and
782 // this in turn tells all the Tracks attached.
783 TEST_F(MediaStreamVideoSourceTest, MutedSourceWithTwoTracks) {
784 MockMediaConstraintFactory factory1;
785 blink::WebMediaStreamTrack track1 =
786 CreateTrackAndStartSource(factory1.CreateWebMediaConstraints(),
787 MediaStreamVideoSource::kDefaultWidth,
788 MediaStreamVideoSource::kDefaultHeight,
789 30);
791 MockMediaConstraintFactory factory2;
792 factory2.AddMandatory(MediaStreamVideoSource::kMaxFrameRate, 15);
793 blink::WebMediaStreamTrack track2 = CreateTrack(
794 "123", factory2.CreateWebMediaConstraints());
795 EXPECT_EQ(0, NumberOfFailedConstraintsCallbacks());
797 MockMediaStreamVideoSink sink1;
798 MediaStreamVideoSink::AddToVideoTrack(&sink1, sink1.GetDeliverFrameCB(),
799 track1);
800 EXPECT_EQ(MediaStreamTrack::GetTrack(track1)->GetMutedState(), false);
802 MockMediaStreamVideoSink sink2;
803 MediaStreamVideoSink::AddToVideoTrack(&sink2, sink2.GetDeliverFrameCB(),
804 track2);
805 EXPECT_EQ(MediaStreamTrack::GetTrack(track2)->GetMutedState(), false);
807 base::RunLoop run_loop;
808 base::Closure quit_closure = run_loop.QuitClosure();
809 bool muted_state = false;
810 EXPECT_CALL(*mock_source(), DoSetMutedState(_))
811 .WillOnce(DoAll(SaveArg<0>(&muted_state), RunClosure(quit_closure)));
812 run_loop.Run();
813 EXPECT_EQ(muted_state, true);
815 // TODO(mcasas): When added, check |track|'s (WebMediaStreamTrack) Muted
816 // attribute, should be true. In the meantime, check the MediaStreamTrack's.
817 EXPECT_EQ(MediaStreamTrack::GetTrack(track1)->GetMutedState(), true);
818 EXPECT_EQ(MediaStreamTrack::GetTrack(track2)->GetMutedState(), true);
820 MediaStreamVideoSink::RemoveFromVideoTrack(&sink1, track1);
821 MediaStreamVideoSink::RemoveFromVideoTrack(&sink2, track2);
824 } // namespace content