Chromium Code Reviews| 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 EXPECT_EQ(0xFF, blob->data[0]); // First SOI byte | 165 EXPECT_EQ(0xFF, blob->data[0]); // First SOI byte |
| 157 EXPECT_EQ(0xD8, blob->data[1]); // Second SOI byte | 166 EXPECT_EQ(0xD8, blob->data[1]); // Second SOI byte |
| 158 EXPECT_EQ(0xFF, blob->data[2]); // First JFIF-APP0 byte | 167 EXPECT_EQ(0xFF, blob->data[2]); // First JFIF-APP0 byte |
| 159 EXPECT_EQ(0xE0, blob->data[3] & 0xF0); // Second JFIF-APP0 byte | 168 EXPECT_EQ(0xE0, blob->data[3] & 0xF0); // Second JFIF-APP0 byte |
| 160 OnCorrectPhotoTaken(); | 169 OnCorrectPhotoTaken(); |
| 161 } else if (strcmp("image/png", blob->mime_type.c_str()) == 0) { | 170 } else if (strcmp("image/png", blob->mime_type.c_str()) == 0) { |
| 162 ASSERT_GT(blob->data.size(), 4u); | 171 ASSERT_GT(blob->data.size(), 4u); |
| 163 EXPECT_EQ('P', blob->data[1]); | 172 EXPECT_EQ('P', blob->data[1]); |
| 164 EXPECT_EQ('N', blob->data[2]); | 173 EXPECT_EQ('N', blob->data[2]); |
| 165 EXPECT_EQ('G', blob->data[3]); | 174 EXPECT_EQ('G', blob->data[3]); |
| 166 OnCorrectPhotoTaken(); | 175 OnCorrectPhotoTaken(); |
|
chfremer
2016/09/23 21:18:30
The expectation on the arriving data is expressed
mcasas
2016/09/23 22:10:57
Yeah, but then we'd have to duplicate this header
chfremer
2016/09/23 22:48:56
Okay to keep it the way it is, especially since it
| |
| 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 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 514 TEST_F(VideoCaptureDeviceTest, NoCameraSupportsPixelFormatMax) { | 536 TEST_F(VideoCaptureDeviceTest, NoCameraSupportsPixelFormatMax) { |
| 515 // Use PIXEL_FORMAT_MAX to iterate all device names for testing | 537 // Use PIXEL_FORMAT_MAX to iterate all device names for testing |
| 516 // GetDeviceSupportedFormats(). | 538 // GetDeviceSupportedFormats(). |
| 517 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = | 539 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = |
| 518 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MAX); | 540 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MAX); |
| 519 // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else to test here | 541 // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else to test here |
| 520 // since we cannot forecast the hardware capabilities. | 542 // since we cannot forecast the hardware capabilities. |
| 521 ASSERT_FALSE(device_descriptor); | 543 ASSERT_FALSE(device_descriptor); |
| 522 } | 544 } |
| 523 | 545 |
| 524 // Starts the camera and take a photo. | 546 // Starts the camera and takes a photo. |
|
chfremer
2016/09/23 21:18:30
This description is not really an answer to the qu
mcasas
2016/09/23 22:10:57
Done.
| |
| 525 TEST_F(VideoCaptureDeviceTest, MAYBE_TakePhoto) { | 547 TEST_F(VideoCaptureDeviceTest, MAYBE_TakePhoto) { |
| 526 if (!EnumerateAndFindUsableDevices()) | 548 if (!EnumerateAndFindUsableDevices()) |
| 527 return; | 549 return; |
| 528 | 550 |
| 529 #if defined(OS_ANDROID) | 551 #if defined(OS_ANDROID) |
| 530 // TODO(mcasas): fails on Lollipop devices, reconnect https://crbug.com/646840 | 552 // TODO(mcasas): fails on Lollipop devices, reconnect https://crbug.com/646840 |
| 531 if (base::android::BuildInfo::GetInstance()->sdk_int() < | 553 if (base::android::BuildInfo::GetInstance()->sdk_int() < |
| 532 base::android::SDK_VERSION_MARSHMALLOW) { | 554 base::android::SDK_VERSION_MARSHMALLOW) { |
| 533 return; | 555 return; |
| 534 } | 556 } |
| 535 #endif | 557 #endif |
| 536 | 558 |
| 537 std::unique_ptr<VideoCaptureDevice> device( | 559 std::unique_ptr<VideoCaptureDevice> device( |
| 538 video_capture_device_factory_->CreateDevice( | 560 video_capture_device_factory_->CreateDevice( |
| 539 device_descriptors_->front())); | 561 device_descriptors_->front())); |
| 540 ASSERT_TRUE(device); | 562 ASSERT_TRUE(device); |
| 541 | 563 |
| 542 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); | 564 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); |
| 543 | 565 |
| 544 VideoCaptureParams capture_params; | 566 VideoCaptureParams capture_params; |
| 545 capture_params.requested_format.frame_size.SetSize(320, 240); | 567 capture_params.requested_format.frame_size.SetSize(320, 240); |
| 546 capture_params.requested_format.frame_rate = 30; | 568 capture_params.requested_format.frame_rate = 30; |
| 547 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 569 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
| 548 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 570 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
| 549 WaitForCapturedFrame(); | 571 WaitForCapturedFrame(); |
|
chfremer
2016/09/23 21:18:29
The description of the interface media::VideoCaptu
mcasas
2016/09/23 22:10:57
Hmm well, it kinda says so:
"...and/or interruptin
chfremer
2016/09/23 22:48:56
As per discussion on IM, I think we should remove
mcasas
2016/09/23 23:16:26
Oh hark. Let me explain: from the ImageCapture
PO
| |
| 550 | 572 |
| 551 VideoCaptureDevice::TakePhotoCallback scoped_callback( | 573 VideoCaptureDevice::TakePhotoCallback scoped_callback( |
| 552 base::Bind(&MockImageCaptureClient::DoOnPhotoTaken, | 574 base::Bind(&MockImageCaptureClient::DoOnPhotoTaken, |
| 553 image_capture_client_), | 575 image_capture_client_), |
| 554 media::BindToCurrentLoop(base::Bind( | 576 media::BindToCurrentLoop(base::Bind( |
| 555 &MockImageCaptureClient::OnTakePhotoFailure, image_capture_client_))); | 577 &MockImageCaptureClient::OnTakePhotoFailure, image_capture_client_))); |
| 556 | 578 |
| 557 EXPECT_CALL(*image_capture_client_.get(), OnCorrectPhotoTaken()).Times(1); | 579 base::RunLoop run_loop; |
| 580 base::Closure quit_closure = media::BindToCurrentLoop(run_loop.QuitClosure()); | |
| 581 EXPECT_CALL(*image_capture_client_.get(), OnCorrectPhotoTaken()) | |
| 582 .Times(1) | |
| 583 .WillOnce(RunClosure(quit_closure)); | |
| 584 | |
| 558 device->TakePhoto(std::move(scoped_callback)); | 585 device->TakePhoto(std::move(scoped_callback)); |
| 559 WaitForCapturedFrame(); | 586 run_loop.Run(); |
| 560 | 587 |
| 561 device->StopAndDeAllocate(); | 588 device->StopAndDeAllocate(); |
| 562 } | 589 } |
| 563 | 590 |
| 591 // Starts the camera and tries to get the Photo capabilities. | |
| 592 TEST_F(VideoCaptureDeviceTest, MAYBE_GetPhotoCapabilities) { | |
| 593 if (!EnumerateAndFindUsableDevices()) | |
| 594 return; | |
|
chfremer
2016/09/23 21:18:29
I assume we do this to not fail on machines that d
mcasas
2016/09/23 22:10:57
Hmm that's a good suggestion. This behaviour is
pe
| |
| 595 | |
| 596 #if defined(OS_ANDROID) | |
| 597 // TODO(mcasas): fails on Lollipop devices, reconnect https://crbug.com/646840 | |
| 598 if (base::android::BuildInfo::GetInstance()->sdk_int() < | |
| 599 base::android::SDK_VERSION_MARSHMALLOW) { | |
| 600 return; | |
| 601 } | |
| 602 #endif | |
| 603 | |
| 604 std::unique_ptr<VideoCaptureDevice> device( | |
| 605 video_capture_device_factory_->CreateDevice( | |
| 606 device_descriptors_->front())); | |
| 607 ASSERT_TRUE(device); | |
| 608 | |
| 609 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); | |
| 610 | |
| 611 VideoCaptureParams capture_params; | |
| 612 capture_params.requested_format.frame_size.SetSize(320, 240); | |
| 613 capture_params.requested_format.frame_rate = 30; | |
| 614 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | |
| 615 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | |
| 616 WaitForCapturedFrame(); | |
| 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 } | |
| 638 | |
| 564 }; // namespace media | 639 }; // namespace media |
| OLD | NEW |