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/video/capture/fake_video_capture_device.h"
12 #include "media/video/capture/fake_video_capture_device_factory.h"
13 #include "media/video/capture/video_capture_device.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
18 using ::testing::SaveArg
;
24 static const FakeVideoCaptureDevice::FakeVideoCaptureDeviceType
26 FakeVideoCaptureDevice::USING_OWN_BUFFERS
,
27 FakeVideoCaptureDevice::USING_OWN_BUFFERS_TRIPLANAR
,
28 FakeVideoCaptureDevice::USING_CLIENT_BUFFERS_I420
,
29 FakeVideoCaptureDevice::USING_CLIENT_BUFFERS_GPU
,
32 // This class is a Client::Buffer that allocates and frees the requested |size|.
33 class MockBuffer
: public VideoCaptureDevice::Client::Buffer
{
35 MockBuffer(int buffer_id
, size_t size
)
36 : id_(buffer_id
), size_(size
), data_(new uint8
[size_
]) {}
37 ~MockBuffer() override
{ delete[] data_
; }
38 int id() const override
{ return id_
; }
39 size_t size() const override
{ return size_
; }
40 void* data() override
{ return data_
; }
41 ClientBuffer
AsClientBuffer() override
{ return nullptr; }
49 class MockClient
: public VideoCaptureDevice::Client
{
51 MOCK_METHOD1(OnError
, void(const std::string
& reason
));
53 explicit MockClient(base::Callback
<void(const VideoCaptureFormat
&)> frame_cb
)
54 : frame_cb_(frame_cb
) {}
56 // Client virtual methods for capturing using Device Buffers.
57 void OnIncomingCapturedData(const uint8
* data
,
59 const VideoCaptureFormat
& format
,
61 const base::TimeTicks
& timestamp
) {
62 frame_cb_
.Run(format
);
64 void OnIncomingCapturedYuvData(const uint8
* y_data
,
70 const VideoCaptureFormat
& frame_format
,
71 int clockwise_rotation
,
72 const base::TimeTicks
& timestamp
) {
73 frame_cb_
.Run(frame_format
);
76 // Virtual methods for capturing using Client's Buffers.
77 scoped_ptr
<Buffer
> ReserveOutputBuffer(media::VideoPixelFormat format
,
78 const gfx::Size
& dimensions
) {
79 EXPECT_TRUE(format
== PIXEL_FORMAT_I420
||
80 format
== PIXEL_FORMAT_GPUMEMORYBUFFER
);
81 EXPECT_GT(dimensions
.GetArea(), 0);
82 const VideoCaptureFormat
frame_format(dimensions
, 0.0, format
);
83 return make_scoped_ptr(
84 new MockBuffer(0, frame_format
.ImageAllocationSize()));
86 void OnIncomingCapturedBuffer(scoped_ptr
<Buffer
> buffer
,
87 const VideoCaptureFormat
& frame_format
,
88 const base::TimeTicks
& timestamp
) {
89 frame_cb_
.Run(frame_format
);
91 void OnIncomingCapturedVideoFrame(
92 scoped_ptr
<Buffer
> buffer
,
93 const scoped_refptr
<media::VideoFrame
>& frame
,
94 const base::TimeTicks
& timestamp
) {
95 VideoCaptureFormat
format(frame
->natural_size(), 30.0, PIXEL_FORMAT_I420
);
96 frame_cb_
.Run(format
);
100 base::Callback
<void(const VideoCaptureFormat
&)> frame_cb_
;
103 class DeviceEnumerationListener
:
104 public base::RefCounted
<DeviceEnumerationListener
> {
106 MOCK_METHOD1(OnEnumeratedDevicesCallbackPtr
,
107 void(VideoCaptureDevice::Names
* names
));
108 // GMock doesn't support move-only arguments, so we use this forward method.
109 void OnEnumeratedDevicesCallback(
110 scoped_ptr
<VideoCaptureDevice::Names
> names
) {
111 OnEnumeratedDevicesCallbackPtr(names
.release());
115 friend class base::RefCounted
<DeviceEnumerationListener
>;
116 virtual ~DeviceEnumerationListener() {}
121 class FakeVideoCaptureDeviceTest
122 : public testing::TestWithParam
<
123 FakeVideoCaptureDevice::FakeVideoCaptureDeviceType
>{
125 FakeVideoCaptureDeviceTest()
126 : loop_(new base::MessageLoop()),
127 client_(new MockClient(
128 base::Bind(&FakeVideoCaptureDeviceTest::OnFrameCaptured
,
129 base::Unretained(this)))),
130 video_capture_device_factory_(new FakeVideoCaptureDeviceFactory()) {
131 device_enumeration_listener_
= new DeviceEnumerationListener();
134 void SetUp() override
{
135 EXPECT_CALL(*client_
, OnError(_
)).Times(0);
138 void OnFrameCaptured(const VideoCaptureFormat
& format
) {
139 last_format_
= format
;
140 run_loop_
->QuitClosure().Run();
143 void WaitForCapturedFrame() {
144 run_loop_
.reset(new base::RunLoop());
148 scoped_ptr
<VideoCaptureDevice::Names
> EnumerateDevices() {
149 VideoCaptureDevice::Names
* names
;
150 EXPECT_CALL(*device_enumeration_listener_
.get(),
151 OnEnumeratedDevicesCallbackPtr(_
)).WillOnce(SaveArg
<0>(&names
));
153 video_capture_device_factory_
->EnumerateDeviceNames(
154 base::Bind(&DeviceEnumerationListener::OnEnumeratedDevicesCallback
,
155 device_enumeration_listener_
));
156 base::MessageLoop::current()->RunUntilIdle();
157 return scoped_ptr
<VideoCaptureDevice::Names
>(names
);
160 const VideoCaptureFormat
& last_format() const { return last_format_
; }
162 VideoCaptureDevice::Names names_
;
163 const scoped_ptr
<base::MessageLoop
> loop_
;
164 scoped_ptr
<base::RunLoop
> run_loop_
;
165 scoped_ptr
<MockClient
> client_
;
166 scoped_refptr
<DeviceEnumerationListener
> device_enumeration_listener_
;
167 VideoCaptureFormat last_format_
;
168 const scoped_ptr
<VideoCaptureDeviceFactory
> video_capture_device_factory_
;
171 TEST_P(FakeVideoCaptureDeviceTest
, CaptureUsing
) {
172 const scoped_ptr
<VideoCaptureDevice::Names
> names(EnumerateDevices());
173 ASSERT_FALSE(names
->empty());
175 scoped_ptr
<VideoCaptureDevice
> device(new FakeVideoCaptureDevice(GetParam()));
178 VideoCaptureParams capture_params
;
179 capture_params
.requested_format
.frame_size
.SetSize(640, 480);
180 capture_params
.requested_format
.frame_rate
= 30;
181 capture_params
.requested_format
.pixel_format
= PIXEL_FORMAT_I420
;
182 device
->AllocateAndStart(capture_params
, client_
.Pass());
184 WaitForCapturedFrame();
185 EXPECT_EQ(last_format().frame_size
.width(), 640);
186 EXPECT_EQ(last_format().frame_size
.height(), 480);
187 EXPECT_EQ(last_format().frame_rate
, 30.0);
188 device
->StopAndDeAllocate();
191 INSTANTIATE_TEST_CASE_P(,
192 FakeVideoCaptureDeviceTest
,
193 testing::ValuesIn(kCaptureTypes
));
195 TEST_F(FakeVideoCaptureDeviceTest
, GetDeviceSupportedFormats
) {
196 scoped_ptr
<VideoCaptureDevice::Names
> names(EnumerateDevices());
198 VideoCaptureFormats supported_formats
;
200 for (const auto& names_iterator
: *names
) {
201 video_capture_device_factory_
->GetDeviceSupportedFormats(
202 names_iterator
, &supported_formats
);
203 ASSERT_EQ(supported_formats
.size(), 4u);
204 EXPECT_EQ(supported_formats
[0].frame_size
.width(), 320);
205 EXPECT_EQ(supported_formats
[0].frame_size
.height(), 240);
206 EXPECT_EQ(supported_formats
[0].pixel_format
, PIXEL_FORMAT_I420
);
207 EXPECT_GE(supported_formats
[0].frame_rate
, 20.0);
208 EXPECT_EQ(supported_formats
[1].frame_size
.width(), 640);
209 EXPECT_EQ(supported_formats
[1].frame_size
.height(), 480);
210 EXPECT_EQ(supported_formats
[1].pixel_format
, PIXEL_FORMAT_I420
);
211 EXPECT_GE(supported_formats
[1].frame_rate
, 20.0);
212 EXPECT_EQ(supported_formats
[2].frame_size
.width(), 1280);
213 EXPECT_EQ(supported_formats
[2].frame_size
.height(), 720);
214 EXPECT_EQ(supported_formats
[2].pixel_format
, PIXEL_FORMAT_I420
);
215 EXPECT_GE(supported_formats
[2].frame_rate
, 20.0);
216 EXPECT_EQ(supported_formats
[3].frame_size
.width(), 1920);
217 EXPECT_EQ(supported_formats
[3].frame_size
.height(), 1080);
218 EXPECT_EQ(supported_formats
[3].pixel_format
, PIXEL_FORMAT_I420
);
219 EXPECT_GE(supported_formats
[3].frame_rate
, 20.0);
223 }; // namespace media