| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/renderer_host/media/video_capture_device_client.h" | 5 #include "content/browser/renderer_host/media/video_capture_device_client.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 namespace content { | 30 namespace content { |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 class MockVideoCaptureController : public VideoCaptureController { | 34 class MockVideoCaptureController : public VideoCaptureController { |
| 35 public: | 35 public: |
| 36 explicit MockVideoCaptureController(int max_buffers) | 36 explicit MockVideoCaptureController(int max_buffers) |
| 37 : VideoCaptureController(max_buffers) {} | 37 : VideoCaptureController(max_buffers) {} |
| 38 ~MockVideoCaptureController() override {} | 38 ~MockVideoCaptureController() override {} |
| 39 | 39 |
| 40 MOCK_METHOD1(MockDoIncomingCapturedVideoFrameOnIOThread, | 40 MOCK_METHOD1(MockOnIncomingCapturedVideoFrame, void(const gfx::Size&)); |
| 41 void(const gfx::Size&)); | 41 MOCK_METHOD0(OnError, void()); |
| 42 MOCK_METHOD0(DoErrorOnIOThread, void()); | 42 MOCK_METHOD1(OnLog, void(const std::string& message)); |
| 43 MOCK_METHOD1(DoLogOnIOThread, void(const std::string& message)); | 43 MOCK_METHOD1(OnBufferDestroyed, void(int buffer_id_to_drop)); |
| 44 MOCK_METHOD1(DoBufferDestroyedOnIOThread, void(int buffer_id_to_drop)); | |
| 45 | 44 |
| 46 void DoIncomingCapturedVideoFrameOnIOThread( | 45 void OnIncomingCapturedVideoFrame( |
| 47 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer, | 46 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer, |
| 48 const scoped_refptr<media::VideoFrame>& frame) override { | 47 const scoped_refptr<media::VideoFrame>& frame) override { |
| 49 MockDoIncomingCapturedVideoFrameOnIOThread(frame->coded_size()); | 48 MockOnIncomingCapturedVideoFrame(frame->coded_size()); |
| 50 } | 49 } |
| 51 }; | 50 }; |
| 52 | 51 |
| 53 class VideoCaptureDeviceClientTest : public ::testing::Test { | 52 class VideoCaptureDeviceClientTest : public ::testing::Test { |
| 54 public: | 53 public: |
| 55 VideoCaptureDeviceClientTest() | 54 VideoCaptureDeviceClientTest() |
| 56 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), | 55 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), |
| 57 controller_(new MockVideoCaptureController(1)), | 56 controller_(new MockVideoCaptureController(1)), |
| 58 device_client_(controller_->NewDeviceClient()) {} | 57 device_client_(controller_->NewDeviceClient()) {} |
| 59 ~VideoCaptureDeviceClientTest() override {} | 58 ~VideoCaptureDeviceClientTest() override {} |
| (...skipping 14 matching lines...) Expand all Loading... |
| 74 // A small test for reference and to verify VideoCaptureDeviceClient is | 73 // A small test for reference and to verify VideoCaptureDeviceClient is |
| 75 // minimally functional. | 74 // minimally functional. |
| 76 TEST_F(VideoCaptureDeviceClientTest, Minimal) { | 75 TEST_F(VideoCaptureDeviceClientTest, Minimal) { |
| 77 const size_t kScratchpadSizeInBytes = 400; | 76 const size_t kScratchpadSizeInBytes = 400; |
| 78 unsigned char data[kScratchpadSizeInBytes] = {}; | 77 unsigned char data[kScratchpadSizeInBytes] = {}; |
| 79 const media::VideoCaptureFormat kFrameFormat( | 78 const media::VideoCaptureFormat kFrameFormat( |
| 80 gfx::Size(10, 10), 30.0f /*frame_rate*/, | 79 gfx::Size(10, 10), 30.0f /*frame_rate*/, |
| 81 media::PIXEL_FORMAT_I420, | 80 media::PIXEL_FORMAT_I420, |
| 82 media::PIXEL_STORAGE_CPU); | 81 media::PIXEL_STORAGE_CPU); |
| 83 DCHECK(device_client_.get()); | 82 DCHECK(device_client_.get()); |
| 84 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); | 83 EXPECT_CALL(*controller_, OnLog(_)).Times(1); |
| 85 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 84 EXPECT_CALL(*controller_, MockOnIncomingCapturedVideoFrame(_)).Times(1); |
| 86 .Times(1); | |
| 87 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 85 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
| 88 kFrameFormat, 0 /*clockwise rotation*/, | 86 kFrameFormat, 0 /*clockwise rotation*/, |
| 89 base::TimeTicks(), base::TimeDelta()); | 87 base::TimeTicks(), base::TimeDelta()); |
| 90 base::RunLoop().RunUntilIdle(); | 88 base::RunLoop().RunUntilIdle(); |
| 91 Mock::VerifyAndClearExpectations(controller_.get()); | 89 Mock::VerifyAndClearExpectations(controller_.get()); |
| 92 } | 90 } |
| 93 | 91 |
| 94 // Tests that we don't try to pass on frames with an invalid frame format. | 92 // Tests that we don't try to pass on frames with an invalid frame format. |
| 95 TEST_F(VideoCaptureDeviceClientTest, FailsSilentlyGivenInvalidFrameFormat) { | 93 TEST_F(VideoCaptureDeviceClientTest, FailsSilentlyGivenInvalidFrameFormat) { |
| 96 const size_t kScratchpadSizeInBytes = 400; | 94 const size_t kScratchpadSizeInBytes = 400; |
| 97 unsigned char data[kScratchpadSizeInBytes] = {}; | 95 unsigned char data[kScratchpadSizeInBytes] = {}; |
| 98 // kFrameFormat is invalid in a number of ways. | 96 // kFrameFormat is invalid in a number of ways. |
| 99 const media::VideoCaptureFormat kFrameFormat( | 97 const media::VideoCaptureFormat kFrameFormat( |
| 100 gfx::Size(media::limits::kMaxDimension + 1, media::limits::kMaxDimension), | 98 gfx::Size(media::limits::kMaxDimension + 1, media::limits::kMaxDimension), |
| 101 media::limits::kMaxFramesPerSecond + 1, | 99 media::limits::kMaxFramesPerSecond + 1, |
| 102 media::VideoPixelFormat::PIXEL_FORMAT_I420, | 100 media::VideoPixelFormat::PIXEL_FORMAT_I420, |
| 103 media::VideoPixelStorage::PIXEL_STORAGE_CPU); | 101 media::VideoPixelStorage::PIXEL_STORAGE_CPU); |
| 104 DCHECK(device_client_.get()); | 102 DCHECK(device_client_.get()); |
| 105 // Expect the the call to fail silently inside the VideoCaptureDeviceClient. | 103 // Expect the the call to fail silently inside the VideoCaptureDeviceClient. |
| 106 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); | 104 EXPECT_CALL(*controller_, OnLog(_)).Times(1); |
| 107 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 105 EXPECT_CALL(*controller_, MockOnIncomingCapturedVideoFrame(_)).Times(0); |
| 108 .Times(0); | |
| 109 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 106 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
| 110 kFrameFormat, 0 /*clockwise rotation*/, | 107 kFrameFormat, 0 /*clockwise rotation*/, |
| 111 base::TimeTicks(), base::TimeDelta()); | 108 base::TimeTicks(), base::TimeDelta()); |
| 112 base::RunLoop().RunUntilIdle(); | 109 base::RunLoop().RunUntilIdle(); |
| 113 Mock::VerifyAndClearExpectations(controller_.get()); | 110 Mock::VerifyAndClearExpectations(controller_.get()); |
| 114 } | 111 } |
| 115 | 112 |
| 116 // Tests that we fail silently if no available buffers to use. | 113 // Tests that we fail silently if no available buffers to use. |
| 117 TEST_F(VideoCaptureDeviceClientTest, DropsFrameIfNoBuffer) { | 114 TEST_F(VideoCaptureDeviceClientTest, DropsFrameIfNoBuffer) { |
| 118 const size_t kScratchpadSizeInBytes = 400; | 115 const size_t kScratchpadSizeInBytes = 400; |
| 119 unsigned char data[kScratchpadSizeInBytes] = {}; | 116 unsigned char data[kScratchpadSizeInBytes] = {}; |
| 120 const media::VideoCaptureFormat kFrameFormat( | 117 const media::VideoCaptureFormat kFrameFormat( |
| 121 gfx::Size(10, 10), 30.0f /*frame_rate*/, | 118 gfx::Size(10, 10), 30.0f /*frame_rate*/, |
| 122 media::PIXEL_FORMAT_I420, | 119 media::PIXEL_FORMAT_I420, |
| 123 media::PIXEL_STORAGE_CPU); | 120 media::PIXEL_STORAGE_CPU); |
| 124 // We expect the second frame to be silently dropped, so these should | 121 // We expect the second frame to be silently dropped, so these should |
| 125 // only be called once despite the two frames. | 122 // only be called once despite the two frames. |
| 126 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); | 123 EXPECT_CALL(*controller_, OnLog(_)).Times(1); |
| 127 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 124 EXPECT_CALL(*controller_, MockOnIncomingCapturedVideoFrame(_)).Times(1); |
| 128 .Times(1); | |
| 129 // Pass two frames. The second will be dropped. | 125 // Pass two frames. The second will be dropped. |
| 130 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 126 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
| 131 kFrameFormat, 0 /*clockwise rotation*/, | 127 kFrameFormat, 0 /*clockwise rotation*/, |
| 132 base::TimeTicks(), base::TimeDelta()); | 128 base::TimeTicks(), base::TimeDelta()); |
| 133 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 129 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
| 134 kFrameFormat, 0 /*clockwise rotation*/, | 130 kFrameFormat, 0 /*clockwise rotation*/, |
| 135 base::TimeTicks(), base::TimeDelta()); | 131 base::TimeTicks(), base::TimeDelta()); |
| 136 base::RunLoop().RunUntilIdle(); | 132 base::RunLoop().RunUntilIdle(); |
| 137 Mock::VerifyAndClearExpectations(controller_.get()); | 133 Mock::VerifyAndClearExpectations(controller_.get()); |
| 138 } | 134 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 165 #if defined(OS_WIN) || defined(OS_LINUX) | 161 #if defined(OS_WIN) || defined(OS_LINUX) |
| 166 media::PIXEL_FORMAT_RGB24, | 162 media::PIXEL_FORMAT_RGB24, |
| 167 #endif | 163 #endif |
| 168 media::PIXEL_FORMAT_RGB32, | 164 media::PIXEL_FORMAT_RGB32, |
| 169 media::PIXEL_FORMAT_ARGB | 165 media::PIXEL_FORMAT_ARGB |
| 170 }; | 166 }; |
| 171 | 167 |
| 172 for (media::VideoPixelFormat format : kSupportedFormats) { | 168 for (media::VideoPixelFormat format : kSupportedFormats) { |
| 173 params.requested_format.pixel_format = format; | 169 params.requested_format.pixel_format = format; |
| 174 | 170 |
| 175 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); | 171 EXPECT_CALL(*controller_, OnLog(_)).Times(1); |
| 176 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 172 EXPECT_CALL(*controller_, MockOnIncomingCapturedVideoFrame(_)).Times(1); |
| 177 .Times(1); | |
| 178 device_client_->OnIncomingCapturedData( | 173 device_client_->OnIncomingCapturedData( |
| 179 data, params.requested_format.ImageAllocationSize(), | 174 data, params.requested_format.ImageAllocationSize(), |
| 180 params.requested_format, 0 /* clockwise_rotation */, base::TimeTicks(), | 175 params.requested_format, 0 /* clockwise_rotation */, base::TimeTicks(), |
| 181 base::TimeDelta()); | 176 base::TimeDelta()); |
| 182 base::RunLoop().RunUntilIdle(); | 177 base::RunLoop().RunUntilIdle(); |
| 183 Mock::VerifyAndClearExpectations(controller_.get()); | 178 Mock::VerifyAndClearExpectations(controller_.get()); |
| 184 } | 179 } |
| 185 } | 180 } |
| 186 | 181 |
| 187 // Test that we receive the expected resolution for a given captured frame | 182 // Test that we receive the expected resolution for a given captured frame |
| (...skipping 12 matching lines...) Expand all Loading... |
| 200 {{7, 4}, 180, {6, 4}}, | 195 {{7, 4}, 180, {6, 4}}, |
| 201 {{7, 4}, 270, {4, 6}}}; | 196 {{7, 4}, 270, {4, 6}}}; |
| 202 | 197 |
| 203 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot | 198 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot |
| 204 // be used since it does not resolve rotations or crops. The memory backed | 199 // be used since it does not resolve rotations or crops. The memory backed |
| 205 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad | 200 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad |
| 206 // buffer. | 201 // buffer. |
| 207 const size_t kScratchpadSizeInBytes = 400; | 202 const size_t kScratchpadSizeInBytes = 400; |
| 208 unsigned char data[kScratchpadSizeInBytes] = {}; | 203 unsigned char data[kScratchpadSizeInBytes] = {}; |
| 209 | 204 |
| 210 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); | 205 EXPECT_CALL(*controller_, OnLog(_)).Times(1); |
| 211 | 206 |
| 212 media::VideoCaptureParams params; | 207 media::VideoCaptureParams params; |
| 213 for (const auto& size_and_rotation : kSizeAndRotations) { | 208 for (const auto& size_and_rotation : kSizeAndRotations) { |
| 214 ASSERT_GE(kScratchpadSizeInBytes, | 209 ASSERT_GE(kScratchpadSizeInBytes, |
| 215 size_and_rotation.input_resolution.GetArea() * 4u) | 210 size_and_rotation.input_resolution.GetArea() * 4u) |
| 216 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; | 211 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; |
| 217 params.requested_format = | 212 params.requested_format = |
| 218 media::VideoCaptureFormat(size_and_rotation.input_resolution, 30.0f, | 213 media::VideoCaptureFormat(size_and_rotation.input_resolution, 30.0f, |
| 219 media::PIXEL_FORMAT_ARGB); | 214 media::PIXEL_FORMAT_ARGB); |
| 220 gfx::Size coded_size; | 215 gfx::Size coded_size; |
| 221 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 216 EXPECT_CALL(*controller_, MockOnIncomingCapturedVideoFrame(_)) |
| 222 .Times(1) | 217 .Times(1) |
| 223 .WillOnce(SaveArg<0>(&coded_size)); | 218 .WillOnce(SaveArg<0>(&coded_size)); |
| 224 device_client_->OnIncomingCapturedData( | 219 device_client_->OnIncomingCapturedData( |
| 225 data, params.requested_format.ImageAllocationSize(), | 220 data, params.requested_format.ImageAllocationSize(), |
| 226 params.requested_format, size_and_rotation.rotation, base::TimeTicks(), | 221 params.requested_format, size_and_rotation.rotation, base::TimeTicks(), |
| 227 base::TimeDelta()); | 222 base::TimeDelta()); |
| 228 base::RunLoop().RunUntilIdle(); | 223 base::RunLoop().RunUntilIdle(); |
| 229 | 224 |
| 230 EXPECT_EQ(coded_size.width(), size_and_rotation.output_resolution.width()); | 225 EXPECT_EQ(coded_size.width(), size_and_rotation.output_resolution.width()); |
| 231 EXPECT_EQ(coded_size.height(), | 226 EXPECT_EQ(coded_size.height(), |
| 232 size_and_rotation.output_resolution.height()); | 227 size_and_rotation.output_resolution.height()); |
| 233 | 228 |
| 234 Mock::VerifyAndClearExpectations(controller_.get()); | 229 Mock::VerifyAndClearExpectations(controller_.get()); |
| 235 } | 230 } |
| 236 } | 231 } |
| 237 | 232 |
| 238 } // namespace content | 233 } // namespace content |
| OLD | NEW |