OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "media/capture/video/video_capture_device.h" | 5 #include "media/capture/video/video_capture_device.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
(...skipping 21 matching lines...) Expand all Loading... |
32 #endif | 32 #endif |
33 | 33 |
34 #if defined(OS_MACOSX) | 34 #if defined(OS_MACOSX) |
35 #include "media/base/mac/avfoundation_glue.h" | 35 #include "media/base/mac/avfoundation_glue.h" |
36 #include "media/capture/video/mac/video_capture_device_factory_mac.h" | 36 #include "media/capture/video/mac/video_capture_device_factory_mac.h" |
37 #endif | 37 #endif |
38 | 38 |
39 #if defined(OS_ANDROID) | 39 #if defined(OS_ANDROID) |
40 #include "base/android/jni_android.h" | 40 #include "base/android/jni_android.h" |
41 #include "media/capture/video/android/video_capture_device_android.h" | 41 #include "media/capture/video/android/video_capture_device_android.h" |
42 #include "media/capture/video/android/video_capture_device_factory_android.h" | |
43 #endif | 42 #endif |
44 | 43 |
45 #if defined(OS_MACOSX) | 44 #if defined(OS_MACOSX) |
46 // Mac will always give you the size you ask for and this case will fail. | 45 // Mac will always give you the size you ask for and this case will fail. |
47 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize | 46 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize |
48 // We will always get YUYV from the Mac AVFoundation implementations. | 47 // We will always get YUYV from the Mac AVFoundation implementations. |
49 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg | 48 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg |
50 #define MAYBE_TakePhoto TakePhoto | 49 #define MAYBE_TakePhoto TakePhoto |
51 #elif defined(OS_WIN) | 50 #elif defined(OS_WIN) |
52 #define MAYBE_AllocateBadSize AllocateBadSize | 51 #define MAYBE_AllocateBadSize AllocateBadSize |
53 #define MAYBE_CaptureMjpeg CaptureMjpeg | 52 #define MAYBE_CaptureMjpeg CaptureMjpeg |
54 #define MAYBE_TakePhoto DISABLED_TakePhoto | 53 #define MAYBE_TakePhoto DISABLED_TakePhoto |
55 #elif defined(OS_ANDROID) | 54 #elif defined(OS_ANDROID) |
56 #define MAYBE_AllocateBadSize AllocateBadSize | 55 // TODO(wjia): enable those tests on Android. |
57 #define MAYBE_CaptureMjpeg CaptureMjpeg | 56 // On Android, native camera (JAVA) delivers frames on UI thread which is the |
| 57 // main thread for tests. This results in no frame received by |
| 58 // VideoCaptureAndroid. |
| 59 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize |
| 60 #define DeAllocateCameraWhileRunning DISABLED_DeAllocateCameraWhileRunning |
| 61 #define DeAllocateCameraWhileRunning DISABLED_DeAllocateCameraWhileRunning |
| 62 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg |
58 #define MAYBE_TakePhoto DISABLED_TakePhoto | 63 #define MAYBE_TakePhoto DISABLED_TakePhoto |
59 #elif defined(OS_LINUX) | 64 #elif defined(OS_LINUX) |
60 // AllocateBadSize will hang when a real camera is attached and if more than one | 65 // AllocateBadSize will hang when a real camera is attached and if more than one |
61 // test is trying to use the camera (even across processes). Do NOT renable | 66 // test is trying to use the camera (even across processes). Do NOT renable |
62 // this test without fixing the many bugs associated with it: | 67 // this test without fixing the many bugs associated with it: |
63 // http://crbug.com/94134 http://crbug.com/137260 http://crbug.com/417824 | 68 // http://crbug.com/94134 http://crbug.com/137260 http://crbug.com/417824 |
64 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize | 69 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize |
65 #define MAYBE_CaptureMjpeg CaptureMjpeg | 70 #define MAYBE_CaptureMjpeg CaptureMjpeg |
66 #define MAYBE_TakePhoto DISABLED_TakePhoto | 71 #define MAYBE_TakePhoto DISABLED_TakePhoto |
67 #else | 72 #else |
(...skipping 24 matching lines...) Expand all Loading... |
92 : main_thread_(base::ThreadTaskRunnerHandle::Get()), | 97 : main_thread_(base::ThreadTaskRunnerHandle::Get()), |
93 frame_cb_(frame_cb) {} | 98 frame_cb_(frame_cb) {} |
94 | 99 |
95 void OnIncomingCapturedData(const uint8_t* data, | 100 void OnIncomingCapturedData(const uint8_t* data, |
96 int length, | 101 int length, |
97 const VideoCaptureFormat& format, | 102 const VideoCaptureFormat& format, |
98 int rotation, | 103 int rotation, |
99 base::TimeTicks reference_time, | 104 base::TimeTicks reference_time, |
100 base::TimeDelta timestamp) override { | 105 base::TimeDelta timestamp) override { |
101 ASSERT_GT(length, 0); | 106 ASSERT_GT(length, 0); |
102 ASSERT_TRUE(data); | 107 ASSERT_TRUE(data != NULL); |
103 main_thread_->PostTask(FROM_HERE, base::Bind(frame_cb_, format)); | 108 main_thread_->PostTask(FROM_HERE, base::Bind(frame_cb_, format)); |
104 } | 109 } |
105 | 110 |
106 // Trampoline methods to workaround GMOCK problems with std::unique_ptr<>. | 111 // Trampoline methods to workaround GMOCK problems with std::unique_ptr<>. |
107 std::unique_ptr<Buffer> ReserveOutputBuffer( | 112 std::unique_ptr<Buffer> ReserveOutputBuffer( |
108 const gfx::Size& dimensions, | 113 const gfx::Size& dimensions, |
109 media::VideoPixelFormat format, | 114 media::VideoPixelFormat format, |
110 media::VideoPixelStorage storage) override { | 115 media::VideoPixelStorage storage) override { |
111 DoReserveOutputBuffer(); | 116 DoReserveOutputBuffer(); |
112 NOTREACHED() << "This should never be called"; | 117 NOTREACHED() << "This should never be called"; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 void(const base::Callback<void(mojom::BlobPtr)>&)); | 161 void(const base::Callback<void(mojom::BlobPtr)>&)); |
157 | 162 |
158 private: | 163 private: |
159 friend class base::RefCounted<MockImageCaptureClient>; | 164 friend class base::RefCounted<MockImageCaptureClient>; |
160 virtual ~MockImageCaptureClient() {} | 165 virtual ~MockImageCaptureClient() {} |
161 }; | 166 }; |
162 | 167 |
163 class DeviceEnumerationListener | 168 class DeviceEnumerationListener |
164 : public base::RefCounted<DeviceEnumerationListener> { | 169 : public base::RefCounted<DeviceEnumerationListener> { |
165 public: | 170 public: |
166 MOCK_METHOD1(DoOnEnumerateDeviceDescriptors, | 171 MOCK_METHOD1(OnEnumerateDeviceDescriptorsCallbackPtr, |
167 void(VideoCaptureDeviceDescriptors* device_descriptors)); | 172 void(VideoCaptureDeviceDescriptors* device_descriptors)); |
168 // GMock doesn't support move-only arguments, so we use this forward method. | 173 // GMock doesn't support move-only arguments, so we use this forward method. |
169 void OnEnumerateDeviceDescriptors( | 174 void OnEnumerateDeviceDescriptorsCallback( |
170 std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors) { | 175 std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors) { |
171 DoOnEnumerateDeviceDescriptors(device_descriptors.release()); | 176 OnEnumerateDeviceDescriptorsCallbackPtr(device_descriptors.release()); |
172 } | 177 } |
173 | 178 |
174 private: | 179 private: |
175 friend class base::RefCounted<DeviceEnumerationListener>; | 180 friend class base::RefCounted<DeviceEnumerationListener>; |
176 virtual ~DeviceEnumerationListener() {} | 181 virtual ~DeviceEnumerationListener() {} |
177 }; | 182 }; |
178 | 183 |
179 } // namespace | 184 } // namespace |
180 | 185 |
181 class VideoCaptureDeviceTest : public testing::TestWithParam<gfx::Size> { | 186 class VideoCaptureDeviceTest : public testing::TestWithParam<gfx::Size> { |
182 protected: | 187 protected: |
183 typedef VideoCaptureDevice::Client Client; | 188 typedef VideoCaptureDevice::Client Client; |
184 | 189 |
185 VideoCaptureDeviceTest() | 190 VideoCaptureDeviceTest() |
186 : loop_(new base::MessageLoop()), | 191 : loop_(new base::MessageLoop()), |
187 video_capture_client_(new MockVideoCaptureClient( | 192 video_capture_client_(new MockVideoCaptureClient( |
188 base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured, | 193 base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured, |
189 base::Unretained(this)))), | 194 base::Unretained(this)))), |
190 device_enumeration_listener_(new DeviceEnumerationListener()), | 195 device_enumeration_listener_(new DeviceEnumerationListener()), |
191 image_capture_client_(new MockImageCaptureClient()), | 196 image_capture_client_(new MockImageCaptureClient()), |
192 video_capture_device_factory_(VideoCaptureDeviceFactory::CreateFactory( | 197 video_capture_device_factory_(VideoCaptureDeviceFactory::CreateFactory( |
193 base::ThreadTaskRunnerHandle::Get())) {} | 198 base::ThreadTaskRunnerHandle::Get())) {} |
194 | 199 |
195 void SetUp() override { | 200 void SetUp() override { |
196 #if defined(OS_ANDROID) | 201 #if defined(OS_ANDROID) |
197 VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice( | 202 VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice( |
198 base::android::AttachCurrentThread()); | 203 base::android::AttachCurrentThread()); |
199 | |
200 static_cast<VideoCaptureDeviceFactoryAndroid*>( | |
201 video_capture_device_factory_.get()) | |
202 ->ConfigureForTesting(); | |
203 #endif | 204 #endif |
204 #if defined(OS_MACOSX) | 205 #if defined(OS_MACOSX) |
205 AVFoundationGlue::InitializeAVFoundation(); | 206 AVFoundationGlue::InitializeAVFoundation(); |
206 #endif | 207 #endif |
207 EXPECT_CALL(*video_capture_client_, DoReserveOutputBuffer()).Times(0); | 208 EXPECT_CALL(*video_capture_client_, DoReserveOutputBuffer()).Times(0); |
208 EXPECT_CALL(*video_capture_client_, DoOnIncomingCapturedBuffer()).Times(0); | 209 EXPECT_CALL(*video_capture_client_, DoOnIncomingCapturedBuffer()).Times(0); |
209 EXPECT_CALL(*video_capture_client_, DoOnIncomingCapturedVideoFrame()) | 210 EXPECT_CALL(*video_capture_client_, DoOnIncomingCapturedVideoFrame()) |
210 .Times(0); | 211 .Times(0); |
211 } | 212 } |
212 | 213 |
213 void ResetWithNewClient() { | 214 void ResetWithNewClient() { |
214 video_capture_client_.reset(new MockVideoCaptureClient(base::Bind( | 215 video_capture_client_.reset(new MockVideoCaptureClient(base::Bind( |
215 &VideoCaptureDeviceTest::OnFrameCaptured, base::Unretained(this)))); | 216 &VideoCaptureDeviceTest::OnFrameCaptured, base::Unretained(this)))); |
216 } | 217 } |
217 | 218 |
218 void OnFrameCaptured(const VideoCaptureFormat& format) { | 219 void OnFrameCaptured(const VideoCaptureFormat& format) { |
219 last_format_ = format; | 220 last_format_ = format; |
220 run_loop_->QuitClosure().Run(); | 221 run_loop_->QuitClosure().Run(); |
221 } | 222 } |
222 | 223 |
223 void WaitForCapturedFrame() { | 224 void WaitForCapturedFrame() { |
224 run_loop_.reset(new base::RunLoop()); | 225 run_loop_.reset(new base::RunLoop()); |
225 run_loop_->Run(); | 226 run_loop_->Run(); |
226 } | 227 } |
227 | 228 |
228 bool EnumerateAndFindUsableDevices() { | 229 std::unique_ptr<VideoCaptureDeviceDescriptors> EnumerateDeviceDescriptors() { |
229 VideoCaptureDeviceDescriptors* descriptors = nullptr; | 230 VideoCaptureDeviceDescriptors* device_descriptors; |
230 EXPECT_CALL(*device_enumeration_listener_.get(), | 231 EXPECT_CALL(*device_enumeration_listener_.get(), |
231 DoOnEnumerateDeviceDescriptors(_)) | 232 OnEnumerateDeviceDescriptorsCallbackPtr(_)) |
232 .WillOnce(SaveArg<0>(&descriptors)); | 233 .WillOnce(SaveArg<0>(&device_descriptors)); |
233 | 234 |
234 video_capture_device_factory_->EnumerateDeviceDescriptors( | 235 video_capture_device_factory_->EnumerateDeviceDescriptors(base::Bind( |
235 base::Bind(&DeviceEnumerationListener::OnEnumerateDeviceDescriptors, | 236 &DeviceEnumerationListener::OnEnumerateDeviceDescriptorsCallback, |
236 device_enumeration_listener_)); | 237 device_enumeration_listener_)); |
237 base::RunLoop().RunUntilIdle(); | 238 base::RunLoop().RunUntilIdle(); |
238 | 239 return std::unique_ptr<VideoCaptureDeviceDescriptors>(device_descriptors); |
239 device_descriptors_.reset(descriptors); | |
240 if (!device_descriptors_) | |
241 return false; | |
242 | |
243 #if defined(OS_ANDROID) | |
244 // Android deprecated/legacy devices capture on a single thread, which is | |
245 // occupied by the tests, so nothing gets actually delivered. | |
246 // TODO(mcasas): use those devices' test mode to deliver frames in a | |
247 // background thread, https://crbug.com/626857 | |
248 for (const auto& descriptor : *descriptors) { | |
249 if (VideoCaptureDeviceFactoryAndroid::IsLegacyOrDeprecatedDevice( | |
250 descriptor.device_id)) { | |
251 return false; | |
252 } | |
253 } | |
254 #endif | |
255 | |
256 return !device_descriptors_->empty(); | |
257 } | 240 } |
258 | 241 |
259 const VideoCaptureFormat& last_format() const { return last_format_; } | 242 const VideoCaptureFormat& last_format() const { return last_format_; } |
260 | 243 |
261 std::unique_ptr<VideoCaptureDeviceDescriptor> | 244 std::unique_ptr<VideoCaptureDeviceDescriptor> |
262 GetFirstDeviceDescriptorSupportingPixelFormat( | 245 GetFirstDeviceDescriptorSupportingPixelFormat( |
263 const VideoPixelFormat& pixel_format) { | 246 const VideoPixelFormat& pixel_format) { |
264 if (!EnumerateAndFindUsableDevices()) | 247 device_descriptors_ = EnumerateDeviceDescriptors(); |
265 return nullptr; | 248 if (device_descriptors_->empty()) { |
266 | 249 DVLOG(1) << "No camera available."; |
267 for (const auto& descriptor : *device_descriptors_) { | 250 return std::unique_ptr<VideoCaptureDeviceDescriptor>(); |
| 251 } |
| 252 for (const auto& descriptors_iterator : *device_descriptors_) { |
268 VideoCaptureFormats supported_formats; | 253 VideoCaptureFormats supported_formats; |
269 video_capture_device_factory_->GetSupportedFormats(descriptor, | 254 video_capture_device_factory_->GetSupportedFormats(descriptors_iterator, |
270 &supported_formats); | 255 &supported_formats); |
271 for (const auto& formats_iterator : supported_formats) { | 256 for (const auto& formats_iterator : supported_formats) { |
272 if (formats_iterator.pixel_format == pixel_format) { | 257 if (formats_iterator.pixel_format == pixel_format) { |
273 return std::unique_ptr<VideoCaptureDeviceDescriptor>( | 258 return std::unique_ptr<VideoCaptureDeviceDescriptor>( |
274 new VideoCaptureDeviceDescriptor(descriptor)); | 259 new VideoCaptureDeviceDescriptor(descriptors_iterator)); |
275 } | 260 } |
276 } | 261 } |
277 } | 262 } |
278 DVLOG_IF(1, pixel_format != PIXEL_FORMAT_MAX) | 263 DVLOG_IF(1, pixel_format != PIXEL_FORMAT_MAX) |
279 << VideoPixelFormatToString(pixel_format); | 264 << "No camera can capture the" |
| 265 << " format: " << VideoPixelFormatToString(pixel_format); |
280 return std::unique_ptr<VideoCaptureDeviceDescriptor>(); | 266 return std::unique_ptr<VideoCaptureDeviceDescriptor>(); |
281 } | 267 } |
282 | 268 |
283 bool IsCaptureSizeSupported(const VideoCaptureDeviceDescriptor& device, | 269 bool IsCaptureSizeSupported(const VideoCaptureDeviceDescriptor& device, |
284 const gfx::Size& size) { | 270 const gfx::Size& size) { |
285 VideoCaptureFormats supported_formats; | 271 VideoCaptureFormats supported_formats; |
286 video_capture_device_factory_->GetSupportedFormats(device, | 272 video_capture_device_factory_->GetSupportedFormats(device, |
287 &supported_formats); | 273 &supported_formats); |
288 const auto it = std::find_if( | 274 const auto it = std::find_if( |
289 supported_formats.begin(), supported_formats.end(), | 275 supported_formats.begin(), supported_formats.end(), |
(...skipping 18 matching lines...) Expand all Loading... |
308 const std::unique_ptr<VideoCaptureDeviceFactory> | 294 const std::unique_ptr<VideoCaptureDeviceFactory> |
309 video_capture_device_factory_; | 295 video_capture_device_factory_; |
310 }; | 296 }; |
311 | 297 |
312 // Cause hangs on Windows Debug. http://crbug.com/417824 | 298 // Cause hangs on Windows Debug. http://crbug.com/417824 |
313 #if defined(OS_WIN) && !defined(NDEBUG) | 299 #if defined(OS_WIN) && !defined(NDEBUG) |
314 #define MAYBE_OpenInvalidDevice DISABLED_OpenInvalidDevice | 300 #define MAYBE_OpenInvalidDevice DISABLED_OpenInvalidDevice |
315 #else | 301 #else |
316 #define MAYBE_OpenInvalidDevice OpenInvalidDevice | 302 #define MAYBE_OpenInvalidDevice OpenInvalidDevice |
317 #endif | 303 #endif |
318 // Tries to allocate an invalid device and verifies it doesn't work. | 304 |
319 TEST_F(VideoCaptureDeviceTest, MAYBE_OpenInvalidDevice) { | 305 TEST_F(VideoCaptureDeviceTest, MAYBE_OpenInvalidDevice) { |
320 VideoCaptureDeviceDescriptor invalid_descriptor; | 306 VideoCaptureDeviceDescriptor invalid_descriptor; |
321 invalid_descriptor.device_id = "jibberish"; | 307 invalid_descriptor.device_id = "jibberish"; |
322 invalid_descriptor.display_name = "jibberish"; | 308 invalid_descriptor.display_name = "jibberish"; |
323 #if defined(OS_WIN) | 309 #if defined(OS_WIN) |
324 invalid_descriptor.capture_api = | 310 invalid_descriptor.capture_api = |
325 VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation() | 311 VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation() |
326 ? VideoCaptureApi::WIN_MEDIA_FOUNDATION | 312 ? VideoCaptureApi::WIN_MEDIA_FOUNDATION |
327 : VideoCaptureApi::WIN_DIRECT_SHOW; | 313 : VideoCaptureApi::WIN_DIRECT_SHOW; |
328 #elif defined(OS_MACOSX) | 314 #elif defined(OS_MACOSX) |
329 invalid_descriptor.capture_api = VideoCaptureApi::MACOSX_AVFOUNDATION; | 315 invalid_descriptor.capture_api = VideoCaptureApi::MACOSX_AVFOUNDATION; |
330 #endif | 316 #endif |
331 std::unique_ptr<VideoCaptureDevice> device = | 317 std::unique_ptr<VideoCaptureDevice> device = |
332 video_capture_device_factory_->CreateDevice(invalid_descriptor); | 318 video_capture_device_factory_->CreateDevice(invalid_descriptor); |
333 | 319 |
334 #if !defined(OS_MACOSX) | 320 #if !defined(OS_MACOSX) |
335 EXPECT_FALSE(device); | 321 EXPECT_TRUE(device == NULL); |
336 #else | 322 #else |
337 // The presence of the actual device is only checked on AllocateAndStart() | 323 // The presence of the actual device is only checked on AllocateAndStart() |
338 // and not on creation. | 324 // and not on creation. |
339 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(1); | 325 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(1); |
340 | 326 |
341 VideoCaptureParams capture_params; | 327 VideoCaptureParams capture_params; |
342 capture_params.requested_format.frame_size.SetSize(640, 480); | 328 capture_params.requested_format.frame_size.SetSize(640, 480); |
343 capture_params.requested_format.frame_rate = 30; | 329 capture_params.requested_format.frame_rate = 30; |
344 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 330 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
345 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 331 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
346 device->StopAndDeAllocate(); | 332 device->StopAndDeAllocate(); |
347 #endif | 333 #endif |
348 } | 334 } |
349 | 335 |
350 // Allocates the first enumerated device, and expects a frame. | |
351 TEST_P(VideoCaptureDeviceTest, CaptureWithSize) { | 336 TEST_P(VideoCaptureDeviceTest, CaptureWithSize) { |
352 if (!EnumerateAndFindUsableDevices()) | 337 device_descriptors_ = EnumerateDeviceDescriptors(); |
| 338 if (device_descriptors_->empty()) { |
| 339 VLOG(1) << "No camera available. Exiting test."; |
353 return; | 340 return; |
| 341 } |
354 | 342 |
355 const gfx::Size& size = GetParam(); | 343 const gfx::Size& size = GetParam(); |
356 if (!IsCaptureSizeSupported(device_descriptors_->front(), size)) | 344 if (!IsCaptureSizeSupported(device_descriptors_->front(), size)) |
357 return; | 345 return; |
358 const int width = size.width(); | 346 const int width = size.width(); |
359 const int height = size.height(); | 347 const int height = size.height(); |
360 | 348 |
361 std::unique_ptr<VideoCaptureDevice> device( | 349 std::unique_ptr<VideoCaptureDevice> device( |
362 video_capture_device_factory_->CreateDevice( | 350 video_capture_device_factory_->CreateDevice( |
363 device_descriptors_->front())); | 351 device_descriptors_->front())); |
364 ASSERT_TRUE(device); | 352 ASSERT_TRUE(device); |
| 353 DVLOG(1) << device_descriptors_->front().device_id; |
365 | 354 |
366 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); | 355 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); |
367 | 356 |
368 VideoCaptureParams capture_params; | 357 VideoCaptureParams capture_params; |
369 capture_params.requested_format.frame_size.SetSize(width, height); | 358 capture_params.requested_format.frame_size.SetSize(width, height); |
370 capture_params.requested_format.frame_rate = 30.0f; | 359 capture_params.requested_format.frame_rate = 30.0f; |
371 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 360 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
372 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 361 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
373 | 362 // Get captured video frames. |
374 WaitForCapturedFrame(); | 363 WaitForCapturedFrame(); |
375 EXPECT_EQ(last_format().frame_size.width(), width); | 364 EXPECT_EQ(last_format().frame_size.width(), width); |
376 EXPECT_EQ(last_format().frame_size.height(), height); | 365 EXPECT_EQ(last_format().frame_size.height(), height); |
377 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) | 366 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) |
378 EXPECT_EQ(size.GetArea(), last_format().frame_size.GetArea()); | 367 EXPECT_EQ(size.GetArea(), last_format().frame_size.GetArea()); |
379 EXPECT_EQ(last_format().frame_rate, 30); | |
380 device->StopAndDeAllocate(); | 368 device->StopAndDeAllocate(); |
381 } | 369 } |
382 | 370 |
| 371 #if !defined(OS_ANDROID) |
383 const gfx::Size kCaptureSizes[] = {gfx::Size(640, 480), gfx::Size(1280, 720)}; | 372 const gfx::Size kCaptureSizes[] = {gfx::Size(640, 480), gfx::Size(1280, 720)}; |
384 | 373 |
385 INSTANTIATE_TEST_CASE_P(VideoCaptureDeviceTests, | 374 INSTANTIATE_TEST_CASE_P(VideoCaptureDeviceTests, |
386 VideoCaptureDeviceTest, | 375 VideoCaptureDeviceTest, |
387 testing::ValuesIn(kCaptureSizes)); | 376 testing::ValuesIn(kCaptureSizes)); |
| 377 #endif |
388 | 378 |
389 // Allocates a device with an uncommon resolution and verifies frames are | |
390 // captured in a close, much more typical one. | |
391 TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) { | 379 TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) { |
392 if (!EnumerateAndFindUsableDevices()) | 380 device_descriptors_ = EnumerateDeviceDescriptors(); |
| 381 if (device_descriptors_->empty()) { |
| 382 VLOG(1) << "No camera available. Exiting test."; |
393 return; | 383 return; |
394 | 384 } |
395 std::unique_ptr<VideoCaptureDevice> device( | 385 std::unique_ptr<VideoCaptureDevice> device( |
396 video_capture_device_factory_->CreateDevice( | 386 video_capture_device_factory_->CreateDevice( |
397 device_descriptors_->front())); | 387 device_descriptors_->front())); |
398 ASSERT_TRUE(device); | 388 ASSERT_TRUE(device); |
399 | 389 |
400 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); | 390 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); |
401 | 391 |
402 const gfx::Size input_size(640, 480); | 392 const gfx::Size input_size(640, 480); |
403 VideoCaptureParams capture_params; | 393 VideoCaptureParams capture_params; |
404 capture_params.requested_format.frame_size.SetSize(637, 472); | 394 capture_params.requested_format.frame_size.SetSize(637, 472); |
405 capture_params.requested_format.frame_rate = 35; | 395 capture_params.requested_format.frame_rate = 35; |
406 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 396 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
407 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 397 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
408 WaitForCapturedFrame(); | 398 WaitForCapturedFrame(); |
409 device->StopAndDeAllocate(); | 399 device->StopAndDeAllocate(); |
410 EXPECT_EQ(last_format().frame_size.width(), input_size.width()); | 400 EXPECT_EQ(last_format().frame_size.width(), input_size.width()); |
411 EXPECT_EQ(last_format().frame_size.height(), input_size.height()); | 401 EXPECT_EQ(last_format().frame_size.height(), input_size.height()); |
412 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) | 402 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) |
413 EXPECT_EQ(input_size.GetArea(), last_format().frame_size.GetArea()); | 403 EXPECT_EQ(input_size.GetArea(), last_format().frame_size.GetArea()); |
414 } | 404 } |
415 | 405 |
416 // Cause hangs on Windows, Linux. Fails Android. https://crbug.com/417824 | 406 // Cause hangs on Windows, Linux. Fails Android. http://crbug.com/417824 |
417 TEST_F(VideoCaptureDeviceTest, DISABLED_ReAllocateCamera) { | 407 TEST_F(VideoCaptureDeviceTest, DISABLED_ReAllocateCamera) { |
418 if (!EnumerateAndFindUsableDevices()) | 408 device_descriptors_ = EnumerateDeviceDescriptors(); |
| 409 if (device_descriptors_->empty()) { |
| 410 VLOG(1) << "No camera available. Exiting test."; |
419 return; | 411 return; |
| 412 } |
420 | 413 |
421 // First, do a number of very fast device start/stops. | 414 // First, do a number of very fast device start/stops. |
422 for (int i = 0; i <= 5; i++) { | 415 for (int i = 0; i <= 5; i++) { |
423 ResetWithNewClient(); | 416 ResetWithNewClient(); |
424 std::unique_ptr<VideoCaptureDevice> device( | 417 std::unique_ptr<VideoCaptureDevice> device( |
425 video_capture_device_factory_->CreateDevice( | 418 video_capture_device_factory_->CreateDevice( |
426 device_descriptors_->front())); | 419 device_descriptors_->front())); |
427 gfx::Size resolution; | 420 gfx::Size resolution; |
428 if (i % 2) | 421 if (i % 2) { |
429 resolution = gfx::Size(640, 480); | 422 resolution = gfx::Size(640, 480); |
430 else | 423 } else { |
431 resolution = gfx::Size(1280, 1024); | 424 resolution = gfx::Size(1280, 1024); |
432 | 425 } |
433 VideoCaptureParams capture_params; | 426 VideoCaptureParams capture_params; |
434 capture_params.requested_format.frame_size = resolution; | 427 capture_params.requested_format.frame_size = resolution; |
435 capture_params.requested_format.frame_rate = 30; | 428 capture_params.requested_format.frame_rate = 30; |
436 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 429 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
437 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 430 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
438 device->StopAndDeAllocate(); | 431 device->StopAndDeAllocate(); |
439 } | 432 } |
440 | 433 |
441 // Finally, do a device start and wait for it to finish. | 434 // Finally, do a device start and wait for it to finish. |
442 VideoCaptureParams capture_params; | 435 VideoCaptureParams capture_params; |
443 capture_params.requested_format.frame_size.SetSize(320, 240); | 436 capture_params.requested_format.frame_size.SetSize(320, 240); |
444 capture_params.requested_format.frame_rate = 30; | 437 capture_params.requested_format.frame_rate = 30; |
445 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 438 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
446 | 439 |
447 ResetWithNewClient(); | 440 ResetWithNewClient(); |
448 std::unique_ptr<VideoCaptureDevice> device( | 441 std::unique_ptr<VideoCaptureDevice> device( |
449 video_capture_device_factory_->CreateDevice( | 442 video_capture_device_factory_->CreateDevice( |
450 device_descriptors_->front())); | 443 device_descriptors_->front())); |
451 | 444 |
452 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 445 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
453 WaitForCapturedFrame(); | 446 WaitForCapturedFrame(); |
454 device->StopAndDeAllocate(); | 447 device->StopAndDeAllocate(); |
455 device.reset(); | 448 device.reset(); |
456 EXPECT_EQ(last_format().frame_size.width(), 320); | 449 EXPECT_EQ(last_format().frame_size.width(), 320); |
457 EXPECT_EQ(last_format().frame_size.height(), 240); | 450 EXPECT_EQ(last_format().frame_size.height(), 240); |
458 } | 451 } |
459 | 452 |
460 // Starts the camera in 720p to try and capture MJPEG format. | 453 TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) { |
| 454 device_descriptors_ = EnumerateDeviceDescriptors(); |
| 455 if (device_descriptors_->empty()) { |
| 456 VLOG(1) << "No camera available. Exiting test."; |
| 457 return; |
| 458 } |
| 459 std::unique_ptr<VideoCaptureDevice> device( |
| 460 video_capture_device_factory_->CreateDevice( |
| 461 device_descriptors_->front())); |
| 462 ASSERT_TRUE(device); |
| 463 |
| 464 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); |
| 465 |
| 466 VideoCaptureParams capture_params; |
| 467 capture_params.requested_format.frame_size.SetSize(640, 480); |
| 468 capture_params.requested_format.frame_rate = 30; |
| 469 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
| 470 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
| 471 // Get captured video frames. |
| 472 WaitForCapturedFrame(); |
| 473 EXPECT_EQ(last_format().frame_size.width(), 640); |
| 474 EXPECT_EQ(last_format().frame_size.height(), 480); |
| 475 EXPECT_EQ(last_format().frame_rate, 30); |
| 476 device->StopAndDeAllocate(); |
| 477 } |
| 478 |
| 479 // Start the camera in 720p to capture MJPEG instead of a raw format. |
461 TEST_F(VideoCaptureDeviceTest, MAYBE_CaptureMjpeg) { | 480 TEST_F(VideoCaptureDeviceTest, MAYBE_CaptureMjpeg) { |
462 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = | 481 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = |
463 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MJPEG); | 482 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MJPEG); |
464 if (!device_descriptor) { | 483 if (!device_descriptor) { |
465 DVLOG(1) << "No camera supports MJPEG format. Exiting test."; | 484 VLOG(1) << "No camera supports MJPEG format. Exiting test."; |
466 return; | 485 return; |
467 } | 486 } |
468 #if defined(OS_WIN) | 487 #if defined(OS_WIN) |
469 base::win::Version version = base::win::GetVersion(); | 488 base::win::Version version = base::win::GetVersion(); |
| 489 VLOG(1) << "Windows version: " << (int)version; |
470 if (version >= base::win::VERSION_WIN10) { | 490 if (version >= base::win::VERSION_WIN10) { |
471 VLOG(1) << "Skipped on Win10: http://crbug.com/570604, current: " | 491 VLOG(1) << "Skipped on Win10: http://crbug.com/570604."; |
472 << static_cast<int>(version); | |
473 return; | 492 return; |
474 } | 493 } |
475 #endif | 494 #endif |
476 std::unique_ptr<VideoCaptureDevice> device( | 495 std::unique_ptr<VideoCaptureDevice> device( |
477 video_capture_device_factory_->CreateDevice(*device_descriptor)); | 496 video_capture_device_factory_->CreateDevice(*device_descriptor)); |
478 ASSERT_TRUE(device); | 497 ASSERT_TRUE(device); |
479 | 498 |
480 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); | 499 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); |
481 | 500 |
482 VideoCaptureParams capture_params; | 501 VideoCaptureParams capture_params; |
483 capture_params.requested_format.frame_size.SetSize(1280, 720); | 502 capture_params.requested_format.frame_size.SetSize(1280, 720); |
484 capture_params.requested_format.frame_rate = 30; | 503 capture_params.requested_format.frame_rate = 30; |
485 capture_params.requested_format.pixel_format = PIXEL_FORMAT_MJPEG; | 504 capture_params.requested_format.pixel_format = PIXEL_FORMAT_MJPEG; |
486 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 505 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
487 | 506 // Get captured video frames. |
488 WaitForCapturedFrame(); | 507 WaitForCapturedFrame(); |
489 // Verify we get MJPEG from the device. Not all devices can capture 1280x720 | 508 // Verify we get MJPEG from the device. Not all devices can capture 1280x720 |
490 // @ 30 fps, so we don't care about the exact resolution we get. | 509 // @ 30 fps, so we don't care about the exact resolution we get. |
491 EXPECT_EQ(last_format().pixel_format, PIXEL_FORMAT_MJPEG); | 510 EXPECT_EQ(last_format().pixel_format, PIXEL_FORMAT_MJPEG); |
492 EXPECT_GE(static_cast<size_t>(1280 * 720), | 511 EXPECT_GE(static_cast<size_t>(1280 * 720), |
493 last_format().ImageAllocationSize()); | 512 last_format().ImageAllocationSize()); |
494 device->StopAndDeAllocate(); | 513 device->StopAndDeAllocate(); |
495 } | 514 } |
496 | 515 |
497 TEST_F(VideoCaptureDeviceTest, NoCameraSupportsPixelFormatMax) { | 516 TEST_F(VideoCaptureDeviceTest, GetDeviceSupportedFormats) { |
498 // Use PIXEL_FORMAT_MAX to iterate all device names for testing | 517 // Use PIXEL_FORMAT_MAX to iterate all device names for testing |
499 // GetDeviceSupportedFormats(). | 518 // GetDeviceSupportedFormats(). |
500 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = | 519 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = |
501 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MAX); | 520 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MAX); |
502 // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else to test here | 521 // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else to test here |
503 // since we cannot forecast the hardware capabilities. | 522 // since we cannot forecast the hardware capabilities. |
504 ASSERT_FALSE(device_descriptor); | 523 ASSERT_FALSE(device_descriptor); |
505 } | 524 } |
506 | 525 |
507 // Starts the camera and take a photo. | 526 // Start the camera and take a photo. |
508 TEST_F(VideoCaptureDeviceTest, MAYBE_TakePhoto) { | 527 TEST_F(VideoCaptureDeviceTest, MAYBE_TakePhoto) { |
509 if (!EnumerateAndFindUsableDevices()) | 528 device_descriptors_ = EnumerateDeviceDescriptors(); |
| 529 if (device_descriptors_->empty()) { |
| 530 VLOG(1) << "No camera available. Exiting test."; |
510 return; | 531 return; |
511 | 532 } |
512 std::unique_ptr<VideoCaptureDevice> device( | 533 std::unique_ptr<VideoCaptureDevice> device( |
513 video_capture_device_factory_->CreateDevice( | 534 video_capture_device_factory_->CreateDevice( |
514 device_descriptors_->front())); | 535 device_descriptors_->front())); |
515 ASSERT_TRUE(device); | 536 ASSERT_TRUE(device); |
516 | 537 |
517 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); | 538 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); |
518 | 539 |
519 VideoCaptureParams capture_params; | 540 VideoCaptureParams capture_params; |
520 capture_params.requested_format.frame_size.SetSize(640, 480); | 541 capture_params.requested_format.frame_size.SetSize(640, 480); |
521 capture_params.requested_format.frame_rate = 30; | 542 capture_params.requested_format.frame_rate = 30; |
522 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 543 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
523 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 544 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
524 WaitForCapturedFrame(); | 545 WaitForCapturedFrame(); |
525 | 546 |
526 VideoCaptureDevice::TakePhotoCallback scoped_callback( | 547 VideoCaptureDevice::TakePhotoCallback scoped_callback( |
527 base::Bind(&MockImageCaptureClient::DoOnPhotoTaken, | 548 base::Bind(&MockImageCaptureClient::DoOnPhotoTaken, |
528 image_capture_client_), | 549 image_capture_client_), |
529 media::BindToCurrentLoop(base::Bind( | 550 media::BindToCurrentLoop(base::Bind( |
530 &MockImageCaptureClient::OnTakePhotoFailure, image_capture_client_))); | 551 &MockImageCaptureClient::OnTakePhotoFailure, image_capture_client_))); |
531 | 552 |
532 EXPECT_CALL(*image_capture_client_.get(), OnCorrectPhotoTaken()).Times(1); | 553 EXPECT_CALL(*image_capture_client_.get(), OnCorrectPhotoTaken()).Times(1); |
533 device->TakePhoto(std::move(scoped_callback)); | 554 device->TakePhoto(std::move(scoped_callback)); |
534 WaitForCapturedFrame(); | 555 WaitForCapturedFrame(); |
535 | 556 |
536 device->StopAndDeAllocate(); | 557 device->StopAndDeAllocate(); |
537 } | 558 } |
538 | 559 |
539 }; // namespace media | 560 }; // namespace media |
OLD | NEW |