| Index: content/browser/renderer_host/media/video_capture_controller_unittest.cc
|
| diff --git a/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
|
| index 41fcc2c262aedb26d812324beb2f5f9c3ff0c837..7e8f055aa130e36147e4dcf337ed678cc0698622 100644
|
| --- a/content/browser/renderer_host/media/video_capture_controller_unittest.cc
|
| +++ b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
|
| @@ -29,8 +29,10 @@
|
| #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
|
| #endif
|
|
|
| +using ::testing::_;
|
| using ::testing::InSequence;
|
| using ::testing::Mock;
|
| +using ::testing::SaveArg;
|
|
|
| namespace content {
|
|
|
| @@ -46,7 +48,7 @@ class MockVideoCaptureControllerEventHandler
|
| // VideoCaptureControllerEventHandler, to be used in EXPECT_CALL().
|
| MOCK_METHOD1(DoBufferCreated, void(VideoCaptureControllerID));
|
| MOCK_METHOD1(DoBufferDestroyed, void(VideoCaptureControllerID));
|
| - MOCK_METHOD1(DoBufferReady, void(VideoCaptureControllerID));
|
| + MOCK_METHOD2(DoBufferReady, void(VideoCaptureControllerID, const gfx::Size&));
|
| MOCK_METHOD1(DoMailboxBufferReady, void(VideoCaptureControllerID));
|
| MOCK_METHOD1(DoEnded, void(VideoCaptureControllerID));
|
| MOCK_METHOD1(DoError, void(VideoCaptureControllerID));
|
| @@ -70,7 +72,7 @@ class MockVideoCaptureControllerEventHandler
|
| const gfx::Rect& visible_rect,
|
| const base::TimeTicks& timestamp,
|
| scoped_ptr<base::DictionaryValue> metadata) override {
|
| - DoBufferReady(id);
|
| + DoBufferReady(id, coded_size);
|
| base::MessageLoop::current()->PostTask(
|
| FROM_HERE,
|
| base::Bind(&VideoCaptureController::ReturnBuffer,
|
| @@ -331,17 +333,17 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
| {
|
| InSequence s;
|
| EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)).Times(1);
|
| - EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(1);
|
| + EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1,_)).Times(1);
|
| }
|
| {
|
| InSequence s;
|
| EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1)).Times(1);
|
| - EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(1);
|
| + EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1,_)).Times(1);
|
| }
|
| {
|
| InSequence s;
|
| EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)).Times(1);
|
| - EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(1);
|
| + EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2,_)).Times(1);
|
| }
|
| device_->OnIncomingCapturedVideoFrame(
|
| buffer,
|
| @@ -367,9 +369,9 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
| buffer = NULL;
|
|
|
| // The buffer should be delivered to the clients in any order.
|
| - EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(1);
|
| - EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(1);
|
| - EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(1);
|
| + EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1,_)).Times(1);
|
| + EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1,_)).Times(1);
|
| + EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2,_)).Times(1);
|
| base::RunLoop().RunUntilIdle();
|
| Mock::VerifyAndClearExpectations(client_a_.get());
|
| Mock::VerifyAndClearExpectations(client_b_.get());
|
| @@ -400,16 +402,16 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
|
|
| // The new client needs to be told of 3 buffers; the old clients only 2.
|
| EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_2)).Times(kPoolSize);
|
| - EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2)).Times(kPoolSize);
|
| + EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2,_)).Times(kPoolSize);
|
| EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1))
|
| .Times(kPoolSize - 1);
|
| - EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(kPoolSize);
|
| + EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1,_)).Times(kPoolSize);
|
| EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2))
|
| .Times(kPoolSize - 1);
|
| - EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(kPoolSize);
|
| + EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2,_)).Times(kPoolSize);
|
| EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1))
|
| .Times(kPoolSize - 1);
|
| - EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(kPoolSize);
|
| + EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1,_)).Times(kPoolSize);
|
| base::RunLoop().RunUntilIdle();
|
| Mock::VerifyAndClearExpectations(client_a_.get());
|
| Mock::VerifyAndClearExpectations(client_b_.get());
|
| @@ -447,7 +449,7 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
| buffer = NULL;
|
| // B2 is the only client left, and is the only one that should
|
| // get the buffer.
|
| - EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2)).Times(2);
|
| + EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2,_)).Times(2);
|
| base::RunLoop().RunUntilIdle();
|
| Mock::VerifyAndClearExpectations(client_a_.get());
|
| Mock::VerifyAndClearExpectations(client_b_.get());
|
| @@ -500,7 +502,7 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
| capture_resolution).get());
|
| ASSERT_FALSE(device_->ReserveOutputBuffer(media::VideoFrame::NATIVE_TEXTURE,
|
| gfx::Size(0, 0)).get());
|
| - EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2)).Times(shm_buffers);
|
| + EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2,_)).Times(shm_buffers);
|
| EXPECT_CALL(*client_b_, DoMailboxBufferReady(client_b_route_2))
|
| .Times(mailbox_buffers);
|
| base::RunLoop().RunUntilIdle();
|
| @@ -618,30 +620,91 @@ TEST_F(VideoCaptureControllerTest, DataCaptureInEachVideoFormatInSequence) {
|
| const gfx::Size capture_resolution(10, 10);
|
| ASSERT_GE(kScratchpadSizeInBytes, capture_resolution.GetArea() * 4u)
|
| << "Scratchpad is too small to hold the largest pixel format (ARGB).";
|
| +
|
| + const int kSessionId = 100;
|
| // This Test skips PIXEL_FORMAT_TEXTURE and PIXEL_FORMAT_UNKNOWN.
|
| for (int format = 0; format < media::PIXEL_FORMAT_TEXTURE; ++format) {
|
| media::VideoCaptureParams params;
|
| params.requested_format = media::VideoCaptureFormat(
|
| capture_resolution, 30, media::VideoPixelFormat(format));
|
|
|
| - const gfx::Size capture_resolution(320, 240);
|
| -
|
| - const VideoCaptureControllerID route(0x99);
|
| -
|
| // Start with one client.
|
| - controller_->AddClient(route,
|
| + const VideoCaptureControllerID route_id(0x99);
|
| + controller_->AddClient(route_id,
|
| client_a_.get(),
|
| base::kNullProcessHandle,
|
| - 100,
|
| + kSessionId,
|
| params);
|
| ASSERT_EQ(1, controller_->GetClientCount());
|
| device_->OnIncomingCapturedData(
|
| - data,
|
| - params.requested_format.ImageAllocationSize(),
|
| - params.requested_format,
|
| - 0 /* rotation */,
|
| - base::TimeTicks());
|
| - EXPECT_EQ(100, controller_->RemoveClient(route, client_a_.get()));
|
| + data,
|
| + params.requested_format.ImageAllocationSize(),
|
| + params.requested_format,
|
| + 0 /* clockwise_rotation */,
|
| + base::TimeTicks());
|
| + EXPECT_EQ(kSessionId, controller_->RemoveClient(route_id, client_a_.get()));
|
| + Mock::VerifyAndClearExpectations(client_a_.get());
|
| + }
|
| +}
|
| +
|
| +// Test that we receive the expected resolution for a given captured frame
|
| +// resolution and rotation. Odd resolutions are also cropped.
|
| +TEST_F(VideoCaptureControllerTest, CheckRotationsAndCrops) {
|
| + const int kSessionId = 100;
|
| + const struct SizeAndRotation {
|
| + gfx::Size input_resolution;
|
| + int rotation;
|
| + gfx::Size output_resolution;
|
| + } kSizeAndRotations[] = {{{6, 4}, 0, {6, 4}},
|
| + {{6, 4}, 90, {4, 6}},
|
| + {{6, 4}, 180, {6, 4}},
|
| + {{6, 4}, 270, {4, 6}},
|
| + {{7, 4}, 0, {6, 4}},
|
| + {{7, 4}, 90, {4, 6}},
|
| + {{7, 4}, 180, {6, 4}},
|
| + {{7, 4}, 270, {4, 6}}};
|
| + // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot
|
| + // be used since it does not resolve rotations or crops. The memory backed
|
| + // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad
|
| + // buffer.
|
| + const size_t kScratchpadSizeInBytes = 400;
|
| + unsigned char data[kScratchpadSizeInBytes] = {};
|
| +
|
| + media::VideoCaptureParams params;
|
| + for (const auto& size_and_rotation : kSizeAndRotations) {
|
| + ASSERT_GE(kScratchpadSizeInBytes,
|
| + size_and_rotation.input_resolution.GetArea() * 4u)
|
| + << "Scratchpad is too small to hold the largest pixel format (ARGB).";
|
| +
|
| + params.requested_format = media::VideoCaptureFormat(
|
| + size_and_rotation.input_resolution, 30, media::PIXEL_FORMAT_ARGB);
|
| +
|
| + const VideoCaptureControllerID route_id(0x99);
|
| + controller_->AddClient(route_id, client_a_.get(), base::kNullProcessHandle,
|
| + kSessionId, params);
|
| + ASSERT_EQ(1, controller_->GetClientCount());
|
| +
|
| + device_->OnIncomingCapturedData(
|
| + data,
|
| + params.requested_format.ImageAllocationSize(),
|
| + params.requested_format,
|
| + size_and_rotation.rotation,
|
| + base::TimeTicks());
|
| + gfx::Size coded_size;
|
| + {
|
| + InSequence s;
|
| + EXPECT_CALL(*client_a_, DoBufferCreated(route_id)).Times(1);
|
| + EXPECT_CALL(*client_a_, DoBufferReady(route_id, _))
|
| + .Times(1)
|
| + .WillOnce(SaveArg<1>(&coded_size));
|
| + }
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + EXPECT_EQ(coded_size.width(), size_and_rotation.output_resolution.width());
|
| + EXPECT_EQ(coded_size.height(),
|
| + size_and_rotation.output_resolution.height());
|
| +
|
| + EXPECT_EQ(kSessionId, controller_->RemoveClient(route_id, client_a_.get()));
|
| Mock::VerifyAndClearExpectations(client_a_.get());
|
| }
|
| }
|
|
|