| 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 21 matching lines...) Expand all Loading... |
| 32 #endif | 32 #endif |
| 33 | 33 |
| 34 #if defined(OS_MACOSX) | 34 #if defined(OS_MACOSX) |
| 35 #include "media/base/mac/avfoundation_glue.h" | 35 #include "media/base/mac/avfoundation_glue.h" |
| 36 #include "media/capture/video/mac/video_capture_device_factory_mac.h" | 36 #include "media/capture/video/mac/video_capture_device_factory_mac.h" |
| 37 #endif | 37 #endif |
| 38 | 38 |
| 39 #if defined(OS_ANDROID) | 39 #if defined(OS_ANDROID) |
| 40 #include "base/android/jni_android.h" | 40 #include "base/android/jni_android.h" |
| 41 #include "media/capture/video/android/video_capture_device_android.h" | 41 #include "media/capture/video/android/video_capture_device_android.h" |
| 42 #include "media/capture/video/android/video_capture_device_factory_android.h" |
| 42 #endif | 43 #endif |
| 43 | 44 |
| 44 #if defined(OS_MACOSX) | 45 #if defined(OS_MACOSX) |
| 45 // Mac will always give you the size you ask for and this case will fail. | 46 // Mac will always give you the size you ask for and this case will fail. |
| 46 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize | 47 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize |
| 47 // We will always get YUYV from the Mac AVFoundation implementations. | 48 // We will always get YUYV from the Mac AVFoundation implementations. |
| 48 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg | 49 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg |
| 49 #define MAYBE_TakePhoto TakePhoto | 50 #define MAYBE_TakePhoto TakePhoto |
| 50 #elif defined(OS_WIN) | 51 #elif defined(OS_WIN) |
| 51 #define MAYBE_AllocateBadSize AllocateBadSize | 52 #define MAYBE_AllocateBadSize AllocateBadSize |
| 52 #define MAYBE_CaptureMjpeg CaptureMjpeg | 53 #define MAYBE_CaptureMjpeg CaptureMjpeg |
| 53 #define MAYBE_TakePhoto DISABLED_TakePhoto | 54 #define MAYBE_TakePhoto DISABLED_TakePhoto |
| 54 #elif defined(OS_ANDROID) | 55 #elif defined(OS_ANDROID) |
| 55 // TODO(wjia): enable those tests on Android. | 56 #define MAYBE_AllocateBadSize AllocateBadSize |
| 56 // On Android, native camera (JAVA) delivers frames on UI thread which is the | 57 #define MAYBE_CaptureMjpeg CaptureMjpeg |
| 57 // main thread for tests. This results in no frame received by | |
| 58 // VideoCaptureAndroid. | |
| 59 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize | |
| 60 #define DeAllocateCameraWhileRunning DISABLED_DeAllocateCameraWhileRunning | |
| 61 #define DeAllocateCameraWhileRunning DISABLED_DeAllocateCameraWhileRunning | |
| 62 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg | |
| 63 #define MAYBE_TakePhoto DISABLED_TakePhoto | 58 #define MAYBE_TakePhoto DISABLED_TakePhoto |
| 64 #elif defined(OS_LINUX) | 59 #elif defined(OS_LINUX) |
| 65 // AllocateBadSize will hang when a real camera is attached and if more than one | 60 // AllocateBadSize will hang when a real camera is attached and if more than one |
| 66 // test is trying to use the camera (even across processes). Do NOT renable | 61 // test is trying to use the camera (even across processes). Do NOT renable |
| 67 // this test without fixing the many bugs associated with it: | 62 // this test without fixing the many bugs associated with it: |
| 68 // http://crbug.com/94134 http://crbug.com/137260 http://crbug.com/417824 | 63 // http://crbug.com/94134 http://crbug.com/137260 http://crbug.com/417824 |
| 69 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize | 64 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize |
| 70 #define MAYBE_CaptureMjpeg CaptureMjpeg | 65 #define MAYBE_CaptureMjpeg CaptureMjpeg |
| 71 #define MAYBE_TakePhoto DISABLED_TakePhoto | 66 #define MAYBE_TakePhoto DISABLED_TakePhoto |
| 72 #else | 67 #else |
| (...skipping 24 matching lines...) Expand all Loading... |
| 97 : main_thread_(base::ThreadTaskRunnerHandle::Get()), | 92 : main_thread_(base::ThreadTaskRunnerHandle::Get()), |
| 98 frame_cb_(frame_cb) {} | 93 frame_cb_(frame_cb) {} |
| 99 | 94 |
| 100 void OnIncomingCapturedData(const uint8_t* data, | 95 void OnIncomingCapturedData(const uint8_t* data, |
| 101 int length, | 96 int length, |
| 102 const VideoCaptureFormat& format, | 97 const VideoCaptureFormat& format, |
| 103 int rotation, | 98 int rotation, |
| 104 base::TimeTicks reference_time, | 99 base::TimeTicks reference_time, |
| 105 base::TimeDelta timestamp) override { | 100 base::TimeDelta timestamp) override { |
| 106 ASSERT_GT(length, 0); | 101 ASSERT_GT(length, 0); |
| 107 ASSERT_TRUE(data != NULL); | 102 ASSERT_TRUE(data); |
| 108 main_thread_->PostTask(FROM_HERE, base::Bind(frame_cb_, format)); | 103 main_thread_->PostTask(FROM_HERE, base::Bind(frame_cb_, format)); |
| 109 } | 104 } |
| 110 | 105 |
| 111 // Trampoline methods to workaround GMOCK problems with std::unique_ptr<>. | 106 // Trampoline methods to workaround GMOCK problems with std::unique_ptr<>. |
| 112 std::unique_ptr<Buffer> ReserveOutputBuffer( | 107 std::unique_ptr<Buffer> ReserveOutputBuffer( |
| 113 const gfx::Size& dimensions, | 108 const gfx::Size& dimensions, |
| 114 media::VideoPixelFormat format, | 109 media::VideoPixelFormat format, |
| 115 media::VideoPixelStorage storage) override { | 110 media::VideoPixelStorage storage) override { |
| 116 DoReserveOutputBuffer(); | 111 DoReserveOutputBuffer(); |
| 117 NOTREACHED() << "This should never be called"; | 112 NOTREACHED() << "This should never be called"; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 void(const base::Callback<void(mojom::BlobPtr)>&)); | 156 void(const base::Callback<void(mojom::BlobPtr)>&)); |
| 162 | 157 |
| 163 private: | 158 private: |
| 164 friend class base::RefCounted<MockImageCaptureClient>; | 159 friend class base::RefCounted<MockImageCaptureClient>; |
| 165 virtual ~MockImageCaptureClient() {} | 160 virtual ~MockImageCaptureClient() {} |
| 166 }; | 161 }; |
| 167 | 162 |
| 168 class DeviceEnumerationListener | 163 class DeviceEnumerationListener |
| 169 : public base::RefCounted<DeviceEnumerationListener> { | 164 : public base::RefCounted<DeviceEnumerationListener> { |
| 170 public: | 165 public: |
| 171 MOCK_METHOD1(OnEnumerateDeviceDescriptorsCallbackPtr, | 166 MOCK_METHOD1(DoOnEnumerateDeviceDescriptors, |
| 172 void(VideoCaptureDeviceDescriptors* device_descriptors)); | 167 void(VideoCaptureDeviceDescriptors* device_descriptors)); |
| 173 // 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. |
| 174 void OnEnumerateDeviceDescriptorsCallback( | 169 void OnEnumerateDeviceDescriptors( |
| 175 std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors) { | 170 std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors) { |
| 176 OnEnumerateDeviceDescriptorsCallbackPtr(device_descriptors.release()); | 171 DoOnEnumerateDeviceDescriptors(device_descriptors.release()); |
| 177 } | 172 } |
| 178 | 173 |
| 179 private: | 174 private: |
| 180 friend class base::RefCounted<DeviceEnumerationListener>; | 175 friend class base::RefCounted<DeviceEnumerationListener>; |
| 181 virtual ~DeviceEnumerationListener() {} | 176 virtual ~DeviceEnumerationListener() {} |
| 182 }; | 177 }; |
| 183 | 178 |
| 184 } // namespace | 179 } // namespace |
| 185 | 180 |
| 186 class VideoCaptureDeviceTest : public testing::TestWithParam<gfx::Size> { | 181 class VideoCaptureDeviceTest : public testing::TestWithParam<gfx::Size> { |
| 187 protected: | 182 protected: |
| 188 typedef VideoCaptureDevice::Client Client; | 183 typedef VideoCaptureDevice::Client Client; |
| 189 | 184 |
| 190 VideoCaptureDeviceTest() | 185 VideoCaptureDeviceTest() |
| 191 : loop_(new base::MessageLoop()), | 186 : loop_(new base::MessageLoop()), |
| 192 video_capture_client_(new MockVideoCaptureClient( | 187 video_capture_client_(new MockVideoCaptureClient( |
| 193 base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured, | 188 base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured, |
| 194 base::Unretained(this)))), | 189 base::Unretained(this)))), |
| 195 device_enumeration_listener_(new DeviceEnumerationListener()), | 190 device_enumeration_listener_(new DeviceEnumerationListener()), |
| 196 image_capture_client_(new MockImageCaptureClient()), | 191 image_capture_client_(new MockImageCaptureClient()), |
| 197 video_capture_device_factory_(VideoCaptureDeviceFactory::CreateFactory( | 192 video_capture_device_factory_(VideoCaptureDeviceFactory::CreateFactory( |
| 198 base::ThreadTaskRunnerHandle::Get())) {} | 193 base::ThreadTaskRunnerHandle::Get())) {} |
| 199 | 194 |
| 200 void SetUp() override { | 195 void SetUp() override { |
| 201 #if defined(OS_ANDROID) | 196 #if defined(OS_ANDROID) |
| 202 VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice( | 197 VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice( |
| 203 base::android::AttachCurrentThread()); | 198 base::android::AttachCurrentThread()); |
| 199 |
| 200 static_cast<VideoCaptureDeviceFactoryAndroid*>( |
| 201 video_capture_device_factory_.get()) |
| 202 ->ConfigureForTesting(); |
| 204 #endif | 203 #endif |
| 205 #if defined(OS_MACOSX) | 204 #if defined(OS_MACOSX) |
| 206 AVFoundationGlue::InitializeAVFoundation(); | 205 AVFoundationGlue::InitializeAVFoundation(); |
| 207 #endif | 206 #endif |
| 208 EXPECT_CALL(*video_capture_client_, DoReserveOutputBuffer()).Times(0); | 207 EXPECT_CALL(*video_capture_client_, DoReserveOutputBuffer()).Times(0); |
| 209 EXPECT_CALL(*video_capture_client_, DoOnIncomingCapturedBuffer()).Times(0); | 208 EXPECT_CALL(*video_capture_client_, DoOnIncomingCapturedBuffer()).Times(0); |
| 210 EXPECT_CALL(*video_capture_client_, DoOnIncomingCapturedVideoFrame()) | 209 EXPECT_CALL(*video_capture_client_, DoOnIncomingCapturedVideoFrame()) |
| 211 .Times(0); | 210 .Times(0); |
| 212 } | 211 } |
| 213 | 212 |
| 214 void ResetWithNewClient() { | 213 void ResetWithNewClient() { |
| 215 video_capture_client_.reset(new MockVideoCaptureClient(base::Bind( | 214 video_capture_client_.reset(new MockVideoCaptureClient(base::Bind( |
| 216 &VideoCaptureDeviceTest::OnFrameCaptured, base::Unretained(this)))); | 215 &VideoCaptureDeviceTest::OnFrameCaptured, base::Unretained(this)))); |
| 217 } | 216 } |
| 218 | 217 |
| 219 void OnFrameCaptured(const VideoCaptureFormat& format) { | 218 void OnFrameCaptured(const VideoCaptureFormat& format) { |
| 220 last_format_ = format; | 219 last_format_ = format; |
| 221 run_loop_->QuitClosure().Run(); | 220 run_loop_->QuitClosure().Run(); |
| 222 } | 221 } |
| 223 | 222 |
| 224 void WaitForCapturedFrame() { | 223 void WaitForCapturedFrame() { |
| 225 run_loop_.reset(new base::RunLoop()); | 224 run_loop_.reset(new base::RunLoop()); |
| 226 run_loop_->Run(); | 225 run_loop_->Run(); |
| 227 } | 226 } |
| 228 | 227 |
| 229 std::unique_ptr<VideoCaptureDeviceDescriptors> EnumerateDeviceDescriptors() { | 228 bool EnumerateAndFindUsableDevices() { |
| 230 VideoCaptureDeviceDescriptors* device_descriptors; | 229 VideoCaptureDeviceDescriptors* descriptors = nullptr; |
| 231 EXPECT_CALL(*device_enumeration_listener_.get(), | 230 EXPECT_CALL(*device_enumeration_listener_.get(), |
| 232 OnEnumerateDeviceDescriptorsCallbackPtr(_)) | 231 DoOnEnumerateDeviceDescriptors(_)) |
| 233 .WillOnce(SaveArg<0>(&device_descriptors)); | 232 .WillOnce(SaveArg<0>(&descriptors)); |
| 234 | 233 |
| 235 video_capture_device_factory_->EnumerateDeviceDescriptors(base::Bind( | 234 video_capture_device_factory_->EnumerateDeviceDescriptors( |
| 236 &DeviceEnumerationListener::OnEnumerateDeviceDescriptorsCallback, | 235 base::Bind(&DeviceEnumerationListener::OnEnumerateDeviceDescriptors, |
| 237 device_enumeration_listener_)); | 236 device_enumeration_listener_)); |
| 238 base::RunLoop().RunUntilIdle(); | 237 base::RunLoop().RunUntilIdle(); |
| 239 return std::unique_ptr<VideoCaptureDeviceDescriptors>(device_descriptors); | 238 |
| 239 device_descriptors_.reset(descriptors); |
| 240 if (!device_descriptors_) |
| 241 return false; |
| 242 |
| 243 #if defined(OS_ANDROID) |
| 244 // Android deprecated/legacy devices capture on a single thread, which is |
| 245 // occupied by the tests, so nothing gets actually delivered. |
| 246 // TODO(mcasas): use those devices' test mode to deliver frames in a |
| 247 // background thread, https://crbug.com/626857 |
| 248 for (const auto& descriptor : *descriptors) { |
| 249 if (VideoCaptureDeviceFactoryAndroid::IsLegacyOrDeprecatedDevice( |
| 250 descriptor.device_id)) { |
| 251 return false; |
| 252 } |
| 253 } |
| 254 #endif |
| 255 |
| 256 return !device_descriptors_->empty(); |
| 240 } | 257 } |
| 241 | 258 |
| 242 const VideoCaptureFormat& last_format() const { return last_format_; } | 259 const VideoCaptureFormat& last_format() const { return last_format_; } |
| 243 | 260 |
| 244 std::unique_ptr<VideoCaptureDeviceDescriptor> | 261 std::unique_ptr<VideoCaptureDeviceDescriptor> |
| 245 GetFirstDeviceDescriptorSupportingPixelFormat( | 262 GetFirstDeviceDescriptorSupportingPixelFormat( |
| 246 const VideoPixelFormat& pixel_format) { | 263 const VideoPixelFormat& pixel_format) { |
| 247 device_descriptors_ = EnumerateDeviceDescriptors(); | 264 if (!EnumerateAndFindUsableDevices()) |
| 248 if (device_descriptors_->empty()) { | 265 return nullptr; |
| 249 DVLOG(1) << "No camera available."; | 266 |
| 250 return std::unique_ptr<VideoCaptureDeviceDescriptor>(); | 267 for (const auto& descriptor : *device_descriptors_) { |
| 251 } | |
| 252 for (const auto& descriptors_iterator : *device_descriptors_) { | |
| 253 VideoCaptureFormats supported_formats; | 268 VideoCaptureFormats supported_formats; |
| 254 video_capture_device_factory_->GetSupportedFormats(descriptors_iterator, | 269 video_capture_device_factory_->GetSupportedFormats(descriptor, |
| 255 &supported_formats); | 270 &supported_formats); |
| 256 for (const auto& formats_iterator : supported_formats) { | 271 for (const auto& formats_iterator : supported_formats) { |
| 257 if (formats_iterator.pixel_format == pixel_format) { | 272 if (formats_iterator.pixel_format == pixel_format) { |
| 258 return std::unique_ptr<VideoCaptureDeviceDescriptor>( | 273 return std::unique_ptr<VideoCaptureDeviceDescriptor>( |
| 259 new VideoCaptureDeviceDescriptor(descriptors_iterator)); | 274 new VideoCaptureDeviceDescriptor(descriptor)); |
| 260 } | 275 } |
| 261 } | 276 } |
| 262 } | 277 } |
| 263 DVLOG_IF(1, pixel_format != PIXEL_FORMAT_MAX) | 278 DVLOG_IF(1, pixel_format != PIXEL_FORMAT_MAX) |
| 264 << "No camera can capture the" | 279 << VideoPixelFormatToString(pixel_format); |
| 265 << " format: " << VideoPixelFormatToString(pixel_format); | |
| 266 return std::unique_ptr<VideoCaptureDeviceDescriptor>(); | 280 return std::unique_ptr<VideoCaptureDeviceDescriptor>(); |
| 267 } | 281 } |
| 268 | 282 |
| 269 bool IsCaptureSizeSupported(const VideoCaptureDeviceDescriptor& device, | 283 bool IsCaptureSizeSupported(const VideoCaptureDeviceDescriptor& device, |
| 270 const gfx::Size& size) { | 284 const gfx::Size& size) { |
| 271 VideoCaptureFormats supported_formats; | 285 VideoCaptureFormats supported_formats; |
| 272 video_capture_device_factory_->GetSupportedFormats(device, | 286 video_capture_device_factory_->GetSupportedFormats(device, |
| 273 &supported_formats); | 287 &supported_formats); |
| 274 const auto it = std::find_if( | 288 const auto it = std::find_if( |
| 275 supported_formats.begin(), supported_formats.end(), | 289 supported_formats.begin(), supported_formats.end(), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 294 const std::unique_ptr<VideoCaptureDeviceFactory> | 308 const std::unique_ptr<VideoCaptureDeviceFactory> |
| 295 video_capture_device_factory_; | 309 video_capture_device_factory_; |
| 296 }; | 310 }; |
| 297 | 311 |
| 298 // Cause hangs on Windows Debug. http://crbug.com/417824 | 312 // Cause hangs on Windows Debug. http://crbug.com/417824 |
| 299 #if defined(OS_WIN) && !defined(NDEBUG) | 313 #if defined(OS_WIN) && !defined(NDEBUG) |
| 300 #define MAYBE_OpenInvalidDevice DISABLED_OpenInvalidDevice | 314 #define MAYBE_OpenInvalidDevice DISABLED_OpenInvalidDevice |
| 301 #else | 315 #else |
| 302 #define MAYBE_OpenInvalidDevice OpenInvalidDevice | 316 #define MAYBE_OpenInvalidDevice OpenInvalidDevice |
| 303 #endif | 317 #endif |
| 304 | 318 // Tries to allocate an invalid device and verifies it doesn't work. |
| 305 TEST_F(VideoCaptureDeviceTest, MAYBE_OpenInvalidDevice) { | 319 TEST_F(VideoCaptureDeviceTest, MAYBE_OpenInvalidDevice) { |
| 306 VideoCaptureDeviceDescriptor invalid_descriptor; | 320 VideoCaptureDeviceDescriptor invalid_descriptor; |
| 307 invalid_descriptor.device_id = "jibberish"; | 321 invalid_descriptor.device_id = "jibberish"; |
| 308 invalid_descriptor.display_name = "jibberish"; | 322 invalid_descriptor.display_name = "jibberish"; |
| 309 #if defined(OS_WIN) | 323 #if defined(OS_WIN) |
| 310 invalid_descriptor.capture_api = | 324 invalid_descriptor.capture_api = |
| 311 VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation() | 325 VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation() |
| 312 ? VideoCaptureApi::WIN_MEDIA_FOUNDATION | 326 ? VideoCaptureApi::WIN_MEDIA_FOUNDATION |
| 313 : VideoCaptureApi::WIN_DIRECT_SHOW; | 327 : VideoCaptureApi::WIN_DIRECT_SHOW; |
| 314 #elif defined(OS_MACOSX) | 328 #elif defined(OS_MACOSX) |
| 315 invalid_descriptor.capture_api = VideoCaptureApi::MACOSX_AVFOUNDATION; | 329 invalid_descriptor.capture_api = VideoCaptureApi::MACOSX_AVFOUNDATION; |
| 316 #endif | 330 #endif |
| 317 std::unique_ptr<VideoCaptureDevice> device = | 331 std::unique_ptr<VideoCaptureDevice> device = |
| 318 video_capture_device_factory_->CreateDevice(invalid_descriptor); | 332 video_capture_device_factory_->CreateDevice(invalid_descriptor); |
| 319 | 333 |
| 320 #if !defined(OS_MACOSX) | 334 #if !defined(OS_MACOSX) |
| 321 EXPECT_TRUE(device == NULL); | 335 EXPECT_FALSE(device); |
| 322 #else | 336 #else |
| 323 // The presence of the actual device is only checked on AllocateAndStart() | 337 // The presence of the actual device is only checked on AllocateAndStart() |
| 324 // and not on creation. | 338 // and not on creation. |
| 325 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(1); | 339 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(1); |
| 326 | 340 |
| 327 VideoCaptureParams capture_params; | 341 VideoCaptureParams capture_params; |
| 328 capture_params.requested_format.frame_size.SetSize(640, 480); | 342 capture_params.requested_format.frame_size.SetSize(640, 480); |
| 329 capture_params.requested_format.frame_rate = 30; | 343 capture_params.requested_format.frame_rate = 30; |
| 330 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 344 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
| 331 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 345 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
| 332 device->StopAndDeAllocate(); | 346 device->StopAndDeAllocate(); |
| 333 #endif | 347 #endif |
| 334 } | 348 } |
| 335 | 349 |
| 350 // Allocates the first enumerated device, and expects a frame. |
| 336 TEST_P(VideoCaptureDeviceTest, CaptureWithSize) { | 351 TEST_P(VideoCaptureDeviceTest, CaptureWithSize) { |
| 337 device_descriptors_ = EnumerateDeviceDescriptors(); | 352 if (!EnumerateAndFindUsableDevices()) |
| 338 if (device_descriptors_->empty()) { | |
| 339 VLOG(1) << "No camera available. Exiting test."; | |
| 340 return; | 353 return; |
| 341 } | |
| 342 | 354 |
| 343 const gfx::Size& size = GetParam(); | 355 const gfx::Size& size = GetParam(); |
| 344 if (!IsCaptureSizeSupported(device_descriptors_->front(), size)) | 356 if (!IsCaptureSizeSupported(device_descriptors_->front(), size)) |
| 345 return; | 357 return; |
| 346 const int width = size.width(); | 358 const int width = size.width(); |
| 347 const int height = size.height(); | 359 const int height = size.height(); |
| 348 | 360 |
| 349 std::unique_ptr<VideoCaptureDevice> device( | 361 std::unique_ptr<VideoCaptureDevice> device( |
| 350 video_capture_device_factory_->CreateDevice( | 362 video_capture_device_factory_->CreateDevice( |
| 351 device_descriptors_->front())); | 363 device_descriptors_->front())); |
| 352 ASSERT_TRUE(device); | 364 ASSERT_TRUE(device); |
| 353 DVLOG(1) << device_descriptors_->front().device_id; | |
| 354 | 365 |
| 355 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); | 366 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); |
| 356 | 367 |
| 357 VideoCaptureParams capture_params; | 368 VideoCaptureParams capture_params; |
| 358 capture_params.requested_format.frame_size.SetSize(width, height); | 369 capture_params.requested_format.frame_size.SetSize(width, height); |
| 359 capture_params.requested_format.frame_rate = 30.0f; | 370 capture_params.requested_format.frame_rate = 30.0f; |
| 360 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 371 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
| 361 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 372 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
| 362 // Get captured video frames. | 373 |
| 363 WaitForCapturedFrame(); | 374 WaitForCapturedFrame(); |
| 364 EXPECT_EQ(last_format().frame_size.width(), width); | 375 EXPECT_EQ(last_format().frame_size.width(), width); |
| 365 EXPECT_EQ(last_format().frame_size.height(), height); | 376 EXPECT_EQ(last_format().frame_size.height(), height); |
| 366 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) | 377 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) |
| 367 EXPECT_EQ(size.GetArea(), last_format().frame_size.GetArea()); | 378 EXPECT_EQ(size.GetArea(), last_format().frame_size.GetArea()); |
| 379 EXPECT_EQ(last_format().frame_rate, 30); |
| 368 device->StopAndDeAllocate(); | 380 device->StopAndDeAllocate(); |
| 369 } | 381 } |
| 370 | 382 |
| 371 #if !defined(OS_ANDROID) | |
| 372 const gfx::Size kCaptureSizes[] = {gfx::Size(640, 480), gfx::Size(1280, 720)}; | 383 const gfx::Size kCaptureSizes[] = {gfx::Size(640, 480), gfx::Size(1280, 720)}; |
| 373 | 384 |
| 374 INSTANTIATE_TEST_CASE_P(VideoCaptureDeviceTests, | 385 INSTANTIATE_TEST_CASE_P(VideoCaptureDeviceTests, |
| 375 VideoCaptureDeviceTest, | 386 VideoCaptureDeviceTest, |
| 376 testing::ValuesIn(kCaptureSizes)); | 387 testing::ValuesIn(kCaptureSizes)); |
| 377 #endif | |
| 378 | 388 |
| 389 // Allocates a device with an uncommon resolution and verifies frames are |
| 390 // captured in a close, much more typical one. |
| 379 TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) { | 391 TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) { |
| 380 device_descriptors_ = EnumerateDeviceDescriptors(); | 392 if (!EnumerateAndFindUsableDevices()) |
| 381 if (device_descriptors_->empty()) { | |
| 382 VLOG(1) << "No camera available. Exiting test."; | |
| 383 return; | 393 return; |
| 384 } | 394 |
| 385 std::unique_ptr<VideoCaptureDevice> device( | 395 std::unique_ptr<VideoCaptureDevice> device( |
| 386 video_capture_device_factory_->CreateDevice( | 396 video_capture_device_factory_->CreateDevice( |
| 387 device_descriptors_->front())); | 397 device_descriptors_->front())); |
| 388 ASSERT_TRUE(device); | 398 ASSERT_TRUE(device); |
| 389 | 399 |
| 390 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); | 400 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); |
| 391 | 401 |
| 392 const gfx::Size input_size(640, 480); | 402 const gfx::Size input_size(640, 480); |
| 393 VideoCaptureParams capture_params; | 403 VideoCaptureParams capture_params; |
| 394 capture_params.requested_format.frame_size.SetSize(637, 472); | 404 capture_params.requested_format.frame_size.SetSize(637, 472); |
| 395 capture_params.requested_format.frame_rate = 35; | 405 capture_params.requested_format.frame_rate = 35; |
| 396 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 406 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
| 397 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 407 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
| 398 WaitForCapturedFrame(); | 408 WaitForCapturedFrame(); |
| 399 device->StopAndDeAllocate(); | 409 device->StopAndDeAllocate(); |
| 400 EXPECT_EQ(last_format().frame_size.width(), input_size.width()); | 410 EXPECT_EQ(last_format().frame_size.width(), input_size.width()); |
| 401 EXPECT_EQ(last_format().frame_size.height(), input_size.height()); | 411 EXPECT_EQ(last_format().frame_size.height(), input_size.height()); |
| 402 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) | 412 if (last_format().pixel_format != PIXEL_FORMAT_MJPEG) |
| 403 EXPECT_EQ(input_size.GetArea(), last_format().frame_size.GetArea()); | 413 EXPECT_EQ(input_size.GetArea(), last_format().frame_size.GetArea()); |
| 404 } | 414 } |
| 405 | 415 |
| 406 // Cause hangs on Windows, Linux. Fails Android. http://crbug.com/417824 | 416 // Cause hangs on Windows, Linux. Fails Android. https://crbug.com/417824 |
| 407 TEST_F(VideoCaptureDeviceTest, DISABLED_ReAllocateCamera) { | 417 TEST_F(VideoCaptureDeviceTest, DISABLED_ReAllocateCamera) { |
| 408 device_descriptors_ = EnumerateDeviceDescriptors(); | 418 if (!EnumerateAndFindUsableDevices()) |
| 409 if (device_descriptors_->empty()) { | |
| 410 VLOG(1) << "No camera available. Exiting test."; | |
| 411 return; | 419 return; |
| 412 } | |
| 413 | 420 |
| 414 // First, do a number of very fast device start/stops. | 421 // First, do a number of very fast device start/stops. |
| 415 for (int i = 0; i <= 5; i++) { | 422 for (int i = 0; i <= 5; i++) { |
| 416 ResetWithNewClient(); | 423 ResetWithNewClient(); |
| 417 std::unique_ptr<VideoCaptureDevice> device( | 424 std::unique_ptr<VideoCaptureDevice> device( |
| 418 video_capture_device_factory_->CreateDevice( | 425 video_capture_device_factory_->CreateDevice( |
| 419 device_descriptors_->front())); | 426 device_descriptors_->front())); |
| 420 gfx::Size resolution; | 427 gfx::Size resolution; |
| 421 if (i % 2) { | 428 if (i % 2) |
| 422 resolution = gfx::Size(640, 480); | 429 resolution = gfx::Size(640, 480); |
| 423 } else { | 430 else |
| 424 resolution = gfx::Size(1280, 1024); | 431 resolution = gfx::Size(1280, 1024); |
| 425 } | 432 |
| 426 VideoCaptureParams capture_params; | 433 VideoCaptureParams capture_params; |
| 427 capture_params.requested_format.frame_size = resolution; | 434 capture_params.requested_format.frame_size = resolution; |
| 428 capture_params.requested_format.frame_rate = 30; | 435 capture_params.requested_format.frame_rate = 30; |
| 429 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 436 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
| 430 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 437 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
| 431 device->StopAndDeAllocate(); | 438 device->StopAndDeAllocate(); |
| 432 } | 439 } |
| 433 | 440 |
| 434 // Finally, do a device start and wait for it to finish. | 441 // Finally, do a device start and wait for it to finish. |
| 435 VideoCaptureParams capture_params; | 442 VideoCaptureParams capture_params; |
| 436 capture_params.requested_format.frame_size.SetSize(320, 240); | 443 capture_params.requested_format.frame_size.SetSize(320, 240); |
| 437 capture_params.requested_format.frame_rate = 30; | 444 capture_params.requested_format.frame_rate = 30; |
| 438 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 445 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
| 439 | 446 |
| 440 ResetWithNewClient(); | 447 ResetWithNewClient(); |
| 441 std::unique_ptr<VideoCaptureDevice> device( | 448 std::unique_ptr<VideoCaptureDevice> device( |
| 442 video_capture_device_factory_->CreateDevice( | 449 video_capture_device_factory_->CreateDevice( |
| 443 device_descriptors_->front())); | 450 device_descriptors_->front())); |
| 444 | 451 |
| 445 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 452 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
| 446 WaitForCapturedFrame(); | 453 WaitForCapturedFrame(); |
| 447 device->StopAndDeAllocate(); | 454 device->StopAndDeAllocate(); |
| 448 device.reset(); | 455 device.reset(); |
| 449 EXPECT_EQ(last_format().frame_size.width(), 320); | 456 EXPECT_EQ(last_format().frame_size.width(), 320); |
| 450 EXPECT_EQ(last_format().frame_size.height(), 240); | 457 EXPECT_EQ(last_format().frame_size.height(), 240); |
| 451 } | 458 } |
| 452 | 459 |
| 453 TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) { | 460 // Starts the camera in 720p to try and capture MJPEG format. |
| 454 device_descriptors_ = EnumerateDeviceDescriptors(); | |
| 455 if (device_descriptors_->empty()) { | |
| 456 VLOG(1) << "No camera available. Exiting test."; | |
| 457 return; | |
| 458 } | |
| 459 std::unique_ptr<VideoCaptureDevice> device( | |
| 460 video_capture_device_factory_->CreateDevice( | |
| 461 device_descriptors_->front())); | |
| 462 ASSERT_TRUE(device); | |
| 463 | |
| 464 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); | |
| 465 | |
| 466 VideoCaptureParams capture_params; | |
| 467 capture_params.requested_format.frame_size.SetSize(640, 480); | |
| 468 capture_params.requested_format.frame_rate = 30; | |
| 469 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | |
| 470 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | |
| 471 // Get captured video frames. | |
| 472 WaitForCapturedFrame(); | |
| 473 EXPECT_EQ(last_format().frame_size.width(), 640); | |
| 474 EXPECT_EQ(last_format().frame_size.height(), 480); | |
| 475 EXPECT_EQ(last_format().frame_rate, 30); | |
| 476 device->StopAndDeAllocate(); | |
| 477 } | |
| 478 | |
| 479 // Start the camera in 720p to capture MJPEG instead of a raw format. | |
| 480 TEST_F(VideoCaptureDeviceTest, MAYBE_CaptureMjpeg) { | 461 TEST_F(VideoCaptureDeviceTest, MAYBE_CaptureMjpeg) { |
| 481 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = | 462 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = |
| 482 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MJPEG); | 463 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MJPEG); |
| 483 if (!device_descriptor) { | 464 if (!device_descriptor) { |
| 484 VLOG(1) << "No camera supports MJPEG format. Exiting test."; | 465 DVLOG(1) << "No camera supports MJPEG format. Exiting test."; |
| 485 return; | 466 return; |
| 486 } | 467 } |
| 487 #if defined(OS_WIN) | 468 #if defined(OS_WIN) |
| 488 base::win::Version version = base::win::GetVersion(); | 469 base::win::Version version = base::win::GetVersion(); |
| 489 VLOG(1) << "Windows version: " << (int)version; | |
| 490 if (version >= base::win::VERSION_WIN10) { | 470 if (version >= base::win::VERSION_WIN10) { |
| 491 VLOG(1) << "Skipped on Win10: http://crbug.com/570604."; | 471 VLOG(1) << "Skipped on Win10: http://crbug.com/570604, current: " |
| 472 << static_cast<int>(version); |
| 492 return; | 473 return; |
| 493 } | 474 } |
| 494 #endif | 475 #endif |
| 495 std::unique_ptr<VideoCaptureDevice> device( | 476 std::unique_ptr<VideoCaptureDevice> device( |
| 496 video_capture_device_factory_->CreateDevice(*device_descriptor)); | 477 video_capture_device_factory_->CreateDevice(*device_descriptor)); |
| 497 ASSERT_TRUE(device); | 478 ASSERT_TRUE(device); |
| 498 | 479 |
| 499 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); | 480 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); |
| 500 | 481 |
| 501 VideoCaptureParams capture_params; | 482 VideoCaptureParams capture_params; |
| 502 capture_params.requested_format.frame_size.SetSize(1280, 720); | 483 capture_params.requested_format.frame_size.SetSize(1280, 720); |
| 503 capture_params.requested_format.frame_rate = 30; | 484 capture_params.requested_format.frame_rate = 30; |
| 504 capture_params.requested_format.pixel_format = PIXEL_FORMAT_MJPEG; | 485 capture_params.requested_format.pixel_format = PIXEL_FORMAT_MJPEG; |
| 505 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 486 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
| 506 // Get captured video frames. | 487 |
| 507 WaitForCapturedFrame(); | 488 WaitForCapturedFrame(); |
| 508 // Verify we get MJPEG from the device. Not all devices can capture 1280x720 | 489 // Verify we get MJPEG from the device. Not all devices can capture 1280x720 |
| 509 // @ 30 fps, so we don't care about the exact resolution we get. | 490 // @ 30 fps, so we don't care about the exact resolution we get. |
| 510 EXPECT_EQ(last_format().pixel_format, PIXEL_FORMAT_MJPEG); | 491 EXPECT_EQ(last_format().pixel_format, PIXEL_FORMAT_MJPEG); |
| 511 EXPECT_GE(static_cast<size_t>(1280 * 720), | 492 EXPECT_GE(static_cast<size_t>(1280 * 720), |
| 512 last_format().ImageAllocationSize()); | 493 last_format().ImageAllocationSize()); |
| 513 device->StopAndDeAllocate(); | 494 device->StopAndDeAllocate(); |
| 514 } | 495 } |
| 515 | 496 |
| 516 TEST_F(VideoCaptureDeviceTest, GetDeviceSupportedFormats) { | 497 TEST_F(VideoCaptureDeviceTest, NoCameraSupportsPixelFormatMax) { |
| 517 // Use PIXEL_FORMAT_MAX to iterate all device names for testing | 498 // Use PIXEL_FORMAT_MAX to iterate all device names for testing |
| 518 // GetDeviceSupportedFormats(). | 499 // GetDeviceSupportedFormats(). |
| 519 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = | 500 std::unique_ptr<VideoCaptureDeviceDescriptor> device_descriptor = |
| 520 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MAX); | 501 GetFirstDeviceDescriptorSupportingPixelFormat(PIXEL_FORMAT_MAX); |
| 521 // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else to test here | 502 // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else to test here |
| 522 // since we cannot forecast the hardware capabilities. | 503 // since we cannot forecast the hardware capabilities. |
| 523 ASSERT_FALSE(device_descriptor); | 504 ASSERT_FALSE(device_descriptor); |
| 524 } | 505 } |
| 525 | 506 |
| 526 // Start the camera and take a photo. | 507 // Starts the camera and take a photo. |
| 527 TEST_F(VideoCaptureDeviceTest, MAYBE_TakePhoto) { | 508 TEST_F(VideoCaptureDeviceTest, MAYBE_TakePhoto) { |
| 528 device_descriptors_ = EnumerateDeviceDescriptors(); | 509 if (!EnumerateAndFindUsableDevices()) |
| 529 if (device_descriptors_->empty()) { | |
| 530 VLOG(1) << "No camera available. Exiting test."; | |
| 531 return; | 510 return; |
| 532 } | 511 |
| 533 std::unique_ptr<VideoCaptureDevice> device( | 512 std::unique_ptr<VideoCaptureDevice> device( |
| 534 video_capture_device_factory_->CreateDevice( | 513 video_capture_device_factory_->CreateDevice( |
| 535 device_descriptors_->front())); | 514 device_descriptors_->front())); |
| 536 ASSERT_TRUE(device); | 515 ASSERT_TRUE(device); |
| 537 | 516 |
| 538 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); | 517 EXPECT_CALL(*video_capture_client_, OnError(_, _)).Times(0); |
| 539 | 518 |
| 540 VideoCaptureParams capture_params; | 519 VideoCaptureParams capture_params; |
| 541 capture_params.requested_format.frame_size.SetSize(640, 480); | 520 capture_params.requested_format.frame_size.SetSize(640, 480); |
| 542 capture_params.requested_format.frame_rate = 30; | 521 capture_params.requested_format.frame_rate = 30; |
| 543 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; | 522 capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; |
| 544 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); | 523 device->AllocateAndStart(capture_params, std::move(video_capture_client_)); |
| 545 WaitForCapturedFrame(); | 524 WaitForCapturedFrame(); |
| 546 | 525 |
| 547 VideoCaptureDevice::TakePhotoCallback scoped_callback( | 526 VideoCaptureDevice::TakePhotoCallback scoped_callback( |
| 548 base::Bind(&MockImageCaptureClient::DoOnPhotoTaken, | 527 base::Bind(&MockImageCaptureClient::DoOnPhotoTaken, |
| 549 image_capture_client_), | 528 image_capture_client_), |
| 550 media::BindToCurrentLoop(base::Bind( | 529 media::BindToCurrentLoop(base::Bind( |
| 551 &MockImageCaptureClient::OnTakePhotoFailure, image_capture_client_))); | 530 &MockImageCaptureClient::OnTakePhotoFailure, image_capture_client_))); |
| 552 | 531 |
| 553 EXPECT_CALL(*image_capture_client_.get(), OnCorrectPhotoTaken()).Times(1); | 532 EXPECT_CALL(*image_capture_client_.get(), OnCorrectPhotoTaken()).Times(1); |
| 554 device->TakePhoto(std::move(scoped_callback)); | 533 device->TakePhoto(std::move(scoped_callback)); |
| 555 WaitForCapturedFrame(); | 534 WaitForCapturedFrame(); |
| 556 | 535 |
| 557 device->StopAndDeAllocate(); | 536 device->StopAndDeAllocate(); |
| 558 } | 537 } |
| 559 | 538 |
| 560 }; // namespace media | 539 }; // namespace media |
| OLD | NEW |