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"
17 #include "base/win/scoped_com_initializer.h"
18 #include "media/video/capture/win/video_capture_device_mf_win.h"
21 #if defined(OS_ANDROID)
22 #include "base/android/jni_android.h"
23 #include "media/video/capture/android/video_capture_device_android.h"
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
32 #define MAYBE_AllocateBadSize AllocateBadSize
33 // Windows currently uses DirectShow to convert from MJPEG and a raw format is
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
49 #define MAYBE_AllocateBadSize AllocateBadSize
50 #define MAYBE_CaptureMjpeg CaptureMjpeg
54 using ::testing::AnyNumber
;
55 using ::testing::Return
;
56 using ::testing::AtLeast
;
57 using ::testing::SaveArg
;
61 class MockFrameObserver
: public media::VideoCaptureDevice::EventHandler
{
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
{
75 virtual void OnIncomingCapturedFrame(
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();
92 base::WaitableEvent
* wait_event_
;
95 class VideoCaptureDeviceTest
: public testing::Test
{
97 VideoCaptureDeviceTest(): wait_event_(false, false) { }
100 loop_
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
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());
114 virtual void TearDown() {
118 base::win::ScopedCOMInitializer initialize_com_
;
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
) {
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
);
134 VideoCaptureDevice::Name
device_name("jibberish", "jibberish");
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.";
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())
159 VideoCaptureCapability
capture_format(640,
162 VideoCaptureCapability::kI420
,
165 ConstantResolutionVideoCaptureDevice
);
166 device
->Allocate(capture_format
, frame_observer_
.get());
168 // Get captured video frames.
170 EXPECT_TRUE(wait_event_
.TimedWait(TestTimeouts::action_max_timeout()));
171 EXPECT_EQ(rx_capability
.width
, 640);
172 EXPECT_EQ(rx_capability
.height
, 480);
174 device
->DeAllocate();
177 TEST_F(VideoCaptureDeviceTest
, Capture720p
) {
178 VideoCaptureDevice::GetDeviceNames(&names_
);
179 if (!names_
.size()) {
180 DVLOG(1) << "No camera available. Exiting test.";
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(_
))
194 EXPECT_CALL(*frame_observer_
, OnErr())
197 VideoCaptureCapability
capture_format(1280,
200 VideoCaptureCapability::kI420
,
203 ConstantResolutionVideoCaptureDevice
);
204 device
->Allocate(capture_format
, frame_observer_
.get());
206 // Get captured video frames.
208 EXPECT_TRUE(wait_event_
.TimedWait(TestTimeouts::action_max_timeout()));
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.";
219 scoped_ptr
<VideoCaptureDevice
> device(
220 VideoCaptureDevice::Create(names_
.front()));
221 ASSERT_TRUE(device
.get() != NULL
);
223 EXPECT_CALL(*frame_observer_
, OnErr())
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,
234 VideoCaptureCapability::kI420
,
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.";
250 scoped_ptr
<VideoCaptureDevice
> device(
251 VideoCaptureDevice::Create(names_
.front()));
252 ASSERT_TRUE(device
.get() != NULL
);
253 EXPECT_CALL(*frame_observer_
, OnErr())
255 // Get info about the new resolution.
256 VideoCaptureCapability rx_capability_1
;
257 VideoCaptureCapability rx_capability_2
;
258 VideoCaptureCapability
capture_format_1(640,
261 VideoCaptureCapability::kI420
,
264 ConstantResolutionVideoCaptureDevice
);
265 VideoCaptureCapability
capture_format_2(1280,
268 VideoCaptureCapability::kI420
,
271 ConstantResolutionVideoCaptureDevice
);
272 VideoCaptureCapability
capture_format_3(320,
275 VideoCaptureCapability::kI420
,
278 ConstantResolutionVideoCaptureDevice
);
280 EXPECT_CALL(*frame_observer_
, OnFrameInfo(_
))
281 .WillOnce(SaveArg
<0>(&rx_capability_1
));
282 device
->Allocate(capture_format_1
, frame_observer_
.get());
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());
293 // Get captured video frames.
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);
301 device
->DeAllocate();
304 TEST_F(VideoCaptureDeviceTest
, DeAllocateCameraWhileRunning
) {
305 VideoCaptureDevice::GetDeviceNames(&names_
);
306 if (!names_
.size()) {
307 DVLOG(1) << "No camera available. Exiting test.";
310 scoped_ptr
<VideoCaptureDevice
> device(
311 VideoCaptureDevice::Create(names_
.front()));
312 ASSERT_TRUE(device
.get() != NULL
);
314 EXPECT_CALL(*frame_observer_
, OnErr())
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,
324 VideoCaptureCapability::kI420
,
327 ConstantResolutionVideoCaptureDevice
);
328 device
->Allocate(capture_format
, frame_observer_
.get());
331 // Get captured video frames.
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())
359 VideoCaptureCapability
capture_format(640,
362 VideoCaptureCapability::kI420
,
365 ConstantResolutionVideoCaptureDevice
);
366 device
->Allocate(capture_format
, frame_observer_
.get());
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);
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.";
384 scoped_ptr
<VideoCaptureDevice
> device(
385 VideoCaptureDevice::Create(names_
.front()));
386 ASSERT_TRUE(device
.get() != NULL
);
388 EXPECT_CALL(*frame_observer_
, OnErr())
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,
399 VideoCaptureCapability::kMJPEG
,
402 ConstantResolutionVideoCaptureDevice
);
403 device
->Allocate(capture_format
, frame_observer_
.get());
406 // Get captured video frames.
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(_
))
433 EXPECT_CALL(*frame_observer_
, OnErr())
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));
446 for (int i
= 0; i
< action_count
; ++i
) {
447 EXPECT_TRUE(wait_event_
.TimedWait(TestTimeouts::action_timeout()));
450 device
->DeAllocate();
453 }; // namespace media