| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 #include "media/capture/video/android/video_capture_device_android.h" | 42 #include "media/capture/video/android/video_capture_device_android.h" |
| 43 #include "media/capture/video/android/video_capture_device_factory_android.h" | 43 #include "media/capture/video/android/video_capture_device_factory_android.h" |
| 44 #endif | 44 #endif |
| 45 | 45 |
| 46 #if defined(OS_MACOSX) | 46 #if defined(OS_MACOSX) |
| 47 // Mac will always give you the size you ask for and this case will fail. | 47 // Mac will always give you the size you ask for and this case will fail. |
| 48 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize | 48 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize |
| 49 // We will always get YUYV from the Mac AVFoundation implementations. | 49 // We will always get YUYV from the Mac AVFoundation implementations. |
| 50 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg | 50 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg |
| 51 #define MAYBE_TakePhoto TakePhoto | 51 #define MAYBE_TakePhoto TakePhoto |
| 52 #define MAYBE_GetPhotoCapabilities DISABLED_GetPhotoCapabilities |
| 52 #elif defined(OS_WIN) | 53 #elif defined(OS_WIN) |
| 53 #define MAYBE_AllocateBadSize AllocateBadSize | 54 #define MAYBE_AllocateBadSize AllocateBadSize |
| 54 #define MAYBE_CaptureMjpeg CaptureMjpeg | 55 #define MAYBE_CaptureMjpeg CaptureMjpeg |
| 55 #define MAYBE_TakePhoto TakePhoto | 56 #define MAYBE_TakePhoto TakePhoto |
| 57 #define MAYBE_GetPhotoCapabilities DISABLED_GetPhotoCapabilities |
| 56 #elif defined(OS_ANDROID) | 58 #elif defined(OS_ANDROID) |
| 57 #define MAYBE_AllocateBadSize AllocateBadSize | 59 #define MAYBE_AllocateBadSize AllocateBadSize |
| 58 #define MAYBE_CaptureMjpeg CaptureMjpeg | 60 #define MAYBE_CaptureMjpeg CaptureMjpeg |
| 59 #define MAYBE_TakePhoto TakePhoto | 61 #define MAYBE_TakePhoto TakePhoto |
| 62 #define MAYBE_GetPhotoCapabilities GetPhotoCapabilities |
| 60 #elif defined(OS_LINUX) | 63 #elif defined(OS_LINUX) |
| 61 // AllocateBadSize will hang when a real camera is attached and if more than one | 64 // AllocateBadSize will hang when a real camera is attached and if more than one |
| 62 // test is trying to use the camera (even across processes). Do NOT renable | 65 // test is trying to use the camera (even across processes). Do NOT renable |
| 63 // this test without fixing the many bugs associated with it: | 66 // this test without fixing the many bugs associated with it: |
| 64 // http://crbug.com/94134 http://crbug.com/137260 http://crbug.com/417824 | 67 // http://crbug.com/94134 http://crbug.com/137260 http://crbug.com/417824 |
| 65 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize | 68 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize |
| 66 #define MAYBE_CaptureMjpeg CaptureMjpeg | 69 #define MAYBE_CaptureMjpeg CaptureMjpeg |
| 67 #define MAYBE_TakePhoto TakePhoto | 70 #define MAYBE_TakePhoto TakePhoto |
| 71 #define MAYBE_GetPhotoCapabilities GetPhotoCapabilities |
| 68 #else | 72 #else |
| 69 #define MAYBE_AllocateBadSize AllocateBadSize | 73 #define MAYBE_AllocateBadSize AllocateBadSize |
| 70 #define MAYBE_CaptureMjpeg CaptureMjpeg | 74 #define MAYBE_CaptureMjpeg CaptureMjpeg |
| 71 #define MAYBE_TakePhoto DISABLED_TakePhoto | 75 #define MAYBE_TakePhoto DISABLED_TakePhoto |
| 76 #define MAYBE_GetPhotoCapabilities DISABLED_GetPhotoCapabilities |
| 72 #endif | 77 #endif |
| 73 | 78 |
| 74 using ::testing::_; | 79 using ::testing::_; |
| 75 using ::testing::Invoke; | 80 using ::testing::Invoke; |
| 76 using ::testing::SaveArg; | 81 using ::testing::SaveArg; |
| 77 | 82 |
| 78 namespace media { | 83 namespace media { |
| 79 namespace { | 84 namespace { |
| 80 | 85 |
| 86 ACTION_P(RunClosure, closure) { |
| 87 closure.Run(); |
| 88 } |
| 89 |
| 81 void DumpError(const tracked_objects::Location& location, | 90 void DumpError(const tracked_objects::Location& location, |
| 82 const std::string& message) { | 91 const std::string& message) { |
| 83 DPLOG(ERROR) << location.ToString() << " " << message; | 92 DPLOG(ERROR) << location.ToString() << " " << message; |
| 84 } | 93 } |
| 85 | 94 |
| 86 class MockVideoCaptureClient : public VideoCaptureDevice::Client { | 95 class MockVideoCaptureClient : public VideoCaptureDevice::Client { |
| 87 public: | 96 public: |
| 88 MOCK_METHOD0(DoReserveOutputBuffer, void(void)); | 97 MOCK_METHOD0(DoReserveOutputBuffer, void(void)); |
| 89 MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void)); | 98 MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void)); |
| 90 MOCK_METHOD0(DoOnIncomingCapturedVideoFrame, void(void)); | 99 MOCK_METHOD0(DoOnIncomingCapturedVideoFrame, void(void)); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 EXPECT_EQ('G', blob->data[3]); | 174 EXPECT_EQ('G', blob->data[3]); |
| 166 OnCorrectPhotoTaken(); | 175 OnCorrectPhotoTaken(); |
| 167 } else { | 176 } else { |
| 168 ADD_FAILURE() << "Photo format should be jpeg or png"; | 177 ADD_FAILURE() << "Photo format should be jpeg or png"; |
| 169 } | 178 } |
| 170 } | 179 } |
| 171 MOCK_METHOD0(OnCorrectPhotoTaken, void(void)); | 180 MOCK_METHOD0(OnCorrectPhotoTaken, void(void)); |
| 172 MOCK_METHOD1(OnTakePhotoFailure, | 181 MOCK_METHOD1(OnTakePhotoFailure, |
| 173 void(const base::Callback<void(mojom::BlobPtr)>&)); | 182 void(const base::Callback<void(mojom::BlobPtr)>&)); |
| 174 | 183 |
| 184 // GMock doesn't support move-only arguments, so we use this forward method. |
| 185 void DoOnGetPhotoCapabilities(mojom::PhotoCapabilitiesPtr capabilities) { |
| 186 capabilities_ = std::move(capabilities); |
| 187 OnCorrectGetPhotoCapabilities(); |
| 188 } |
| 189 MOCK_METHOD0(OnCorrectGetPhotoCapabilities, void(void)); |
| 190 MOCK_METHOD1(OnGetPhotoCapabilitiesFailure, |
| 191 void(const base::Callback<void(mojom::PhotoCapabilitiesPtr)>&)); |
| 192 |
| 193 const mojom::PhotoCapabilities* capabilities() { return capabilities_.get(); } |
| 194 |
| 175 private: | 195 private: |
| 176 friend class base::RefCounted<MockImageCaptureClient>; | 196 friend class base::RefCounted<MockImageCaptureClient>; |
| 177 virtual ~MockImageCaptureClient() {} | 197 virtual ~MockImageCaptureClient() {} |
| 198 |
| 199 mojom::PhotoCapabilitiesPtr capabilities_; |
| 178 }; | 200 }; |
| 179 | 201 |
| 180 class DeviceEnumerationListener | 202 class DeviceEnumerationListener |
| 181 : public base::RefCounted<DeviceEnumerationListener> { | 203 : public base::RefCounted<DeviceEnumerationListener> { |
| 182 public: | 204 public: |
| 183 MOCK_METHOD1(DoOnEnumerateDeviceDescriptors, | 205 MOCK_METHOD1(DoOnEnumerateDeviceDescriptors, |
| 184 void(VideoCaptureDeviceDescriptors* device_descriptors)); | 206 void(VideoCaptureDeviceDescriptors* device_descriptors)); |
| 185 // GMock doesn't support move-only arguments, so we use this forward method. | 207 // GMock doesn't support move-only arguments, so we use this forward method. |
| 186 void OnEnumerateDeviceDescriptors( | 208 void OnEnumerateDeviceDescriptors( |
| 187 std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors) { | 209 std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 .Times(0); | 249 .Times(0); |
| 228 } | 250 } |
| 229 | 251 |
| 230 void ResetWithNewClient() { | 252 void ResetWithNewClient() { |
| 231 video_capture_client_.reset(new MockVideoCaptureClient(base::Bind( | 253 video_capture_client_.reset(new MockVideoCaptureClient(base::Bind( |
| 232 &VideoCaptureDeviceTest::OnFrameCaptured, base::Unretained(this)))); | 254 &VideoCaptureDeviceTest::OnFrameCaptured, base::Unretained(this)))); |
| 233 } | 255 } |
| 234 | 256 |
| 235 void OnFrameCaptured(const VideoCaptureFormat& format) { | 257 void OnFrameCaptured(const VideoCaptureFormat& format) { |
| 236 last_format_ = format; | 258 last_format_ = format; |
| 237 run_loop_->QuitClosure().Run(); | 259 if (run_loop_) |
| 260 run_loop_->QuitClosure().Run(); |
| 238 } | 261 } |
| 239 | 262 |
| 240 void WaitForCapturedFrame() { | 263 void WaitForCapturedFrame() { |
| 241 run_loop_.reset(new base::RunLoop()); | 264 run_loop_.reset(new base::RunLoop()); |
| 242 run_loop_->Run(); | 265 run_loop_->Run(); |
| 243 } | 266 } |
| 244 | 267 |
| 245 bool EnumerateAndFindUsableDevices() { | 268 bool EnumerateAndFindUsableDevices() { |
| 246 VideoCaptureDeviceDescriptors* descriptors = nullptr; | 269 VideoCaptureDeviceDescriptors* descriptors = nullptr; |
| 247 EXPECT_CALL(*device_enumeration_listener_.get(), | 270 EXPECT_CALL(*device_enumeration_listener_.get(), |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 TEST_F(VideoCaptureDeviceTest, NoCameraSupportsPixelFormatMax) { | 537 TEST_F(VideoCaptureDeviceTest, NoCameraSupportsPixelFormatMax) { |
| 515 // Use PIXEL_FORMAT_MAX to iterate all device names for testing | 538 // Use PIXEL_FORMAT_MAX to iterate all device names for testing |
| 516 // GetDeviceSupportedFormats(). | 539 // GetDeviceSupportedFormats(). |
| 517 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = | 540 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = |
| 518 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MAX); | 541 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MAX); |
| 519 // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else to test here | 542 // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else to test here |
| 520 // since we cannot forecast the hardware capabilities. | 543 // since we cannot forecast the hardware capabilities. |
| 521 ASSERT_FALSE(device_descriptor); | 544 ASSERT_FALSE(device_descriptor); |
| 522 } | 545 } |
| 523 | 546 |
| 524 // Starts the camera and take a photo. | 547 // Starts the camera and verifies that a photo can be taken. The correctness of |
| 548 // the photo is enforced by MockImageCaptureClient. |
| 525 TEST_F(VideoCaptureDeviceTest, MAYBE_TakePhoto) { | 549 TEST_F(VideoCaptureDeviceTest, MAYBE_TakePhoto) { |
| 526 if (!EnumerateAndFindUsableDevices()) | 550 if (!EnumerateAndFindUsableDevices()) |
| 527 return; | 551 return; |
| 528 | 552 |
| 529 #if defined(OS_ANDROID) | 553 #if defined(OS_ANDROID) |
| 530 // TODO(mcasas): fails on Lollipop devices, reconnect https://crbug.com/646840 | 554 // TODO(mcasas): fails on Lollipop devices, reconnect https://crbug.com/646840 |
| 531 if (base::android::BuildInfo::GetInstance()->sdk_int() < | 555 if (base::android::BuildInfo::GetInstance()->sdk_int() < |
| 532 base::android::SDK_VERSION_MARSHMALLOW) { | 556 base::android::SDK_VERSION_MARSHMALLOW) { |
| 533 return; | 557 return; |
| 534 } | 558 } |
| 535 #endif | 559 #endif |
| 536 | 560 |
| 537 std::unique_ptr<VideoCaptureDevice> device( | 561 std::unique_ptr<VideoCaptureDevice> device( |
| 538 video_capture_device_factory_->CreateDevice( | 562 video_capture_device_factory_->CreateDevice( |
| 539 device_descriptors_->front())); | 563 device_descriptors_->front())); |
| 540 ASSERT_TRUE(device); | 564 ASSERT_TRUE(device); |
| 541 | 565 |
| 542 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); | 566 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); |
| 543 | 567 |
| 544 VideoCaptureParams capture_params; | 568 VideoCaptureParams capture_params; |
| 545 capture_params.requested_format.frame_size.SetSize(320, 240); | 569 capture_params.requested_format.frame_size.SetSize(320, 240); |
| 546 capture_params.requested_format.frame_rate = 30; | 570 capture_params.requested_format.frame_rate = 30; |
| 547 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 571 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
| 548 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 572 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
| 549 WaitForCapturedFrame(); | |
| 550 | 573 |
| 551 VideoCaptureDevice::TakePhotoCallback scoped_callback( | 574 VideoCaptureDevice::TakePhotoCallback scoped_callback( |
| 552 base::Bind(&MockImageCaptureClient::DoOnPhotoTaken, | 575 base::Bind(&MockImageCaptureClient::DoOnPhotoTaken, |
| 553 image_capture_client_), | 576 image_capture_client_), |
| 554 media::BindToCurrentLoop(base::Bind( | 577 media::BindToCurrentLoop(base::Bind( |
| 555 &MockImageCaptureClient::OnTakePhotoFailure, image_capture_client_))); | 578 &MockImageCaptureClient::OnTakePhotoFailure, image_capture_client_))); |
| 556 | 579 |
| 557 EXPECT_CALL(*image_capture_client_.get(), OnCorrectPhotoTaken()).Times(1); | 580 base::RunLoop run_loop; |
| 581 base::Closure quit_closure = media::BindToCurrentLoop(run_loop.QuitClosure()); |
| 582 EXPECT_CALL(*image_capture_client_.get(), OnCorrectPhotoTaken()) |
| 583 .Times(1) |
| 584 .WillOnce(RunClosure(quit_closure)); |
| 585 |
| 558 device->TakePhoto(std::move(scoped_callback)); | 586 device->TakePhoto(std::move(scoped_callback)); |
| 559 WaitForCapturedFrame(); | 587 run_loop.Run(); |
| 560 | 588 |
| 561 device->StopAndDeAllocate(); | 589 device->StopAndDeAllocate(); |
| 562 } | 590 } |
| 591 |
| 592 // Starts the camera and verifies that the photo capabilities can be retrieved. |
| 593 TEST_F(VideoCaptureDeviceTest, MAYBE_GetPhotoCapabilities) { |
| 594 if (!EnumerateAndFindUsableDevices()) |
| 595 return; |
| 596 |
| 597 #if defined(OS_ANDROID) |
| 598 // TODO(mcasas): fails on Lollipop devices, reconnect https://crbug.com/646840 |
| 599 if (base::android::BuildInfo::GetInstance()->sdk_int() < |
| 600 base::android::SDK_VERSION_MARSHMALLOW) { |
| 601 return; |
| 602 } |
| 603 #endif |
| 604 |
| 605 std::unique_ptr<VideoCaptureDevice> device( |
| 606 video_capture_device_factory_->CreateDevice( |
| 607 device_descriptors_->front())); |
| 608 ASSERT_TRUE(device); |
| 609 |
| 610 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); |
| 611 |
| 612 VideoCaptureParams capture_params; |
| 613 capture_params.requested_format.frame_size.SetSize(320, 240); |
| 614 capture_params.requested_format.frame_rate = 30; |
| 615 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
| 616 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
| 617 |
| 618 VideoCaptureDevice::GetPhotoCapabilitiesCallback scoped_get_callback( |
| 619 base::Bind(&MockImageCaptureClient::DoOnGetPhotoCapabilities, |
| 620 image_capture_client_), |
| 621 media::BindToCurrentLoop( |
| 622 base::Bind(&MockImageCaptureClient::OnGetPhotoCapabilitiesFailure, |
| 623 image_capture_client_))); |
| 624 |
| 625 base::RunLoop run_loop; |
| 626 base::Closure quit_closure = media::BindToCurrentLoop(run_loop.QuitClosure()); |
| 627 EXPECT_CALL(*image_capture_client_.get(), OnCorrectGetPhotoCapabilities()) |
| 628 .Times(1) |
| 629 .WillOnce(RunClosure(quit_closure)); |
| 630 |
| 631 device->GetPhotoCapabilities(std::move(scoped_get_callback)); |
| 632 run_loop.Run(); |
| 633 |
| 634 ASSERT_TRUE(image_capture_client_->capabilities()); |
| 635 |
| 636 device->StopAndDeAllocate(); |
| 637 } |
| 563 | 638 |
| 564 }; // namespace media | 639 }; // namespace media |
| OLD | NEW |