Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(693)

Side by Side Diff: media/capture/video/video_capture_device_unittest.cc

Issue 2129733004: ImageCapture: Implement takePhoto() for Mac AVFoundation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased _unittests.cc and rsesek@ comments Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
15 #include "base/memory/ref_counted.h" 15 #include "base/memory/ref_counted.h"
16 #include "base/run_loop.h" 16 #include "base/run_loop.h"
17 #include "base/single_thread_task_runner.h" 17 #include "base/single_thread_task_runner.h"
18 #include "base/test/test_timeouts.h" 18 #include "base/test/test_timeouts.h"
19 #include "base/threading/thread.h" 19 #include "base/threading/thread.h"
20 #include "base/threading/thread_task_runner_handle.h" 20 #include "base/threading/thread_task_runner_handle.h"
21 #include "build/build_config.h" 21 #include "build/build_config.h"
22 #include "media/base/bind_to_current_loop.h"
22 #include "media/base/video_capture_types.h" 23 #include "media/base/video_capture_types.h"
23 #include "media/capture/video/video_capture_device_factory.h" 24 #include "media/capture/video/video_capture_device_factory.h"
24 #include "testing/gmock/include/gmock/gmock.h" 25 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h" 26 #include "testing/gtest/include/gtest/gtest.h"
26 27
27 #if defined(OS_WIN) 28 #if defined(OS_WIN)
28 #include "base/win/scoped_com_initializer.h" 29 #include "base/win/scoped_com_initializer.h"
29 #include "base/win/windows_version.h" // For fine-grained suppression. 30 #include "base/win/windows_version.h" // For fine-grained suppression.
30 #include "media/capture/video/win/video_capture_device_factory_win.h" 31 #include "media/capture/video/win/video_capture_device_factory_win.h"
31 #endif 32 #endif
32 33
33 #if defined(OS_MACOSX) 34 #if defined(OS_MACOSX)
34 #include "media/base/mac/avfoundation_glue.h" 35 #include "media/base/mac/avfoundation_glue.h"
35 #include "media/capture/video/mac/video_capture_device_factory_mac.h" 36 #include "media/capture/video/mac/video_capture_device_factory_mac.h"
36 #endif 37 #endif
37 38
38 #if defined(OS_ANDROID) 39 #if defined(OS_ANDROID)
39 #include "base/android/jni_android.h" 40 #include "base/android/jni_android.h"
40 #include "media/capture/video/android/video_capture_device_android.h" 41 #include "media/capture/video/android/video_capture_device_android.h"
41 #endif 42 #endif
42 43
43 #if defined(OS_MACOSX) 44 #if defined(OS_MACOSX)
44 // 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.
45 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize 46 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize
46 // We will always get YUYV from the Mac AVFoundation implementations. 47 // We will always get YUYV from the Mac AVFoundation implementations.
47 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg 48 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg
49 #define MAYBE_TakePhoto TakePhoto
48 #elif defined(OS_WIN) 50 #elif defined(OS_WIN)
49 #define MAYBE_AllocateBadSize AllocateBadSize 51 #define MAYBE_AllocateBadSize AllocateBadSize
50 #define MAYBE_CaptureMjpeg CaptureMjpeg 52 #define MAYBE_CaptureMjpeg CaptureMjpeg
53 #define MAYBE_TakePhoto DISABLED_TakePhoto
51 #elif defined(OS_ANDROID) 54 #elif defined(OS_ANDROID)
52 // TODO(wjia): enable those tests on Android. 55 // TODO(wjia): enable those tests on Android.
53 // On Android, native camera (JAVA) delivers frames on UI thread which is the 56 // On Android, native camera (JAVA) delivers frames on UI thread which is the
54 // main thread for tests. This results in no frame received by 57 // main thread for tests. This results in no frame received by
55 // VideoCaptureAndroid. 58 // VideoCaptureAndroid.
56 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize 59 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize
57 #define DeAllocateCameraWhileRunning DISABLED_DeAllocateCameraWhileRunning 60 #define DeAllocateCameraWhileRunning DISABLED_DeAllocateCameraWhileRunning
58 #define DeAllocateCameraWhileRunning DISABLED_DeAllocateCameraWhileRunning 61 #define DeAllocateCameraWhileRunning DISABLED_DeAllocateCameraWhileRunning
59 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg 62 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg
63 #define MAYBE_TakePhoto DISABLED_TakePhoto
60 #elif defined(OS_LINUX) 64 #elif defined(OS_LINUX)
61 // 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
62 // 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
63 // this test without fixing the many bugs associated with it: 67 // this test without fixing the many bugs associated with it:
64 // 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
65 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize 69 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize
66 #define MAYBE_CaptureMjpeg CaptureMjpeg 70 #define MAYBE_CaptureMjpeg CaptureMjpeg
71 #define MAYBE_TakePhoto DISABLED_TakePhoto
67 #else 72 #else
68 #define MAYBE_AllocateBadSize AllocateBadSize 73 #define MAYBE_AllocateBadSize AllocateBadSize
69 #define MAYBE_CaptureMjpeg CaptureMjpeg 74 #define MAYBE_CaptureMjpeg CaptureMjpeg
75 #define MAYBE_TakePhoto DISABLED_TakePhoto
70 #endif 76 #endif
71 77
72 using ::testing::_; 78 using ::testing::_;
73 using ::testing::SaveArg; 79 using ::testing::SaveArg;
74 80
75 namespace media { 81 namespace media {
76 namespace { 82 namespace {
77 83
78 class MockVideoCaptureClient : public VideoCaptureDevice::Client { 84 class MockVideoCaptureClient : public VideoCaptureDevice::Client {
79 public: 85 public:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 DoResurrectLastOutputBuffer(); 135 DoResurrectLastOutputBuffer();
130 NOTREACHED() << "This should never be called"; 136 NOTREACHED() << "This should never be called";
131 return std::unique_ptr<Buffer>(); 137 return std::unique_ptr<Buffer>();
132 } 138 }
133 139
134 private: 140 private:
135 scoped_refptr<base::SingleThreadTaskRunner> main_thread_; 141 scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
136 base::Callback<void(const VideoCaptureFormat&)> frame_cb_; 142 base::Callback<void(const VideoCaptureFormat&)> frame_cb_;
137 }; 143 };
138 144
145 class MockImageCaptureClient : public base::RefCounted<MockImageCaptureClient> {
146 public:
147 // GMock doesn't support move-only arguments, so we use this forward method.
148 void DoOnPhotoTaken(mojo::String mime_type, mojo::Array<uint8_t> data) {
149 EXPECT_STREQ("image/jpeg", mime_type.storage().c_str());
150 ASSERT_GT(data.size(), 4u);
emircan 2016/07/11 21:23:08 Why is this checking for >=4?
mcasas 2016/07/11 23:29:59 Ooops, unfinished, done. (nit: it's _GT, not _GE)
151 OnCorrectPhotoTaken();
152 }
153 MOCK_METHOD0(OnCorrectPhotoTaken, void(void));
154 MOCK_METHOD1(
155 OnTakePhotoFailure,
156 void(const base::Callback<void(mojo::String, mojo::Array<uint8_t>)>&));
157
158 private:
159 friend class base::RefCounted<MockImageCaptureClient>;
160 virtual ~MockImageCaptureClient() {}
161 };
162
139 class DeviceEnumerationListener 163 class DeviceEnumerationListener
140 : public base::RefCounted<DeviceEnumerationListener> { 164 : public base::RefCounted<DeviceEnumerationListener> {
141 public: 165 public:
142 MOCK_METHOD1(OnEnumeratedDevicesCallbackPtr, 166 MOCK_METHOD1(OnEnumeratedDevicesCallbackPtr,
143 void(VideoCaptureDevice::Names* names)); 167 void(VideoCaptureDevice::Names* names));
144 // GMock doesn't support move-only arguments, so we use this forward method. 168 // GMock doesn't support move-only arguments, so we use this forward method.
145 void OnEnumeratedDevicesCallback( 169 void OnEnumeratedDevicesCallback(
146 std::unique_ptr<VideoCaptureDevice::Names> names) { 170 std::unique_ptr<VideoCaptureDevice::Names> names) {
147 OnEnumeratedDevicesCallbackPtr(names.release()); 171 OnEnumeratedDevicesCallbackPtr(names.release());
148 } 172 }
149 173
150 private: 174 private:
151 friend class base::RefCounted<DeviceEnumerationListener>; 175 friend class base::RefCounted<DeviceEnumerationListener>;
152 virtual ~DeviceEnumerationListener() {} 176 virtual ~DeviceEnumerationListener() {}
153 }; 177 };
154 178
155 } // namespace 179 } // namespace
156 180
157 class VideoCaptureDeviceTest : public testing::TestWithParam<gfx::Size> { 181 class VideoCaptureDeviceTest : public testing::TestWithParam<gfx::Size> {
158 protected: 182 protected:
159 typedef VideoCaptureDevice::Client Client; 183 typedef VideoCaptureDevice::Client Client;
160 184
161 VideoCaptureDeviceTest() 185 VideoCaptureDeviceTest()
162 : loop_(new base::MessageLoop()), 186 : loop_(new base::MessageLoop()),
163 video_capture_client_(new MockVideoCaptureClient( 187 video_capture_client_(new MockVideoCaptureClient(
164 base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured, 188 base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured,
165 base::Unretained(this)))), 189 base::Unretained(this)))),
190 device_enumeration_listener_(new DeviceEnumerationListener()),
191 image_capture_client_(new MockImageCaptureClient()),
166 video_capture_device_factory_(VideoCaptureDeviceFactory::CreateFactory( 192 video_capture_device_factory_(VideoCaptureDeviceFactory::CreateFactory(
167 base::ThreadTaskRunnerHandle::Get())) { 193 base::ThreadTaskRunnerHandle::Get())) {}
168 device_enumeration_listener_ = new DeviceEnumerationListener();
169 }
170 194
171 void SetUp() override { 195 void SetUp() override {
172 #if defined(OS_ANDROID) 196 #if defined(OS_ANDROID)
173 VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice( 197 VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice(
174 base::android::AttachCurrentThread()); 198 base::android::AttachCurrentThread());
175 #endif 199 #endif
176 #if defined(OS_MACOSX) 200 #if defined(OS_MACOSX)
177 AVFoundationGlue::InitializeAVFoundation(); 201 AVFoundationGlue::InitializeAVFoundation();
178 #endif 202 #endif
179 EXPECT_CALL(*video_capture_client_, DoReserveOutputBuffer()).Times(0); 203 EXPECT_CALL(*video_capture_client_, DoReserveOutputBuffer()).Times(0);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 DVLOG(1) << "Size " << size.ToString() << " is not supported."; 272 DVLOG(1) << "Size " << size.ToString() << " is not supported.";
249 return false; 273 return false;
250 } 274 }
251 return true; 275 return true;
252 } 276 }
253 277
254 #if defined(OS_WIN) 278 #if defined(OS_WIN)
255 base::win::ScopedCOMInitializer initialize_com_; 279 base::win::ScopedCOMInitializer initialize_com_;
256 #endif 280 #endif
257 std::unique_ptr<VideoCaptureDevice::Names> names_; 281 std::unique_ptr<VideoCaptureDevice::Names> names_;
258 std::unique_ptr<base::MessageLoop> loop_; 282 const std::unique_ptr<base::MessageLoop> loop_;
259 std::unique_ptr<base::RunLoop> run_loop_; 283 std::unique_ptr<base::RunLoop> run_loop_;
260 std::unique_ptr<MockVideoCaptureClient> video_capture_client_; 284 std::unique_ptr<MockVideoCaptureClient> video_capture_client_;
261 scoped_refptr<DeviceEnumerationListener> device_enumeration_listener_; 285 const scoped_refptr<DeviceEnumerationListener> device_enumeration_listener_;
286 const scoped_refptr<MockImageCaptureClient> image_capture_client_;
262 VideoCaptureFormat last_format_; 287 VideoCaptureFormat last_format_;
263 std::unique_ptr<VideoCaptureDeviceFactory> video_capture_device_factory_; 288 const std::unique_ptr<VideoCaptureDeviceFactory>
289 video_capture_device_factory_;
264 }; 290 };
265 291
266 // Cause hangs on Windows Debug. http://crbug.com/417824 292 // Cause hangs on Windows Debug. http://crbug.com/417824
267 #if defined(OS_WIN) && !defined(NDEBUG) 293 #if defined(OS_WIN) && !defined(NDEBUG)
268 #define MAYBE_OpenInvalidDevice DISABLED_OpenInvalidDevice 294 #define MAYBE_OpenInvalidDevice DISABLED_OpenInvalidDevice
269 #else 295 #else
270 #define MAYBE_OpenInvalidDevice OpenInvalidDevice 296 #define MAYBE_OpenInvalidDevice OpenInvalidDevice
271 #endif 297 #endif
272 298
273 TEST_F(VideoCaptureDeviceTest, MAYBE_OpenInvalidDevice) { 299 TEST_F(VideoCaptureDeviceTest, MAYBE_OpenInvalidDevice) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 std::unique_ptr<VideoCaptureDevice> device( 344 std::unique_ptr<VideoCaptureDevice> device(
319 video_capture_device_factory_->Create(names_->front())); 345 video_capture_device_factory_->Create(names_->front()));
320 ASSERT_TRUE(device); 346 ASSERT_TRUE(device);
321 DVLOG(1) << names_->front().id(); 347 DVLOG(1) << names_->front().id();
322 348
323 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); 349 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0);
324 350
325 VideoCaptureParams capture_params; 351 VideoCaptureParams capture_params;
326 capture_params.requested_format.frame_size.SetSize(width, height); 352 capture_params.requested_format.frame_size.SetSize(width, height);
327 capture_params.requested_format.frame_rate = 30.0f; 353 capture_params.requested_format.frame_rate = 30.0f;
328 capture_params.requested_format.pixel_format = 354 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
329 PIXEL_FORMAT_I420;
330 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); 355 device->AllocateAndStart(capture_params, std::move(video_capture_client_));
331 // Get captured video frames. 356 // Get captured video frames.
332 WaitForCapturedFrame(); 357 WaitForCapturedFrame();
333 EXPECT_EQ(last_format().frame_size.width(), width); 358 EXPECT_EQ(last_format().frame_size.width(), width);
334 EXPECT_EQ(last_format().frame_size.height(), height); 359 EXPECT_EQ(last_format().frame_size.height(), height);
335 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) 360 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG)
336 EXPECT_EQ(size.GetArea(), last_format().frame_size.GetArea()); 361 EXPECT_EQ(size.GetArea(), last_format().frame_size.GetArea());
337 device->StopAndDeAllocate(); 362 device->StopAndDeAllocate();
338 } 363 }
339 364
(...skipping 14 matching lines...) Expand all
354 std::unique_ptr<VideoCaptureDevice> device( 379 std::unique_ptr<VideoCaptureDevice> device(
355 video_capture_device_factory_->Create(names_->front())); 380 video_capture_device_factory_->Create(names_->front()));
356 ASSERT_TRUE(device); 381 ASSERT_TRUE(device);
357 382
358 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); 383 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0);
359 384
360 const gfx::Size input_size(640, 480); 385 const gfx::Size input_size(640, 480);
361 VideoCaptureParams capture_params; 386 VideoCaptureParams capture_params;
362 capture_params.requested_format.frame_size.SetSize(637, 472); 387 capture_params.requested_format.frame_size.SetSize(637, 472);
363 capture_params.requested_format.frame_rate = 35; 388 capture_params.requested_format.frame_rate = 35;
364 capture_params.requested_format.pixel_format = 389 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
365 PIXEL_FORMAT_I420;
366 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); 390 device->AllocateAndStart(capture_params, std::move(video_capture_client_));
367 WaitForCapturedFrame(); 391 WaitForCapturedFrame();
368 device->StopAndDeAllocate(); 392 device->StopAndDeAllocate();
369 EXPECT_EQ(last_format().frame_size.width(), input_size.width()); 393 EXPECT_EQ(last_format().frame_size.width(), input_size.width());
370 EXPECT_EQ(last_format().frame_size.height(), input_size.height()); 394 EXPECT_EQ(last_format().frame_size.height(), input_size.height());
371 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) 395 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG)
372 EXPECT_EQ(input_size.GetArea(), last_format().frame_size.GetArea()); 396 EXPECT_EQ(input_size.GetArea(), last_format().frame_size.GetArea());
373 } 397 }
374 398
375 // Cause hangs on Windows, Linux. Fails Android. http://crbug.com/417824 399 // Cause hangs on Windows, Linux. Fails Android. http://crbug.com/417824
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 EXPECT_GE(static_cast<size_t>(1280 * 720), 501 EXPECT_GE(static_cast<size_t>(1280 * 720),
478 last_format().ImageAllocationSize()); 502 last_format().ImageAllocationSize());
479 device->StopAndDeAllocate(); 503 device->StopAndDeAllocate();
480 } 504 }
481 505
482 TEST_F(VideoCaptureDeviceTest, GetDeviceSupportedFormats) { 506 TEST_F(VideoCaptureDeviceTest, GetDeviceSupportedFormats) {
483 // Use PIXEL_FORMAT_MAX to iterate all device names for testing 507 // Use PIXEL_FORMAT_MAX to iterate all device names for testing
484 // GetDeviceSupportedFormats(). 508 // GetDeviceSupportedFormats().
485 std::unique_ptr<VideoCaptureDevice::Name> name = 509 std::unique_ptr<VideoCaptureDevice::Name> name =
486 GetFirstDeviceNameSupportingPixelFormat(PIXEL_FORMAT_MAX); 510 GetFirstDeviceNameSupportingPixelFormat(PIXEL_FORMAT_MAX);
487 // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else 511 // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else to test here
488 // to test here
489 // since we cannot forecast the hardware capabilities. 512 // since we cannot forecast the hardware capabilities.
490 ASSERT_FALSE(name); 513 ASSERT_FALSE(name);
491 } 514 }
492 515
516 // Start the camera and take a photo.
517 TEST_F(VideoCaptureDeviceTest, MAYBE_TakePhoto) {
518 DVLOG(1) << __FUNCTION__;
Robert Sesek 2016/07/11 15:20:44 Remove.
mcasas 2016/07/11 23:30:00 Done.
519 names_ = EnumerateDevices();
520 if (names_->empty()) {
521 VLOG(1) << "No camera available. Exiting test.";
522 return;
523 }
524 std::unique_ptr<VideoCaptureDevice> device(
525 video_capture_device_factory_->Create(names_->front()));
526 ASSERT_TRUE(device);
527
528 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0);
529
530 VideoCaptureParams capture_params;
531 capture_params.requested_format.frame_size.SetSize(640, 480);
532 capture_params.requested_format.frame_rate = 30;
533 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
534 device->AllocateAndStart(capture_params, std::move(video_capture_client_));
535 WaitForCapturedFrame();
536
537 VideoCaptureDevice::TakePhotoCallback scoped_callback(
538 base::Bind(&MockImageCaptureClient::DoOnPhotoTaken,
539 image_capture_client_),
540 media::BindToCurrentLoop(base::Bind(
541 &MockImageCaptureClient::OnTakePhotoFailure, image_capture_client_)));
542
543 EXPECT_CALL(*image_capture_client_.get(), OnCorrectPhotoTaken()).Times(1);
544 device->TakePhoto(std::move(scoped_callback));
545 WaitForCapturedFrame();
546
547 device->StopAndDeAllocate();
548 }
549
493 }; // namespace media 550 }; // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698