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

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

Issue 2146973002: RELAND: ImageCapture: Implement takePhoto() for Mac AVFoundation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add a [captureSession_ canAddOutput:stillImageOutput_] guard 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
« no previous file with comments | « media/capture/video/mac/video_capture_device_mac.mm ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
151 // Check some bytes that univocally identify |data| as a JPEG File.
152 // https://en.wikipedia.org/wiki/JPEG_File_Interchange_Format#File_format_st ructure
153 EXPECT_EQ(0xFF, data[0]); // First SOI byte
154 EXPECT_EQ(0xD8, data[1]); // Second SOI byte
155 EXPECT_EQ(0xFF, data[2]); // First JFIF-APP0 byte
156 EXPECT_EQ(0xE0, data[3]); // Second JFIF-APP0 byte
157 OnCorrectPhotoTaken();
158 }
159 MOCK_METHOD0(OnCorrectPhotoTaken, void(void));
160 MOCK_METHOD1(
161 OnTakePhotoFailure,
162 void(const base::Callback<void(mojo::String, mojo::Array<uint8_t>)>&));
163
164 private:
165 friend class base::RefCounted<MockImageCaptureClient>;
166 virtual ~MockImageCaptureClient() {}
167 };
168
139 class DeviceEnumerationListener 169 class DeviceEnumerationListener
140 : public base::RefCounted<DeviceEnumerationListener> { 170 : public base::RefCounted<DeviceEnumerationListener> {
141 public: 171 public:
142 MOCK_METHOD1(OnEnumeratedDevicesCallbackPtr, 172 MOCK_METHOD1(OnEnumeratedDevicesCallbackPtr,
143 void(VideoCaptureDevice::Names* names)); 173 void(VideoCaptureDevice::Names* names));
144 // GMock doesn't support move-only arguments, so we use this forward method. 174 // GMock doesn't support move-only arguments, so we use this forward method.
145 void OnEnumeratedDevicesCallback( 175 void OnEnumeratedDevicesCallback(
146 std::unique_ptr<VideoCaptureDevice::Names> names) { 176 std::unique_ptr<VideoCaptureDevice::Names> names) {
147 OnEnumeratedDevicesCallbackPtr(names.release()); 177 OnEnumeratedDevicesCallbackPtr(names.release());
148 } 178 }
149 179
150 private: 180 private:
151 friend class base::RefCounted<DeviceEnumerationListener>; 181 friend class base::RefCounted<DeviceEnumerationListener>;
152 virtual ~DeviceEnumerationListener() {} 182 virtual ~DeviceEnumerationListener() {}
153 }; 183 };
154 184
155 } // namespace 185 } // namespace
156 186
157 class VideoCaptureDeviceTest : public testing::TestWithParam<gfx::Size> { 187 class VideoCaptureDeviceTest : public testing::TestWithParam<gfx::Size> {
158 protected: 188 protected:
159 typedef VideoCaptureDevice::Client Client; 189 typedef VideoCaptureDevice::Client Client;
160 190
161 VideoCaptureDeviceTest() 191 VideoCaptureDeviceTest()
162 : loop_(new base::MessageLoop()), 192 : loop_(new base::MessageLoop()),
163 video_capture_client_(new MockVideoCaptureClient( 193 video_capture_client_(new MockVideoCaptureClient(
164 base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured, 194 base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured,
165 base::Unretained(this)))), 195 base::Unretained(this)))),
196 device_enumeration_listener_(new DeviceEnumerationListener()),
197 image_capture_client_(new MockImageCaptureClient()),
166 video_capture_device_factory_(VideoCaptureDeviceFactory::CreateFactory( 198 video_capture_device_factory_(VideoCaptureDeviceFactory::CreateFactory(
167 base::ThreadTaskRunnerHandle::Get())) { 199 base::ThreadTaskRunnerHandle::Get())) {}
168 device_enumeration_listener_ = new DeviceEnumerationListener();
169 }
170 200
171 void SetUp() override { 201 void SetUp() override {
172 #if defined(OS_ANDROID) 202 #if defined(OS_ANDROID)
173 VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice( 203 VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice(
174 base::android::AttachCurrentThread()); 204 base::android::AttachCurrentThread());
175 #endif 205 #endif
176 #if defined(OS_MACOSX) 206 #if defined(OS_MACOSX)
177 AVFoundationGlue::InitializeAVFoundation(); 207 AVFoundationGlue::InitializeAVFoundation();
178 #endif 208 #endif
179 EXPECT_CALL(*video_capture_client_, DoReserveOutputBuffer()).Times(0); 209 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."; 278 DVLOG(1) << "Size " << size.ToString() << " is not supported.";
249 return false; 279 return false;
250 } 280 }
251 return true; 281 return true;
252 } 282 }
253 283
254 #if defined(OS_WIN) 284 #if defined(OS_WIN)
255 base::win::ScopedCOMInitializer initialize_com_; 285 base::win::ScopedCOMInitializer initialize_com_;
256 #endif 286 #endif
257 std::unique_ptr<VideoCaptureDevice::Names> names_; 287 std::unique_ptr<VideoCaptureDevice::Names> names_;
258 std::unique_ptr<base::MessageLoop> loop_; 288 const std::unique_ptr<base::MessageLoop> loop_;
259 std::unique_ptr<base::RunLoop> run_loop_; 289 std::unique_ptr<base::RunLoop> run_loop_;
260 std::unique_ptr<MockVideoCaptureClient> video_capture_client_; 290 std::unique_ptr<MockVideoCaptureClient> video_capture_client_;
261 scoped_refptr<DeviceEnumerationListener> device_enumeration_listener_; 291 const scoped_refptr<DeviceEnumerationListener> device_enumeration_listener_;
292 const scoped_refptr<MockImageCaptureClient> image_capture_client_;
262 VideoCaptureFormat last_format_; 293 VideoCaptureFormat last_format_;
263 std::unique_ptr<VideoCaptureDeviceFactory> video_capture_device_factory_; 294 const std::unique_ptr<VideoCaptureDeviceFactory>
295 video_capture_device_factory_;
264 }; 296 };
265 297
266 // Cause hangs on Windows Debug. http://crbug.com/417824 298 // Cause hangs on Windows Debug. http://crbug.com/417824
267 #if defined(OS_WIN) && !defined(NDEBUG) 299 #if defined(OS_WIN) && !defined(NDEBUG)
268 #define MAYBE_OpenInvalidDevice DISABLED_OpenInvalidDevice 300 #define MAYBE_OpenInvalidDevice DISABLED_OpenInvalidDevice
269 #else 301 #else
270 #define MAYBE_OpenInvalidDevice OpenInvalidDevice 302 #define MAYBE_OpenInvalidDevice OpenInvalidDevice
271 #endif 303 #endif
272 304
273 TEST_F(VideoCaptureDeviceTest, MAYBE_OpenInvalidDevice) { 305 TEST_F(VideoCaptureDeviceTest, MAYBE_OpenInvalidDevice) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 std::unique_ptr<VideoCaptureDevice> device( 350 std::unique_ptr<VideoCaptureDevice> device(
319 video_capture_device_factory_->Create(names_->front())); 351 video_capture_device_factory_->Create(names_->front()));
320 ASSERT_TRUE(device); 352 ASSERT_TRUE(device);
321 DVLOG(1) << names_->front().id(); 353 DVLOG(1) << names_->front().id();
322 354
323 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); 355 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0);
324 356
325 VideoCaptureParams capture_params; 357 VideoCaptureParams capture_params;
326 capture_params.requested_format.frame_size.SetSize(width, height); 358 capture_params.requested_format.frame_size.SetSize(width, height);
327 capture_params.requested_format.frame_rate = 30.0f; 359 capture_params.requested_format.frame_rate = 30.0f;
328 capture_params.requested_format.pixel_format = 360 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
329 PIXEL_FORMAT_I420;
330 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); 361 device->AllocateAndStart(capture_params, std::move(video_capture_client_));
331 // Get captured video frames. 362 // Get captured video frames.
332 WaitForCapturedFrame(); 363 WaitForCapturedFrame();
333 EXPECT_EQ(last_format().frame_size.width(), width); 364 EXPECT_EQ(last_format().frame_size.width(), width);
334 EXPECT_EQ(last_format().frame_size.height(), height); 365 EXPECT_EQ(last_format().frame_size.height(), height);
335 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) 366 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG)
336 EXPECT_EQ(size.GetArea(), last_format().frame_size.GetArea()); 367 EXPECT_EQ(size.GetArea(), last_format().frame_size.GetArea());
337 device->StopAndDeAllocate(); 368 device->StopAndDeAllocate();
338 } 369 }
339 370
(...skipping 14 matching lines...) Expand all
354 std::unique_ptr<VideoCaptureDevice> device( 385 std::unique_ptr<VideoCaptureDevice> device(
355 video_capture_device_factory_->Create(names_->front())); 386 video_capture_device_factory_->Create(names_->front()));
356 ASSERT_TRUE(device); 387 ASSERT_TRUE(device);
357 388
358 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); 389 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0);
359 390
360 const gfx::Size input_size(640, 480); 391 const gfx::Size input_size(640, 480);
361 VideoCaptureParams capture_params; 392 VideoCaptureParams capture_params;
362 capture_params.requested_format.frame_size.SetSize(637, 472); 393 capture_params.requested_format.frame_size.SetSize(637, 472);
363 capture_params.requested_format.frame_rate = 35; 394 capture_params.requested_format.frame_rate = 35;
364 capture_params.requested_format.pixel_format = 395 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
365 PIXEL_FORMAT_I420;
366 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); 396 device->AllocateAndStart(capture_params, std::move(video_capture_client_));
367 WaitForCapturedFrame(); 397 WaitForCapturedFrame();
368 device->StopAndDeAllocate(); 398 device->StopAndDeAllocate();
369 EXPECT_EQ(last_format().frame_size.width(), input_size.width()); 399 EXPECT_EQ(last_format().frame_size.width(), input_size.width());
370 EXPECT_EQ(last_format().frame_size.height(), input_size.height()); 400 EXPECT_EQ(last_format().frame_size.height(), input_size.height());
371 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) 401 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG)
372 EXPECT_EQ(input_size.GetArea(), last_format().frame_size.GetArea()); 402 EXPECT_EQ(input_size.GetArea(), last_format().frame_size.GetArea());
373 } 403 }
374 404
375 // Cause hangs on Windows, Linux. Fails Android. http://crbug.com/417824 405 // 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), 507 EXPECT_GE(static_cast<size_t>(1280 * 720),
478 last_format().ImageAllocationSize()); 508 last_format().ImageAllocationSize());
479 device->StopAndDeAllocate(); 509 device->StopAndDeAllocate();
480 } 510 }
481 511
482 TEST_F(VideoCaptureDeviceTest, GetDeviceSupportedFormats) { 512 TEST_F(VideoCaptureDeviceTest, GetDeviceSupportedFormats) {
483 // Use PIXEL_FORMAT_MAX to iterate all device names for testing 513 // Use PIXEL_FORMAT_MAX to iterate all device names for testing
484 // GetDeviceSupportedFormats(). 514 // GetDeviceSupportedFormats().
485 std::unique_ptr<VideoCaptureDevice::Name> name = 515 std::unique_ptr<VideoCaptureDevice::Name> name =
486 GetFirstDeviceNameSupportingPixelFormat(PIXEL_FORMAT_MAX); 516 GetFirstDeviceNameSupportingPixelFormat(PIXEL_FORMAT_MAX);
487 // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else 517 // 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. 518 // since we cannot forecast the hardware capabilities.
490 ASSERT_FALSE(name); 519 ASSERT_FALSE(name);
491 } 520 }
492 521
522 // Start the camera and take a photo.
523 TEST_F(VideoCaptureDeviceTest, MAYBE_TakePhoto) {
524 names_ = EnumerateDevices();
525 if (names_->empty()) {
526 VLOG(1) << "No camera available. Exiting test.";
527 return;
528 }
529 std::unique_ptr<VideoCaptureDevice> device(
530 video_capture_device_factory_->Create(names_->front()));
531 ASSERT_TRUE(device);
532
533 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0);
534
535 VideoCaptureParams capture_params;
536 capture_params.requested_format.frame_size.SetSize(640, 480);
537 capture_params.requested_format.frame_rate = 30;
538 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
539 device->AllocateAndStart(capture_params, std::move(video_capture_client_));
540 WaitForCapturedFrame();
541
542 VideoCaptureDevice::TakePhotoCallback scoped_callback(
543 base::Bind(&MockImageCaptureClient::DoOnPhotoTaken,
544 image_capture_client_),
545 media::BindToCurrentLoop(base::Bind(
546 &MockImageCaptureClient::OnTakePhotoFailure, image_capture_client_)));
547
548 EXPECT_CALL(*image_capture_client_.get(), OnCorrectPhotoTaken()).Times(1);
549 device->TakePhoto(std::move(scoped_callback));
550 WaitForCapturedFrame();
551
552 device->StopAndDeAllocate();
553 }
554
493 }; // namespace media 555 }; // namespace media
OLDNEW
« no previous file with comments | « media/capture/video/mac/video_capture_device_mac.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698