Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / content / renderer / media / media_stream_video_source_unittest.cc
blobf454bed8abb28f45596d330fe132d087c0b39e74
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"
21 #include "third_party/WebKit/public/web/WebHeap.h"
23 using ::testing::_;
24 using ::testing::DoAll;
25 using ::testing::SaveArg;
27 namespace content {
29 ACTION_P(RunClosure, closure) {
30 closure.Run();
33 class MediaStreamVideoSourceTest
34 : public ::testing::Test {
35 public:
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),
41 result_name_(""),
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();
65 protected:
66 // Create a track that's associated with |webkit_source_|.
67 blink::WebMediaStreamTrack CreateTrack(
68 const std::string& id,
69 const blink::WebMediaConstraints& constraints) {
70 bool enabled = true;
71 return MediaStreamVideoTrack::CreateVideoTrack(
72 mock_source_, constraints,
73 base::Bind(
74 &MediaStreamVideoSourceTest::OnConstraintsApplied,
75 base::Unretained(this)),
76 enabled);
79 blink::WebMediaStreamTrack CreateTrackAndStartSource(
80 const blink::WebMediaConstraints& constraints,
81 int expected_width,
82 int expected_height,
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());
97 return track;
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,
116 int capture_height,
117 const blink::WebMediaConstraints& constraints,
118 int expected_width,
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,
123 30);
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);
146 run_loop.Run();
149 void DeliverVideoFrameAndWaitForTwoRenderers(
150 int width,
151 int height,
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);
162 run_loop.Run();
165 void TestTwoTracksWithDifferentConstraints(
166 const blink::WebMediaConstraints& constraints1,
167 const blink::WebMediaConstraints& constraints2,
168 int capture_width,
169 int capture_height,
170 int expected_width1,
171 int expected_height1,
172 int expected_width2,
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(),
183 track1);
184 EXPECT_EQ(0, sink1.number_of_frames());
186 MockMediaStreamVideoSink sink2;
187 MediaStreamVideoSink::AddToVideoTrack(&sink2, sink2.GetDeliverFrameCB(),
188 track2);
189 EXPECT_EQ(0, sink2.number_of_frames());
191 DeliverVideoFrameAndWaitForTwoRenderers(capture_width,
192 capture_height,
193 &sink1,
194 &sink2);
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;
217 private:
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_;
225 } else {
226 result_ = result;
227 result_name_ = result_name;
228 ++number_of_failed_constraints_applied_;
231 if (!track_to_release_.isNull()) {
232 mock_source_ = NULL;
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,
318 1280.0 / 720);
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,
331 640.0 / 480);
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
426 // supported.
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,
457 30);
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,
479 30);
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(),
560 1280, 720);
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(),
573 640, 480,
574 640, 480,
575 640, 360);
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(),
590 1280, 720,
591 1280, 720,
592 640, 360);
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(),
606 1280, 720,
607 1280, 720,
608 700, 700);
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(),
621 1280, 720,
622 1280, 720,
623 960, 720);
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(),
636 640, 480,
637 640, 480,
638 640, 360);
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,
651 15);
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
662 // cropped.
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(),
671 640, 480, 30);
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
680 // max requested.
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
687 // max requested.
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
746 // max requested.
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(),
766 640, 480, 2000);
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)));
777 run_loop.Run();
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);
788 run_loop2.Run();
790 EXPECT_EQ(muted_state, false);
791 EXPECT_EQ(track.source().readyState(),
792 blink::WebMediaStreamSource::ReadyStateLive);
794 MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
797 } // namespace content