Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / content / renderer / media / media_stream_video_source_unittest.cc
blobb2afab4f4ad2791556c9bebec24e13b8c73b8898
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 : 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 false /* remote */, true /* readonly */);
56 webkit_source_.setExtraData(mock_source_);
59 void TearDown() override {
60 webkit_source_.reset();
61 blink::WebHeap::collectAllGarbageForTesting();
64 protected:
65 // Create a track that's associated with |webkit_source_|.
66 blink::WebMediaStreamTrack CreateTrack(
67 const std::string& id,
68 const blink::WebMediaConstraints& constraints) {
69 bool enabled = true;
70 return MediaStreamVideoTrack::CreateVideoTrack(
71 mock_source_, constraints,
72 base::Bind(&MediaStreamVideoSourceTest::OnConstraintsApplied,
73 base::Unretained(this)),
74 enabled);
77 blink::WebMediaStreamTrack CreateTrackAndStartSource(
78 const blink::WebMediaConstraints& constraints,
79 int expected_width,
80 int expected_height,
81 int expected_frame_rate) {
82 blink::WebMediaStreamTrack track = CreateTrack("123", constraints);
84 mock_source_->CompleteGetSupportedFormats();
85 const media::VideoCaptureFormat& format = mock_source()->start_format();
86 EXPECT_EQ(expected_width, format.frame_size.width());
87 EXPECT_EQ(expected_height, format.frame_size.height());
88 EXPECT_EQ(expected_frame_rate, format.frame_rate);
90 EXPECT_EQ(0, NumberOfSuccessConstraintsCallbacks());
91 mock_source_->StartMockedSource();
92 // Once the source has started successfully we expect that the
93 // ConstraintsCallback in MediaStreamSource::AddTrack completes.
94 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
95 return track;
98 int NumberOfSuccessConstraintsCallbacks() const {
99 return number_of_successful_constraints_applied_;
102 int NumberOfFailedConstraintsCallbacks() const {
103 return number_of_failed_constraints_applied_;
106 content::MediaStreamRequestResult error_type() const { return result_; }
107 blink::WebString error_name() const { return result_name_; }
109 MockMediaStreamVideoSource* mock_source() { return mock_source_; }
111 // Test that the source crops/scales to the requested width and
112 // height even though the camera delivers a larger frame.
113 void TestSourceCropFrame(int capture_width,
114 int capture_height,
115 const blink::WebMediaConstraints& constraints,
116 int expected_width,
117 int expected_height) {
118 // Expect the source to start capture with the supported resolution.
119 blink::WebMediaStreamTrack track =
120 CreateTrackAndStartSource(constraints, capture_width, capture_height,
121 30);
123 MockMediaStreamVideoSink sink;
124 MediaStreamVideoSink::AddToVideoTrack(
125 &sink, sink.GetDeliverFrameCB(), track);
126 DeliverVideoFrameAndWaitForRenderer(capture_width, capture_height, &sink);
127 EXPECT_EQ(1, sink.number_of_frames());
129 // Expect the delivered frame to be cropped.
130 EXPECT_EQ(expected_height, sink.frame_size().height());
131 EXPECT_EQ(expected_width, sink.frame_size().width());
132 MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
135 void DeliverVideoFrameAndWaitForRenderer(int width, int height,
136 MockMediaStreamVideoSink* sink) {
137 base::RunLoop run_loop;
138 base::Closure quit_closure = run_loop.QuitClosure();
139 EXPECT_CALL(*sink, OnVideoFrame()).WillOnce(
140 RunClosure(quit_closure));
141 scoped_refptr<media::VideoFrame> frame =
142 media::VideoFrame::CreateBlackFrame(gfx::Size(width, height));
143 mock_source()->DeliverVideoFrame(frame);
144 run_loop.Run();
147 void DeliverVideoFrameAndWaitForTwoRenderers(
148 int width,
149 int height,
150 MockMediaStreamVideoSink* sink1,
151 MockMediaStreamVideoSink* sink2) {
152 base::RunLoop run_loop;
153 base::Closure quit_closure = run_loop.QuitClosure();
154 EXPECT_CALL(*sink1, OnVideoFrame());
155 EXPECT_CALL(*sink2, OnVideoFrame()).WillOnce(
156 RunClosure(quit_closure));
157 scoped_refptr<media::VideoFrame> frame =
158 media::VideoFrame::CreateBlackFrame(gfx::Size(width, height));
159 mock_source()->DeliverVideoFrame(frame);
160 run_loop.Run();
163 void TestTwoTracksWithDifferentConstraints(
164 const blink::WebMediaConstraints& constraints1,
165 const blink::WebMediaConstraints& constraints2,
166 int capture_width,
167 int capture_height,
168 int expected_width1,
169 int expected_height1,
170 int expected_width2,
171 int expected_height2) {
172 blink::WebMediaStreamTrack track1 =
173 CreateTrackAndStartSource(constraints1, capture_width, capture_height,
174 MediaStreamVideoSource::kDefaultFrameRate);
176 blink::WebMediaStreamTrack track2 = CreateTrack("dummy", constraints2);
178 MockMediaStreamVideoSink sink1;
179 MediaStreamVideoSink::AddToVideoTrack(&sink1, sink1.GetDeliverFrameCB(),
180 track1);
181 EXPECT_EQ(0, sink1.number_of_frames());
183 MockMediaStreamVideoSink sink2;
184 MediaStreamVideoSink::AddToVideoTrack(&sink2, sink2.GetDeliverFrameCB(),
185 track2);
186 EXPECT_EQ(0, sink2.number_of_frames());
188 DeliverVideoFrameAndWaitForTwoRenderers(capture_width,
189 capture_height,
190 &sink1,
191 &sink2);
193 EXPECT_EQ(1, sink1.number_of_frames());
194 EXPECT_EQ(expected_width1, sink1.frame_size().width());
195 EXPECT_EQ(expected_height1, sink1.frame_size().height());
197 EXPECT_EQ(1, sink2.number_of_frames());
198 EXPECT_EQ(expected_width2, sink2.frame_size().width());
199 EXPECT_EQ(expected_height2, sink2.frame_size().height());
201 MediaStreamVideoSink::RemoveFromVideoTrack(&sink1, track1);
202 MediaStreamVideoSink::RemoveFromVideoTrack(&sink2, track2);
205 void SetSourceSupportedFormats(const media::VideoCaptureFormats& formats) {
206 mock_source_->SetSupportedFormats(formats);
209 void ReleaseTrackAndSourceOnAddTrackCallback(
210 const blink::WebMediaStreamTrack& track_to_release) {
211 track_to_release_ = track_to_release;
214 private:
215 void OnConstraintsApplied(MediaStreamSource* source,
216 MediaStreamRequestResult result,
217 const blink::WebString& result_name) {
218 ASSERT_EQ(source, webkit_source_.extraData());
220 if (result == MEDIA_DEVICE_OK) {
221 ++number_of_successful_constraints_applied_;
222 } else {
223 result_ = result;
224 result_name_ = result_name;
225 ++number_of_failed_constraints_applied_;
228 if (!track_to_release_.isNull()) {
229 mock_source_ = NULL;
230 webkit_source_.reset();
231 track_to_release_.reset();
234 const base::MessageLoopForUI message_loop_;
235 const scoped_ptr<ChildProcess> child_process_;
236 blink::WebMediaStreamTrack track_to_release_;
237 int number_of_successful_constraints_applied_;
238 int number_of_failed_constraints_applied_;
239 content::MediaStreamRequestResult result_;
240 blink::WebString result_name_;
241 blink::WebMediaStreamSource webkit_source_;
242 // |mock_source_| is owned by |webkit_source_|.
243 MockMediaStreamVideoSource* mock_source_;
246 TEST_F(MediaStreamVideoSourceTest, AddTrackAndStartSource) {
247 blink::WebMediaConstraints constraints;
248 constraints.initialize();
249 blink::WebMediaStreamTrack track = CreateTrack("123", constraints);
250 mock_source()->CompleteGetSupportedFormats();
251 mock_source()->StartMockedSource();
252 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
255 TEST_F(MediaStreamVideoSourceTest, AddTwoTracksBeforeSourceStarts) {
256 blink::WebMediaConstraints constraints;
257 constraints.initialize();
258 blink::WebMediaStreamTrack track1 = CreateTrack("123", constraints);
259 mock_source()->CompleteGetSupportedFormats();
260 blink::WebMediaStreamTrack track2 = CreateTrack("123", constraints);
261 EXPECT_EQ(0, NumberOfSuccessConstraintsCallbacks());
262 mock_source()->StartMockedSource();
263 EXPECT_EQ(2, NumberOfSuccessConstraintsCallbacks());
266 TEST_F(MediaStreamVideoSourceTest, AddTrackAfterSourceStarts) {
267 blink::WebMediaConstraints constraints;
268 constraints.initialize();
269 blink::WebMediaStreamTrack track1 = CreateTrack("123", constraints);
270 mock_source()->CompleteGetSupportedFormats();
271 mock_source()->StartMockedSource();
272 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
273 blink::WebMediaStreamTrack track2 = CreateTrack("123", constraints);
274 EXPECT_EQ(2, NumberOfSuccessConstraintsCallbacks());
277 TEST_F(MediaStreamVideoSourceTest, AddTrackAndFailToStartSource) {
278 blink::WebMediaConstraints constraints;
279 constraints.initialize();
280 blink::WebMediaStreamTrack track = CreateTrack("123", constraints);
281 mock_source()->CompleteGetSupportedFormats();
282 mock_source()->FailToStartMockedSource();
283 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
286 TEST_F(MediaStreamVideoSourceTest, AddTwoTracksBeforeGetSupportedFormats) {
287 blink::WebMediaConstraints constraints;
288 constraints.initialize();
289 blink::WebMediaStreamTrack track1 = CreateTrack("123", constraints);
290 blink::WebMediaStreamTrack track2 = CreateTrack("123", constraints);
291 mock_source()->CompleteGetSupportedFormats();
292 mock_source()->StartMockedSource();
293 EXPECT_EQ(2, NumberOfSuccessConstraintsCallbacks());
296 // Test that the capture output is CIF if we set max constraints to CIF.
297 // and the capture device support CIF.
298 TEST_F(MediaStreamVideoSourceTest, MandatoryConstraintCif5Fps) {
299 MockMediaConstraintFactory factory;
300 factory.AddMandatory(MediaStreamVideoSource::kMaxWidth, 352);
301 factory.AddMandatory(MediaStreamVideoSource::kMaxHeight, 288);
302 factory.AddMandatory(MediaStreamVideoSource::kMaxFrameRate, 5);
304 CreateTrackAndStartSource(factory.CreateWebMediaConstraints(), 352, 288, 5);
307 // Test that the capture output is 720P if the camera support it and the
308 // optional constraint is set to 720P.
309 TEST_F(MediaStreamVideoSourceTest, MandatoryMinVgaOptional720P) {
310 MockMediaConstraintFactory factory;
311 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 640);
312 factory.AddMandatory(MediaStreamVideoSource::kMinHeight, 480);
313 factory.AddOptional(MediaStreamVideoSource::kMinWidth, 1280);
314 factory.AddOptional(MediaStreamVideoSource::kMinAspectRatio, 1280.0 / 720);
316 CreateTrackAndStartSource(factory.CreateWebMediaConstraints(), 1280, 720, 30);
319 // Test that the capture output have aspect ratio 4:3 if a mandatory constraint
320 // require it even if an optional constraint request a higher resolution
321 // that don't have this aspect ratio.
322 TEST_F(MediaStreamVideoSourceTest, MandatoryAspectRatio4To3) {
323 MockMediaConstraintFactory factory;
324 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 640);
325 factory.AddMandatory(MediaStreamVideoSource::kMinHeight, 480);
326 factory.AddMandatory(MediaStreamVideoSource::kMaxAspectRatio, 640.0 / 480);
327 factory.AddOptional(MediaStreamVideoSource::kMinWidth, 1280);
329 TestSourceCropFrame(1280, 720,
330 factory.CreateWebMediaConstraints(), 960, 720);
333 // Test that AddTrack succeeds if the mandatory min aspect ratio it set to 2.
334 TEST_F(MediaStreamVideoSourceTest, MandatoryAspectRatio2) {
335 MockMediaConstraintFactory factory;
336 factory.AddMandatory(MediaStreamVideoSource::kMinAspectRatio, 2);
338 TestSourceCropFrame(MediaStreamVideoSource::kDefaultWidth,
339 MediaStreamVideoSource::kDefaultHeight,
340 factory.CreateWebMediaConstraints(), 640, 320);
343 TEST_F(MediaStreamVideoSourceTest, MinAspectRatioLargerThanMaxAspectRatio) {
344 MockMediaConstraintFactory factory;
345 factory.AddMandatory(MediaStreamVideoSource::kMinAspectRatio, 2);
346 factory.AddMandatory(MediaStreamVideoSource::kMaxAspectRatio, 1);
347 blink::WebMediaStreamTrack track = CreateTrack(
348 "123", factory.CreateWebMediaConstraints());
349 mock_source()->CompleteGetSupportedFormats();
350 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
353 TEST_F(MediaStreamVideoSourceTest, MaxAspectRatioZero) {
354 MockMediaConstraintFactory factory;
355 factory.AddOptional(MediaStreamVideoSource::kMaxAspectRatio, 0);
356 blink::WebMediaStreamTrack track = CreateTrack(
357 "123", factory.CreateWebMediaConstraints());
358 mock_source()->CompleteGetSupportedFormats();
359 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
362 TEST_F(MediaStreamVideoSourceTest, MinWidthLargerThanMaxWidth) {
363 MockMediaConstraintFactory factory;
364 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 640);
365 factory.AddMandatory(MediaStreamVideoSource::kMaxWidth, 320);
366 blink::WebMediaStreamTrack track = CreateTrack(
367 "123", factory.CreateWebMediaConstraints());
368 mock_source()->CompleteGetSupportedFormats();
369 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
372 TEST_F(MediaStreamVideoSourceTest, MinHeightLargerThanMaxHeight) {
373 MockMediaConstraintFactory factory;
374 factory.AddMandatory(MediaStreamVideoSource::kMinHeight, 480);
375 factory.AddMandatory(MediaStreamVideoSource::kMaxHeight, 360);
376 blink::WebMediaStreamTrack track = CreateTrack(
377 "123", factory.CreateWebMediaConstraints());
378 mock_source()->CompleteGetSupportedFormats();
379 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
382 TEST_F(MediaStreamVideoSourceTest, MinFrameRateLargerThanMaxFrameRate) {
383 MockMediaConstraintFactory factory;
384 factory.AddMandatory(MediaStreamVideoSource::kMinFrameRate, 25);
385 factory.AddMandatory(MediaStreamVideoSource::kMaxFrameRate, 15);
386 blink::WebMediaStreamTrack track = CreateTrack(
387 "123", factory.CreateWebMediaConstraints());
388 mock_source()->CompleteGetSupportedFormats();
389 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
392 // Test that its safe to release the last reference of a blink track and the
393 // source during the callback if adding a track succeeds.
394 TEST_F(MediaStreamVideoSourceTest, ReleaseTrackAndSourceOnSuccessCallBack) {
395 MockMediaConstraintFactory factory;
397 blink::WebMediaStreamTrack track =
398 CreateTrack("123", factory.CreateWebMediaConstraints());
399 ReleaseTrackAndSourceOnAddTrackCallback(track);
401 mock_source()->CompleteGetSupportedFormats();
402 mock_source()->StartMockedSource();
403 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
406 // Test that its safe to release the last reference of a blink track and the
407 // source during the callback if adding a track fails.
408 TEST_F(MediaStreamVideoSourceTest, ReleaseTrackAndSourceOnFailureCallBack) {
409 MockMediaConstraintFactory factory;
410 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 99999);
412 blink::WebMediaStreamTrack track =
413 CreateTrack("123", factory.CreateWebMediaConstraints());
414 ReleaseTrackAndSourceOnAddTrackCallback(track);
416 mock_source()->CompleteGetSupportedFormats();
417 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
420 // Test that the source ignores an optional aspect ratio that is higher than
421 // supported.
422 TEST_F(MediaStreamVideoSourceTest, OptionalAspectRatioTooHigh) {
423 MockMediaConstraintFactory factory;
424 factory.AddOptional(MediaStreamVideoSource::kMinAspectRatio, 2);
425 blink::WebMediaStreamTrack track = CreateTrack(
426 "123", factory.CreateWebMediaConstraints());
427 mock_source()->CompleteGetSupportedFormats();
429 const media::VideoCaptureFormat& format = mock_source()->start_format();
430 const double aspect_ratio = static_cast<double>(format.frame_size.width()) /
431 format.frame_size.height();
432 EXPECT_LT(aspect_ratio, 2);
435 // Test that the source starts video with the default resolution if the
436 // that is the only supported.
437 TEST_F(MediaStreamVideoSourceTest, DefaultCapability) {
438 media::VideoCaptureFormats formats;
439 formats.push_back(media::VideoCaptureFormat(
440 gfx::Size(MediaStreamVideoSource::kDefaultWidth,
441 MediaStreamVideoSource::kDefaultHeight),
442 MediaStreamVideoSource::kDefaultFrameRate,
443 media::PIXEL_FORMAT_I420));
444 mock_source()->SetSupportedFormats(formats);
446 blink::WebMediaConstraints constraints;
447 constraints.initialize();
448 CreateTrackAndStartSource(constraints,
449 MediaStreamVideoSource::kDefaultWidth,
450 MediaStreamVideoSource::kDefaultHeight,
451 30);
454 TEST_F(MediaStreamVideoSourceTest, InvalidMandatoryConstraint) {
455 MockMediaConstraintFactory factory;
456 factory.AddMandatory("weird key", 640);
457 blink::WebMediaStreamTrack track = CreateTrack(
458 "123", factory.CreateWebMediaConstraints());
459 mock_source()->CompleteGetSupportedFormats();
460 EXPECT_EQ(MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, error_type());
461 EXPECT_EQ("weird key", error_name());
462 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
465 // Test that the source ignores an unknown optional constraint.
466 TEST_F(MediaStreamVideoSourceTest, InvalidOptionalConstraint) {
467 MockMediaConstraintFactory factory;
468 factory.AddOptional("weird key", 640);
470 CreateTrackAndStartSource(factory.CreateWebMediaConstraints(),
471 MediaStreamVideoSource::kDefaultWidth,
472 MediaStreamVideoSource::kDefaultHeight,
473 30);
476 // Tests that the source starts video with the max width and height set by
477 // constraints for screencast.
478 TEST_F(MediaStreamVideoSourceTest, ScreencastResolutionWithConstraint) {
479 media::VideoCaptureFormats formats;
480 formats.push_back(media::VideoCaptureFormat(
481 gfx::Size(480, 270), 30, media::PIXEL_FORMAT_I420));
482 mock_source()->SetSupportedFormats(formats);
483 MockMediaConstraintFactory factory;
484 factory.AddMandatory(MediaStreamVideoSource::kMaxWidth, 480);
485 factory.AddMandatory(MediaStreamVideoSource::kMaxHeight, 270);
487 blink::WebMediaStreamTrack track = CreateTrackAndStartSource(
488 factory.CreateWebMediaConstraints(), 480, 270, 30);
489 EXPECT_EQ(480, mock_source()->max_requested_height());
490 EXPECT_EQ(270, mock_source()->max_requested_width());
493 // Test that optional constraints are applied in order.
494 TEST_F(MediaStreamVideoSourceTest, OptionalConstraints) {
495 MockMediaConstraintFactory factory;
496 // Min width of 2056 pixels can not be fulfilled.
497 factory.AddOptional(MediaStreamVideoSource::kMinWidth, 2056);
498 factory.AddOptional(MediaStreamVideoSource::kMinWidth, 641);
499 // Since min width is set to 641 pixels, max width 640 can not be fulfilled.
500 factory.AddOptional(MediaStreamVideoSource::kMaxWidth, 640);
501 CreateTrackAndStartSource(factory.CreateWebMediaConstraints(), 1280, 720, 30);
504 // Test that the source crops to the requested max width and
505 // height even though the camera delivers a larger frame.
506 TEST_F(MediaStreamVideoSourceTest, DeliverCroppedVideoFrameOptional640360) {
507 MockMediaConstraintFactory factory;
508 factory.AddOptional(MediaStreamVideoSource::kMaxWidth, 640);
509 factory.AddOptional(MediaStreamVideoSource::kMaxHeight, 360);
510 TestSourceCropFrame(640, 480, factory.CreateWebMediaConstraints(), 640, 360);
513 TEST_F(MediaStreamVideoSourceTest, DeliverCroppedVideoFrameMandatory640360) {
514 MockMediaConstraintFactory factory;
515 factory.AddMandatory(MediaStreamVideoSource::kMaxWidth, 640);
516 factory.AddMandatory(MediaStreamVideoSource::kMaxHeight, 360);
517 TestSourceCropFrame(640, 480, factory.CreateWebMediaConstraints(), 640, 360);
520 TEST_F(MediaStreamVideoSourceTest, DeliverCroppedVideoFrameMandatory732489) {
521 MockMediaConstraintFactory factory;
522 factory.AddMandatory(MediaStreamVideoSource::kMaxWidth, 732);
523 factory.AddMandatory(MediaStreamVideoSource::kMaxHeight, 489);
524 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 732);
525 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 489);
526 TestSourceCropFrame(1280, 720, factory.CreateWebMediaConstraints(), 732, 489);
529 // Test that the source crops to the requested max width and
530 // height even though the requested frame has odd size.
531 TEST_F(MediaStreamVideoSourceTest, DeliverCroppedVideoFrame637359) {
532 MockMediaConstraintFactory factory;
533 factory.AddOptional(MediaStreamVideoSource::kMaxWidth, 637);
534 factory.AddOptional(MediaStreamVideoSource::kMaxHeight, 359);
535 TestSourceCropFrame(640, 480, factory.CreateWebMediaConstraints(), 637, 359);
538 TEST_F(MediaStreamVideoSourceTest, DeliverCroppedVideoFrame320320) {
539 MockMediaConstraintFactory factory;
540 factory.AddMandatory(MediaStreamVideoSource::kMaxWidth, 320);
541 factory.AddMandatory(MediaStreamVideoSource::kMaxHeight, 320);
542 factory.AddMandatory(MediaStreamVideoSource::kMinHeight, 320);
543 factory.AddMandatory(MediaStreamVideoSource::kMinWidth, 320);
544 TestSourceCropFrame(640, 480, factory.CreateWebMediaConstraints(), 320, 320);
547 TEST_F(MediaStreamVideoSourceTest, DeliverSmallerSizeWhenTooLargeMax) {
548 MockMediaConstraintFactory factory;
549 factory.AddOptional(MediaStreamVideoSource::kMaxWidth, 1920);
550 factory.AddOptional(MediaStreamVideoSource::kMaxHeight, 1080);
551 factory.AddOptional(MediaStreamVideoSource::kMinWidth, 1280);
552 factory.AddOptional(MediaStreamVideoSource::kMinHeight, 720);
553 TestSourceCropFrame(1280, 720, factory.CreateWebMediaConstraints(),
554 1280, 720);
557 TEST_F(MediaStreamVideoSourceTest, TwoTracksWithVGAAndWVGA) {
558 MockMediaConstraintFactory factory1;
559 factory1.AddOptional(MediaStreamVideoSource::kMaxWidth, 640);
560 factory1.AddOptional(MediaStreamVideoSource::kMaxHeight, 480);
562 MockMediaConstraintFactory factory2;
563 factory2.AddOptional(MediaStreamVideoSource::kMaxHeight, 360);
565 TestTwoTracksWithDifferentConstraints(factory1.CreateWebMediaConstraints(),
566 factory2.CreateWebMediaConstraints(),
567 640, 480,
568 640, 480,
569 640, 360);
572 TEST_F(MediaStreamVideoSourceTest, TwoTracksWith720AndWVGA) {
573 MockMediaConstraintFactory factory1;
574 factory1.AddOptional(MediaStreamVideoSource::kMinWidth, 1280);
575 factory1.AddOptional(MediaStreamVideoSource::kMinHeight, 720);
578 MockMediaConstraintFactory factory2;
579 factory2.AddMandatory(MediaStreamVideoSource::kMaxWidth, 640);
580 factory2.AddMandatory(MediaStreamVideoSource::kMaxHeight, 360);
582 TestTwoTracksWithDifferentConstraints(factory1.CreateWebMediaConstraints(),
583 factory2.CreateWebMediaConstraints(),
584 1280, 720,
585 1280, 720,
586 640, 360);
589 TEST_F(MediaStreamVideoSourceTest, TwoTracksWith720AndW700H700) {
590 MockMediaConstraintFactory factory1;
591 factory1.AddOptional(MediaStreamVideoSource::kMinWidth, 1280);
592 factory1.AddOptional(MediaStreamVideoSource::kMinHeight, 720);
594 MockMediaConstraintFactory factory2;
595 factory2.AddMandatory(MediaStreamVideoSource::kMaxWidth, 700);
596 factory2.AddMandatory(MediaStreamVideoSource::kMaxHeight, 700);
598 TestTwoTracksWithDifferentConstraints(factory1.CreateWebMediaConstraints(),
599 factory2.CreateWebMediaConstraints(),
600 1280, 720,
601 1280, 720,
602 700, 700);
605 TEST_F(MediaStreamVideoSourceTest, TwoTracksWith720AndMaxAspectRatio4To3) {
606 MockMediaConstraintFactory factory1;
607 factory1.AddOptional(MediaStreamVideoSource::kMinWidth, 1280);
608 factory1.AddOptional(MediaStreamVideoSource::kMinHeight, 720);
610 MockMediaConstraintFactory factory2;
611 factory2.AddMandatory(MediaStreamVideoSource::kMaxAspectRatio, 640.0 / 480);
613 TestTwoTracksWithDifferentConstraints(factory1.CreateWebMediaConstraints(),
614 factory2.CreateWebMediaConstraints(),
615 1280, 720,
616 1280, 720,
617 960, 720);
620 TEST_F(MediaStreamVideoSourceTest, TwoTracksWithVgaAndMinAspectRatio) {
621 MockMediaConstraintFactory factory1;
622 factory1.AddOptional(MediaStreamVideoSource::kMaxWidth, 640);
623 factory1.AddOptional(MediaStreamVideoSource::kMaxHeight, 480);
625 MockMediaConstraintFactory factory2;
626 factory2.AddMandatory(MediaStreamVideoSource::kMinAspectRatio, 640.0 / 360);
628 TestTwoTracksWithDifferentConstraints(factory1.CreateWebMediaConstraints(),
629 factory2.CreateWebMediaConstraints(),
630 640, 480,
631 640, 480,
632 640, 360);
635 TEST_F(MediaStreamVideoSourceTest,
636 TwoTracksWithSecondTrackFrameRateHigherThanFirst) {
637 MockMediaConstraintFactory factory1;
638 factory1.AddMandatory(MediaStreamVideoSource::kMinFrameRate, 15);
639 factory1.AddMandatory(MediaStreamVideoSource::kMaxFrameRate, 15);
641 blink::WebMediaStreamTrack track1 =
642 CreateTrackAndStartSource(factory1.CreateWebMediaConstraints(),
643 MediaStreamVideoSource::kDefaultWidth,
644 MediaStreamVideoSource::kDefaultHeight,
645 15);
647 MockMediaConstraintFactory factory2;
648 factory2.AddMandatory(MediaStreamVideoSource::kMinFrameRate, 30);
649 blink::WebMediaStreamTrack track2 = CreateTrack(
650 "123", factory2.CreateWebMediaConstraints());
651 EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
654 // Test that a source can change the frame resolution on the fly and that
655 // tracks sinks get the new frame size unless constraints force the frame to be
656 // cropped.
657 TEST_F(MediaStreamVideoSourceTest, SourceChangeFrameSize) {
658 MockMediaConstraintFactory factory;
659 factory.AddOptional(MediaStreamVideoSource::kMaxWidth, 800);
660 factory.AddOptional(MediaStreamVideoSource::kMaxHeight, 700);
662 // Expect the source to start capture with the supported resolution.
663 blink::WebMediaStreamTrack track =
664 CreateTrackAndStartSource(factory.CreateWebMediaConstraints(),
665 640, 480, 30);
667 MockMediaStreamVideoSink sink;
668 MediaStreamVideoSink::AddToVideoTrack(
669 &sink, sink.GetDeliverFrameCB(), track);
670 EXPECT_EQ(0, sink.number_of_frames());
671 DeliverVideoFrameAndWaitForRenderer(320, 240, &sink);
672 EXPECT_EQ(1, sink.number_of_frames());
673 // Expect the delivered frame to be passed unchanged since its smaller than
674 // max requested.
675 EXPECT_EQ(320, sink.frame_size().width());
676 EXPECT_EQ(240, sink.frame_size().height());
678 DeliverVideoFrameAndWaitForRenderer(640, 480, &sink);
679 EXPECT_EQ(2, sink.number_of_frames());
680 // Expect the delivered frame to be passed unchanged since its smaller than
681 // max requested.
682 EXPECT_EQ(640, sink.frame_size().width());
683 EXPECT_EQ(480, sink.frame_size().height());
685 DeliverVideoFrameAndWaitForRenderer(1280, 720, &sink);
687 EXPECT_EQ(3, sink.number_of_frames());
688 // Expect a frame to be cropped since its larger than max requested.
689 EXPECT_EQ(800, sink.frame_size().width());
690 EXPECT_EQ(700, sink.frame_size().height());
692 MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
695 TEST_F(MediaStreamVideoSourceTest, IsConstraintSupported) {
696 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
697 MediaStreamVideoSource::kMaxFrameRate));
698 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
699 MediaStreamVideoSource::kMinFrameRate));
700 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
701 MediaStreamVideoSource::kMaxWidth));
702 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
703 MediaStreamVideoSource::kMinWidth));
704 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
705 MediaStreamVideoSource::kMaxHeight));
706 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
707 MediaStreamVideoSource::kMinHeight));
708 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
709 MediaStreamVideoSource::kMaxAspectRatio));
710 EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
711 MediaStreamVideoSource::kMinAspectRatio));
713 EXPECT_FALSE(MediaStreamVideoSource::IsConstraintSupported(
714 "something unsupported"));
717 // Test that the constraint negotiation can handle 0.0 fps as frame rate.
718 TEST_F(MediaStreamVideoSourceTest, Use0FpsSupportedFormat) {
719 media::VideoCaptureFormats formats;
720 formats.push_back(media::VideoCaptureFormat(
721 gfx::Size(640, 480), 0.0f, media::PIXEL_FORMAT_I420));
722 formats.push_back(media::VideoCaptureFormat(
723 gfx::Size(320, 240), 0.0f, media::PIXEL_FORMAT_I420));
724 mock_source()->SetSupportedFormats(formats);
726 blink::WebMediaConstraints constraints;
727 constraints.initialize();
728 blink::WebMediaStreamTrack track = CreateTrack("123", constraints);
729 mock_source()->CompleteGetSupportedFormats();
730 mock_source()->StartMockedSource();
731 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
733 MockMediaStreamVideoSink sink;
734 MediaStreamVideoSink::AddToVideoTrack(
735 &sink, sink.GetDeliverFrameCB(), track);
736 EXPECT_EQ(0, sink.number_of_frames());
737 DeliverVideoFrameAndWaitForRenderer(320, 240, &sink);
738 EXPECT_EQ(1, sink.number_of_frames());
739 // Expect the delivered frame to be passed unchanged since its smaller than
740 // max requested.
741 EXPECT_EQ(320, sink.frame_size().width());
742 EXPECT_EQ(240, sink.frame_size().height());
743 MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
746 // Test that a source producing no frames change the source readyState to muted.
747 // that in a reasonable time frame the muted state turns to false.
748 TEST_F(MediaStreamVideoSourceTest, MutedSource) {
749 // Setup the source for support a frame rate of 2000fps in order to test
750 // the muted event faster. This is since the frame monitoring uses
751 // PostDelayedTask that is dependent on the source frame rate.
752 media::VideoCaptureFormats formats;
753 formats.push_back(media::VideoCaptureFormat(
754 gfx::Size(640, 480), 2000, media::PIXEL_FORMAT_I420));
755 SetSourceSupportedFormats(formats);
757 MockMediaConstraintFactory factory;
758 blink::WebMediaStreamTrack track =
759 CreateTrackAndStartSource(factory.CreateWebMediaConstraints(),
760 640, 480, 2000);
761 MockMediaStreamVideoSink sink;
762 MediaStreamVideoSink::AddToVideoTrack(&sink, sink.GetDeliverFrameCB(), track);
763 EXPECT_EQ(track.source().readyState(),
764 blink::WebMediaStreamSource::ReadyStateLive);
766 base::RunLoop run_loop;
767 base::Closure quit_closure = run_loop.QuitClosure();
768 bool muted_state = false;
769 EXPECT_CALL(*mock_source(), DoSetMutedState(_))
770 .WillOnce(DoAll(SaveArg<0>(&muted_state), RunClosure(quit_closure)));
771 run_loop.Run();
772 EXPECT_EQ(muted_state, true);
774 EXPECT_EQ(track.source().readyState(),
775 blink::WebMediaStreamSource::ReadyStateMuted);
777 base::RunLoop run_loop2;
778 base::Closure quit_closure2 = run_loop2.QuitClosure();
779 EXPECT_CALL(*mock_source(), DoSetMutedState(_))
780 .WillOnce(DoAll(SaveArg<0>(&muted_state), RunClosure(quit_closure2)));
781 DeliverVideoFrameAndWaitForRenderer(640, 480, &sink);
782 run_loop2.Run();
784 EXPECT_EQ(muted_state, false);
785 EXPECT_EQ(track.source().readyState(),
786 blink::WebMediaStreamSource::ReadyStateLive);
788 MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
791 } // namespace content