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 mapped_size
)
32 mapped_size_(mapped_size
),
33 data_(new uint8
[mapped_size
]) {}
34 ~MockBuffer() override
{ delete[] data_
; }
36 int id() const override
{ return id_
; }
37 gfx::Size
dimensions() const override
{ return gfx::Size(); }
38 size_t mapped_size() const override
{ return mapped_size_
; }
39 void* data(int plane
) override
{ return data_
; }
40 ClientBuffer
AsClientBuffer(int plane
) override
{ return nullptr; }
42 base::FileDescriptor
AsPlatformFile() override
{
43 return base::FileDescriptor();
49 const size_t mapped_size_
;
53 class MockClient
: public VideoCaptureDevice::Client
{
55 MOCK_METHOD1(OnError
, void(const std::string
& reason
));
57 explicit MockClient(base::Callback
<void(const VideoCaptureFormat
&)> frame_cb
)
58 : frame_cb_(frame_cb
) {}
60 // Client virtual methods for capturing using Device Buffers.
61 void OnIncomingCapturedData(const uint8
* data
,
63 const VideoCaptureFormat
& format
,
65 const base::TimeTicks
& timestamp
) {
66 frame_cb_
.Run(format
);
68 void OnIncomingCapturedYuvData(const uint8
* y_data
,
74 const VideoCaptureFormat
& frame_format
,
75 int clockwise_rotation
,
76 const base::TimeTicks
& timestamp
) {
77 frame_cb_
.Run(frame_format
);
80 // Virtual methods for capturing using Client's Buffers.
81 scoped_ptr
<Buffer
> ReserveOutputBuffer(const gfx::Size
& dimensions
,
82 media::VideoPixelFormat format
,
83 media::VideoPixelStorage storage
) {
84 EXPECT_TRUE((format
== media::PIXEL_FORMAT_ARGB
&&
85 storage
== media::PIXEL_STORAGE_CPU
) ||
86 (format
== media::PIXEL_FORMAT_I420
&&
87 storage
== media::PIXEL_STORAGE_GPUMEMORYBUFFER
));
88 EXPECT_GT(dimensions
.GetArea(), 0);
89 const VideoCaptureFormat
frame_format(dimensions
, 0.0, format
);
90 return make_scoped_ptr(
91 new MockBuffer(0, frame_format
.ImageAllocationSize()));
93 void OnIncomingCapturedBuffer(scoped_ptr
<Buffer
> buffer
,
94 const VideoCaptureFormat
& frame_format
,
95 const base::TimeTicks
& timestamp
) {
96 frame_cb_
.Run(frame_format
);
98 void OnIncomingCapturedVideoFrame(
99 scoped_ptr
<Buffer
> buffer
,
100 const scoped_refptr
<media::VideoFrame
>& frame
,
101 const base::TimeTicks
& timestamp
) {
102 VideoCaptureFormat
format(frame
->natural_size(), 30.0,
104 frame_cb_
.Run(format
);
107 double GetBufferPoolUtilization() const override
{ return 0.0; }
110 base::Callback
<void(const VideoCaptureFormat
&)> frame_cb_
;
113 class DeviceEnumerationListener
114 : public base::RefCounted
<DeviceEnumerationListener
> {
116 MOCK_METHOD1(OnEnumeratedDevicesCallbackPtr
,
117 void(VideoCaptureDevice::Names
* names
));
118 // GMock doesn't support move-only arguments, so we use this forward method.
119 void OnEnumeratedDevicesCallback(
120 scoped_ptr
<VideoCaptureDevice::Names
> names
) {
121 OnEnumeratedDevicesCallbackPtr(names
.release());
125 friend class base::RefCounted
<DeviceEnumerationListener
>;
126 virtual ~DeviceEnumerationListener() {}
131 class FakeVideoCaptureDeviceTest
132 : public testing::TestWithParam
<::testing::tuple
<
133 FakeVideoCaptureDevice::BufferOwnership
,
134 FakeVideoCaptureDevice::BufferPlanarity
>> {
136 FakeVideoCaptureDeviceTest()
137 : loop_(new base::MessageLoop()),
138 client_(new MockClient(
139 base::Bind(&FakeVideoCaptureDeviceTest::OnFrameCaptured
,
140 base::Unretained(this)))),
141 video_capture_device_factory_(new FakeVideoCaptureDeviceFactory()) {
142 device_enumeration_listener_
= new DeviceEnumerationListener();
145 void SetUp() override
{ EXPECT_CALL(*client_
, OnError(_
)).Times(0); }
147 void OnFrameCaptured(const VideoCaptureFormat
& format
) {
148 last_format_
= format
;
149 run_loop_
->QuitClosure().Run();
152 void WaitForCapturedFrame() {
153 run_loop_
.reset(new base::RunLoop());
157 scoped_ptr
<VideoCaptureDevice::Names
> EnumerateDevices() {
158 VideoCaptureDevice::Names
* names
;
159 EXPECT_CALL(*device_enumeration_listener_
.get(),
160 OnEnumeratedDevicesCallbackPtr(_
)).WillOnce(SaveArg
<0>(&names
));
162 video_capture_device_factory_
->EnumerateDeviceNames(
163 base::Bind(&DeviceEnumerationListener::OnEnumeratedDevicesCallback
,
164 device_enumeration_listener_
));
165 base::MessageLoop::current()->RunUntilIdle();
166 return scoped_ptr
<VideoCaptureDevice::Names
>(names
);
169 const VideoCaptureFormat
& last_format() const { return last_format_
; }
171 VideoCaptureDevice::Names names_
;
172 const scoped_ptr
<base::MessageLoop
> loop_
;
173 scoped_ptr
<base::RunLoop
> run_loop_
;
174 scoped_ptr
<MockClient
> client_
;
175 scoped_refptr
<DeviceEnumerationListener
> device_enumeration_listener_
;
176 VideoCaptureFormat last_format_
;
177 const scoped_ptr
<VideoCaptureDeviceFactory
> video_capture_device_factory_
;
180 TEST_P(FakeVideoCaptureDeviceTest
, CaptureUsing
) {
181 const scoped_ptr
<VideoCaptureDevice::Names
> names(EnumerateDevices());
182 ASSERT_FALSE(names
->empty());
184 scoped_ptr
<VideoCaptureDevice
> device(new FakeVideoCaptureDevice(
185 testing::get
<0>(GetParam()), testing::get
<1>(GetParam())));
188 VideoCaptureParams capture_params
;
189 capture_params
.requested_format
.frame_size
.SetSize(640, 480);
190 capture_params
.requested_format
.frame_rate
= 30;
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::BufferOwnership::OWN_BUFFERS
,
204 FakeVideoCaptureDevice::BufferOwnership::CLIENT_BUFFERS
),
205 Values(FakeVideoCaptureDevice::BufferPlanarity::PACKED
,
206 FakeVideoCaptureDevice::BufferPlanarity::TRIPLANAR
)));
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
, PIXEL_FORMAT_I420
);
220 EXPECT_GE(supported_formats
[0].frame_rate
, 20.0);
221 EXPECT_EQ(supported_formats
[1].frame_size
.width(), 640);
222 EXPECT_EQ(supported_formats
[1].frame_size
.height(), 480);
223 EXPECT_EQ(supported_formats
[1].pixel_format
, PIXEL_FORMAT_I420
);
224 EXPECT_GE(supported_formats
[1].frame_rate
, 20.0);
225 EXPECT_EQ(supported_formats
[2].frame_size
.width(), 1280);
226 EXPECT_EQ(supported_formats
[2].frame_size
.height(), 720);
227 EXPECT_EQ(supported_formats
[2].pixel_format
, PIXEL_FORMAT_I420
);
228 EXPECT_GE(supported_formats
[2].frame_rate
, 20.0);
229 EXPECT_EQ(supported_formats
[3].frame_size
.width(), 1920);
230 EXPECT_EQ(supported_formats
[3].frame_size
.height(), 1080);
231 EXPECT_EQ(supported_formats
[3].pixel_format
, PIXEL_FORMAT_I420
);
232 EXPECT_GE(supported_formats
[3].frame_rate
, 20.0);
236 }; // namespace media