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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 | 198 |
199 const mojom::PhotoCapabilities* capabilities() { return capabilities_.get(); } | 199 const mojom::PhotoCapabilities* capabilities() { return capabilities_.get(); } |
200 | 200 |
201 private: | 201 private: |
202 friend class base::RefCountedThreadSafe<MockImageCaptureClient>; | 202 friend class base::RefCountedThreadSafe<MockImageCaptureClient>; |
203 virtual ~MockImageCaptureClient() {} | 203 virtual ~MockImageCaptureClient() {} |
204 | 204 |
205 mojom::PhotoCapabilitiesPtr capabilities_; | 205 mojom::PhotoCapabilitiesPtr capabilities_; |
206 }; | 206 }; |
207 | 207 |
208 class DeviceEnumerationListener | |
209 : public base::RefCounted<DeviceEnumerationListener> { | |
210 public: | |
211 MOCK_METHOD1(DoOnEnumerateDeviceDescriptors, | |
212 void(VideoCaptureDeviceDescriptors* device_descriptors)); | |
213 // GMock doesn't support move-only arguments, so we use this forward method. | |
214 void OnEnumerateDeviceDescriptors( | |
215 std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors) { | |
216 DoOnEnumerateDeviceDescriptors(device_descriptors.release()); | |
217 } | |
218 | |
219 private: | |
220 friend class base::RefCounted<DeviceEnumerationListener>; | |
221 virtual ~DeviceEnumerationListener() {} | |
222 }; | |
223 | |
224 } // namespace | 208 } // namespace |
225 | 209 |
226 class VideoCaptureDeviceTest : public testing::TestWithParam<gfx::Size> { | 210 class VideoCaptureDeviceTest : public testing::TestWithParam<gfx::Size> { |
227 protected: | 211 protected: |
228 typedef VideoCaptureDevice::Client Client; | 212 typedef VideoCaptureDevice::Client Client; |
229 | 213 |
230 VideoCaptureDeviceTest() | 214 VideoCaptureDeviceTest() |
231 : loop_(new base::MessageLoop()), | 215 : loop_(new base::MessageLoop()), |
| 216 device_descriptors_(new VideoCaptureDeviceDescriptors()), |
232 video_capture_client_(new MockVideoCaptureClient( | 217 video_capture_client_(new MockVideoCaptureClient( |
233 base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured, | 218 base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured, |
234 base::Unretained(this)))), | 219 base::Unretained(this)))), |
235 device_enumeration_listener_(new DeviceEnumerationListener()), | |
236 image_capture_client_(new MockImageCaptureClient()), | 220 image_capture_client_(new MockImageCaptureClient()), |
237 video_capture_device_factory_(VideoCaptureDeviceFactory::CreateFactory( | 221 video_capture_device_factory_(VideoCaptureDeviceFactory::CreateFactory( |
238 base::ThreadTaskRunnerHandle::Get())) {} | 222 base::ThreadTaskRunnerHandle::Get())) {} |
239 | 223 |
240 void SetUp() override { | 224 void SetUp() override { |
241 #if defined(OS_ANDROID) | 225 #if defined(OS_ANDROID) |
242 VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice( | 226 VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice( |
243 base::android::AttachCurrentThread()); | 227 base::android::AttachCurrentThread()); |
244 | 228 |
245 static_cast<VideoCaptureDeviceFactoryAndroid*>( | 229 static_cast<VideoCaptureDeviceFactoryAndroid*>( |
(...skipping 15 matching lines...) Expand all Loading... |
261 last_format_ = format; | 245 last_format_ = format; |
262 if (run_loop_) | 246 if (run_loop_) |
263 run_loop_->QuitClosure().Run(); | 247 run_loop_->QuitClosure().Run(); |
264 } | 248 } |
265 | 249 |
266 void WaitForCapturedFrame() { | 250 void WaitForCapturedFrame() { |
267 run_loop_.reset(new base::RunLoop()); | 251 run_loop_.reset(new base::RunLoop()); |
268 run_loop_->Run(); | 252 run_loop_->Run(); |
269 } | 253 } |
270 | 254 |
271 bool EnumerateAndFindUsableDevices() { | 255 bool FindUsableDevices() { |
272 VideoCaptureDeviceDescriptors* descriptors = nullptr; | 256 video_capture_device_factory_->GetDeviceDescriptors( |
273 EXPECT_CALL(*device_enumeration_listener_.get(), | 257 device_descriptors_.get()); |
274 DoOnEnumerateDeviceDescriptors(_)) | |
275 .WillOnce(SaveArg<0>(&descriptors)); | |
276 | |
277 video_capture_device_factory_->EnumerateDeviceDescriptors( | |
278 base::Bind(&DeviceEnumerationListener::OnEnumerateDeviceDescriptors, | |
279 device_enumeration_listener_)); | |
280 base::RunLoop().RunUntilIdle(); | |
281 | |
282 device_descriptors_.reset(descriptors); | |
283 if (!device_descriptors_) | |
284 return false; | |
285 | 258 |
286 #if defined(OS_ANDROID) | 259 #if defined(OS_ANDROID) |
287 // Android deprecated/legacy devices capture on a single thread, which is | 260 // Android deprecated/legacy devices capture on a single thread, which is |
288 // occupied by the tests, so nothing gets actually delivered. | 261 // occupied by the tests, so nothing gets actually delivered. |
289 // TODO(mcasas): use those devices' test mode to deliver frames in a | 262 // TODO(mcasas): use those devices' test mode to deliver frames in a |
290 // background thread, https://crbug.com/626857 | 263 // background thread, https://crbug.com/626857 |
291 for (const auto& descriptor : *descriptors) { | 264 for (const auto& descriptor : *device_descriptors_) { |
292 if (VideoCaptureDeviceFactoryAndroid::IsLegacyOrDeprecatedDevice( | 265 if (VideoCaptureDeviceFactoryAndroid::IsLegacyOrDeprecatedDevice( |
293 descriptor.device_id)) { | 266 descriptor.device_id)) { |
294 return false; | 267 return false; |
295 } | 268 } |
296 } | 269 } |
297 #endif | 270 #endif |
298 | 271 |
299 return !device_descriptors_->empty(); | 272 return !device_descriptors_->empty(); |
300 } | 273 } |
301 | 274 |
302 const VideoCaptureFormat& last_format() const { return last_format_; } | 275 const VideoCaptureFormat& last_format() const { return last_format_; } |
303 | 276 |
304 std::unique_ptr<VideoCaptureDeviceDescriptor> | 277 std::unique_ptr<VideoCaptureDeviceDescriptor> |
305 GetFirstDeviceDescriptorSupportingPixelFormat( | 278 GetFirstDeviceDescriptorSupportingPixelFormat( |
306 const VideoPixelFormat& pixel_format) { | 279 const VideoPixelFormat& pixel_format) { |
307 if (!EnumerateAndFindUsableDevices()) | 280 if (!FindUsableDevices()) |
308 return nullptr; | 281 return nullptr; |
309 | 282 |
310 for (const auto& descriptor : *device_descriptors_) { | 283 for (const auto& descriptor : *device_descriptors_) { |
311 VideoCaptureFormats supported_formats; | 284 VideoCaptureFormats supported_formats; |
312 video_capture_device_factory_->GetSupportedFormats(descriptor, | 285 video_capture_device_factory_->GetSupportedFormats(descriptor, |
313 &supported_formats); | 286 &supported_formats); |
314 for (const auto& formats_iterator : supported_formats) { | 287 for (const auto& formats_iterator : supported_formats) { |
315 if (formats_iterator.pixel_format == pixel_format) { | 288 if (formats_iterator.pixel_format == pixel_format) { |
316 return std::unique_ptr<VideoCaptureDeviceDescriptor>( | 289 return std::unique_ptr<VideoCaptureDeviceDescriptor>( |
317 new VideoCaptureDeviceDescriptor(descriptor)); | 290 new VideoCaptureDeviceDescriptor(descriptor)); |
(...skipping 16 matching lines...) Expand all Loading... |
334 if (it == supported_formats.end()) { | 307 if (it == supported_formats.end()) { |
335 DVLOG(1) << "Size " << size.ToString() << " is not supported."; | 308 DVLOG(1) << "Size " << size.ToString() << " is not supported."; |
336 return false; | 309 return false; |
337 } | 310 } |
338 return true; | 311 return true; |
339 } | 312 } |
340 | 313 |
341 #if defined(OS_WIN) | 314 #if defined(OS_WIN) |
342 base::win::ScopedCOMInitializer initialize_com_; | 315 base::win::ScopedCOMInitializer initialize_com_; |
343 #endif | 316 #endif |
| 317 const std::unique_ptr<base::MessageLoop> loop_; |
344 std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors_; | 318 std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors_; |
345 const std::unique_ptr<base::MessageLoop> loop_; | |
346 std::unique_ptr<base::RunLoop> run_loop_; | 319 std::unique_ptr<base::RunLoop> run_loop_; |
347 std::unique_ptr<MockVideoCaptureClient> video_capture_client_; | 320 std::unique_ptr<MockVideoCaptureClient> video_capture_client_; |
348 const scoped_refptr<DeviceEnumerationListener> device_enumeration_listener_; | |
349 const scoped_refptr<MockImageCaptureClient> image_capture_client_; | 321 const scoped_refptr<MockImageCaptureClient> image_capture_client_; |
350 VideoCaptureFormat last_format_; | 322 VideoCaptureFormat last_format_; |
351 const std::unique_ptr<VideoCaptureDeviceFactory> | 323 const std::unique_ptr<VideoCaptureDeviceFactory> |
352 video_capture_device_factory_; | 324 video_capture_device_factory_; |
353 }; | 325 }; |
354 | 326 |
355 // Cause hangs on Windows Debug. http://crbug.com/417824 | 327 // Cause hangs on Windows Debug. http://crbug.com/417824 |
356 #if defined(OS_WIN) && !defined(NDEBUG) | 328 #if defined(OS_WIN) && !defined(NDEBUG) |
357 #define MAYBE_OpenInvalidDevice DISABLED_OpenInvalidDevice | 329 #define MAYBE_OpenInvalidDevice DISABLED_OpenInvalidDevice |
358 #else | 330 #else |
(...skipping 26 matching lines...) Expand all Loading... |
385 capture_params.requested_format.frame_size.SetSize(640, 480); | 357 capture_params.requested_format.frame_size.SetSize(640, 480); |
386 capture_params.requested_format.frame_rate = 30; | 358 capture_params.requested_format.frame_rate = 30; |
387 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 359 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
388 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 360 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
389 device->StopAndDeAllocate(); | 361 device->StopAndDeAllocate(); |
390 #endif | 362 #endif |
391 } | 363 } |
392 | 364 |
393 // Allocates the first enumerated device, and expects a frame. | 365 // Allocates the first enumerated device, and expects a frame. |
394 TEST_P(VideoCaptureDeviceTest, CaptureWithSize) { | 366 TEST_P(VideoCaptureDeviceTest, CaptureWithSize) { |
395 if (!EnumerateAndFindUsableDevices()) | 367 if (!FindUsableDevices()) |
396 return; | 368 return; |
397 | 369 |
398 const gfx::Size& size = GetParam(); | 370 const gfx::Size& size = GetParam(); |
399 if (!IsCaptureSizeSupported(device_descriptors_->front(), size)) | 371 if (!IsCaptureSizeSupported(device_descriptors_->front(), size)) |
400 return; | 372 return; |
401 const int width = size.width(); | 373 const int width = size.width(); |
402 const int height = size.height(); | 374 const int height = size.height(); |
403 | 375 |
404 std::unique_ptr<VideoCaptureDevice> device( | 376 std::unique_ptr<VideoCaptureDevice> device( |
405 video_capture_device_factory_->CreateDevice( | 377 video_capture_device_factory_->CreateDevice( |
(...skipping 20 matching lines...) Expand all Loading... |
426 | 398 |
427 const gfx::Size kCaptureSizes[] = {gfx::Size(640, 480), gfx::Size(1280, 720)}; | 399 const gfx::Size kCaptureSizes[] = {gfx::Size(640, 480), gfx::Size(1280, 720)}; |
428 | 400 |
429 INSTANTIATE_TEST_CASE_P(VideoCaptureDeviceTests, | 401 INSTANTIATE_TEST_CASE_P(VideoCaptureDeviceTests, |
430 VideoCaptureDeviceTest, | 402 VideoCaptureDeviceTest, |
431 testing::ValuesIn(kCaptureSizes)); | 403 testing::ValuesIn(kCaptureSizes)); |
432 | 404 |
433 // Allocates a device with an uncommon resolution and verifies frames are | 405 // Allocates a device with an uncommon resolution and verifies frames are |
434 // captured in a close, much more typical one. | 406 // captured in a close, much more typical one. |
435 TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) { | 407 TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) { |
436 if (!EnumerateAndFindUsableDevices()) | 408 if (!FindUsableDevices()) |
437 return; | 409 return; |
438 | 410 |
439 std::unique_ptr<VideoCaptureDevice> device( | 411 std::unique_ptr<VideoCaptureDevice> device( |
440 video_capture_device_factory_->CreateDevice( | 412 video_capture_device_factory_->CreateDevice( |
441 device_descriptors_->front())); | 413 device_descriptors_->front())); |
442 ASSERT_TRUE(device); | 414 ASSERT_TRUE(device); |
443 | 415 |
444 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); | 416 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); |
445 EXPECT_CALL(*video_capture_client_, OnStarted()); | 417 EXPECT_CALL(*video_capture_client_, OnStarted()); |
446 | 418 |
447 const gfx::Size input_size(640, 480); | 419 const gfx::Size input_size(640, 480); |
448 VideoCaptureParams capture_params; | 420 VideoCaptureParams capture_params; |
449 capture_params.requested_format.frame_size.SetSize(637, 472); | 421 capture_params.requested_format.frame_size.SetSize(637, 472); |
450 capture_params.requested_format.frame_rate = 35; | 422 capture_params.requested_format.frame_rate = 35; |
451 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 423 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
452 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 424 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
453 WaitForCapturedFrame(); | 425 WaitForCapturedFrame(); |
454 device->StopAndDeAllocate(); | 426 device->StopAndDeAllocate(); |
455 EXPECT_EQ(last_format().frame_size.width(), input_size.width()); | 427 EXPECT_EQ(last_format().frame_size.width(), input_size.width()); |
456 EXPECT_EQ(last_format().frame_size.height(), input_size.height()); | 428 EXPECT_EQ(last_format().frame_size.height(), input_size.height()); |
457 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) | 429 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) |
458 EXPECT_EQ(input_size.GetArea(), last_format().frame_size.GetArea()); | 430 EXPECT_EQ(input_size.GetArea(), last_format().frame_size.GetArea()); |
459 } | 431 } |
460 | 432 |
461 // Cause hangs on Windows, Linux. Fails Android. https://crbug.com/417824 | 433 // Cause hangs on Windows, Linux. Fails Android. https://crbug.com/417824 |
462 TEST_F(VideoCaptureDeviceTest, DISABLED_ReAllocateCamera) { | 434 TEST_F(VideoCaptureDeviceTest, DISABLED_ReAllocateCamera) { |
463 if (!EnumerateAndFindUsableDevices()) | 435 if (!FindUsableDevices()) |
464 return; | 436 return; |
465 | 437 |
466 // First, do a number of very fast device start/stops. | 438 // First, do a number of very fast device start/stops. |
467 for (int i = 0; i <= 5; i++) { | 439 for (int i = 0; i <= 5; i++) { |
468 ResetWithNewClient(); | 440 ResetWithNewClient(); |
469 std::unique_ptr<VideoCaptureDevice> device( | 441 std::unique_ptr<VideoCaptureDevice> device( |
470 video_capture_device_factory_->CreateDevice( | 442 video_capture_device_factory_->CreateDevice( |
471 device_descriptors_->front())); | 443 device_descriptors_->front())); |
472 gfx::Size resolution; | 444 gfx::Size resolution; |
473 if (i % 2) | 445 if (i % 2) |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = | 518 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = |
547 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MAX); | 519 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MAX); |
548 // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else to test here | 520 // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else to test here |
549 // since we cannot forecast the hardware capabilities. | 521 // since we cannot forecast the hardware capabilities. |
550 ASSERT_FALSE(device_descriptor); | 522 ASSERT_FALSE(device_descriptor); |
551 } | 523 } |
552 | 524 |
553 // Starts the camera and verifies that a photo can be taken. The correctness of | 525 // Starts the camera and verifies that a photo can be taken. The correctness of |
554 // the photo is enforced by MockImageCaptureClient. | 526 // the photo is enforced by MockImageCaptureClient. |
555 TEST_F(VideoCaptureDeviceTest, MAYBE_TakePhoto) { | 527 TEST_F(VideoCaptureDeviceTest, MAYBE_TakePhoto) { |
556 if (!EnumerateAndFindUsableDevices()) | 528 if (!FindUsableDevices()) |
557 return; | 529 return; |
558 | 530 |
559 #if defined(OS_ANDROID) | 531 #if defined(OS_ANDROID) |
560 // TODO(mcasas): fails on Lollipop devices, reconnect https://crbug.com/646840 | 532 // TODO(mcasas): fails on Lollipop devices, reconnect https://crbug.com/646840 |
561 if (base::android::BuildInfo::GetInstance()->sdk_int() < | 533 if (base::android::BuildInfo::GetInstance()->sdk_int() < |
562 base::android::SDK_VERSION_MARSHMALLOW) { | 534 base::android::SDK_VERSION_MARSHMALLOW) { |
563 return; | 535 return; |
564 } | 536 } |
565 #endif | 537 #endif |
566 | 538 |
(...skipping 24 matching lines...) Expand all Loading... |
591 .WillOnce(RunClosure(quit_closure)); | 563 .WillOnce(RunClosure(quit_closure)); |
592 | 564 |
593 device->TakePhoto(std::move(scoped_callback)); | 565 device->TakePhoto(std::move(scoped_callback)); |
594 run_loop.Run(); | 566 run_loop.Run(); |
595 | 567 |
596 device->StopAndDeAllocate(); | 568 device->StopAndDeAllocate(); |
597 } | 569 } |
598 | 570 |
599 // Starts the camera and verifies that the photo capabilities can be retrieved. | 571 // Starts the camera and verifies that the photo capabilities can be retrieved. |
600 TEST_F(VideoCaptureDeviceTest, MAYBE_GetPhotoCapabilities) { | 572 TEST_F(VideoCaptureDeviceTest, MAYBE_GetPhotoCapabilities) { |
601 if (!EnumerateAndFindUsableDevices()) | 573 if (!FindUsableDevices()) |
602 return; | 574 return; |
603 | 575 |
604 #if defined(OS_ANDROID) | 576 #if defined(OS_ANDROID) |
605 // TODO(mcasas): fails on Lollipop devices, reconnect https://crbug.com/646840 | 577 // TODO(mcasas): fails on Lollipop devices, reconnect https://crbug.com/646840 |
606 if (base::android::BuildInfo::GetInstance()->sdk_int() < | 578 if (base::android::BuildInfo::GetInstance()->sdk_int() < |
607 base::android::SDK_VERSION_MARSHMALLOW) { | 579 base::android::SDK_VERSION_MARSHMALLOW) { |
608 return; | 580 return; |
609 } | 581 } |
610 #endif | 582 #endif |
611 | 583 |
(...skipping 26 matching lines...) Expand all Loading... |
638 | 610 |
639 device->GetPhotoCapabilities(std::move(scoped_get_callback)); | 611 device->GetPhotoCapabilities(std::move(scoped_get_callback)); |
640 run_loop.Run(); | 612 run_loop.Run(); |
641 | 613 |
642 ASSERT_TRUE(image_capture_client_->capabilities()); | 614 ASSERT_TRUE(image_capture_client_->capabilities()); |
643 | 615 |
644 device->StopAndDeAllocate(); | 616 device->StopAndDeAllocate(); |
645 } | 617 } |
646 | 618 |
647 }; // namespace media | 619 }; // namespace media |
OLD | NEW |