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 3 // found in the LICENSE file. 4 5 #include "base/memory/scoped_ptr.h" 6 #include "base/message_loop/message_loop.h" 7 #include "base/synchronization/waitable_event.h" 8 #include "base/test/test_timeouts.h" 9 #include "base/threading/thread.h" 10 #include "media/video/capture/fake_video_capture_device.h" 11 #include "media/video/capture/video_capture_device.h" 12 #include "media/video/capture/video_capture_types.h" 13 #include "testing/gmock/include/gmock/gmock.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 16 #if defined(OS_WIN) 17 #include "base/win/scoped_com_initializer.h" 18 #include "media/video/capture/win/video_capture_device_mf_win.h" 19 #endif 20 21 #if defined(OS_ANDROID) 22 #include "base/android/jni_android.h" 23 #include "media/video/capture/android/video_capture_device_android.h" 24 #endif 25 26 #if defined(OS_MACOSX) 27 // Mac/QTKit will always give you the size you ask for and this case will fail. 28 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize 29 // We will always get ARGB from the Mac/QTKit implementation. 30 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg 31 #elif defined(OS_WIN) 32 #define MAYBE_AllocateBadSize AllocateBadSize 33 // Windows currently uses DirectShow to convert from MJPEG and a raw format is 34 // always delivered. 35 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg 36 #elif defined(OS_ANDROID) 37 // TODO(wjia): enable those tests on Android. 38 // On Android, native camera (JAVA) delivers frames on UI thread which is the 39 // main thread for tests. This results in no frame received by 40 // VideoCaptureAndroid. 41 #define CaptureVGA DISABLED_CaptureVGA 42 #define Capture720p DISABLED_Capture720p 43 #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize 44 #define ReAllocateCamera DISABLED_ReAllocateCamera 45 #define DeAllocateCameraWhileRunning DISABLED_DeAllocateCameraWhileRunning 46 #define DeAllocateCameraWhileRunning DISABLED_DeAllocateCameraWhileRunning 47 #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg 48 #else 49 #define MAYBE_AllocateBadSize AllocateBadSize 50 #define MAYBE_CaptureMjpeg CaptureMjpeg 51 #endif 52 53 using ::testing::_; 54 using ::testing::AnyNumber; 55 using ::testing::Return; 56 using ::testing::AtLeast; 57 using ::testing::SaveArg; 58 59 namespace media { 60 61 class MockFrameObserver : public media::VideoCaptureDevice::EventHandler { 62 public: 63 MOCK_METHOD0(ReserveOutputBuffer, scoped_refptr<media::VideoFrame>()); 64 MOCK_METHOD0(OnErr, void()); 65 MOCK_METHOD1(OnFrameInfo, void(const VideoCaptureCapability&)); 66 MOCK_METHOD1(OnFrameInfoChanged, void(const VideoCaptureCapability&)); 67 68 explicit MockFrameObserver(base::WaitableEvent* wait_event) 69 : wait_event_(wait_event) {} 70 71 virtual void OnError() OVERRIDE { 72 OnErr(); 73 } 74 75 virtual void OnIncomingCapturedFrame( 76 const uint8* data, 77 int length, 78 base::Time timestamp, 79 int rotation, 80 bool flip_vert, 81 bool flip_horiz) OVERRIDE { 82 wait_event_->Signal(); 83 } 84 85 virtual void OnIncomingCapturedVideoFrame( 86 const scoped_refptr<media::VideoFrame>& frame, 87 base::Time timestamp) OVERRIDE { 88 wait_event_->Signal(); 89 } 90 91 private: 92 base::WaitableEvent* wait_event_; 93 }; 94 95 class VideoCaptureDeviceTest : public testing::Test { 96 public: 97 VideoCaptureDeviceTest(): wait_event_(false, false) { } 98 99 void PostQuitTask() { 100 loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); 101 loop_->Run(); 102 } 103 104 protected: 105 virtual void SetUp() { 106 frame_observer_.reset(new MockFrameObserver(&wait_event_)); 107 loop_.reset(new base::MessageLoopForUI()); 108 #if defined(OS_ANDROID) 109 media::VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice( 110 base::android::AttachCurrentThread()); 111 #endif 112 } 113 114 virtual void TearDown() { 115 } 116 117 #if defined(OS_WIN) 118 base::win::ScopedCOMInitializer initialize_com_; 119 #endif 120 base::WaitableEvent wait_event_; 121 scoped_ptr<MockFrameObserver> frame_observer_; 122 VideoCaptureDevice::Names names_; 123 scoped_ptr<base::MessageLoop> loop_; 124 }; 125 126 TEST_F(VideoCaptureDeviceTest, OpenInvalidDevice) { 127 #if defined(OS_WIN) 128 VideoCaptureDevice::Name::CaptureApiType api_type = 129 VideoCaptureDeviceMFWin::PlatformSupported() 130 ? VideoCaptureDevice::Name::MEDIA_FOUNDATION 131 : VideoCaptureDevice::Name::DIRECT_SHOW; 132 VideoCaptureDevice::Name device_name("jibberish", "jibberish", api_type); 133 #else 134 VideoCaptureDevice::Name device_name("jibberish", "jibberish"); 135 #endif 136 VideoCaptureDevice* device = VideoCaptureDevice::Create(device_name); 137 EXPECT_TRUE(device == NULL); 138 } 139 140 TEST_F(VideoCaptureDeviceTest, CaptureVGA) { 141 VideoCaptureDevice::GetDeviceNames(&names_); 142 if (!names_.size()) { 143 DVLOG(1) << "No camera available. Exiting test."; 144 return; 145 } 146 147 scoped_ptr<VideoCaptureDevice> device( 148 VideoCaptureDevice::Create(names_.front())); 149 ASSERT_FALSE(device.get() == NULL); 150 DVLOG(1) << names_.front().id(); 151 // Get info about the new resolution. 152 VideoCaptureCapability rx_capability; 153 EXPECT_CALL(*frame_observer_, OnFrameInfo(_)) 154 .Times(1).WillOnce(SaveArg<0>(&rx_capability)); 155 156 EXPECT_CALL(*frame_observer_, OnErr()) 157 .Times(0); 158 159 VideoCaptureCapability capture_format(640, 160 480, 161 30, 162 VideoCaptureCapability::kI420, 163 0, 164 false, 165 ConstantResolutionVideoCaptureDevice); 166 device->Allocate(capture_format, frame_observer_.get()); 167 device->Start(); 168 // Get captured video frames. 169 PostQuitTask(); 170 EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_max_timeout())); 171 EXPECT_EQ(rx_capability.width, 640); 172 EXPECT_EQ(rx_capability.height, 480); 173 device->Stop(); 174 device->DeAllocate(); 175 } 176 177 TEST_F(VideoCaptureDeviceTest, Capture720p) { 178 VideoCaptureDevice::GetDeviceNames(&names_); 179 if (!names_.size()) { 180 DVLOG(1) << "No camera available. Exiting test."; 181 return; 182 } 183 184 scoped_ptr<VideoCaptureDevice> device( 185 VideoCaptureDevice::Create(names_.front())); 186 ASSERT_FALSE(device.get() == NULL); 187 188 // Get info about the new resolution. 189 // We don't care about the resulting resolution or frame rate as it might 190 // be different from one machine to the next. 191 EXPECT_CALL(*frame_observer_, OnFrameInfo(_)) 192 .Times(1); 193 194 EXPECT_CALL(*frame_observer_, OnErr()) 195 .Times(0); 196 197 VideoCaptureCapability capture_format(1280, 198 720, 199 30, 200 VideoCaptureCapability::kI420, 201 0, 202 false, 203 ConstantResolutionVideoCaptureDevice); 204 device->Allocate(capture_format, frame_observer_.get()); 205 device->Start(); 206 // Get captured video frames. 207 PostQuitTask(); 208 EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_max_timeout())); 209 device->Stop(); 210 device->DeAllocate(); 211 } 212 213 TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) { 214 VideoCaptureDevice::GetDeviceNames(&names_); 215 if (!names_.size()) { 216 DVLOG(1) << "No camera available. Exiting test."; 217 return; 218 } 219 scoped_ptr<VideoCaptureDevice> device( 220 VideoCaptureDevice::Create(names_.front())); 221 ASSERT_TRUE(device.get() != NULL); 222 223 EXPECT_CALL(*frame_observer_, OnErr()) 224 .Times(0); 225 226 // Get info about the new resolution. 227 VideoCaptureCapability rx_capability; 228 EXPECT_CALL(*frame_observer_, OnFrameInfo(_)) 229 .Times(AtLeast(1)).WillOnce(SaveArg<0>(&rx_capability)); 230 231 VideoCaptureCapability capture_format(637, 232 472, 233 35, 234 VideoCaptureCapability::kI420, 235 0, 236 false, 237 ConstantResolutionVideoCaptureDevice); 238 device->Allocate(capture_format, frame_observer_.get()); 239 device->DeAllocate(); 240 EXPECT_EQ(rx_capability.width, 640); 241 EXPECT_EQ(rx_capability.height, 480); 242 } 243 244 TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) { 245 VideoCaptureDevice::GetDeviceNames(&names_); 246 if (!names_.size()) { 247 DVLOG(1) << "No camera available. Exiting test."; 248 return; 249 } 250 scoped_ptr<VideoCaptureDevice> device( 251 VideoCaptureDevice::Create(names_.front())); 252 ASSERT_TRUE(device.get() != NULL); 253 EXPECT_CALL(*frame_observer_, OnErr()) 254 .Times(0); 255 // Get info about the new resolution. 256 VideoCaptureCapability rx_capability_1; 257 VideoCaptureCapability rx_capability_2; 258 VideoCaptureCapability capture_format_1(640, 259 480, 260 30, 261 VideoCaptureCapability::kI420, 262 0, 263 false, 264 ConstantResolutionVideoCaptureDevice); 265 VideoCaptureCapability capture_format_2(1280, 266 1024, 267 30, 268 VideoCaptureCapability::kI420, 269 0, 270 false, 271 ConstantResolutionVideoCaptureDevice); 272 VideoCaptureCapability capture_format_3(320, 273 240, 274 30, 275 VideoCaptureCapability::kI420, 276 0, 277 false, 278 ConstantResolutionVideoCaptureDevice); 279 280 EXPECT_CALL(*frame_observer_, OnFrameInfo(_)) 281 .WillOnce(SaveArg<0>(&rx_capability_1)); 282 device->Allocate(capture_format_1, frame_observer_.get()); 283 device->Start(); 284 // Nothing shall happen. 285 device->Allocate(capture_format_2, frame_observer_.get()); 286 device->DeAllocate(); 287 // Allocate new size 320, 240 288 EXPECT_CALL(*frame_observer_, OnFrameInfo(_)) 289 .WillOnce(SaveArg<0>(&rx_capability_2)); 290 device->Allocate(capture_format_3, frame_observer_.get()); 291 292 device->Start(); 293 // Get captured video frames. 294 PostQuitTask(); 295 EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_max_timeout())); 296 EXPECT_EQ(rx_capability_1.width, 640); 297 EXPECT_EQ(rx_capability_1.height, 480); 298 EXPECT_EQ(rx_capability_2.width, 320); 299 EXPECT_EQ(rx_capability_2.height, 240); 300 device->Stop(); 301 device->DeAllocate(); 302 } 303 304 TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) { 305 VideoCaptureDevice::GetDeviceNames(&names_); 306 if (!names_.size()) { 307 DVLOG(1) << "No camera available. Exiting test."; 308 return; 309 } 310 scoped_ptr<VideoCaptureDevice> device( 311 VideoCaptureDevice::Create(names_.front())); 312 ASSERT_TRUE(device.get() != NULL); 313 314 EXPECT_CALL(*frame_observer_, OnErr()) 315 .Times(0); 316 // Get info about the new resolution. 317 VideoCaptureCapability rx_capability; 318 EXPECT_CALL(*frame_observer_, OnFrameInfo(_)) 319 .WillOnce(SaveArg<0>(&rx_capability)); 320 321 VideoCaptureCapability capture_format(640, 322 480, 323 30, 324 VideoCaptureCapability::kI420, 325 0, 326 false, 327 ConstantResolutionVideoCaptureDevice); 328 device->Allocate(capture_format, frame_observer_.get()); 329 330 device->Start(); 331 // Get captured video frames. 332 PostQuitTask(); 333 EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_max_timeout())); 334 EXPECT_EQ(rx_capability.width, 640); 335 EXPECT_EQ(rx_capability.height, 480); 336 EXPECT_EQ(rx_capability.frame_rate, 30); 337 device->DeAllocate(); 338 } 339 340 TEST_F(VideoCaptureDeviceTest, FakeCapture) { 341 VideoCaptureDevice::Names names; 342 343 FakeVideoCaptureDevice::GetDeviceNames(&names); 344 345 ASSERT_GT(static_cast<int>(names.size()), 0); 346 347 scoped_ptr<VideoCaptureDevice> device( 348 FakeVideoCaptureDevice::Create(names.front())); 349 ASSERT_TRUE(device.get() != NULL); 350 351 // Get info about the new resolution. 352 VideoCaptureCapability rx_capability; 353 EXPECT_CALL(*frame_observer_, OnFrameInfo(_)) 354 .Times(1).WillOnce(SaveArg<0>(&rx_capability)); 355 356 EXPECT_CALL(*frame_observer_, OnErr()) 357 .Times(0); 358 359 VideoCaptureCapability capture_format(640, 360 480, 361 30, 362 VideoCaptureCapability::kI420, 363 0, 364 false, 365 ConstantResolutionVideoCaptureDevice); 366 device->Allocate(capture_format, frame_observer_.get()); 367 368 device->Start(); 369 EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_max_timeout())); 370 EXPECT_EQ(rx_capability.width, 640); 371 EXPECT_EQ(rx_capability.height, 480); 372 EXPECT_EQ(rx_capability.frame_rate, 30); 373 device->Stop(); 374 device->DeAllocate(); 375 } 376 377 // Start the camera in 720p to capture MJPEG instead of a raw format. 378 TEST_F(VideoCaptureDeviceTest, MAYBE_CaptureMjpeg) { 379 VideoCaptureDevice::GetDeviceNames(&names_); 380 if (!names_.size()) { 381 DVLOG(1) << "No camera available. Exiting test."; 382 return; 383 } 384 scoped_ptr<VideoCaptureDevice> device( 385 VideoCaptureDevice::Create(names_.front())); 386 ASSERT_TRUE(device.get() != NULL); 387 388 EXPECT_CALL(*frame_observer_, OnErr()) 389 .Times(0); 390 // Verify we get MJPEG from the device. Not all devices can capture 1280x720 391 // @ 30 fps, so we don't care about the exact resolution we get. 392 VideoCaptureCapability rx_capability; 393 EXPECT_CALL(*frame_observer_, OnFrameInfo(_)) 394 .WillOnce(SaveArg<0>(&rx_capability)); 395 396 VideoCaptureCapability capture_format(1280, 397 720, 398 30, 399 VideoCaptureCapability::kMJPEG, 400 0, 401 false, 402 ConstantResolutionVideoCaptureDevice); 403 device->Allocate(capture_format, frame_observer_.get()); 404 405 device->Start(); 406 // Get captured video frames. 407 PostQuitTask(); 408 EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_max_timeout())); 409 EXPECT_EQ(rx_capability.color, VideoCaptureCapability::kMJPEG); 410 device->DeAllocate(); 411 } 412 413 TEST_F(VideoCaptureDeviceTest, FakeCaptureVariableResolution) { 414 VideoCaptureDevice::Names names; 415 416 FakeVideoCaptureDevice::GetDeviceNames(&names); 417 media::VideoCaptureCapability capture_format; 418 capture_format.width = 640; 419 capture_format.height = 480; 420 capture_format.frame_rate = 30; 421 capture_format.frame_size_type = media::VariableResolutionVideoCaptureDevice; 422 423 ASSERT_GT(static_cast<int>(names.size()), 0); 424 425 scoped_ptr<VideoCaptureDevice> device( 426 FakeVideoCaptureDevice::Create(names.front())); 427 ASSERT_TRUE(device.get() != NULL); 428 429 // Get info about the new resolution. 430 EXPECT_CALL(*frame_observer_, OnFrameInfo(_)) 431 .Times(1); 432 433 EXPECT_CALL(*frame_observer_, OnErr()) 434 .Times(0); 435 436 device->Allocate(capture_format, frame_observer_.get()); 437 438 // The amount of times the OnFrameInfoChanged gets called depends on how often 439 // FakeDevice is supposed to change and what is its actual frame rate. 440 // We set TimeWait to 200 action timeouts and this should be enough for at 441 // least action_count/kFakeCaptureCapabilityChangePeriod calls. 442 int action_count = 200; 443 EXPECT_CALL(*frame_observer_, OnFrameInfoChanged(_)) 444 .Times(AtLeast(action_count / 30)); 445 device->Start(); 446 for (int i = 0; i < action_count; ++i) { 447 EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_timeout())); 448 } 449 device->Stop(); 450 device->DeAllocate(); 451 } 452 453 }; // namespace media 454