| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/media/capture/web_contents_video_capture_device.h" | 5 #include "content/browser/media/capture/web_contents_video_capture_device.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/debug/debugger.h" | 12 #include "base/debug/debugger.h" |
| 13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/run_loop.h" | 14 #include "base/run_loop.h" |
| 15 #include "base/test/test_timeouts.h" | 15 #include "base/test/test_timeouts.h" |
| 16 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 17 #include "base/timer/timer.h" | 17 #include "base/timer/timer.h" |
| 18 #include "build/build_config.h" | 18 #include "build/build_config.h" |
| 19 #include "content/browser/browser_thread_impl.h" | 19 #include "content/browser/browser_thread_impl.h" |
| 20 #include "content/browser/frame_host/render_frame_host_impl.h" | 20 #include "content/browser/frame_host/render_frame_host_impl.h" |
| 21 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" | 21 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" |
| 22 #include "content/browser/renderer_host/render_view_host_factory.h" | 22 #include "content/browser/renderer_host/render_view_host_factory.h" |
| 23 #include "content/browser/renderer_host/render_widget_host_impl.h" | 23 #include "content/browser/renderer_host/render_widget_host_impl.h" |
| 24 #include "content/browser/web_contents/web_contents_impl.h" | 24 #include "content/browser/web_contents/web_contents_impl.h" |
| 25 #include "content/public/browser/notification_service.h" | |
| 26 #include "content/public/browser/notification_types.h" | |
| 27 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" | 25 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" |
| 28 #include "content/public/browser/web_contents_media_capture_id.h" | 26 #include "content/public/browser/web_contents_media_capture_id.h" |
| 29 #include "content/public/test/mock_render_process_host.h" | 27 #include "content/public/test/mock_render_process_host.h" |
| 30 #include "content/public/test/test_browser_context.h" | 28 #include "content/public/test/test_browser_context.h" |
| 31 #include "content/public/test/test_browser_thread_bundle.h" | 29 #include "content/public/test/test_browser_thread_bundle.h" |
| 32 #include "content/public/test/test_utils.h" | 30 #include "content/public/test/test_utils.h" |
| 33 #include "content/test/test_render_frame_host_factory.h" | 31 #include "content/test/test_render_frame_host_factory.h" |
| 34 #include "content/test/test_render_view_host.h" | 32 #include "content/test/test_render_view_host.h" |
| 35 #include "content/test/test_web_contents.h" | 33 #include "content/test/test_web_contents.h" |
| 36 #include "media/base/video_capture_types.h" | 34 #include "media/base/video_capture_types.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 53 | 51 |
| 54 const int kTestWidth = 320; | 52 const int kTestWidth = 320; |
| 55 const int kTestHeight = 240; | 53 const int kTestHeight = 240; |
| 56 const int kTestFramesPerSecond = 20; | 54 const int kTestFramesPerSecond = 20; |
| 57 const float kTestDeviceScaleFactor = 2.0f; | 55 const float kTestDeviceScaleFactor = 2.0f; |
| 58 const SkColor kNothingYet = 0xdeadbeef; | 56 const SkColor kNothingYet = 0xdeadbeef; |
| 59 const SkColor kNotInterested = ~kNothingYet; | 57 const SkColor kNotInterested = ~kNothingYet; |
| 60 | 58 |
| 61 void DeadlineExceeded(base::Closure quit_closure) { | 59 void DeadlineExceeded(base::Closure quit_closure) { |
| 62 if (!base::debug::BeingDebugged()) { | 60 if (!base::debug::BeingDebugged()) { |
| 63 quit_closure.Run(); | 61 if (!quit_closure.is_null()) |
| 62 quit_closure.Run(); |
| 64 FAIL() << "Deadline exceeded while waiting, quitting"; | 63 FAIL() << "Deadline exceeded while waiting, quitting"; |
| 65 } else { | 64 } else { |
| 66 LOG(WARNING) << "Deadline exceeded; test would fail if debugger weren't " | 65 LOG(WARNING) << "Deadline exceeded; test would fail if debugger weren't " |
| 67 << "attached."; | 66 << "attached."; |
| 68 } | 67 } |
| 69 } | 68 } |
| 70 | 69 |
| 71 void RunCurrentLoopWithDeadline() { | 70 void RunCurrentLoopWithDeadline() { |
| 72 base::Timer deadline(false, false); | 71 base::Timer deadline(false, false); |
| 73 deadline.Start( | 72 deadline.Start( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 87 | 86 |
| 88 // Thread-safe class that controls the source pattern to be captured by the | 87 // Thread-safe class that controls the source pattern to be captured by the |
| 89 // system under test. The lifetime of this class is greater than the lifetime | 88 // system under test. The lifetime of this class is greater than the lifetime |
| 90 // of all objects that reference it, so it does not need to be reference | 89 // of all objects that reference it, so it does not need to be reference |
| 91 // counted. | 90 // counted. |
| 92 class CaptureTestSourceController { | 91 class CaptureTestSourceController { |
| 93 public: | 92 public: |
| 94 CaptureTestSourceController() | 93 CaptureTestSourceController() |
| 95 : color_(SK_ColorMAGENTA), | 94 : color_(SK_ColorMAGENTA), |
| 96 copy_result_size_(kTestWidth, kTestHeight), | 95 copy_result_size_(kTestWidth, kTestHeight), |
| 97 can_copy_to_video_frame_(false), | 96 can_copy_to_video_frame_(true) {} |
| 98 use_frame_subscriber_(false) {} | |
| 99 | 97 |
| 100 void SetSolidColor(SkColor color) { | 98 void SetSolidColor(SkColor color) { |
| 101 base::AutoLock guard(lock_); | 99 base::AutoLock guard(lock_); |
| 102 color_ = color; | 100 color_ = color; |
| 103 } | 101 } |
| 104 | 102 |
| 105 SkColor GetSolidColor() { | 103 SkColor GetSolidColor() { |
| 106 base::AutoLock guard(lock_); | 104 base::AutoLock guard(lock_); |
| 107 return color_; | 105 return color_; |
| 108 } | 106 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 129 void SetCanCopyToVideoFrame(bool value) { | 127 void SetCanCopyToVideoFrame(bool value) { |
| 130 base::AutoLock guard(lock_); | 128 base::AutoLock guard(lock_); |
| 131 can_copy_to_video_frame_ = value; | 129 can_copy_to_video_frame_ = value; |
| 132 } | 130 } |
| 133 | 131 |
| 134 bool CanCopyToVideoFrame() { | 132 bool CanCopyToVideoFrame() { |
| 135 base::AutoLock guard(lock_); | 133 base::AutoLock guard(lock_); |
| 136 return can_copy_to_video_frame_; | 134 return can_copy_to_video_frame_; |
| 137 } | 135 } |
| 138 | 136 |
| 139 void SetUseFrameSubscriber(bool value) { | |
| 140 base::AutoLock guard(lock_); | |
| 141 use_frame_subscriber_ = value; | |
| 142 } | |
| 143 | |
| 144 bool CanUseFrameSubscriber() { | |
| 145 base::AutoLock guard(lock_); | |
| 146 return use_frame_subscriber_; | |
| 147 } | |
| 148 | |
| 149 void WaitForNextCopy() { | 137 void WaitForNextCopy() { |
| 150 { | 138 { |
| 151 base::AutoLock guard(lock_); | 139 base::AutoLock guard(lock_); |
| 152 copy_done_ = base::MessageLoop::current()->QuitWhenIdleClosure(); | 140 copy_done_ = base::MessageLoop::current()->QuitWhenIdleClosure(); |
| 153 } | 141 } |
| 154 | 142 |
| 155 RunCurrentLoopWithDeadline(); | 143 RunCurrentLoopWithDeadline(); |
| 156 } | 144 } |
| 157 | 145 |
| 158 private: | 146 private: |
| 159 base::Lock lock_; // Guards changes to all members. | 147 base::Lock lock_; // Guards changes to all members. |
| 160 SkColor color_; | 148 SkColor color_; |
| 161 gfx::Size copy_result_size_; | 149 gfx::Size copy_result_size_; |
| 162 bool can_copy_to_video_frame_; | 150 bool can_copy_to_video_frame_; |
| 163 bool use_frame_subscriber_; | |
| 164 base::Closure copy_done_; | 151 base::Closure copy_done_; |
| 165 | 152 |
| 166 DISALLOW_COPY_AND_ASSIGN(CaptureTestSourceController); | 153 DISALLOW_COPY_AND_ASSIGN(CaptureTestSourceController); |
| 167 }; | 154 }; |
| 168 | 155 |
| 169 // A stub implementation which returns solid-color bitmaps in calls to | 156 // A stub implementation which returns solid-color bitmaps in calls to |
| 170 // CopyFromCompositingSurfaceToVideoFrame(), and which allows the video-frame | 157 // CopyFromCompositingSurfaceToVideoFrame(), and which allows the video-frame |
| 171 // readback path to be switched on and off. The behavior is controlled by a | 158 // readback path to be switched on and off. The behavior is controlled by a |
| 172 // CaptureTestSourceController. | 159 // CaptureTestSourceController. |
| 173 class CaptureTestView : public TestRenderWidgetHostView { | 160 class CaptureTestView : public TestRenderWidgetHostView { |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 base::Callback<void(SkColor, const gfx::Size&)> report_callback_; | 467 base::Callback<void(SkColor, const gfx::Size&)> report_callback_; |
| 481 base::Closure error_callback_; | 468 base::Closure error_callback_; |
| 482 | 469 |
| 483 DISALLOW_COPY_AND_ASSIGN(StubClient); | 470 DISALLOW_COPY_AND_ASSIGN(StubClient); |
| 484 }; | 471 }; |
| 485 | 472 |
| 486 class StubClientObserver { | 473 class StubClientObserver { |
| 487 public: | 474 public: |
| 488 StubClientObserver() | 475 StubClientObserver() |
| 489 : error_encountered_(false), | 476 : error_encountered_(false), |
| 490 wait_color_yuv_(0xcafe1950), | 477 wait_color_yuv_(0xcafe1950) { |
| 491 wait_size_(kTestWidth, kTestHeight) { | |
| 492 client_.reset(new StubClient( | 478 client_.reset(new StubClient( |
| 493 base::Bind(&StubClientObserver::DidDeliverFrame, | 479 base::Bind(&StubClientObserver::DidDeliverFrame, |
| 494 base::Unretained(this)), | 480 base::Unretained(this)), |
| 495 base::Bind(&StubClientObserver::OnError, base::Unretained(this)))); | 481 base::Bind(&StubClientObserver::OnError, base::Unretained(this)))); |
| 496 } | 482 } |
| 497 | 483 |
| 498 virtual ~StubClientObserver() {} | 484 virtual ~StubClientObserver() {} |
| 499 | 485 |
| 500 scoped_ptr<media::VideoCaptureDevice::Client> PassClient() { | 486 scoped_ptr<media::VideoCaptureDevice::Client> PassClient() { |
| 501 return std::move(client_); | 487 return std::move(client_); |
| 502 } | 488 } |
| 503 | 489 |
| 504 void QuitIfConditionsMet(SkColor color, const gfx::Size& size) { | 490 void QuitIfConditionsMet(SkColor color, const gfx::Size& size) { |
| 505 base::AutoLock guard(lock_); | 491 base::AutoLock guard(lock_); |
| 506 if (error_encountered_) | 492 if (error_encountered_ || wait_color_yuv_ == kNotInterested || |
| 493 wait_color_yuv_ == color) { |
| 494 last_frame_color_yuv_ = color; |
| 495 last_frame_size_ = size; |
| 507 base::MessageLoop::current()->QuitWhenIdle(); | 496 base::MessageLoop::current()->QuitWhenIdle(); |
| 508 else if (wait_color_yuv_ == color && wait_size_.IsEmpty()) | 497 } |
| 509 base::MessageLoop::current()->QuitWhenIdle(); | |
| 510 else if (wait_color_yuv_ == color && wait_size_ == size) | |
| 511 base::MessageLoop::current()->QuitWhenIdle(); | |
| 512 } | 498 } |
| 513 | 499 |
| 514 // Run the current loop until a frame is delivered with the |expected_color| | 500 // Run the current loop until the next frame is delivered. Returns the YUV |
| 515 // and any non-empty frame size. | 501 // color and frame size. |
| 516 void WaitForNextColor(SkColor expected_color) { | 502 std::pair<SkColor, gfx::Size> WaitForNextFrame() { |
| 517 WaitForNextColorAndFrameSize(expected_color, gfx::Size()); | 503 { |
| 504 base::AutoLock guard(lock_); |
| 505 wait_color_yuv_ = kNotInterested; |
| 506 error_encountered_ = false; |
| 507 } |
| 508 RunCurrentLoopWithDeadline(); |
| 509 { |
| 510 base::AutoLock guard(lock_); |
| 511 CHECK(!error_encountered_); |
| 512 return std::make_pair(last_frame_color_yuv_, last_frame_size_); |
| 513 } |
| 518 } | 514 } |
| 519 | 515 |
| 520 // Run the current loop until a frame is delivered with the |expected_color| | 516 // Run the current loop until a frame is delivered with the |expected_color|. |
| 521 // and is of the |expected_size|. | 517 void WaitForNextColor(SkColor expected_color) { |
| 522 void WaitForNextColorAndFrameSize(SkColor expected_color, | |
| 523 const gfx::Size& expected_size) { | |
| 524 { | 518 { |
| 525 base::AutoLock guard(lock_); | 519 base::AutoLock guard(lock_); |
| 526 wait_color_yuv_ = ConvertRgbToYuv(expected_color); | 520 wait_color_yuv_ = ConvertRgbToYuv(expected_color); |
| 527 wait_size_ = expected_size; | |
| 528 error_encountered_ = false; | 521 error_encountered_ = false; |
| 529 } | 522 } |
| 530 RunCurrentLoopWithDeadline(); | 523 RunCurrentLoopWithDeadline(); |
| 531 { | 524 { |
| 532 base::AutoLock guard(lock_); | 525 base::AutoLock guard(lock_); |
| 533 ASSERT_FALSE(error_encountered_); | 526 ASSERT_FALSE(error_encountered_); |
| 534 } | 527 } |
| 535 } | 528 } |
| 536 | 529 |
| 537 void WaitForError() { | 530 void WaitForError() { |
| 538 { | 531 { |
| 539 base::AutoLock guard(lock_); | 532 base::AutoLock guard(lock_); |
| 540 wait_color_yuv_ = kNotInterested; | 533 wait_color_yuv_ = kNotInterested; |
| 541 wait_size_ = gfx::Size(); | |
| 542 error_encountered_ = false; | 534 error_encountered_ = false; |
| 543 } | 535 } |
| 544 RunCurrentLoopWithDeadline(); | 536 RunCurrentLoopWithDeadline(); |
| 545 { | 537 { |
| 546 base::AutoLock guard(lock_); | 538 base::AutoLock guard(lock_); |
| 547 ASSERT_TRUE(error_encountered_); | 539 ASSERT_TRUE(error_encountered_); |
| 548 } | 540 } |
| 549 } | 541 } |
| 550 | 542 |
| 551 bool HasError() { | 543 bool HasError() { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 570 &StubClientObserver::QuitIfConditionsMet, | 562 &StubClientObserver::QuitIfConditionsMet, |
| 571 base::Unretained(this), | 563 base::Unretained(this), |
| 572 color, | 564 color, |
| 573 size)); | 565 size)); |
| 574 } | 566 } |
| 575 | 567 |
| 576 private: | 568 private: |
| 577 base::Lock lock_; | 569 base::Lock lock_; |
| 578 bool error_encountered_; | 570 bool error_encountered_; |
| 579 SkColor wait_color_yuv_; | 571 SkColor wait_color_yuv_; |
| 580 gfx::Size wait_size_; | 572 SkColor last_frame_color_yuv_; |
| 573 gfx::Size last_frame_size_; |
| 581 scoped_ptr<StubClient> client_; | 574 scoped_ptr<StubClient> client_; |
| 582 | 575 |
| 583 DISALLOW_COPY_AND_ASSIGN(StubClientObserver); | 576 DISALLOW_COPY_AND_ASSIGN(StubClientObserver); |
| 584 }; | 577 }; |
| 585 | 578 |
| 586 // crbug.com/159234 | 579 // crbug.com/159234 |
| 587 #if defined(OS_ANDROID) | 580 #if defined(OS_ANDROID) |
| 588 #define MAYBE_WebContentsVideoCaptureDeviceTest \ | 581 #define MAYBE_WebContentsVideoCaptureDeviceTest \ |
| 589 DISABLED_WebContentsVideoCaptureDeviceTest | 582 DISABLED_WebContentsVideoCaptureDeviceTest |
| 590 #else | 583 #else |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 // ignored on Mac platforms (when determining the device scale factor for a | 672 // ignored on Mac platforms (when determining the device scale factor for a |
| 680 // particular window). | 673 // particular window). |
| 681 float GetDeviceScaleFactor() const { | 674 float GetDeviceScaleFactor() const { |
| 682 RenderWidgetHostView* const view = | 675 RenderWidgetHostView* const view = |
| 683 web_contents_->GetRenderViewHost()->GetWidget()->GetView(); | 676 web_contents_->GetRenderViewHost()->GetWidget()->GetView(); |
| 684 CHECK(view); | 677 CHECK(view); |
| 685 return ui::GetScaleFactorForNativeView(view->GetNativeView()); | 678 return ui::GetScaleFactorForNativeView(view->GetNativeView()); |
| 686 } | 679 } |
| 687 | 680 |
| 688 void SimulateDrawEvent() { | 681 void SimulateDrawEvent() { |
| 689 if (source()->CanUseFrameSubscriber()) { | 682 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 690 // Print | 683 |
| 691 CaptureTestView* test_view = static_cast<CaptureTestView*>( | 684 // Force at least one frame period's worth of time to pass. Otherwise, |
| 692 web_contents_->GetRenderViewHost()->GetWidget()->GetView()); | 685 // internal logic may decide not to capture a frame because the draw events |
| 693 test_view->SimulateUpdate(); | 686 // are more frequent that kTestFramesPerSecond. |
| 694 } else { | 687 // |
| 695 // Simulate a non-accelerated paint. | 688 // TODO(miu): Instead of physically waiting, we should inject simulated |
| 696 NotificationService::current()->Notify( | 689 // clocks for testing. |
| 697 NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, | 690 base::RunLoop run_loop; |
| 698 Source<RenderWidgetHost>( | 691 BrowserThread::PostDelayedTask( |
| 699 web_contents_->GetRenderViewHost()->GetWidget()), | 692 BrowserThread::UI, FROM_HERE, |
| 700 NotificationService::NoDetails()); | 693 run_loop.QuitClosure(), |
| 701 } | 694 base::TimeDelta::FromMicroseconds( |
| 695 base::Time::kMicrosecondsPerSecond / kTestFramesPerSecond)); |
| 696 run_loop.Run(); |
| 697 |
| 698 // Schedule the update to occur when the test runs the event loop (and not |
| 699 // before expectations have been set). |
| 700 CaptureTestView* test_view = static_cast<CaptureTestView*>( |
| 701 web_contents_->GetRenderViewHost()->GetWidget()->GetView()); |
| 702 BrowserThread::PostTask( |
| 703 BrowserThread::UI, FROM_HERE, |
| 704 base::Bind(&CaptureTestView::SimulateUpdate, |
| 705 base::Unretained(test_view))); |
| 702 } | 706 } |
| 703 | 707 |
| 704 void SimulateSourceSizeChange(const gfx::Size& size) { | 708 void SimulateSourceSizeChange(const gfx::Size& size) { |
| 705 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 709 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 706 CaptureTestView* test_view = static_cast<CaptureTestView*>( | 710 CaptureTestView* test_view = static_cast<CaptureTestView*>( |
| 707 web_contents_->GetRenderViewHost()->GetWidget()->GetView()); | 711 web_contents_->GetRenderViewHost()->GetWidget()->GetView()); |
| 708 test_view->SetSize(size); | 712 test_view->SetSize(size); |
| 709 // Normally, RenderWidgetHostImpl would notify WebContentsImpl that the size | 713 // Normally, RenderWidgetHostImpl would notify WebContentsImpl that the size |
| 710 // has changed. However, in this test setup where there is no render | 714 // has changed. However, in this test setup where there is no render |
| 711 // process, we must notify WebContentsImpl directly. | 715 // process, we must notify WebContentsImpl directly. |
| 712 WebContentsImpl* const as_web_contents_impl = | 716 WebContentsImpl* const as_web_contents_impl = |
| 713 static_cast<WebContentsImpl*>(web_contents_.get()); | 717 static_cast<WebContentsImpl*>(web_contents_.get()); |
| 714 RenderWidgetHostDelegate* const as_rwh_delegate = | 718 RenderWidgetHostDelegate* const as_rwh_delegate = |
| 715 static_cast<RenderWidgetHostDelegate*>(as_web_contents_impl); | 719 static_cast<RenderWidgetHostDelegate*>(as_web_contents_impl); |
| 716 as_rwh_delegate->RenderWidgetWasResized( | 720 as_rwh_delegate->RenderWidgetWasResized( |
| 717 as_web_contents_impl->GetMainFrame()->GetRenderWidgetHost(), true); | 721 as_web_contents_impl->GetMainFrame()->GetRenderWidgetHost(), true); |
| 718 } | 722 } |
| 719 | 723 |
| 724 // Repeatedly schedules draw events and scans for frames until the output from |
| 725 // the capture device matches the given RGB |color| and frame |size|. |
| 726 void SimulateDrawsUntilNewFrameSizeArrives(SkColor color, |
| 727 const gfx::Size& size) { |
| 728 const base::TimeTicks start_time = base::TimeTicks::Now(); |
| 729 while ((base::TimeTicks::Now() - start_time) < |
| 730 TestTimeouts::action_max_timeout()) { |
| 731 SimulateDrawEvent(); |
| 732 const auto color_and_size = client_observer()->WaitForNextFrame(); |
| 733 if (color_and_size.first == ConvertRgbToYuv(color) && |
| 734 color_and_size.second == size) { |
| 735 return; |
| 736 } |
| 737 } |
| 738 DeadlineExceeded(base::Closure()); |
| 739 } |
| 740 |
| 741 void SimulateRefreshFrameRequest() { |
| 742 // Force at least three frame period's worth of time to pass. The wait is |
| 743 // needed because refresh frame requests are only honored when drawing |
| 744 // events, which trigger frame captures, are not occurring frequently |
| 745 // enough. |
| 746 // |
| 747 // TODO(miu): Instead of physically waiting, we should inject simulated |
| 748 // clocks for testing. |
| 749 base::RunLoop run_loop; |
| 750 BrowserThread::PostDelayedTask( |
| 751 BrowserThread::UI, FROM_HERE, |
| 752 run_loop.QuitClosure(), |
| 753 base::TimeDelta::FromMicroseconds( |
| 754 3 * base::Time::kMicrosecondsPerSecond / kTestFramesPerSecond)); |
| 755 run_loop.Run(); |
| 756 |
| 757 BrowserThread::PostTask( |
| 758 BrowserThread::UI, FROM_HERE, |
| 759 base::Bind(&media::VideoCaptureDevice::RequestRefreshFrame, |
| 760 base::Unretained(device_.get()))); |
| 761 } |
| 762 |
| 720 void DestroyVideoCaptureDevice() { device_.reset(); } | 763 void DestroyVideoCaptureDevice() { device_.reset(); } |
| 721 | 764 |
| 722 StubClientObserver* client_observer() { | 765 StubClientObserver* client_observer() { |
| 723 return &client_observer_; | 766 return &client_observer_; |
| 724 } | 767 } |
| 725 | 768 |
| 726 private: | 769 private: |
| 727 gfx::test::TestScreen test_screen_; | 770 gfx::test::TestScreen test_screen_; |
| 728 | 771 |
| 729 StubClientObserver client_observer_; | 772 StubClientObserver client_observer_; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 static_cast<int>(kTestHeight / device_scale_factor)); | 817 static_cast<int>(kTestHeight / device_scale_factor)); |
| 775 ASSERT_NE(capture_preferred_size, web_contents()->GetPreferredSize()); | 818 ASSERT_NE(capture_preferred_size, web_contents()->GetPreferredSize()); |
| 776 | 819 |
| 777 // We'll simulate the tab being closed after the capture pipeline is up and | 820 // We'll simulate the tab being closed after the capture pipeline is up and |
| 778 // running. | 821 // running. |
| 779 media::VideoCaptureParams capture_params; | 822 media::VideoCaptureParams capture_params; |
| 780 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); | 823 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); |
| 781 capture_params.requested_format.frame_rate = kTestFramesPerSecond; | 824 capture_params.requested_format.frame_rate = kTestFramesPerSecond; |
| 782 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; | 825 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
| 783 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); | 826 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); |
| 784 // Do one capture to prove | 827 |
| 828 // Do one capture to prove the tab is initially open and being captured |
| 829 // normally. |
| 785 source()->SetSolidColor(SK_ColorRED); | 830 source()->SetSolidColor(SK_ColorRED); |
| 786 SimulateDrawEvent(); | 831 SimulateDrawEvent(); |
| 787 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); | 832 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); |
| 788 | 833 |
| 789 base::RunLoop().RunUntilIdle(); | 834 base::RunLoop().RunUntilIdle(); |
| 790 | 835 |
| 791 // Check that the preferred size of the WebContents matches the one provided | 836 // Check that the preferred size of the WebContents matches the one provided |
| 792 // by WebContentsVideoCaptureDevice. | 837 // by WebContentsVideoCaptureDevice. |
| 793 EXPECT_EQ(capture_preferred_size, web_contents()->GetPreferredSize()); | 838 EXPECT_EQ(capture_preferred_size, web_contents()->GetPreferredSize()); |
| 794 | 839 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 814 DestroyVideoCaptureDevice(); | 859 DestroyVideoCaptureDevice(); |
| 815 | 860 |
| 816 // Currently, there should be CreateCaptureMachineOnUIThread() and | 861 // Currently, there should be CreateCaptureMachineOnUIThread() and |
| 817 // DestroyCaptureMachineOnUIThread() tasks pending on the current (UI) message | 862 // DestroyCaptureMachineOnUIThread() tasks pending on the current (UI) message |
| 818 // loop. These should both succeed without crashing, and the machine should | 863 // loop. These should both succeed without crashing, and the machine should |
| 819 // wind up in the idle state. | 864 // wind up in the idle state. |
| 820 base::RunLoop().RunUntilIdle(); | 865 base::RunLoop().RunUntilIdle(); |
| 821 } | 866 } |
| 822 | 867 |
| 823 TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, StopWithRendererWorkToDo) { | 868 TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, StopWithRendererWorkToDo) { |
| 824 // Set up the test to use RGB copies and an normal | 869 // Set up the test to use RGB captures into SkBitmaps instead of YUV captures |
| 870 // into VideoFrames. |
| 825 source()->SetCanCopyToVideoFrame(false); | 871 source()->SetCanCopyToVideoFrame(false); |
| 826 source()->SetUseFrameSubscriber(false); | |
| 827 media::VideoCaptureParams capture_params; | 872 media::VideoCaptureParams capture_params; |
| 828 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); | 873 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); |
| 829 capture_params.requested_format.frame_rate = kTestFramesPerSecond; | 874 capture_params.requested_format.frame_rate = kTestFramesPerSecond; |
| 830 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; | 875 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
| 831 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); | 876 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); |
| 832 | 877 |
| 833 base::RunLoop().RunUntilIdle(); | 878 base::RunLoop().RunUntilIdle(); |
| 834 | 879 |
| 835 for (int i = 0; i < 10; ++i) | 880 for (int i = 0; i < 3; ++i) |
| 836 SimulateDrawEvent(); | 881 SimulateDrawEvent(); |
| 837 | 882 |
| 838 ASSERT_FALSE(client_observer()->HasError()); | 883 ASSERT_FALSE(client_observer()->HasError()); |
| 839 device()->StopAndDeAllocate(); | 884 device()->StopAndDeAllocate(); |
| 840 ASSERT_FALSE(client_observer()->HasError()); | 885 ASSERT_FALSE(client_observer()->HasError()); |
| 841 base::RunLoop().RunUntilIdle(); | 886 base::RunLoop().RunUntilIdle(); |
| 842 ASSERT_FALSE(client_observer()->HasError()); | 887 ASSERT_FALSE(client_observer()->HasError()); |
| 843 } | 888 } |
| 844 | 889 |
| 845 TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, DeviceRestart) { | 890 TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, DeviceRestart) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 871 SimulateDrawEvent(); | 916 SimulateDrawEvent(); |
| 872 ASSERT_NO_FATAL_FAILURE(observer2.WaitForNextColor(SK_ColorBLUE)); | 917 ASSERT_NO_FATAL_FAILURE(observer2.WaitForNextColor(SK_ColorBLUE)); |
| 873 source()->SetSolidColor(SK_ColorYELLOW); | 918 source()->SetSolidColor(SK_ColorYELLOW); |
| 874 SimulateDrawEvent(); | 919 SimulateDrawEvent(); |
| 875 ASSERT_NO_FATAL_FAILURE(observer2.WaitForNextColor(SK_ColorYELLOW)); | 920 ASSERT_NO_FATAL_FAILURE(observer2.WaitForNextColor(SK_ColorYELLOW)); |
| 876 device()->StopAndDeAllocate(); | 921 device()->StopAndDeAllocate(); |
| 877 } | 922 } |
| 878 | 923 |
| 879 // The "happy case" test. No scaling is needed, so we should be able to change | 924 // The "happy case" test. No scaling is needed, so we should be able to change |
| 880 // the picture emitted from the source and expect to see each delivered to the | 925 // the picture emitted from the source and expect to see each delivered to the |
| 881 // consumer. The test will alternate between the three capture paths, simulating | 926 // consumer. The test will alternate between the RGB/SkBitmap and YUV/VideoFrame |
| 882 // falling in and out of accelerated compositing. | 927 // capture paths. |
| 883 TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, GoesThroughAllTheMotions) { | 928 TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, GoesThroughAllTheMotions) { |
| 884 media::VideoCaptureParams capture_params; | 929 media::VideoCaptureParams capture_params; |
| 885 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); | 930 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); |
| 886 capture_params.requested_format.frame_rate = kTestFramesPerSecond; | 931 capture_params.requested_format.frame_rate = kTestFramesPerSecond; |
| 887 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; | 932 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
| 888 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); | 933 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); |
| 889 | 934 |
| 890 for (int i = 0; i < 6; i++) { | 935 for (int i = 0; i < 4; i++) { |
| 891 const char* name = NULL; | 936 const char* name = NULL; |
| 892 switch (i % 3) { | 937 if (i % 2) { |
| 893 case 0: | 938 source()->SetCanCopyToVideoFrame(false); |
| 894 source()->SetCanCopyToVideoFrame(true); | 939 name = "SkBitmap"; |
| 895 source()->SetUseFrameSubscriber(false); | 940 } else { |
| 896 name = "VideoFrame"; | 941 source()->SetCanCopyToVideoFrame(true); |
| 897 break; | 942 name = "VideoFrame"; |
| 898 case 1: | |
| 899 source()->SetCanCopyToVideoFrame(false); | |
| 900 source()->SetUseFrameSubscriber(true); | |
| 901 name = "Subscriber"; | |
| 902 break; | |
| 903 case 2: | |
| 904 source()->SetCanCopyToVideoFrame(false); | |
| 905 source()->SetUseFrameSubscriber(false); | |
| 906 name = "SkBitmap"; | |
| 907 break; | |
| 908 default: | |
| 909 FAIL(); | |
| 910 } | 943 } |
| 911 | 944 |
| 912 SCOPED_TRACE(base::StringPrintf("Using %s path, iteration #%d", name, i)); | 945 SCOPED_TRACE(base::StringPrintf("Using %s path, iteration #%d", name, i)); |
| 913 | 946 |
| 914 source()->SetSolidColor(SK_ColorRED); | 947 source()->SetSolidColor(SK_ColorRED); |
| 915 SimulateDrawEvent(); | 948 SimulateDrawEvent(); |
| 916 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); | 949 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); |
| 917 | 950 |
| 918 source()->SetSolidColor(SK_ColorGREEN); | 951 source()->SetSolidColor(SK_ColorGREEN); |
| 919 SimulateDrawEvent(); | 952 SimulateDrawEvent(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 935 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); | 968 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); |
| 936 capture_params.requested_format.frame_rate = kTestFramesPerSecond; | 969 capture_params.requested_format.frame_rate = kTestFramesPerSecond; |
| 937 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; | 970 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
| 938 // 1x1 is too small to process; we intend for this to result in an error. | 971 // 1x1 is too small to process; we intend for this to result in an error. |
| 939 source()->SetCopyResultSize(1, 1); | 972 source()->SetCopyResultSize(1, 1); |
| 940 source()->SetSolidColor(SK_ColorRED); | 973 source()->SetSolidColor(SK_ColorRED); |
| 941 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); | 974 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); |
| 942 | 975 |
| 943 // These frames ought to be dropped during the Render stage. Let | 976 // These frames ought to be dropped during the Render stage. Let |
| 944 // several captures to happen. | 977 // several captures to happen. |
| 945 ASSERT_NO_FATAL_FAILURE(source()->WaitForNextCopy()); | 978 for (int i = 0; i < 3; ++i) { |
| 946 ASSERT_NO_FATAL_FAILURE(source()->WaitForNextCopy()); | 979 SimulateDrawEvent(); |
| 947 ASSERT_NO_FATAL_FAILURE(source()->WaitForNextCopy()); | 980 ASSERT_NO_FATAL_FAILURE(source()->WaitForNextCopy()); |
| 948 ASSERT_NO_FATAL_FAILURE(source()->WaitForNextCopy()); | 981 } |
| 949 ASSERT_NO_FATAL_FAILURE(source()->WaitForNextCopy()); | |
| 950 | 982 |
| 951 // Now push some good frames through; they should be processed normally. | 983 // Now push some good frames through; they should be processed normally. |
| 952 source()->SetCopyResultSize(kTestWidth, kTestHeight); | 984 source()->SetCopyResultSize(kTestWidth, kTestHeight); |
| 953 source()->SetSolidColor(SK_ColorGREEN); | 985 source()->SetSolidColor(SK_ColorGREEN); |
| 986 SimulateDrawEvent(); |
| 954 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); | 987 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); |
| 955 source()->SetSolidColor(SK_ColorRED); | 988 source()->SetSolidColor(SK_ColorRED); |
| 989 SimulateDrawEvent(); |
| 956 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); | 990 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); |
| 957 | 991 |
| 958 device()->StopAndDeAllocate(); | 992 device()->StopAndDeAllocate(); |
| 959 } | 993 } |
| 960 | 994 |
| 961 // Tests that, when configured with the FIXED_ASPECT_RATIO resolution change | 995 // Tests that, when configured with the FIXED_ASPECT_RATIO resolution change |
| 962 // policy, the source size changes result in video frames of possibly varying | 996 // policy, the source size changes result in video frames of possibly varying |
| 963 // resolutions, but all with the same aspect ratio. | 997 // resolutions, but all with the same aspect ratio. |
| 964 TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, | 998 TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, |
| 965 VariableResolution_FixedAspectRatio) { | 999 VariableResolution_FixedAspectRatio) { |
| 966 media::VideoCaptureParams capture_params; | 1000 media::VideoCaptureParams capture_params; |
| 967 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); | 1001 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); |
| 968 capture_params.requested_format.frame_rate = kTestFramesPerSecond; | 1002 capture_params.requested_format.frame_rate = kTestFramesPerSecond; |
| 969 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; | 1003 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
| 970 capture_params.resolution_change_policy = | 1004 capture_params.resolution_change_policy = |
| 971 media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO; | 1005 media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO; |
| 972 | 1006 |
| 973 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); | 1007 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); |
| 974 | 1008 |
| 975 source()->SetUseFrameSubscriber(true); | |
| 976 | |
| 977 // Source size equals maximum size. Expect delivered frames to be | 1009 // Source size equals maximum size. Expect delivered frames to be |
| 978 // kTestWidth by kTestHeight. | 1010 // kTestWidth by kTestHeight. |
| 979 source()->SetSolidColor(SK_ColorRED); | 1011 source()->SetSolidColor(SK_ColorRED); |
| 980 const float device_scale_factor = GetDeviceScaleFactor(); | 1012 const float device_scale_factor = GetDeviceScaleFactor(); |
| 981 SimulateSourceSizeChange(gfx::ConvertSizeToDIP( | 1013 SimulateSourceSizeChange(gfx::ConvertSizeToDIP( |
| 982 device_scale_factor, gfx::Size(kTestWidth, kTestHeight))); | 1014 device_scale_factor, gfx::Size(kTestWidth, kTestHeight))); |
| 983 SimulateDrawEvent(); | 1015 SimulateDrawsUntilNewFrameSizeArrives( |
| 984 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( | 1016 SK_ColorRED, gfx::Size(kTestWidth, kTestHeight)); |
| 985 SK_ColorRED, gfx::Size(kTestWidth, kTestHeight))); | |
| 986 | 1017 |
| 987 // Source size is half in both dimensions. Expect delivered frames to be of | 1018 // Source size is half in both dimensions. Expect delivered frames to be of |
| 988 // the same aspect ratio as kTestWidth by kTestHeight, but larger than the | 1019 // the same aspect ratio as kTestWidth by kTestHeight, but larger than the |
| 989 // half size because the minimum height is 180 lines. | 1020 // half size because the minimum height is 180 lines. |
| 990 source()->SetSolidColor(SK_ColorGREEN); | 1021 source()->SetSolidColor(SK_ColorGREEN); |
| 991 SimulateSourceSizeChange(gfx::ConvertSizeToDIP( | 1022 SimulateSourceSizeChange(gfx::ConvertSizeToDIP( |
| 992 device_scale_factor, gfx::Size(kTestWidth / 2, kTestHeight / 2))); | 1023 device_scale_factor, gfx::Size(kTestWidth / 2, kTestHeight / 2))); |
| 993 SimulateDrawEvent(); | 1024 SimulateDrawsUntilNewFrameSizeArrives( |
| 994 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( | 1025 SK_ColorGREEN, gfx::Size(180 * kTestWidth / kTestHeight, 180)); |
| 995 SK_ColorGREEN, gfx::Size(180 * kTestWidth / kTestHeight, 180))); | |
| 996 | 1026 |
| 997 // Source size changes aspect ratio. Expect delivered frames to be padded | 1027 // Source size changes aspect ratio. Expect delivered frames to be padded |
| 998 // in the horizontal dimension to preserve aspect ratio. | 1028 // in the horizontal dimension to preserve aspect ratio. |
| 999 source()->SetSolidColor(SK_ColorBLUE); | 1029 source()->SetSolidColor(SK_ColorBLUE); |
| 1000 SimulateSourceSizeChange(gfx::ConvertSizeToDIP( | 1030 SimulateSourceSizeChange(gfx::ConvertSizeToDIP( |
| 1001 device_scale_factor, gfx::Size(kTestWidth / 2, kTestHeight))); | 1031 device_scale_factor, gfx::Size(kTestWidth / 2, kTestHeight))); |
| 1002 SimulateDrawEvent(); | 1032 SimulateDrawsUntilNewFrameSizeArrives( |
| 1003 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( | 1033 SK_ColorBLUE, gfx::Size(kTestWidth, kTestHeight)); |
| 1004 SK_ColorBLUE, gfx::Size(kTestWidth, kTestHeight))); | |
| 1005 | 1034 |
| 1006 // Source size changes aspect ratio again. Expect delivered frames to be | 1035 // Source size changes aspect ratio again. Expect delivered frames to be |
| 1007 // padded in the vertical dimension to preserve aspect ratio. | 1036 // padded in the vertical dimension to preserve aspect ratio. |
| 1008 source()->SetSolidColor(SK_ColorBLACK); | 1037 source()->SetSolidColor(SK_ColorBLACK); |
| 1009 SimulateSourceSizeChange(gfx::ConvertSizeToDIP( | 1038 SimulateSourceSizeChange(gfx::ConvertSizeToDIP( |
| 1010 device_scale_factor, gfx::Size(kTestWidth, kTestHeight / 2))); | 1039 device_scale_factor, gfx::Size(kTestWidth, kTestHeight / 2))); |
| 1011 SimulateDrawEvent(); | 1040 SimulateDrawsUntilNewFrameSizeArrives( |
| 1012 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( | 1041 SK_ColorBLACK, gfx::Size(kTestWidth, kTestHeight)); |
| 1013 SK_ColorBLACK, gfx::Size(kTestWidth, kTestHeight))); | |
| 1014 | 1042 |
| 1015 device()->StopAndDeAllocate(); | 1043 device()->StopAndDeAllocate(); |
| 1016 } | 1044 } |
| 1017 | 1045 |
| 1018 // Tests that, when configured with the ANY_WITHIN_LIMIT resolution change | 1046 // Tests that, when configured with the ANY_WITHIN_LIMIT resolution change |
| 1019 // policy, the source size changes result in video frames of possibly varying | 1047 // policy, the source size changes result in video frames of possibly varying |
| 1020 // resolutions. | 1048 // resolutions. |
| 1021 TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, | 1049 TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, |
| 1022 VariableResolution_AnyWithinLimits) { | 1050 VariableResolution_AnyWithinLimits) { |
| 1023 media::VideoCaptureParams capture_params; | 1051 media::VideoCaptureParams capture_params; |
| 1024 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); | 1052 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); |
| 1025 capture_params.requested_format.frame_rate = kTestFramesPerSecond; | 1053 capture_params.requested_format.frame_rate = kTestFramesPerSecond; |
| 1026 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; | 1054 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
| 1027 capture_params.resolution_change_policy = | 1055 capture_params.resolution_change_policy = |
| 1028 media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT; | 1056 media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT; |
| 1029 | 1057 |
| 1030 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); | 1058 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); |
| 1031 | 1059 |
| 1032 source()->SetUseFrameSubscriber(true); | |
| 1033 | |
| 1034 // Source size equals maximum size. Expect delivered frames to be | 1060 // Source size equals maximum size. Expect delivered frames to be |
| 1035 // kTestWidth by kTestHeight. | 1061 // kTestWidth by kTestHeight. |
| 1036 source()->SetSolidColor(SK_ColorRED); | 1062 source()->SetSolidColor(SK_ColorRED); |
| 1037 const float device_scale_factor = GetDeviceScaleFactor(); | 1063 const float device_scale_factor = GetDeviceScaleFactor(); |
| 1038 SimulateSourceSizeChange(gfx::ConvertSizeToDIP( | 1064 SimulateSourceSizeChange(gfx::ConvertSizeToDIP( |
| 1039 device_scale_factor, gfx::Size(kTestWidth, kTestHeight))); | 1065 device_scale_factor, gfx::Size(kTestWidth, kTestHeight))); |
| 1040 SimulateDrawEvent(); | 1066 SimulateDrawsUntilNewFrameSizeArrives( |
| 1041 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( | 1067 SK_ColorRED, gfx::Size(kTestWidth, kTestHeight)); |
| 1042 SK_ColorRED, gfx::Size(kTestWidth, kTestHeight))); | |
| 1043 | 1068 |
| 1044 // Source size is half in both dimensions. Expect delivered frames to also | 1069 // Source size is half in both dimensions. Expect delivered frames to also |
| 1045 // be half in both dimensions. | 1070 // be half in both dimensions. |
| 1046 source()->SetSolidColor(SK_ColorGREEN); | 1071 source()->SetSolidColor(SK_ColorGREEN); |
| 1047 SimulateSourceSizeChange(gfx::ConvertSizeToDIP( | 1072 SimulateSourceSizeChange(gfx::ConvertSizeToDIP( |
| 1048 device_scale_factor, gfx::Size(kTestWidth / 2, kTestHeight / 2))); | 1073 device_scale_factor, gfx::Size(kTestWidth / 2, kTestHeight / 2))); |
| 1049 SimulateDrawEvent(); | 1074 SimulateDrawsUntilNewFrameSizeArrives( |
| 1050 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( | 1075 SK_ColorGREEN, gfx::Size(kTestWidth / 2, kTestHeight / 2)); |
| 1051 SK_ColorGREEN, gfx::Size(kTestWidth / 2, kTestHeight / 2))); | |
| 1052 | 1076 |
| 1053 // Source size changes to something arbitrary. Since the source size is | 1077 // Source size changes to something arbitrary. Since the source size is |
| 1054 // less than the maximum size, expect delivered frames to be the same size | 1078 // less than the maximum size, expect delivered frames to be the same size |
| 1055 // as the source size. | 1079 // as the source size. |
| 1056 source()->SetSolidColor(SK_ColorBLUE); | 1080 source()->SetSolidColor(SK_ColorBLUE); |
| 1057 gfx::Size arbitrary_source_size(kTestWidth / 2 + 42, kTestHeight - 10); | 1081 gfx::Size arbitrary_source_size(kTestWidth / 2 + 42, kTestHeight - 10); |
| 1058 SimulateSourceSizeChange(gfx::ConvertSizeToDIP(device_scale_factor, | 1082 SimulateSourceSizeChange(gfx::ConvertSizeToDIP(device_scale_factor, |
| 1059 arbitrary_source_size)); | 1083 arbitrary_source_size)); |
| 1060 SimulateDrawEvent(); | 1084 SimulateDrawsUntilNewFrameSizeArrives(SK_ColorBLUE, arbitrary_source_size); |
| 1061 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( | |
| 1062 SK_ColorBLUE, arbitrary_source_size)); | |
| 1063 | 1085 |
| 1064 // Source size changes to something arbitrary that exceeds the maximum frame | 1086 // Source size changes to something arbitrary that exceeds the maximum frame |
| 1065 // size. Since the source size exceeds the maximum size, expect delivered | 1087 // size. Since the source size exceeds the maximum size, expect delivered |
| 1066 // frames to be downscaled. | 1088 // frames to be downscaled. |
| 1067 source()->SetSolidColor(SK_ColorBLACK); | 1089 source()->SetSolidColor(SK_ColorBLACK); |
| 1068 arbitrary_source_size = gfx::Size(kTestWidth * 2, kTestHeight / 2); | 1090 arbitrary_source_size = gfx::Size(kTestWidth * 2, kTestHeight / 2); |
| 1069 SimulateSourceSizeChange(gfx::ConvertSizeToDIP(device_scale_factor, | 1091 SimulateSourceSizeChange(gfx::ConvertSizeToDIP(device_scale_factor, |
| 1070 arbitrary_source_size)); | 1092 arbitrary_source_size)); |
| 1071 SimulateDrawEvent(); | 1093 SimulateDrawsUntilNewFrameSizeArrives( |
| 1072 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColorAndFrameSize( | |
| 1073 SK_ColorBLACK, gfx::Size(kTestWidth, | 1094 SK_ColorBLACK, gfx::Size(kTestWidth, |
| 1074 kTestWidth * arbitrary_source_size.height() / | 1095 kTestWidth * arbitrary_source_size.height() / |
| 1075 arbitrary_source_size.width()))); | 1096 arbitrary_source_size.width())); |
| 1076 | 1097 |
| 1077 device()->StopAndDeAllocate(); | 1098 device()->StopAndDeAllocate(); |
| 1078 } | 1099 } |
| 1079 | 1100 |
| 1080 TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, | 1101 TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, |
| 1081 ComputesStandardResolutionsForPreferredSize) { | 1102 ComputesStandardResolutionsForPreferredSize) { |
| 1082 // Helper function to run the same testing procedure for multiple combinations | 1103 // Helper function to run the same testing procedure for multiple combinations |
| 1083 // of |policy|, |standard_size| and |oddball_size|. | 1104 // of |policy|, |standard_size| and |oddball_size|. |
| 1084 const auto RunTestForPreferredSize = | 1105 const auto RunTestForPreferredSize = |
| 1085 [=](media::ResolutionChangePolicy policy, | 1106 [=](media::ResolutionChangePolicy policy, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1164 // adjustment made. | 1185 // adjustment made. |
| 1165 RunTestForPreferredSize( | 1186 RunTestForPreferredSize( |
| 1166 policies[i], gfx::Size(1000, 1000), gfx::Size(1000, 1000)); | 1187 policies[i], gfx::Size(1000, 1000), gfx::Size(1000, 1000)); |
| 1167 RunTestForPreferredSize( | 1188 RunTestForPreferredSize( |
| 1168 policies[i], gfx::Size(1600, 1000), gfx::Size(1600, 1000)); | 1189 policies[i], gfx::Size(1600, 1000), gfx::Size(1600, 1000)); |
| 1169 RunTestForPreferredSize( | 1190 RunTestForPreferredSize( |
| 1170 policies[i], gfx::Size(837, 999), gfx::Size(837, 999)); | 1191 policies[i], gfx::Size(837, 999), gfx::Size(837, 999)); |
| 1171 } | 1192 } |
| 1172 } | 1193 } |
| 1173 | 1194 |
| 1195 // Tests the RequestRefreshFrame() functionality. |
| 1196 TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, ProvidesRefreshFrames) { |
| 1197 media::VideoCaptureParams capture_params; |
| 1198 capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); |
| 1199 capture_params.requested_format.frame_rate = kTestFramesPerSecond; |
| 1200 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
| 1201 device()->AllocateAndStart(capture_params, client_observer()->PassClient()); |
| 1202 |
| 1203 // Request a refresh frame before the first frame has been drawn. This forces |
| 1204 // a capture. |
| 1205 source()->SetSolidColor(SK_ColorRED); |
| 1206 SimulateRefreshFrameRequest(); |
| 1207 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); |
| 1208 |
| 1209 // Now, draw a frame and wait for a normal frame capture to occur. |
| 1210 source()->SetSolidColor(SK_ColorGREEN); |
| 1211 SimulateDrawEvent(); |
| 1212 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); |
| 1213 |
| 1214 // Now, make three more refresh frame requests. Although the source has |
| 1215 // changed to BLUE, no draw event has occurred. Therefore, expect the refresh |
| 1216 // frames to contain the content from the last drawn frame, which is GREEN. |
| 1217 source()->SetSolidColor(SK_ColorBLUE); |
| 1218 for (int i = 0; i < 3; ++i) { |
| 1219 SimulateRefreshFrameRequest(); |
| 1220 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); |
| 1221 } |
| 1222 |
| 1223 device()->StopAndDeAllocate(); |
| 1224 } |
| 1225 |
| 1174 } // namespace | 1226 } // namespace |
| 1175 } // namespace content | 1227 } // namespace content |
| OLD | NEW |