Index: content/browser/media/capture/web_contents_video_capture_device_unittest.cc |
diff --git a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc |
index ab430a7625f31ecb52a1b94d90e1d34c17e63164..911feae0a4da9f82921de898f4056b374a20808f 100644 |
--- a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc |
+++ b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc |
@@ -162,13 +162,25 @@ class CaptureTestView : public TestRenderWidgetHostView { |
explicit CaptureTestView(RenderWidgetHostImpl* rwh, |
CaptureTestSourceController* controller) |
: TestRenderWidgetHostView(rwh), |
- controller_(controller) {} |
+ rwh_(rwh), |
+ controller_(controller), |
+ fake_bounds_(100, 100, 100 + kTestWidth, 100 + kTestHeight) {} |
~CaptureTestView() override {} |
// TestRenderWidgetHostView overrides. |
gfx::Rect GetViewBounds() const override { |
- return gfx::Rect(100, 100, 100 + kTestWidth, 100 + kTestHeight); |
+ return fake_bounds_; |
+ } |
+ |
+ void SetSize(const gfx::Size& size) override { |
+ fake_bounds_.set_size(size); |
+ rwh_->WasResized(); |
Wez
2015/05/14 01:44:56
nit: Reimpl this in terms of SetBounds() via gfx::
miu
2015/05/14 21:12:27
Done.
|
+ } |
+ |
+ void SetBounds(const gfx::Rect& rect) override { |
+ fake_bounds_ = rect; |
+ rwh_->WasResized(); |
miu
2015/05/14 21:12:27
FYI--I found a bug, where WasResized() wasn't noti
|
} |
bool CanCopyToVideoFrame() const override { |
@@ -212,7 +224,12 @@ class CaptureTestView : public TestRenderWidgetHostView { |
private: |
scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber_; |
+ // TODO(miu): Investigate why TestRenderWidgetHostView::GetRenderWidgetHost() |
+ // always returns null, and perhaps fix it in order to remove this |rwh_| |
+ // member. |
Wez
2015/05/14 01:44:56
Bug # for that change?
Looking at the code, doesn
miu
2015/05/14 21:12:27
Done. http://crbug.com/487939
FYI--I reworked a
|
+ RenderWidgetHostImpl* const rwh_; |
CaptureTestSourceController* const controller_; |
+ gfx::Rect fake_bounds_; |
DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestView); |
}; |
@@ -311,7 +328,9 @@ class StubClient : public media::VideoCaptureDevice::Client { |
StubClient(const base::Callback<void(SkColor)>& color_callback, |
const base::Closure& error_callback) |
: color_callback_(color_callback), |
- error_callback_(error_callback) { |
+ error_callback_(error_callback), |
+ expected_frame_size_(kTestWidth, kTestHeight), |
+ resolution_change_policy_(media::RESOLUTION_POLICY_FIXED_RESOLUTION) { |
buffer_pool_ = new VideoCaptureBufferPool(2); |
} |
~StubClient() override {} |
@@ -335,6 +354,12 @@ class StubClient : public media::VideoCaptureDevice::Client { |
MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void)); |
+ void SetExpectedFrameSizeProperties(const gfx::Size& max_size, |
miu
2015/05/14 21:12:27
FYI--This was moved into StubClientObserver, since
|
+ media::ResolutionChangePolicy policy) { |
+ expected_frame_size_ = max_size; |
+ resolution_change_policy_ = policy; |
+ } |
+ |
scoped_ptr<media::VideoCaptureDevice::Client::Buffer> ReserveOutputBuffer( |
media::VideoPixelFormat format, |
const gfx::Size& dimensions) override { |
@@ -360,7 +385,31 @@ class StubClient : public media::VideoCaptureDevice::Client { |
scoped_ptr<Buffer> buffer, |
const scoped_refptr<media::VideoFrame>& frame, |
const base::TimeTicks& timestamp) override { |
- EXPECT_EQ(gfx::Size(kTestWidth, kTestHeight), frame->visible_rect().size()); |
+ switch (resolution_change_policy_) { |
+ case media::RESOLUTION_POLICY_FIXED_RESOLUTION: |
+ EXPECT_EQ(expected_frame_size_, frame->visible_rect().size()); |
+ break; |
+ case media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO: |
+ EXPECT_FALSE(frame->visible_rect().IsEmpty()); |
+ EXPECT_GE(expected_frame_size_.width(), frame->visible_rect().width()); |
+ EXPECT_GE(expected_frame_size_.height(), |
+ frame->visible_rect().height()); |
+ EXPECT_NEAR(static_cast<double>(expected_frame_size_.width()) / |
+ expected_frame_size_.height(), |
+ static_cast<double>(frame->visible_rect().width()) / |
+ frame->visible_rect().height(), |
+ 0.01); |
+ break; |
+ case media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT: |
+ EXPECT_FALSE(frame->visible_rect().IsEmpty()); |
+ EXPECT_GE(expected_frame_size_.width(), frame->visible_rect().width()); |
+ EXPECT_GE(expected_frame_size_.height(), |
+ frame->visible_rect().height()); |
+ break; |
+ default: |
+ FAIL(); |
+ break; |
+ } |
EXPECT_EQ(media::VideoFrame::I420, frame->format()); |
double frame_rate = 0; |
EXPECT_TRUE( |
@@ -410,6 +459,9 @@ class StubClient : public media::VideoCaptureDevice::Client { |
base::Callback<void(SkColor)> color_callback_; |
base::Closure error_callback_; |
+ gfx::Size expected_frame_size_; |
Wez
2015/05/14 01:44:56
This is a misleading name, since it's not the actu
miu
2015/05/14 21:12:27
Done.
|
+ media::ResolutionChangePolicy resolution_change_policy_; |
+ |
DISALLOW_COPY_AND_ASSIGN(StubClient); |
}; |
@@ -622,6 +674,13 @@ class WebContentsVideoCaptureDeviceTest : public testing::Test { |
} |
} |
+ void SimulateSourceSizeChange(const gfx::Size& size) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ CaptureTestView* test_view = static_cast<CaptureTestView*>( |
+ web_contents_->GetRenderViewHost()->GetView()); |
+ test_view->SetSize(size); |
+ } |
+ |
void DestroyVideoCaptureDevice() { device_.reset(); } |
StubClientObserver* client_observer() { |
@@ -879,5 +938,157 @@ TEST_F(WebContentsVideoCaptureDeviceTest, BadFramesGoodFrames) { |
device()->StopAndDeAllocate(); |
} |
+// Tests that, when configured with the FIXED_ASPECT_RATIO resolution change |
+// policy, the source size changes result in video frames of possibly varying |
+// resolutions, but all with the same aspect ratio. |
+TEST_F(WebContentsVideoCaptureDeviceTest, VariableResolution_FixedAspectRatio) { |
+ media::VideoCaptureParams capture_params; |
+ capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); |
+ capture_params.requested_format.frame_rate = kTestFramesPerSecond; |
+ capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
+ capture_params.resolution_change_policy = |
+ media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO; |
+ |
+ scoped_ptr<media::VideoCaptureDevice::Client> client = |
+ client_observer()->PassClient(); |
+ StubClient* const stub_client = static_cast<StubClient*>(client.get()); |
+ stub_client->SetExpectedFrameSizeProperties( |
+ gfx::Size(kTestWidth, kTestHeight), |
+ media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO); |
+ device()->AllocateAndStart(capture_params, client.Pass()); |
+ |
+ for (int i = 0; i < 6; i++) { |
+ const char* name = NULL; |
+ switch (i % 3) { |
+ case 0: |
+ source()->SetCanCopyToVideoFrame(true); |
+ source()->SetUseFrameSubscriber(false); |
+ name = "VideoFrame"; |
+ break; |
+ case 1: |
+ source()->SetCanCopyToVideoFrame(false); |
+ source()->SetUseFrameSubscriber(true); |
+ name = "Subscriber"; |
+ break; |
+ case 2: |
+ source()->SetCanCopyToVideoFrame(false); |
+ source()->SetUseFrameSubscriber(false); |
+ name = "SkBitmap"; |
+ break; |
+ default: |
+ FAIL(); |
+ } |
+ |
+ SCOPED_TRACE(base::StringPrintf("Using %s path, iteration #%d", name, i)); |
+ |
+ // Source size equals maximum size. StubClient will expect frames to be |
+ // kTestWidth by kTestHeight. |
+ SimulateSourceSizeChange(gfx::Size(kTestWidth, kTestHeight)); |
+ source()->SetSolidColor(SK_ColorRED); |
+ SimulateDrawEvent(); |
+ ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); |
+ |
+ // Source size is half in both dimensions. StubClient will confirm the |
+ // aspect ratio of the resulting frames is correct. |
+ SimulateSourceSizeChange(gfx::Size(kTestWidth / 2, kTestHeight / 2)); |
+ source()->SetSolidColor(SK_ColorGREEN); |
+ SimulateDrawEvent(); |
+ ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); |
+ |
+ // Source size changes aspect ratio. StubClient will confirm the aspect |
+ // ratio of the resulting frames is correct. |
+ SimulateSourceSizeChange(gfx::Size(kTestWidth / 2, kTestHeight)); |
+ source()->SetSolidColor(SK_ColorBLUE); |
+ SimulateDrawEvent(); |
+ ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorBLUE)); |
+ |
+ // Source size changes aspect ratio again. StubClient will confirm the |
+ // aspect ratio of the resulting frames is correct. |
+ SimulateSourceSizeChange(gfx::Size(kTestWidth, kTestHeight / 2)); |
+ source()->SetSolidColor(SK_ColorBLACK); |
+ SimulateDrawEvent(); |
+ ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorBLACK)); |
+ } |
+ |
+ device()->StopAndDeAllocate(); |
+} |
+ |
+// Tests that, when configured with the ANY_WITHIN_LIMIT resolution change |
+// policy, the source size changes result in video frames of possibly varying |
+// resolutions. |
+TEST_F(WebContentsVideoCaptureDeviceTest, VariableResolution_AnyWithinLimits) { |
+ media::VideoCaptureParams capture_params; |
+ capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); |
+ capture_params.requested_format.frame_rate = kTestFramesPerSecond; |
+ capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
+ capture_params.resolution_change_policy = |
+ media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT; |
+ |
+ scoped_ptr<media::VideoCaptureDevice::Client> client = |
+ client_observer()->PassClient(); |
+ StubClient* const stub_client = static_cast<StubClient*>(client.get()); |
+ stub_client->SetExpectedFrameSizeProperties( |
+ gfx::Size(kTestWidth, kTestHeight), |
+ media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT); |
+ device()->AllocateAndStart(capture_params, client.Pass()); |
+ |
+ for (int i = 0; i < 6; i++) { |
+ const char* name = NULL; |
+ switch (i % 3) { |
+ case 0: |
+ source()->SetCanCopyToVideoFrame(true); |
+ source()->SetUseFrameSubscriber(false); |
+ name = "VideoFrame"; |
+ break; |
+ case 1: |
+ source()->SetCanCopyToVideoFrame(false); |
+ source()->SetUseFrameSubscriber(true); |
+ name = "Subscriber"; |
+ break; |
+ case 2: |
+ source()->SetCanCopyToVideoFrame(false); |
+ source()->SetUseFrameSubscriber(false); |
+ name = "SkBitmap"; |
+ break; |
+ default: |
+ FAIL(); |
+ } |
+ |
+ SCOPED_TRACE(base::StringPrintf("Using %s path, iteration #%d", name, i)); |
+ |
+ // Source size equals maximum size. StubClient will expect frames to be |
+ // kTestWidth by kTestHeight. |
+ SimulateSourceSizeChange(gfx::Size(kTestWidth, kTestHeight)); |
+ source()->SetSolidColor(SK_ColorRED); |
+ SimulateDrawEvent(); |
+ ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); |
+ |
+ // Source size is half in both dimensions. StubClient will confirm the |
+ // resulting frame is also half in both dimensions. |
+ SimulateSourceSizeChange(gfx::Size(kTestWidth / 2, kTestHeight / 2)); |
+ source()->SetSolidColor(SK_ColorGREEN); |
+ SimulateDrawEvent(); |
+ ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); |
+ |
+ // Source size changes to something arbitrary. StubClient will confirm the |
+ // resulting frame has the same dimensions. |
+ SimulateSourceSizeChange(gfx::Size(kTestWidth / 2 + 42, |
+ kTestHeight * 2 - 10)); |
+ source()->SetSolidColor(SK_ColorBLUE); |
+ SimulateDrawEvent(); |
+ ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorBLUE)); |
+ |
+ // Source size changes to something arbitrary that exceeds the maximum frame |
+ // size. StubClient will confirm the resulting frame has dimensions within |
+ // the maximum limit. |
+ SimulateSourceSizeChange(gfx::Size(kTestWidth * 2 + 99, kTestHeight / 2)); |
+ source()->SetSolidColor(SK_ColorBLACK); |
+ SimulateDrawEvent(); |
+ ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorBLACK)); |
+ } |
+ |
+ device()->StopAndDeAllocate(); |
+} |
+ |
} // namespace |
} // namespace content |