cc: Added inline to Tile::IsReadyToDraw
[chromium-blink-merge.git] / media / video / capture / video_capture_device_unittest.cc
blobe39c59b0541c76db88513d72b01d51e23e0e274c
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.
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"
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
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
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
53 using ::testing::_;
54 using ::testing::AnyNumber;
55 using ::testing::Return;
56 using ::testing::AtLeast;
57 using ::testing::SaveArg;
59 namespace media {
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&));
68 explicit MockFrameObserver(base::WaitableEvent* wait_event)
69 : wait_event_(wait_event) {}
71 virtual void OnError() OVERRIDE {
72 OnErr();
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();
85 virtual void OnIncomingCapturedVideoFrame(
86 const scoped_refptr<media::VideoFrame>& frame,
87 base::Time timestamp) OVERRIDE {
88 wait_event_->Signal();
91 private:
92 base::WaitableEvent* wait_event_;
95 class VideoCaptureDeviceTest : public testing::Test {
96 public:
97 VideoCaptureDeviceTest(): wait_event_(false, false) { }
99 void PostQuitTask() {
100 loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
101 loop_->Run();
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
114 virtual void TearDown() {
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_;
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);
140 TEST_F(VideoCaptureDeviceTest, CaptureVGA) {
141 VideoCaptureDevice::GetDeviceNames(&names_);
142 if (!names_.size()) {
143 DVLOG(1) << "No camera available. Exiting test.";
144 return;
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));
156 EXPECT_CALL(*frame_observer_, OnErr())
157 .Times(0);
159 VideoCaptureCapability capture_format(640,
160 480,
162 VideoCaptureCapability::kI420,
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();
177 TEST_F(VideoCaptureDeviceTest, Capture720p) {
178 VideoCaptureDevice::GetDeviceNames(&names_);
179 if (!names_.size()) {
180 DVLOG(1) << "No camera available. Exiting test.";
181 return;
184 scoped_ptr<VideoCaptureDevice> device(
185 VideoCaptureDevice::Create(names_.front()));
186 ASSERT_FALSE(device.get() == NULL);
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);
194 EXPECT_CALL(*frame_observer_, OnErr())
195 .Times(0);
197 VideoCaptureCapability capture_format(1280,
198 720,
200 VideoCaptureCapability::kI420,
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();
213 TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) {
214 VideoCaptureDevice::GetDeviceNames(&names_);
215 if (!names_.size()) {
216 DVLOG(1) << "No camera available. Exiting test.";
217 return;
219 scoped_ptr<VideoCaptureDevice> device(
220 VideoCaptureDevice::Create(names_.front()));
221 ASSERT_TRUE(device.get() != NULL);
223 EXPECT_CALL(*frame_observer_, OnErr())
224 .Times(0);
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));
231 VideoCaptureCapability capture_format(637,
232 472,
234 VideoCaptureCapability::kI420,
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);
244 TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) {
245 VideoCaptureDevice::GetDeviceNames(&names_);
246 if (!names_.size()) {
247 DVLOG(1) << "No camera available. Exiting test.";
248 return;
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,
261 VideoCaptureCapability::kI420,
263 false,
264 ConstantResolutionVideoCaptureDevice);
265 VideoCaptureCapability capture_format_2(1280,
266 1024,
268 VideoCaptureCapability::kI420,
270 false,
271 ConstantResolutionVideoCaptureDevice);
272 VideoCaptureCapability capture_format_3(320,
273 240,
275 VideoCaptureCapability::kI420,
277 false,
278 ConstantResolutionVideoCaptureDevice);
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());
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();
304 TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) {
305 VideoCaptureDevice::GetDeviceNames(&names_);
306 if (!names_.size()) {
307 DVLOG(1) << "No camera available. Exiting test.";
308 return;
310 scoped_ptr<VideoCaptureDevice> device(
311 VideoCaptureDevice::Create(names_.front()));
312 ASSERT_TRUE(device.get() != NULL);
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));
321 VideoCaptureCapability capture_format(640,
322 480,
324 VideoCaptureCapability::kI420,
326 false,
327 ConstantResolutionVideoCaptureDevice);
328 device->Allocate(capture_format, frame_observer_.get());
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();
340 TEST_F(VideoCaptureDeviceTest, FakeCapture) {
341 VideoCaptureDevice::Names names;
343 FakeVideoCaptureDevice::GetDeviceNames(&names);
345 ASSERT_GT(static_cast<int>(names.size()), 0);
347 scoped_ptr<VideoCaptureDevice> device(
348 FakeVideoCaptureDevice::Create(names.front()));
349 ASSERT_TRUE(device.get() != NULL);
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));
356 EXPECT_CALL(*frame_observer_, OnErr())
357 .Times(0);
359 VideoCaptureCapability capture_format(640,
360 480,
362 VideoCaptureCapability::kI420,
364 false,
365 ConstantResolutionVideoCaptureDevice);
366 device->Allocate(capture_format, frame_observer_.get());
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();
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;
384 scoped_ptr<VideoCaptureDevice> device(
385 VideoCaptureDevice::Create(names_.front()));
386 ASSERT_TRUE(device.get() != NULL);
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));
396 VideoCaptureCapability capture_format(1280,
397 720,
399 VideoCaptureCapability::kMJPEG,
401 false,
402 ConstantResolutionVideoCaptureDevice);
403 device->Allocate(capture_format, frame_observer_.get());
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();
413 TEST_F(VideoCaptureDeviceTest, FakeCaptureVariableResolution) {
414 VideoCaptureDevice::Names names;
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;
423 ASSERT_GT(static_cast<int>(names.size()), 0);
425 scoped_ptr<VideoCaptureDevice> device(
426 FakeVideoCaptureDevice::Create(names.front()));
427 ASSERT_TRUE(device.get() != NULL);
429 // Get info about the new resolution.
430 EXPECT_CALL(*frame_observer_, OnFrameInfo(_))
431 .Times(1);
433 EXPECT_CALL(*frame_observer_, OnErr())
434 .Times(0);
436 device->Allocate(capture_format, frame_observer_.get());
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()));
449 device->Stop();
450 device->DeAllocate();
453 }; // namespace media