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.
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"
21 #include "third_party/WebKit/public/web/WebHeap.h"
24 using ::testing::DoAll
;
25 using ::testing::SaveArg
;
29 ACTION_P(RunClosure
, closure
) {
33 class MediaStreamVideoSourceTest
34 : public ::testing::Test
{
36 MediaStreamVideoSourceTest()
37 : child_process_(new ChildProcess()),
38 number_of_successful_constraints_applied_(0),
39 number_of_failed_constraints_applied_(0),
40 result_(MEDIA_DEVICE_OK
),
42 mock_source_(new MockMediaStreamVideoSource(true)) {
43 media::VideoCaptureFormats formats
;
44 formats
.push_back(media::VideoCaptureFormat(
45 gfx::Size(1280, 720), 30, media::VIDEO_CAPTURE_PIXEL_FORMAT_I420
));
46 formats
.push_back(media::VideoCaptureFormat(
47 gfx::Size(640, 480), 30, media::VIDEO_CAPTURE_PIXEL_FORMAT_I420
));
48 formats
.push_back(media::VideoCaptureFormat(
49 gfx::Size(352, 288), 30, media::VIDEO_CAPTURE_PIXEL_FORMAT_I420
));
50 formats
.push_back(media::VideoCaptureFormat(
51 gfx::Size(320, 240), 30, media::VIDEO_CAPTURE_PIXEL_FORMAT_I420
));
52 mock_source_
->SetSupportedFormats(formats
);
53 webkit_source_
.initialize(base::UTF8ToUTF16("dummy_source_id"),
54 blink::WebMediaStreamSource::TypeVideo
,
55 base::UTF8ToUTF16("dummy_source_name"),
56 false /* remote */, true /* readonly */);
57 webkit_source_
.setExtraData(mock_source_
);
60 void TearDown() override
{
61 webkit_source_
.reset();
62 blink::WebHeap::collectAllGarbageForTesting();
66 // Create a track that's associated with |webkit_source_|.
67 blink::WebMediaStreamTrack
CreateTrack(
68 const std::string
& id
,
69 const blink::WebMediaConstraints
& constraints
) {
71 return MediaStreamVideoTrack::CreateVideoTrack(
72 mock_source_
, constraints
,
74 &MediaStreamVideoSourceTest::OnConstraintsApplied
,
75 base::Unretained(this)),
79 blink::WebMediaStreamTrack
CreateTrackAndStartSource(
80 const blink::WebMediaConstraints
& constraints
,
83 int expected_frame_rate
) {
84 blink::WebMediaStreamTrack track
= CreateTrack("123", constraints
);
86 mock_source_
->CompleteGetSupportedFormats();
87 const media::VideoCaptureFormat
& format
= mock_source()->start_format();
88 EXPECT_EQ(expected_width
, format
.frame_size
.width());
89 EXPECT_EQ(expected_height
, format
.frame_size
.height());
90 EXPECT_EQ(expected_frame_rate
, format
.frame_rate
);
92 EXPECT_EQ(0, NumberOfSuccessConstraintsCallbacks());
93 mock_source_
->StartMockedSource();
94 // Once the source has started successfully we expect that the
95 // ConstraintsCallback in MediaStreamSource::AddTrack completes.
96 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
100 int NumberOfSuccessConstraintsCallbacks() const {
101 return number_of_successful_constraints_applied_
;
104 int NumberOfFailedConstraintsCallbacks() const {
105 return number_of_failed_constraints_applied_
;
108 content::MediaStreamRequestResult
error_type() const { return result_
; }
109 blink::WebString
error_name() const { return result_name_
; }
111 MockMediaStreamVideoSource
* mock_source() { return mock_source_
; }
113 // Test that the source crops/scales to the requested width and
114 // height even though the camera delivers a larger frame.
115 void TestSourceCropFrame(int capture_width
,
117 const blink::WebMediaConstraints
& constraints
,
119 int expected_height
) {
120 // Expect the source to start capture with the supported resolution.
121 blink::WebMediaStreamTrack track
=
122 CreateTrackAndStartSource(constraints
, capture_width
, capture_height
,
125 MockMediaStreamVideoSink sink
;
126 MediaStreamVideoSink::AddToVideoTrack(
127 &sink
, sink
.GetDeliverFrameCB(), track
);
128 DeliverVideoFrameAndWaitForRenderer(capture_width
, capture_height
, &sink
);
129 EXPECT_EQ(1, sink
.number_of_frames());
131 // Expect the delivered frame to be cropped.
132 EXPECT_EQ(expected_height
, sink
.frame_size().height());
133 EXPECT_EQ(expected_width
, sink
.frame_size().width());
134 MediaStreamVideoSink::RemoveFromVideoTrack(&sink
, track
);
137 void DeliverVideoFrameAndWaitForRenderer(int width
, int height
,
138 MockMediaStreamVideoSink
* sink
) {
139 base::RunLoop run_loop
;
140 base::Closure quit_closure
= run_loop
.QuitClosure();
141 EXPECT_CALL(*sink
, OnVideoFrame()).WillOnce(
142 RunClosure(quit_closure
));
143 scoped_refptr
<media::VideoFrame
> frame
=
144 media::VideoFrame::CreateBlackFrame(gfx::Size(width
, height
));
145 mock_source()->DeliverVideoFrame(frame
);
149 void DeliverVideoFrameAndWaitForTwoRenderers(
152 MockMediaStreamVideoSink
* sink1
,
153 MockMediaStreamVideoSink
* sink2
) {
154 base::RunLoop run_loop
;
155 base::Closure quit_closure
= run_loop
.QuitClosure();
156 EXPECT_CALL(*sink1
, OnVideoFrame());
157 EXPECT_CALL(*sink2
, OnVideoFrame()).WillOnce(
158 RunClosure(quit_closure
));
159 scoped_refptr
<media::VideoFrame
> frame
=
160 media::VideoFrame::CreateBlackFrame(gfx::Size(width
, height
));
161 mock_source()->DeliverVideoFrame(frame
);
165 void TestTwoTracksWithDifferentConstraints(
166 const blink::WebMediaConstraints
& constraints1
,
167 const blink::WebMediaConstraints
& constraints2
,
171 int expected_height1
,
173 int expected_height2
) {
174 blink::WebMediaStreamTrack track1
=
175 CreateTrackAndStartSource(constraints1
, capture_width
, capture_height
,
176 MediaStreamVideoSource::kDefaultFrameRate
);
178 blink::WebMediaStreamTrack track2
=
179 CreateTrack("dummy", constraints2
);
181 MockMediaStreamVideoSink sink1
;
182 MediaStreamVideoSink::AddToVideoTrack(&sink1
, sink1
.GetDeliverFrameCB(),
184 EXPECT_EQ(0, sink1
.number_of_frames());
186 MockMediaStreamVideoSink sink2
;
187 MediaStreamVideoSink::AddToVideoTrack(&sink2
, sink2
.GetDeliverFrameCB(),
189 EXPECT_EQ(0, sink2
.number_of_frames());
191 DeliverVideoFrameAndWaitForTwoRenderers(capture_width
,
196 EXPECT_EQ(1, sink1
.number_of_frames());
197 EXPECT_EQ(expected_width1
, sink1
.frame_size().width());
198 EXPECT_EQ(expected_height1
, sink1
.frame_size().height());
200 EXPECT_EQ(1, sink2
.number_of_frames());
201 EXPECT_EQ(expected_width2
, sink2
.frame_size().width());
202 EXPECT_EQ(expected_height2
, sink2
.frame_size().height());
204 MediaStreamVideoSink::RemoveFromVideoTrack(&sink1
, track1
);
205 MediaStreamVideoSink::RemoveFromVideoTrack(&sink2
, track2
);
208 void SetSourceSupportedFormats(const media::VideoCaptureFormats
& formats
) {
209 mock_source_
->SetSupportedFormats(formats
);
212 void ReleaseTrackAndSourceOnAddTrackCallback(
213 const blink::WebMediaStreamTrack
& track_to_release
) {
214 track_to_release_
= track_to_release
;
218 void OnConstraintsApplied(MediaStreamSource
* source
,
219 MediaStreamRequestResult result
,
220 const blink::WebString
& result_name
) {
221 ASSERT_EQ(source
, webkit_source_
.extraData());
223 if (result
== MEDIA_DEVICE_OK
) {
224 ++number_of_successful_constraints_applied_
;
227 result_name_
= result_name
;
228 ++number_of_failed_constraints_applied_
;
231 if (!track_to_release_
.isNull()) {
233 webkit_source_
.reset();
234 track_to_release_
.reset();
237 base::MessageLoopForUI message_loop_
;
238 scoped_ptr
<ChildProcess
> child_process_
;
239 blink::WebMediaStreamTrack track_to_release_
;
240 int number_of_successful_constraints_applied_
;
241 int number_of_failed_constraints_applied_
;
242 content::MediaStreamRequestResult result_
;
243 blink::WebString result_name_
;
244 blink::WebMediaStreamSource webkit_source_
;
245 // |mock_source_| is owned by |webkit_source_|.
246 MockMediaStreamVideoSource
* mock_source_
;
249 TEST_F(MediaStreamVideoSourceTest
, AddTrackAndStartSource
) {
250 blink::WebMediaConstraints constraints
;
251 constraints
.initialize();
252 blink::WebMediaStreamTrack track
= CreateTrack("123", constraints
);
253 mock_source()->CompleteGetSupportedFormats();
254 mock_source()->StartMockedSource();
255 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
258 TEST_F(MediaStreamVideoSourceTest
, AddTwoTracksBeforeSourceStarts
) {
259 blink::WebMediaConstraints constraints
;
260 constraints
.initialize();
261 blink::WebMediaStreamTrack track1
= CreateTrack("123", constraints
);
262 mock_source()->CompleteGetSupportedFormats();
263 blink::WebMediaStreamTrack track2
= CreateTrack("123", constraints
);
264 EXPECT_EQ(0, NumberOfSuccessConstraintsCallbacks());
265 mock_source()->StartMockedSource();
266 EXPECT_EQ(2, NumberOfSuccessConstraintsCallbacks());
269 TEST_F(MediaStreamVideoSourceTest
, AddTrackAfterSourceStarts
) {
270 blink::WebMediaConstraints constraints
;
271 constraints
.initialize();
272 blink::WebMediaStreamTrack track1
= CreateTrack("123", constraints
);
273 mock_source()->CompleteGetSupportedFormats();
274 mock_source()->StartMockedSource();
275 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
276 blink::WebMediaStreamTrack track2
= CreateTrack("123", constraints
);
277 EXPECT_EQ(2, NumberOfSuccessConstraintsCallbacks());
280 TEST_F(MediaStreamVideoSourceTest
, AddTrackAndFailToStartSource
) {
281 blink::WebMediaConstraints constraints
;
282 constraints
.initialize();
283 blink::WebMediaStreamTrack track
= CreateTrack("123", constraints
);
284 mock_source()->CompleteGetSupportedFormats();
285 mock_source()->FailToStartMockedSource();
286 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
289 TEST_F(MediaStreamVideoSourceTest
, AddTwoTracksBeforeGetSupportedFormats
) {
290 blink::WebMediaConstraints constraints
;
291 constraints
.initialize();
292 blink::WebMediaStreamTrack track1
= CreateTrack("123", constraints
);
293 blink::WebMediaStreamTrack track2
= CreateTrack("123", constraints
);
294 mock_source()->CompleteGetSupportedFormats();
295 mock_source()->StartMockedSource();
296 EXPECT_EQ(2, NumberOfSuccessConstraintsCallbacks());
299 // Test that the capture output is CIF if we set max constraints to CIF.
300 // and the capture device support CIF.
301 TEST_F(MediaStreamVideoSourceTest
, MandatoryConstraintCif5Fps
) {
302 MockMediaConstraintFactory factory
;
303 factory
.AddMandatory(MediaStreamVideoSource::kMaxWidth
, 352);
304 factory
.AddMandatory(MediaStreamVideoSource::kMaxHeight
, 288);
305 factory
.AddMandatory(MediaStreamVideoSource::kMaxFrameRate
, 5);
307 CreateTrackAndStartSource(factory
.CreateWebMediaConstraints(), 352, 288, 5);
310 // Test that the capture output is 720P if the camera support it and the
311 // optional constraint is set to 720P.
312 TEST_F(MediaStreamVideoSourceTest
, MandatoryMinVgaOptional720P
) {
313 MockMediaConstraintFactory factory
;
314 factory
.AddMandatory(MediaStreamVideoSource::kMinWidth
, 640);
315 factory
.AddMandatory(MediaStreamVideoSource::kMinHeight
, 480);
316 factory
.AddOptional(MediaStreamVideoSource::kMinWidth
, 1280);
317 factory
.AddOptional(MediaStreamVideoSource::kMinAspectRatio
,
320 CreateTrackAndStartSource(factory
.CreateWebMediaConstraints(), 1280, 720, 30);
323 // Test that the capture output have aspect ratio 4:3 if a mandatory constraint
324 // require it even if an optional constraint request a higher resolution
325 // that don't have this aspect ratio.
326 TEST_F(MediaStreamVideoSourceTest
, MandatoryAspectRatio4To3
) {
327 MockMediaConstraintFactory factory
;
328 factory
.AddMandatory(MediaStreamVideoSource::kMinWidth
, 640);
329 factory
.AddMandatory(MediaStreamVideoSource::kMinHeight
, 480);
330 factory
.AddMandatory(MediaStreamVideoSource::kMaxAspectRatio
,
332 factory
.AddOptional(MediaStreamVideoSource::kMinWidth
, 1280);
334 TestSourceCropFrame(1280, 720,
335 factory
.CreateWebMediaConstraints(), 960, 720);
338 // Test that AddTrack succeeds if the mandatory min aspect ratio it set to 2.
339 TEST_F(MediaStreamVideoSourceTest
, MandatoryAspectRatio2
) {
340 MockMediaConstraintFactory factory
;
341 factory
.AddMandatory(MediaStreamVideoSource::kMinAspectRatio
, 2);
343 TestSourceCropFrame(MediaStreamVideoSource::kDefaultWidth
,
344 MediaStreamVideoSource::kDefaultHeight
,
345 factory
.CreateWebMediaConstraints(), 640, 320);
348 TEST_F(MediaStreamVideoSourceTest
, MinAspectRatioLargerThanMaxAspectRatio
) {
349 MockMediaConstraintFactory factory
;
350 factory
.AddMandatory(MediaStreamVideoSource::kMinAspectRatio
, 2);
351 factory
.AddMandatory(MediaStreamVideoSource::kMaxAspectRatio
, 1);
352 blink::WebMediaStreamTrack track
= CreateTrack(
353 "123", factory
.CreateWebMediaConstraints());
354 mock_source()->CompleteGetSupportedFormats();
355 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
358 TEST_F(MediaStreamVideoSourceTest
, MaxAspectRatioZero
) {
359 MockMediaConstraintFactory factory
;
360 factory
.AddOptional(MediaStreamVideoSource::kMaxAspectRatio
, 0);
361 blink::WebMediaStreamTrack track
= CreateTrack(
362 "123", factory
.CreateWebMediaConstraints());
363 mock_source()->CompleteGetSupportedFormats();
364 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
367 TEST_F(MediaStreamVideoSourceTest
, MinWidthLargerThanMaxWidth
) {
368 MockMediaConstraintFactory factory
;
369 factory
.AddMandatory(MediaStreamVideoSource::kMinWidth
, 640);
370 factory
.AddMandatory(MediaStreamVideoSource::kMaxWidth
, 320);
371 blink::WebMediaStreamTrack track
= CreateTrack(
372 "123", factory
.CreateWebMediaConstraints());
373 mock_source()->CompleteGetSupportedFormats();
374 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
377 TEST_F(MediaStreamVideoSourceTest
, MinHeightLargerThanMaxHeight
) {
378 MockMediaConstraintFactory factory
;
379 factory
.AddMandatory(MediaStreamVideoSource::kMinHeight
, 480);
380 factory
.AddMandatory(MediaStreamVideoSource::kMaxHeight
, 360);
381 blink::WebMediaStreamTrack track
= CreateTrack(
382 "123", factory
.CreateWebMediaConstraints());
383 mock_source()->CompleteGetSupportedFormats();
384 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
387 TEST_F(MediaStreamVideoSourceTest
, MinFrameRateLargerThanMaxFrameRate
) {
388 MockMediaConstraintFactory factory
;
389 factory
.AddMandatory(MediaStreamVideoSource::kMinFrameRate
, 25);
390 factory
.AddMandatory(MediaStreamVideoSource::kMaxFrameRate
, 15);
391 blink::WebMediaStreamTrack track
= CreateTrack(
392 "123", factory
.CreateWebMediaConstraints());
393 mock_source()->CompleteGetSupportedFormats();
394 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
397 // Test that its safe to release the last reference of a blink track and the
398 // source during the callback if adding a track succeeds.
399 TEST_F(MediaStreamVideoSourceTest
, ReleaseTrackAndSourceOnSuccessCallBack
) {
400 MockMediaConstraintFactory factory
;
402 blink::WebMediaStreamTrack track
=
403 CreateTrack("123", factory
.CreateWebMediaConstraints());
404 ReleaseTrackAndSourceOnAddTrackCallback(track
);
406 mock_source()->CompleteGetSupportedFormats();
407 mock_source()->StartMockedSource();
408 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
411 // Test that its safe to release the last reference of a blink track and the
412 // source during the callback if adding a track fails.
413 TEST_F(MediaStreamVideoSourceTest
, ReleaseTrackAndSourceOnFailureCallBack
) {
414 MockMediaConstraintFactory factory
;
415 factory
.AddMandatory(MediaStreamVideoSource::kMinWidth
, 99999);
417 blink::WebMediaStreamTrack track
=
418 CreateTrack("123", factory
.CreateWebMediaConstraints());
419 ReleaseTrackAndSourceOnAddTrackCallback(track
);
421 mock_source()->CompleteGetSupportedFormats();
422 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
425 // Test that the source ignores an optional aspect ratio that is higher than
427 TEST_F(MediaStreamVideoSourceTest
, OptionalAspectRatioTooHigh
) {
428 MockMediaConstraintFactory factory
;
429 factory
.AddOptional(MediaStreamVideoSource::kMinAspectRatio
, 2);
430 blink::WebMediaStreamTrack track
= CreateTrack(
431 "123", factory
.CreateWebMediaConstraints());
432 mock_source()->CompleteGetSupportedFormats();
434 const media::VideoCaptureFormat
& format
= mock_source()->start_format();
435 double aspect_ratio
=
436 static_cast<double>(format
.frame_size
.width()) /
437 format
.frame_size
.height();
438 EXPECT_LT(aspect_ratio
, 2);
441 // Test that the source starts video with the default resolution if the
442 // that is the only supported.
443 TEST_F(MediaStreamVideoSourceTest
, DefaultCapability
) {
444 media::VideoCaptureFormats formats
;
445 formats
.push_back(media::VideoCaptureFormat(
446 gfx::Size(MediaStreamVideoSource::kDefaultWidth
,
447 MediaStreamVideoSource::kDefaultHeight
),
448 MediaStreamVideoSource::kDefaultFrameRate
,
449 media::VIDEO_CAPTURE_PIXEL_FORMAT_I420
));
450 mock_source()->SetSupportedFormats(formats
);
452 blink::WebMediaConstraints constraints
;
453 constraints
.initialize();
454 CreateTrackAndStartSource(constraints
,
455 MediaStreamVideoSource::kDefaultWidth
,
456 MediaStreamVideoSource::kDefaultHeight
,
460 TEST_F(MediaStreamVideoSourceTest
, InvalidMandatoryConstraint
) {
461 MockMediaConstraintFactory factory
;
462 factory
.AddMandatory("weird key", 640);
463 blink::WebMediaStreamTrack track
= CreateTrack(
464 "123", factory
.CreateWebMediaConstraints());
465 mock_source()->CompleteGetSupportedFormats();
466 EXPECT_EQ(MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED
, error_type());
467 EXPECT_EQ("weird key", error_name());
468 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
471 // Test that the source ignores an unknown optional constraint.
472 TEST_F(MediaStreamVideoSourceTest
, InvalidOptionalConstraint
) {
473 MockMediaConstraintFactory factory
;
474 factory
.AddOptional("weird key", 640);
476 CreateTrackAndStartSource(factory
.CreateWebMediaConstraints(),
477 MediaStreamVideoSource::kDefaultWidth
,
478 MediaStreamVideoSource::kDefaultHeight
,
482 // Tests that the source starts video with the max width and height set by
483 // constraints for screencast.
484 TEST_F(MediaStreamVideoSourceTest
, ScreencastResolutionWithConstraint
) {
485 media::VideoCaptureFormats formats
;
486 formats
.push_back(media::VideoCaptureFormat(
487 gfx::Size(480, 270), 30, media::VIDEO_CAPTURE_PIXEL_FORMAT_I420
));
488 mock_source()->SetSupportedFormats(formats
);
489 MockMediaConstraintFactory factory
;
490 factory
.AddMandatory(MediaStreamVideoSource::kMaxWidth
, 480);
491 factory
.AddMandatory(MediaStreamVideoSource::kMaxHeight
, 270);
493 blink::WebMediaStreamTrack track
= CreateTrackAndStartSource(
494 factory
.CreateWebMediaConstraints(), 480, 270, 30);
495 EXPECT_EQ(480, mock_source()->max_requested_height());
496 EXPECT_EQ(270, mock_source()->max_requested_width());
499 // Test that optional constraints are applied in order.
500 TEST_F(MediaStreamVideoSourceTest
, OptionalConstraints
) {
501 MockMediaConstraintFactory factory
;
502 // Min width of 2056 pixels can not be fulfilled.
503 factory
.AddOptional(MediaStreamVideoSource::kMinWidth
, 2056);
504 factory
.AddOptional(MediaStreamVideoSource::kMinWidth
, 641);
505 // Since min width is set to 641 pixels, max width 640 can not be fulfilled.
506 factory
.AddOptional(MediaStreamVideoSource::kMaxWidth
, 640);
507 CreateTrackAndStartSource(factory
.CreateWebMediaConstraints(), 1280, 720, 30);
510 // Test that the source crops to the requested max width and
511 // height even though the camera delivers a larger frame.
512 TEST_F(MediaStreamVideoSourceTest
, DeliverCroppedVideoFrameOptional640360
) {
513 MockMediaConstraintFactory factory
;
514 factory
.AddOptional(MediaStreamVideoSource::kMaxWidth
, 640);
515 factory
.AddOptional(MediaStreamVideoSource::kMaxHeight
, 360);
516 TestSourceCropFrame(640, 480, factory
.CreateWebMediaConstraints(), 640, 360);
519 TEST_F(MediaStreamVideoSourceTest
, DeliverCroppedVideoFrameMandatory640360
) {
520 MockMediaConstraintFactory factory
;
521 factory
.AddMandatory(MediaStreamVideoSource::kMaxWidth
, 640);
522 factory
.AddMandatory(MediaStreamVideoSource::kMaxHeight
, 360);
523 TestSourceCropFrame(640, 480, factory
.CreateWebMediaConstraints(), 640, 360);
526 TEST_F(MediaStreamVideoSourceTest
, DeliverCroppedVideoFrameMandatory732489
) {
527 MockMediaConstraintFactory factory
;
528 factory
.AddMandatory(MediaStreamVideoSource::kMaxWidth
, 732);
529 factory
.AddMandatory(MediaStreamVideoSource::kMaxHeight
, 489);
530 factory
.AddMandatory(MediaStreamVideoSource::kMinWidth
, 732);
531 factory
.AddMandatory(MediaStreamVideoSource::kMinWidth
, 489);
532 TestSourceCropFrame(1280, 720, factory
.CreateWebMediaConstraints(), 732, 489);
535 // Test that the source crops to the requested max width and
536 // height even though the requested frame has odd size.
537 TEST_F(MediaStreamVideoSourceTest
, DeliverCroppedVideoFrame637359
) {
538 MockMediaConstraintFactory factory
;
539 factory
.AddOptional(MediaStreamVideoSource::kMaxWidth
, 637);
540 factory
.AddOptional(MediaStreamVideoSource::kMaxHeight
, 359);
541 TestSourceCropFrame(640, 480, factory
.CreateWebMediaConstraints(), 637, 359);
544 TEST_F(MediaStreamVideoSourceTest
, DeliverCroppedVideoFrame320320
) {
545 MockMediaConstraintFactory factory
;
546 factory
.AddMandatory(MediaStreamVideoSource::kMaxWidth
, 320);
547 factory
.AddMandatory(MediaStreamVideoSource::kMaxHeight
, 320);
548 factory
.AddMandatory(MediaStreamVideoSource::kMinHeight
, 320);
549 factory
.AddMandatory(MediaStreamVideoSource::kMinWidth
, 320);
550 TestSourceCropFrame(640, 480, factory
.CreateWebMediaConstraints(), 320, 320);
553 TEST_F(MediaStreamVideoSourceTest
, DeliverSmallerSizeWhenTooLargeMax
) {
554 MockMediaConstraintFactory factory
;
555 factory
.AddOptional(MediaStreamVideoSource::kMaxWidth
, 1920);
556 factory
.AddOptional(MediaStreamVideoSource::kMaxHeight
, 1080);
557 factory
.AddOptional(MediaStreamVideoSource::kMinWidth
, 1280);
558 factory
.AddOptional(MediaStreamVideoSource::kMinHeight
, 720);
559 TestSourceCropFrame(1280, 720, factory
.CreateWebMediaConstraints(),
563 TEST_F(MediaStreamVideoSourceTest
, TwoTracksWithVGAAndWVGA
) {
564 MockMediaConstraintFactory factory1
;
565 factory1
.AddOptional(MediaStreamVideoSource::kMaxWidth
, 640);
566 factory1
.AddOptional(MediaStreamVideoSource::kMaxHeight
, 480);
568 MockMediaConstraintFactory factory2
;
569 factory2
.AddOptional(MediaStreamVideoSource::kMaxHeight
, 360);
571 TestTwoTracksWithDifferentConstraints(factory1
.CreateWebMediaConstraints(),
572 factory2
.CreateWebMediaConstraints(),
578 TEST_F(MediaStreamVideoSourceTest
, TwoTracksWith720AndWVGA
) {
579 MockMediaConstraintFactory factory1
;
580 factory1
.AddOptional(MediaStreamVideoSource::kMinWidth
, 1280);
581 factory1
.AddOptional(MediaStreamVideoSource::kMinHeight
, 720);
584 MockMediaConstraintFactory factory2
;
585 factory2
.AddMandatory(MediaStreamVideoSource::kMaxWidth
, 640);
586 factory2
.AddMandatory(MediaStreamVideoSource::kMaxHeight
, 360);
588 TestTwoTracksWithDifferentConstraints(factory1
.CreateWebMediaConstraints(),
589 factory2
.CreateWebMediaConstraints(),
595 TEST_F(MediaStreamVideoSourceTest
, TwoTracksWith720AndW700H700
) {
596 MockMediaConstraintFactory factory1
;
597 factory1
.AddOptional(MediaStreamVideoSource::kMinWidth
, 1280);
598 factory1
.AddOptional(MediaStreamVideoSource::kMinHeight
, 720);
600 MockMediaConstraintFactory factory2
;
601 factory2
.AddMandatory(MediaStreamVideoSource::kMaxWidth
, 700);
602 factory2
.AddMandatory(MediaStreamVideoSource::kMaxHeight
, 700);
604 TestTwoTracksWithDifferentConstraints(factory1
.CreateWebMediaConstraints(),
605 factory2
.CreateWebMediaConstraints(),
611 TEST_F(MediaStreamVideoSourceTest
, TwoTracksWith720AndMaxAspectRatio4To3
) {
612 MockMediaConstraintFactory factory1
;
613 factory1
.AddOptional(MediaStreamVideoSource::kMinWidth
, 1280);
614 factory1
.AddOptional(MediaStreamVideoSource::kMinHeight
, 720);
616 MockMediaConstraintFactory factory2
;
617 factory2
.AddMandatory(MediaStreamVideoSource::kMaxAspectRatio
, 640.0 / 480);
619 TestTwoTracksWithDifferentConstraints(factory1
.CreateWebMediaConstraints(),
620 factory2
.CreateWebMediaConstraints(),
626 TEST_F(MediaStreamVideoSourceTest
, TwoTracksWithVgaAndMinAspectRatio
) {
627 MockMediaConstraintFactory factory1
;
628 factory1
.AddOptional(MediaStreamVideoSource::kMaxWidth
, 640);
629 factory1
.AddOptional(MediaStreamVideoSource::kMaxHeight
, 480);
631 MockMediaConstraintFactory factory2
;
632 factory2
.AddMandatory(MediaStreamVideoSource::kMinAspectRatio
, 640.0 / 360);
634 TestTwoTracksWithDifferentConstraints(factory1
.CreateWebMediaConstraints(),
635 factory2
.CreateWebMediaConstraints(),
641 TEST_F(MediaStreamVideoSourceTest
,
642 TwoTracksWithSecondTrackFrameRateHigherThanFirst
) {
643 MockMediaConstraintFactory factory1
;
644 factory1
.AddMandatory(MediaStreamVideoSource::kMinFrameRate
, 15);
645 factory1
.AddMandatory(MediaStreamVideoSource::kMaxFrameRate
, 15);
647 blink::WebMediaStreamTrack track1
=
648 CreateTrackAndStartSource(factory1
.CreateWebMediaConstraints(),
649 MediaStreamVideoSource::kDefaultWidth
,
650 MediaStreamVideoSource::kDefaultHeight
,
653 MockMediaConstraintFactory factory2
;
654 factory2
.AddMandatory(MediaStreamVideoSource::kMinFrameRate
, 30);
655 blink::WebMediaStreamTrack track2
= CreateTrack(
656 "123", factory2
.CreateWebMediaConstraints());
657 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
660 // Test that a source can change the frame resolution on the fly and that
661 // tracks sinks get the new frame size unless constraints force the frame to be
663 TEST_F(MediaStreamVideoSourceTest
, SourceChangeFrameSize
) {
664 MockMediaConstraintFactory factory
;
665 factory
.AddOptional(MediaStreamVideoSource::kMaxWidth
, 800);
666 factory
.AddOptional(MediaStreamVideoSource::kMaxHeight
, 700);
668 // Expect the source to start capture with the supported resolution.
669 blink::WebMediaStreamTrack track
=
670 CreateTrackAndStartSource(factory
.CreateWebMediaConstraints(),
673 MockMediaStreamVideoSink sink
;
674 MediaStreamVideoSink::AddToVideoTrack(
675 &sink
, sink
.GetDeliverFrameCB(), track
);
676 EXPECT_EQ(0, sink
.number_of_frames());
677 DeliverVideoFrameAndWaitForRenderer(320, 240, &sink
);
678 EXPECT_EQ(1, sink
.number_of_frames());
679 // Expect the delivered frame to be passed unchanged since its smaller than
681 EXPECT_EQ(320, sink
.frame_size().width());
682 EXPECT_EQ(240, sink
.frame_size().height());
684 DeliverVideoFrameAndWaitForRenderer(640, 480, &sink
);
685 EXPECT_EQ(2, sink
.number_of_frames());
686 // Expect the delivered frame to be passed unchanged since its smaller than
688 EXPECT_EQ(640, sink
.frame_size().width());
689 EXPECT_EQ(480, sink
.frame_size().height());
691 DeliverVideoFrameAndWaitForRenderer(1280, 720, &sink
);
693 EXPECT_EQ(3, sink
.number_of_frames());
694 // Expect a frame to be cropped since its larger than max requested.
695 EXPECT_EQ(800, sink
.frame_size().width());
696 EXPECT_EQ(700, sink
.frame_size().height());
698 MediaStreamVideoSink::RemoveFromVideoTrack(&sink
, track
);
701 TEST_F(MediaStreamVideoSourceTest
, IsConstraintSupported
) {
702 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
703 MediaStreamVideoSource::kMaxFrameRate
));
704 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
705 MediaStreamVideoSource::kMinFrameRate
));
706 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
707 MediaStreamVideoSource::kMaxWidth
));
708 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
709 MediaStreamVideoSource::kMinWidth
));
710 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
711 MediaStreamVideoSource::kMaxHeight
));
712 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
713 MediaStreamVideoSource::kMinHeight
));
714 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
715 MediaStreamVideoSource::kMaxAspectRatio
));
716 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
717 MediaStreamVideoSource::kMinAspectRatio
));
719 EXPECT_FALSE(MediaStreamVideoSource::IsConstraintSupported(
720 "something unsupported"));
723 // Test that the constraint negotiation can handle 0.0 fps as frame rate.
724 TEST_F(MediaStreamVideoSourceTest
, Use0FpsSupportedFormat
) {
725 media::VideoCaptureFormats formats
;
726 formats
.push_back(media::VideoCaptureFormat(
727 gfx::Size(640, 480), 0.0f
, media::VIDEO_CAPTURE_PIXEL_FORMAT_I420
));
728 formats
.push_back(media::VideoCaptureFormat(
729 gfx::Size(320, 240), 0.0f
, media::VIDEO_CAPTURE_PIXEL_FORMAT_I420
));
730 mock_source()->SetSupportedFormats(formats
);
732 blink::WebMediaConstraints constraints
;
733 constraints
.initialize();
734 blink::WebMediaStreamTrack track
= CreateTrack("123", constraints
);
735 mock_source()->CompleteGetSupportedFormats();
736 mock_source()->StartMockedSource();
737 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
739 MockMediaStreamVideoSink sink
;
740 MediaStreamVideoSink::AddToVideoTrack(
741 &sink
, sink
.GetDeliverFrameCB(), track
);
742 EXPECT_EQ(0, sink
.number_of_frames());
743 DeliverVideoFrameAndWaitForRenderer(320, 240, &sink
);
744 EXPECT_EQ(1, sink
.number_of_frames());
745 // Expect the delivered frame to be passed unchanged since its smaller than
747 EXPECT_EQ(320, sink
.frame_size().width());
748 EXPECT_EQ(240, sink
.frame_size().height());
749 MediaStreamVideoSink::RemoveFromVideoTrack(&sink
, track
);
752 // Test that a source producing no frames change the source readyState to muted.
753 // that in a reasonable time frame the muted state turns to false.
754 TEST_F(MediaStreamVideoSourceTest
, MutedSource
) {
755 // Setup the source for support a frame rate of 2000fps in order to test
756 // the muted event faster. This is since the frame monitoring uses
757 // PostDelayedTask that is dependent on the source frame rate.
758 media::VideoCaptureFormats formats
;
759 formats
.push_back(media::VideoCaptureFormat(
760 gfx::Size(640, 480), 2000, media::VIDEO_CAPTURE_PIXEL_FORMAT_I420
));
761 SetSourceSupportedFormats(formats
);
763 MockMediaConstraintFactory factory
;
764 blink::WebMediaStreamTrack track
=
765 CreateTrackAndStartSource(factory
.CreateWebMediaConstraints(),
767 MockMediaStreamVideoSink sink
;
768 MediaStreamVideoSink::AddToVideoTrack(&sink
, sink
.GetDeliverFrameCB(), track
);
769 EXPECT_EQ(track
.source().readyState(),
770 blink::WebMediaStreamSource::ReadyStateLive
);
772 base::RunLoop run_loop
;
773 base::Closure quit_closure
= run_loop
.QuitClosure();
774 bool muted_state
= false;
775 EXPECT_CALL(*mock_source(), DoSetMutedState(_
))
776 .WillOnce(DoAll(SaveArg
<0>(&muted_state
), RunClosure(quit_closure
)));
778 EXPECT_EQ(muted_state
, true);
780 EXPECT_EQ(track
.source().readyState(),
781 blink::WebMediaStreamSource::ReadyStateMuted
);
783 base::RunLoop run_loop2
;
784 base::Closure quit_closure2
= run_loop2
.QuitClosure();
785 EXPECT_CALL(*mock_source(), DoSetMutedState(_
))
786 .WillOnce(DoAll(SaveArg
<0>(&muted_state
), RunClosure(quit_closure2
)));
787 DeliverVideoFrameAndWaitForRenderer(640, 480, &sink
);
790 EXPECT_EQ(muted_state
, false);
791 EXPECT_EQ(track
.source().readyState(),
792 blink::WebMediaStreamSource::ReadyStateLive
);
794 MediaStreamVideoSink::RemoveFromVideoTrack(&sink
, track
);
797 } // namespace content