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 <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" |
8 #include "base/macros.h" | 9 #include "base/macros.h" |
9 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
10 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
11 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
12 #include "base/thread_task_runner_handle.h" | 13 #include "base/thread_task_runner_handle.h" |
13 #include "build/build_config.h" | 14 #include "build/build_config.h" |
14 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" | 15 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" |
15 #include "content/browser/renderer_host/media/video_capture_controller.h" | 16 #include "content/browser/renderer_host/media/video_capture_controller.h" |
16 #include "content/browser/renderer_host/media/video_capture_device_client.h" | 17 #include "content/browser/renderer_host/media/video_capture_device_client.h" |
17 #include "content/public/test/test_browser_thread_bundle.h" | 18 #include "content/public/test/test_browser_thread_bundle.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 // A small test for reference and to verify VideoCaptureDeviceClient is | 73 // A small test for reference and to verify VideoCaptureDeviceClient is |
73 // minimally functional. | 74 // minimally functional. |
74 TEST_F(VideoCaptureDeviceClientTest, Minimal) { | 75 TEST_F(VideoCaptureDeviceClientTest, Minimal) { |
75 const size_t kScratchpadSizeInBytes = 400; | 76 const size_t kScratchpadSizeInBytes = 400; |
76 unsigned char data[kScratchpadSizeInBytes] = {}; | 77 unsigned char data[kScratchpadSizeInBytes] = {}; |
77 const media::VideoCaptureFormat kFrameFormat( | 78 const media::VideoCaptureFormat kFrameFormat( |
78 gfx::Size(10, 10), 30.0f /*frame_rate*/, | 79 gfx::Size(10, 10), 30.0f /*frame_rate*/, |
79 media::PIXEL_FORMAT_I420, | 80 media::PIXEL_FORMAT_I420, |
80 media::PIXEL_STORAGE_CPU); | 81 media::PIXEL_STORAGE_CPU); |
81 DCHECK(device_client_.get()); | 82 DCHECK(device_client_.get()); |
| 83 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
82 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 84 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
83 .Times(1); | 85 .Times(1); |
84 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 86 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
85 kFrameFormat, 0 /*clockwise rotation*/, | 87 kFrameFormat, 0 /*clockwise rotation*/, |
86 base::TimeTicks()); | 88 base::TimeTicks()); |
87 base::RunLoop().RunUntilIdle(); | 89 base::RunLoop().RunUntilIdle(); |
88 Mock::VerifyAndClearExpectations(controller_.get()); | 90 Mock::VerifyAndClearExpectations(controller_.get()); |
89 } | 91 } |
90 | 92 |
91 // Tests that we don't try to pass on frames with an invalid frame format. | 93 // Tests that we don't try to pass on frames with an invalid frame format. |
92 TEST_F(VideoCaptureDeviceClientTest, FailsSilentlyGivenInvalidFrameFormat) { | 94 TEST_F(VideoCaptureDeviceClientTest, FailsSilentlyGivenInvalidFrameFormat) { |
93 const size_t kScratchpadSizeInBytes = 400; | 95 const size_t kScratchpadSizeInBytes = 400; |
94 unsigned char data[kScratchpadSizeInBytes] = {}; | 96 unsigned char data[kScratchpadSizeInBytes] = {}; |
95 // kFrameFormat is invalid in a number of ways. | 97 // kFrameFormat is invalid in a number of ways. |
96 const media::VideoCaptureFormat kFrameFormat( | 98 const media::VideoCaptureFormat kFrameFormat( |
97 gfx::Size(media::limits::kMaxDimension + 1, media::limits::kMaxDimension), | 99 gfx::Size(media::limits::kMaxDimension + 1, media::limits::kMaxDimension), |
98 media::limits::kMaxFramesPerSecond + 1, | 100 media::limits::kMaxFramesPerSecond + 1, |
99 media::VideoPixelFormat::PIXEL_FORMAT_I420, | 101 media::VideoPixelFormat::PIXEL_FORMAT_I420, |
100 media::VideoPixelStorage::PIXEL_STORAGE_CPU); | 102 media::VideoPixelStorage::PIXEL_STORAGE_CPU); |
101 DCHECK(device_client_.get()); | 103 DCHECK(device_client_.get()); |
102 // Expect the the call to fail silently inside the VideoCaptureDeviceClient. | 104 // Expect the the call to fail silently inside the VideoCaptureDeviceClient. |
| 105 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
103 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 106 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
104 .Times(0); | 107 .Times(0); |
105 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 108 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
106 kFrameFormat, 0 /*clockwise rotation*/, | 109 kFrameFormat, 0 /*clockwise rotation*/, |
107 base::TimeTicks()); | 110 base::TimeTicks()); |
108 base::RunLoop().RunUntilIdle(); | 111 base::RunLoop().RunUntilIdle(); |
109 Mock::VerifyAndClearExpectations(controller_.get()); | 112 Mock::VerifyAndClearExpectations(controller_.get()); |
110 } | 113 } |
111 | 114 |
112 // Tests that we fail silently if no available buffers to use. | 115 // Tests that we fail silently if no available buffers to use. |
113 TEST_F(VideoCaptureDeviceClientTest, DropsFrameIfNoBuffer) { | 116 TEST_F(VideoCaptureDeviceClientTest, DropsFrameIfNoBuffer) { |
114 const size_t kScratchpadSizeInBytes = 400; | 117 const size_t kScratchpadSizeInBytes = 400; |
115 unsigned char data[kScratchpadSizeInBytes] = {}; | 118 unsigned char data[kScratchpadSizeInBytes] = {}; |
116 const media::VideoCaptureFormat kFrameFormat( | 119 const media::VideoCaptureFormat kFrameFormat( |
117 gfx::Size(10, 10), 30.0f /*frame_rate*/, | 120 gfx::Size(10, 10), 30.0f /*frame_rate*/, |
118 media::PIXEL_FORMAT_I420, | 121 media::PIXEL_FORMAT_I420, |
119 media::PIXEL_STORAGE_CPU); | 122 media::PIXEL_STORAGE_CPU); |
120 // We expect the second frame to be silently dropped, so these should | 123 // We expect the second frame to be silently dropped, so these should |
121 // only be called once despite the two frames. | 124 // only be called once despite the two frames. |
| 125 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
122 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 126 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
123 .Times(1); | 127 .Times(1); |
124 // Pass two frames. The second will be dropped. | 128 // Pass two frames. The second will be dropped. |
125 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 129 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
126 kFrameFormat, 0 /*clockwise rotation*/, | 130 kFrameFormat, 0 /*clockwise rotation*/, |
127 base::TimeTicks()); | 131 base::TimeTicks()); |
128 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, | 132 device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, |
129 kFrameFormat, 0 /*clockwise rotation*/, | 133 kFrameFormat, 0 /*clockwise rotation*/, |
130 base::TimeTicks()); | 134 base::TimeTicks()); |
131 base::RunLoop().RunUntilIdle(); | 135 base::RunLoop().RunUntilIdle(); |
132 Mock::VerifyAndClearExpectations(controller_.get()); | 136 Mock::VerifyAndClearExpectations(controller_.get()); |
133 } | 137 } |
134 | 138 |
135 // Tests that buffer-based capture API accepts all memory-backed pixel formats. | 139 // Tests that buffer-based capture API accepts some memory-backed pixel formats. |
136 TEST_F(VideoCaptureDeviceClientTest, DataCaptureInEachVideoFormatInSequence) { | 140 TEST_F(VideoCaptureDeviceClientTest, DataCaptureGoodPixelFormats) { |
137 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot | 141 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot |
138 // be used since it does not accept all pixel formats. The memory backed | 142 // be used since it does not accept all pixel formats. The memory backed |
139 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad | 143 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad |
140 // buffer. | 144 // buffer. |
141 const size_t kScratchpadSizeInBytes = 400; | 145 const size_t kScratchpadSizeInBytes = 400; |
142 unsigned char data[kScratchpadSizeInBytes] = {}; | 146 unsigned char data[kScratchpadSizeInBytes] = {}; |
143 const gfx::Size capture_resolution(10, 10); | 147 const gfx::Size kCaptureResolution(10, 10); |
144 ASSERT_GE(kScratchpadSizeInBytes, capture_resolution.GetArea() * 4u) | 148 ASSERT_GE(kScratchpadSizeInBytes, kCaptureResolution.GetArea() * 4u) |
145 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; | 149 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; |
146 | 150 |
147 for (int format = 0; format < media::PIXEL_FORMAT_MAX; | 151 media::VideoCaptureParams params; |
148 ++format) { | 152 params.requested_format = media::VideoCaptureFormat( |
149 // Conversion from some formats are unsupported. | 153 kCaptureResolution, 30.0f, media::PIXEL_FORMAT_UNKNOWN); |
150 if (format == media::PIXEL_FORMAT_UNKNOWN || | 154 |
151 format == media::PIXEL_FORMAT_YV16 || | 155 // Only use the VideoPixelFormats that we know supported. Do not add |
152 format == media::PIXEL_FORMAT_YV12A || | 156 // PIXEL_FORMAT_MJPEG since it would need a real JPEG header. |
153 format == media::PIXEL_FORMAT_YV24 || | 157 const media::VideoPixelFormat kSupportedFormats[] = { |
154 format == media::PIXEL_FORMAT_ARGB || | 158 media::PIXEL_FORMAT_I420, |
155 format == media::PIXEL_FORMAT_XRGB || | 159 media::PIXEL_FORMAT_YV12, |
156 format == media::PIXEL_FORMAT_MJPEG || | 160 media::PIXEL_FORMAT_NV12, |
157 format == media::PIXEL_FORMAT_MT21 || | 161 media::PIXEL_FORMAT_NV21, |
158 format == media::PIXEL_FORMAT_YUV420P9 || | 162 media::PIXEL_FORMAT_YUY2, |
159 format == media::PIXEL_FORMAT_YUV420P10 || | 163 media::PIXEL_FORMAT_UYVY, |
160 format == media::PIXEL_FORMAT_YUV422P9 || | 164 #if defined(OS_WIN) || defined(OS_LINUX) |
161 format == media::PIXEL_FORMAT_YUV422P10 || | 165 media::PIXEL_FORMAT_RGB24, |
162 format == media::PIXEL_FORMAT_YUV444P9 || | |
163 format == media::PIXEL_FORMAT_YUV444P10) { | |
164 continue; | |
165 } | |
166 #if !defined(OS_LINUX) && !defined(OS_WIN) | |
167 if (format == media::PIXEL_FORMAT_RGB24) { | |
168 continue; | |
169 } | |
170 #endif | 166 #endif |
171 media::VideoCaptureParams params; | 167 media::PIXEL_FORMAT_RGB32, |
172 params.requested_format = media::VideoCaptureFormat( | 168 media::PIXEL_FORMAT_ARGB |
173 capture_resolution, 30.0f, media::VideoPixelFormat(format)); | 169 }; |
| 170 |
| 171 for (media::VideoPixelFormat format : kSupportedFormats) { |
| 172 params.requested_format.pixel_format = format; |
| 173 |
| 174 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
174 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 175 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
175 .Times(1); | 176 .Times(1); |
176 device_client_->OnIncomingCapturedData( | 177 device_client_->OnIncomingCapturedData( |
177 data, params.requested_format.ImageAllocationSize(), | 178 data, params.requested_format.ImageAllocationSize(), |
178 params.requested_format, 0 /* clockwise_rotation */, base::TimeTicks()); | 179 params.requested_format, 0 /* clockwise_rotation */, base::TimeTicks()); |
179 base::RunLoop().RunUntilIdle(); | 180 base::RunLoop().RunUntilIdle(); |
180 Mock::VerifyAndClearExpectations(controller_.get()); | 181 Mock::VerifyAndClearExpectations(controller_.get()); |
181 } | 182 } |
182 } | 183 } |
183 | 184 |
(...skipping 13 matching lines...) Expand all Loading... |
197 {{7, 4}, 180, {6, 4}}, | 198 {{7, 4}, 180, {6, 4}}, |
198 {{7, 4}, 270, {4, 6}}}; | 199 {{7, 4}, 270, {4, 6}}}; |
199 | 200 |
200 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot | 201 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot |
201 // be used since it does not resolve rotations or crops. The memory backed | 202 // be used since it does not resolve rotations or crops. The memory backed |
202 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad | 203 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad |
203 // buffer. | 204 // buffer. |
204 const size_t kScratchpadSizeInBytes = 400; | 205 const size_t kScratchpadSizeInBytes = 400; |
205 unsigned char data[kScratchpadSizeInBytes] = {}; | 206 unsigned char data[kScratchpadSizeInBytes] = {}; |
206 | 207 |
| 208 EXPECT_CALL(*controller_, DoLogOnIOThread(_)).Times(1); |
| 209 |
207 media::VideoCaptureParams params; | 210 media::VideoCaptureParams params; |
208 for (const auto& size_and_rotation : kSizeAndRotations) { | 211 for (const auto& size_and_rotation : kSizeAndRotations) { |
209 ASSERT_GE(kScratchpadSizeInBytes, | 212 ASSERT_GE(kScratchpadSizeInBytes, |
210 size_and_rotation.input_resolution.GetArea() * 4u) | 213 size_and_rotation.input_resolution.GetArea() * 4u) |
211 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; | 214 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; |
212 params.requested_format = | 215 params.requested_format = |
213 media::VideoCaptureFormat(size_and_rotation.input_resolution, 30.0f, | 216 media::VideoCaptureFormat(size_and_rotation.input_resolution, 30.0f, |
214 media::PIXEL_FORMAT_ARGB); | 217 media::PIXEL_FORMAT_ARGB); |
215 gfx::Size coded_size; | 218 gfx::Size coded_size; |
216 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) | 219 EXPECT_CALL(*controller_, MockDoIncomingCapturedVideoFrameOnIOThread(_)) |
217 .Times(1) | 220 .Times(1) |
218 .WillOnce(SaveArg<0>(&coded_size)); | 221 .WillOnce(SaveArg<0>(&coded_size)); |
219 device_client_->OnIncomingCapturedData( | 222 device_client_->OnIncomingCapturedData( |
220 data, params.requested_format.ImageAllocationSize(), | 223 data, params.requested_format.ImageAllocationSize(), |
221 params.requested_format, size_and_rotation.rotation, base::TimeTicks()); | 224 params.requested_format, size_and_rotation.rotation, base::TimeTicks()); |
222 base::RunLoop().RunUntilIdle(); | 225 base::RunLoop().RunUntilIdle(); |
223 | 226 |
224 EXPECT_EQ(coded_size.width(), size_and_rotation.output_resolution.width()); | 227 EXPECT_EQ(coded_size.width(), size_and_rotation.output_resolution.width()); |
225 EXPECT_EQ(coded_size.height(), | 228 EXPECT_EQ(coded_size.height(), |
226 size_and_rotation.output_resolution.height()); | 229 size_and_rotation.output_resolution.height()); |
227 | 230 |
228 Mock::VerifyAndClearExpectations(controller_.get()); | 231 Mock::VerifyAndClearExpectations(controller_.get()); |
229 } | 232 } |
230 } | 233 } |
231 | 234 |
232 } // namespace content | 235 } // namespace content |
OLD | NEW |