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 |