1 // Copyright 2014 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.
6 #include "base/memory/scoped_ptr.h"
7 #include "base/run_loop.h"
8 #include "base/test/test_timeouts.h"
9 #include "base/threading/thread.h"
10 #include "media/base/video_capture_types.h"
11 #include "media/capture/video/fake_video_capture_device.h"
12 #include "media/capture/video/fake_video_capture_device_factory.h"
13 #include "media/capture/video/video_capture_device.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
18 using ::testing::Bool
;
19 using ::testing::Combine
;
20 using ::testing::SaveArg
;
21 using ::testing::Values
;
27 // This class is a Client::Buffer that allocates and frees the requested |size|.
28 class MockBuffer
: public VideoCaptureDevice::Client::Buffer
{
30 MockBuffer(int buffer_id
, size_t size
)
31 : id_(buffer_id
), size_(size
), data_(new uint8
[size_
]) {}
32 ~MockBuffer() override
{ delete[] data_
; }
34 int id() const override
{ return id_
; }
35 size_t size() const override
{ return size_
; }
36 void* data() override
{ return data_
; }
37 ClientBuffer
AsClientBuffer() override
{ return nullptr; }
39 base::FileDescriptor
AsPlatformFile() override
{
40 return base::FileDescriptor();
50 class MockClient
: public VideoCaptureDevice::Client
{
52 MOCK_METHOD1(OnError
, void(const std::string
& reason
));
54 explicit MockClient(base::Callback
<void(const VideoCaptureFormat
&)> frame_cb
)
55 : frame_cb_(frame_cb
) {}
57 // Client virtual methods for capturing using Device Buffers.
58 void OnIncomingCapturedData(const uint8
* data
,
60 const VideoCaptureFormat
& format
,
62 const base::TimeTicks
& timestamp
) {
63 frame_cb_
.Run(format
);
65 void OnIncomingCapturedYuvData(const uint8
* y_data
,
71 const VideoCaptureFormat
& frame_format
,
72 int clockwise_rotation
,
73 const base::TimeTicks
& timestamp
) {
74 frame_cb_
.Run(frame_format
);
77 // Virtual methods for capturing using Client's Buffers.
78 scoped_ptr
<Buffer
> ReserveOutputBuffer(const gfx::Size
& dimensions
,
79 media::VideoCapturePixelFormat format
,
80 media::VideoPixelStorage storage
) {
81 EXPECT_TRUE((format
== media::VIDEO_CAPTURE_PIXEL_FORMAT_I420
&&
82 storage
== media::PIXEL_STORAGE_CPU
) ||
83 (format
== media::VIDEO_CAPTURE_PIXEL_FORMAT_ARGB
&&
84 storage
== media::PIXEL_STORAGE_GPUMEMORYBUFFER
));
85 EXPECT_GT(dimensions
.GetArea(), 0);
86 const VideoCaptureFormat
frame_format(dimensions
, 0.0, format
);
87 return make_scoped_ptr(
88 new MockBuffer(0, frame_format
.ImageAllocationSize()));
90 void OnIncomingCapturedBuffer(scoped_ptr
<Buffer
> buffer
,
91 const VideoCaptureFormat
& frame_format
,
92 const base::TimeTicks
& timestamp
) {
93 frame_cb_
.Run(frame_format
);
95 void OnIncomingCapturedVideoFrame(
96 scoped_ptr
<Buffer
> buffer
,
97 const scoped_refptr
<media::VideoFrame
>& frame
,
98 const base::TimeTicks
& timestamp
) {
99 VideoCaptureFormat
format(frame
->natural_size(), 30.0,
100 VIDEO_CAPTURE_PIXEL_FORMAT_I420
);
101 frame_cb_
.Run(format
);
104 double GetBufferPoolUtilization() const override
{ return 0.0; }
107 base::Callback
<void(const VideoCaptureFormat
&)> frame_cb_
;
110 class DeviceEnumerationListener
111 : public base::RefCounted
<DeviceEnumerationListener
> {
113 MOCK_METHOD1(OnEnumeratedDevicesCallbackPtr
,
114 void(VideoCaptureDevice::Names
* names
));
115 // GMock doesn't support move-only arguments, so we use this forward method.
116 void OnEnumeratedDevicesCallback(
117 scoped_ptr
<VideoCaptureDevice::Names
> names
) {
118 OnEnumeratedDevicesCallbackPtr(names
.release());
122 friend class base::RefCounted
<DeviceEnumerationListener
>;
123 virtual ~DeviceEnumerationListener() {}
128 class FakeVideoCaptureDeviceTest
129 : public testing::TestWithParam
<
130 ::testing::tuple
<FakeVideoCaptureDevice::FakeVideoCaptureDeviceType
,
133 FakeVideoCaptureDeviceTest()
134 : loop_(new base::MessageLoop()),
135 client_(new MockClient(
136 base::Bind(&FakeVideoCaptureDeviceTest::OnFrameCaptured
,
137 base::Unretained(this)))),
138 video_capture_device_factory_(new FakeVideoCaptureDeviceFactory()) {
139 device_enumeration_listener_
= new DeviceEnumerationListener();
142 void SetUp() override
{ EXPECT_CALL(*client_
, OnError(_
)).Times(0); }
144 void OnFrameCaptured(const VideoCaptureFormat
& format
) {
145 last_format_
= format
;
146 run_loop_
->QuitClosure().Run();
149 void WaitForCapturedFrame() {
150 run_loop_
.reset(new base::RunLoop());
154 scoped_ptr
<VideoCaptureDevice::Names
> EnumerateDevices() {
155 VideoCaptureDevice::Names
* names
;
156 EXPECT_CALL(*device_enumeration_listener_
.get(),
157 OnEnumeratedDevicesCallbackPtr(_
)).WillOnce(SaveArg
<0>(&names
));
159 video_capture_device_factory_
->EnumerateDeviceNames(
160 base::Bind(&DeviceEnumerationListener::OnEnumeratedDevicesCallback
,
161 device_enumeration_listener_
));
162 base::MessageLoop::current()->RunUntilIdle();
163 return scoped_ptr
<VideoCaptureDevice::Names
>(names
);
166 const VideoCaptureFormat
& last_format() const { return last_format_
; }
168 VideoCaptureDevice::Names names_
;
169 const scoped_ptr
<base::MessageLoop
> loop_
;
170 scoped_ptr
<base::RunLoop
> run_loop_
;
171 scoped_ptr
<MockClient
> client_
;
172 scoped_refptr
<DeviceEnumerationListener
> device_enumeration_listener_
;
173 VideoCaptureFormat last_format_
;
174 const scoped_ptr
<VideoCaptureDeviceFactory
> video_capture_device_factory_
;
177 TEST_P(FakeVideoCaptureDeviceTest
, CaptureUsing
) {
178 const scoped_ptr
<VideoCaptureDevice::Names
> names(EnumerateDevices());
179 ASSERT_FALSE(names
->empty());
181 scoped_ptr
<VideoCaptureDevice
> device(
182 new FakeVideoCaptureDevice(testing::get
<0>(GetParam())));
185 VideoCaptureParams capture_params
;
186 capture_params
.requested_format
.frame_size
.SetSize(640, 480);
187 capture_params
.requested_format
.frame_rate
= 30;
188 capture_params
.requested_format
.pixel_format
=
189 VIDEO_CAPTURE_PIXEL_FORMAT_I420
;
190 capture_params
.use_gpu_memory_buffers
= ::testing::get
<1>(GetParam());
191 device
->AllocateAndStart(capture_params
, client_
.Pass());
193 WaitForCapturedFrame();
194 EXPECT_EQ(last_format().frame_size
.width(), 640);
195 EXPECT_EQ(last_format().frame_size
.height(), 480);
196 EXPECT_EQ(last_format().frame_rate
, 30.0);
197 device
->StopAndDeAllocate();
200 INSTANTIATE_TEST_CASE_P(
202 FakeVideoCaptureDeviceTest
,
203 Combine(Values(FakeVideoCaptureDevice::USING_OWN_BUFFERS
,
204 FakeVideoCaptureDevice::USING_OWN_BUFFERS_TRIPLANAR
,
205 FakeVideoCaptureDevice::USING_CLIENT_BUFFERS
),
208 TEST_F(FakeVideoCaptureDeviceTest
, GetDeviceSupportedFormats
) {
209 scoped_ptr
<VideoCaptureDevice::Names
> names(EnumerateDevices());
211 VideoCaptureFormats supported_formats
;
213 for (const auto& names_iterator
: *names
) {
214 video_capture_device_factory_
->GetDeviceSupportedFormats(
215 names_iterator
, &supported_formats
);
216 ASSERT_EQ(supported_formats
.size(), 4u);
217 EXPECT_EQ(supported_formats
[0].frame_size
.width(), 320);
218 EXPECT_EQ(supported_formats
[0].frame_size
.height(), 240);
219 EXPECT_EQ(supported_formats
[0].pixel_format
,
220 VIDEO_CAPTURE_PIXEL_FORMAT_I420
);
221 EXPECT_GE(supported_formats
[0].frame_rate
, 20.0);
222 EXPECT_EQ(supported_formats
[1].frame_size
.width(), 640);
223 EXPECT_EQ(supported_formats
[1].frame_size
.height(), 480);
224 EXPECT_EQ(supported_formats
[1].pixel_format
,
225 VIDEO_CAPTURE_PIXEL_FORMAT_I420
);
226 EXPECT_GE(supported_formats
[1].frame_rate
, 20.0);
227 EXPECT_EQ(supported_formats
[2].frame_size
.width(), 1280);
228 EXPECT_EQ(supported_formats
[2].frame_size
.height(), 720);
229 EXPECT_EQ(supported_formats
[2].pixel_format
,
230 VIDEO_CAPTURE_PIXEL_FORMAT_I420
);
231 EXPECT_GE(supported_formats
[2].frame_rate
, 20.0);
232 EXPECT_EQ(supported_formats
[3].frame_size
.width(), 1920);
233 EXPECT_EQ(supported_formats
[3].frame_size
.height(), 1080);
234 EXPECT_EQ(supported_formats
[3].pixel_format
,
235 VIDEO_CAPTURE_PIXEL_FORMAT_I420
);
236 EXPECT_GE(supported_formats
[3].frame_rate
, 20.0);
240 }; // namespace media