Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(428)

Side by Side Diff: media/capture/video/fake_video_capture_device_unittest.cc

Issue 2214533002: move //media/capture to //device/capture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "media/capture/video/fake_video_capture_device.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <memory>
11 #include <utility>
12
13 #include "base/bind.h"
14 #include "base/command_line.h"
15 #include "base/memory/ptr_util.h"
16 #include "base/run_loop.h"
17 #include "base/test/test_timeouts.h"
18 #include "base/threading/thread.h"
19 #include "build/build_config.h"
20 #include "media/base/media_switches.h"
21 #include "media/base/video_capture_types.h"
22 #include "media/capture/video/fake_video_capture_device_factory.h"
23 #include "media/capture/video/video_capture_device.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 using ::testing::_;
28 using ::testing::Bool;
29 using ::testing::Combine;
30 using ::testing::SaveArg;
31 using ::testing::Values;
32
33 namespace media {
34
35 namespace {
36
37 // This class is a Client::Buffer that allocates and frees the requested |size|.
38 class MockBuffer : public VideoCaptureDevice::Client::Buffer {
39 public:
40 MockBuffer(int buffer_id, size_t mapped_size)
41 : id_(buffer_id),
42 mapped_size_(mapped_size),
43 data_(new uint8_t[mapped_size]) {}
44 ~MockBuffer() override { delete[] data_; }
45
46 int id() const override { return id_; }
47 gfx::Size dimensions() const override { return gfx::Size(); }
48 size_t mapped_size() const override { return mapped_size_; }
49 void* data(int plane) override { return data_; }
50 ClientBuffer AsClientBuffer(int plane) override { return nullptr; }
51 #if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS))
52 base::FileDescriptor AsPlatformFile() override {
53 return base::FileDescriptor();
54 }
55 #endif
56
57 private:
58 const int id_;
59 const size_t mapped_size_;
60 uint8_t* const data_;
61 };
62
63 class MockClient : public VideoCaptureDevice::Client {
64 public:
65 MOCK_METHOD2(OnError,
66 void(const tracked_objects::Location& from_here,
67 const std::string& reason));
68
69 explicit MockClient(base::Callback<void(const VideoCaptureFormat&)> frame_cb)
70 : frame_cb_(frame_cb) {}
71
72 // Client virtual methods for capturing using Device Buffers.
73 void OnIncomingCapturedData(const uint8_t* data,
74 int length,
75 const VideoCaptureFormat& format,
76 int rotation,
77 base::TimeTicks reference_time,
78 base::TimeDelta timestamp) override {
79 frame_cb_.Run(format);
80 }
81 // Virtual methods for capturing using Client's Buffers.
82 std::unique_ptr<Buffer> ReserveOutputBuffer(
83 const gfx::Size& dimensions,
84 media::VideoPixelFormat format,
85 media::VideoPixelStorage storage) {
86 EXPECT_TRUE((format == media::PIXEL_FORMAT_ARGB &&
87 storage == media::PIXEL_STORAGE_CPU) ||
88 (format == media::PIXEL_FORMAT_I420 &&
89 storage == media::PIXEL_STORAGE_GPUMEMORYBUFFER));
90 EXPECT_GT(dimensions.GetArea(), 0);
91 const VideoCaptureFormat frame_format(dimensions, 0.0, format);
92 return base::WrapUnique(
93 new MockBuffer(0, frame_format.ImageAllocationSize()));
94 }
95 void OnIncomingCapturedBuffer(std::unique_ptr<Buffer> buffer,
96 const VideoCaptureFormat& frame_format,
97 base::TimeTicks reference_time,
98 base::TimeDelta timestamp) {
99 frame_cb_.Run(frame_format);
100 }
101 void OnIncomingCapturedVideoFrame(
102 std::unique_ptr<Buffer> buffer,
103 const scoped_refptr<media::VideoFrame>& frame) {
104 VideoCaptureFormat format(frame->natural_size(), 30.0,
105 PIXEL_FORMAT_I420);
106 frame_cb_.Run(format);
107 }
108 std::unique_ptr<Buffer> ResurrectLastOutputBuffer(
109 const gfx::Size& dimensions,
110 media::VideoPixelFormat format,
111 media::VideoPixelStorage storage) {
112 return std::unique_ptr<Buffer>();
113 }
114 double GetBufferPoolUtilization() const override { return 0.0; }
115
116 private:
117 base::Callback<void(const VideoCaptureFormat&)> frame_cb_;
118 };
119
120 class DeviceEnumerationListener
121 : public base::RefCounted<DeviceEnumerationListener> {
122 public:
123 MOCK_METHOD1(OnEnumeratedDevicesCallbackPtr,
124 void(VideoCaptureDeviceDescriptors* descriptors));
125 // GMock doesn't support move-only arguments, so we use this forward method.
126 void OnEnumeratedDevicesCallback(
127 std::unique_ptr<VideoCaptureDeviceDescriptors> descriptors) {
128 OnEnumeratedDevicesCallbackPtr(descriptors.release());
129 }
130
131 private:
132 friend class base::RefCounted<DeviceEnumerationListener>;
133 virtual ~DeviceEnumerationListener() {}
134 };
135
136 class ImageCaptureClient : public base::RefCounted<ImageCaptureClient> {
137 public:
138 // GMock doesn't support move-only arguments, so we use this forward method.
139 void DoOnGetPhotoCapabilities(mojom::PhotoCapabilitiesPtr capabilities) {
140 capabilities_ = std::move(capabilities);
141 OnCorrectGetPhotoCapabilities();
142 }
143 MOCK_METHOD0(OnCorrectGetPhotoCapabilities, void(void));
144 MOCK_METHOD1(OnGetPhotoCapabilitiesFailure,
145 void(const base::Callback<void(mojom::PhotoCapabilitiesPtr)>&));
146
147 const mojom::PhotoCapabilities* capabilities() { return capabilities_.get(); }
148
149 MOCK_METHOD1(OnCorrectSetPhotoOptions, void(bool));
150 MOCK_METHOD1(OnSetPhotoOptionsFailure,
151 void(const base::Callback<void(bool)>&));
152
153 // GMock doesn't support move-only arguments, so we use this forward method.
154 void DoOnPhotoTaken(mojom::BlobPtr blob) {
155 // Only PNG images are supported right now.
156 EXPECT_STREQ("image/png", blob->mime_type.c_str());
157 // Not worth decoding the incoming data. Just check that the header is PNG.
158 // http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-file-sign ature
159 ASSERT_GT(blob->data.size(), 4u);
160 EXPECT_EQ('P', blob->data[1]);
161 EXPECT_EQ('N', blob->data[2]);
162 EXPECT_EQ('G', blob->data[3]);
163 OnCorrectPhotoTaken();
164 }
165 MOCK_METHOD0(OnCorrectPhotoTaken, void(void));
166 MOCK_METHOD1(OnTakePhotoFailure,
167 void(const base::Callback<void(mojom::BlobPtr)>&));
168
169 private:
170 friend class base::RefCounted<ImageCaptureClient>;
171 virtual ~ImageCaptureClient() {}
172
173 mojom::PhotoCapabilitiesPtr capabilities_;
174 };
175
176 } // namespace
177
178 class FakeVideoCaptureDeviceBase : public ::testing::Test {
179 protected:
180 FakeVideoCaptureDeviceBase()
181 : loop_(new base::MessageLoop()),
182 client_(new MockClient(
183 base::Bind(&FakeVideoCaptureDeviceBase::OnFrameCaptured,
184 base::Unretained(this)))),
185 device_enumeration_listener_(new DeviceEnumerationListener()),
186 image_capture_client_(new ImageCaptureClient()),
187 video_capture_device_factory_(new FakeVideoCaptureDeviceFactory()) {}
188
189 void SetUp() override { EXPECT_CALL(*client_, OnError(_, _)).Times(0); }
190
191 void OnFrameCaptured(const VideoCaptureFormat& format) {
192 last_format_ = format;
193 run_loop_->QuitClosure().Run();
194 }
195
196 void WaitForCapturedFrame() {
197 run_loop_.reset(new base::RunLoop());
198 run_loop_->Run();
199 }
200
201 std::unique_ptr<VideoCaptureDeviceDescriptors> EnumerateDevices() {
202 VideoCaptureDeviceDescriptors* descriptors;
203 EXPECT_CALL(*device_enumeration_listener_.get(),
204 OnEnumeratedDevicesCallbackPtr(_))
205 .WillOnce(SaveArg<0>(&descriptors));
206
207 video_capture_device_factory_->EnumerateDeviceDescriptors(
208 base::Bind(&DeviceEnumerationListener::OnEnumeratedDevicesCallback,
209 device_enumeration_listener_));
210 base::RunLoop().RunUntilIdle();
211 return std::unique_ptr<VideoCaptureDeviceDescriptors>(descriptors);
212 }
213
214 const VideoCaptureFormat& last_format() const { return last_format_; }
215
216 VideoCaptureDeviceDescriptors descriptors_;
217 const std::unique_ptr<base::MessageLoop> loop_;
218 std::unique_ptr<base::RunLoop> run_loop_;
219 std::unique_ptr<MockClient> client_;
220 const scoped_refptr<DeviceEnumerationListener> device_enumeration_listener_;
221 const scoped_refptr<ImageCaptureClient> image_capture_client_;
222 VideoCaptureFormat last_format_;
223 const std::unique_ptr<VideoCaptureDeviceFactory>
224 video_capture_device_factory_;
225 };
226
227 class FakeVideoCaptureDeviceTest
228 : public FakeVideoCaptureDeviceBase,
229 public ::testing::WithParamInterface<
230 ::testing::tuple<FakeVideoCaptureDevice::BufferOwnership, float>> {};
231
232 struct CommandLineTestData {
233 // Command line argument
234 std::string argument;
235 // Expected values
236 float fps;
237 };
238
239 class FakeVideoCaptureDeviceCommandLineTest
240 : public FakeVideoCaptureDeviceBase,
241 public ::testing::WithParamInterface<CommandLineTestData> {};
242
243 TEST_P(FakeVideoCaptureDeviceTest, CaptureUsing) {
244 const std::unique_ptr<VideoCaptureDeviceDescriptors> descriptors(
245 EnumerateDevices());
246 ASSERT_FALSE(descriptors->empty());
247
248 std::unique_ptr<VideoCaptureDevice> device(new FakeVideoCaptureDevice(
249 testing::get<0>(GetParam()), testing::get<1>(GetParam())));
250 ASSERT_TRUE(device);
251
252 VideoCaptureParams capture_params;
253 capture_params.requested_format.frame_size.SetSize(640, 480);
254 capture_params.requested_format.frame_rate = testing::get<1>(GetParam());
255 device->AllocateAndStart(capture_params, std::move(client_));
256
257 WaitForCapturedFrame();
258 EXPECT_EQ(last_format().frame_size.width(), 640);
259 EXPECT_EQ(last_format().frame_size.height(), 480);
260 EXPECT_EQ(last_format().frame_rate, testing::get<1>(GetParam()));
261 device->StopAndDeAllocate();
262 }
263
264 INSTANTIATE_TEST_CASE_P(
265 ,
266 FakeVideoCaptureDeviceTest,
267 Combine(Values(FakeVideoCaptureDevice::BufferOwnership::OWN_BUFFERS,
268 FakeVideoCaptureDevice::BufferOwnership::CLIENT_BUFFERS),
269 Values(20, 29.97, 30, 50, 60)));
270
271 TEST_F(FakeVideoCaptureDeviceTest, GetDeviceSupportedFormats) {
272 std::unique_ptr<VideoCaptureDeviceDescriptors> descriptors(
273 EnumerateDevices());
274
275 for (const auto& descriptors_iterator : *descriptors) {
276 VideoCaptureFormats supported_formats;
277 video_capture_device_factory_->GetSupportedFormats(descriptors_iterator,
278 &supported_formats);
279 ASSERT_EQ(supported_formats.size(), 4u);
280 EXPECT_EQ(supported_formats[0].frame_size.width(), 320);
281 EXPECT_EQ(supported_formats[0].frame_size.height(), 240);
282 EXPECT_EQ(supported_formats[0].pixel_format, PIXEL_FORMAT_I420);
283 EXPECT_GE(supported_formats[0].frame_rate, 20.0);
284 EXPECT_EQ(supported_formats[1].frame_size.width(), 640);
285 EXPECT_EQ(supported_formats[1].frame_size.height(), 480);
286 EXPECT_EQ(supported_formats[1].pixel_format, PIXEL_FORMAT_I420);
287 EXPECT_GE(supported_formats[1].frame_rate, 20.0);
288 EXPECT_EQ(supported_formats[2].frame_size.width(), 1280);
289 EXPECT_EQ(supported_formats[2].frame_size.height(), 720);
290 EXPECT_EQ(supported_formats[2].pixel_format, PIXEL_FORMAT_I420);
291 EXPECT_GE(supported_formats[2].frame_rate, 20.0);
292 EXPECT_EQ(supported_formats[3].frame_size.width(), 1920);
293 EXPECT_EQ(supported_formats[3].frame_size.height(), 1080);
294 EXPECT_EQ(supported_formats[3].pixel_format, PIXEL_FORMAT_I420);
295 EXPECT_GE(supported_formats[3].frame_rate, 20.0);
296 }
297 }
298
299 TEST_F(FakeVideoCaptureDeviceTest, GetAndSetCapabilities) {
300 std::unique_ptr<VideoCaptureDevice> device(new FakeVideoCaptureDevice(
301 FakeVideoCaptureDevice::BufferOwnership::OWN_BUFFERS, 30.0));
302 ASSERT_TRUE(device);
303
304 VideoCaptureParams capture_params;
305 capture_params.requested_format.frame_size.SetSize(640, 480);
306 capture_params.requested_format.frame_rate = 30.0;
307 device->AllocateAndStart(capture_params, std::move(client_));
308
309 VideoCaptureDevice::GetPhotoCapabilitiesCallback scoped_get_callback(
310 base::Bind(&ImageCaptureClient::DoOnGetPhotoCapabilities,
311 image_capture_client_),
312 base::Bind(&ImageCaptureClient::OnGetPhotoCapabilitiesFailure,
313 image_capture_client_));
314
315 EXPECT_CALL(*image_capture_client_.get(), OnCorrectGetPhotoCapabilities())
316 .Times(1);
317 device->GetPhotoCapabilities(std::move(scoped_get_callback));
318 run_loop_.reset(new base::RunLoop());
319 run_loop_->Run();
320
321 auto* capabilities = image_capture_client_->capabilities();
322 ASSERT_TRUE(capabilities);
323 EXPECT_EQ(100u, capabilities->iso->min);
324 EXPECT_EQ(100u, capabilities->iso->max);
325 EXPECT_EQ(100u, capabilities->iso->current);
326 EXPECT_EQ(capture_params.requested_format.frame_size.height(),
327 static_cast<int>(capabilities->height->current));
328 EXPECT_EQ(240u, capabilities->height->min);
329 EXPECT_EQ(1080u, capabilities->height->max);
330 EXPECT_EQ(capture_params.requested_format.frame_size.width(),
331 static_cast<int>(capabilities->width->current));
332 EXPECT_EQ(320u, capabilities->width->min);
333 EXPECT_EQ(1920u, capabilities->width->max);
334 EXPECT_EQ(100u, capabilities->zoom->min);
335 EXPECT_EQ(400u, capabilities->zoom->max);
336 EXPECT_GE(capabilities->zoom->current, capabilities->zoom->min);
337 EXPECT_GE(capabilities->zoom->max, capabilities->zoom->current);
338 EXPECT_EQ(mojom::FocusMode::UNAVAILABLE, capabilities->focus_mode);
339
340 // Set options: zoom to the maximum value.
341 const unsigned int max_zoom_value = capabilities->zoom->max;
342 VideoCaptureDevice::SetPhotoOptionsCallback scoped_set_callback(
343 base::Bind(&ImageCaptureClient::OnCorrectSetPhotoOptions,
344 image_capture_client_),
345 base::Bind(&ImageCaptureClient::OnSetPhotoOptionsFailure,
346 image_capture_client_));
347
348 mojom::PhotoSettingsPtr settings = mojom::PhotoSettings::New();
349 settings->zoom = max_zoom_value;
350 settings->has_zoom = true;
351
352 EXPECT_CALL(*image_capture_client_.get(), OnCorrectSetPhotoOptions(true))
353 .Times(1);
354 device->SetPhotoOptions(std::move(settings), std::move(scoped_set_callback));
355 run_loop_.reset(new base::RunLoop());
356 run_loop_->Run();
357
358 // Retrieve Capabilities again and check against the set values.
359 VideoCaptureDevice::GetPhotoCapabilitiesCallback scoped_get_callback2(
360 base::Bind(&ImageCaptureClient::DoOnGetPhotoCapabilities,
361 image_capture_client_),
362 base::Bind(&ImageCaptureClient::OnGetPhotoCapabilitiesFailure,
363 image_capture_client_));
364
365 EXPECT_CALL(*image_capture_client_.get(), OnCorrectGetPhotoCapabilities())
366 .Times(1);
367 device->GetPhotoCapabilities(std::move(scoped_get_callback2));
368 run_loop_.reset(new base::RunLoop());
369 run_loop_->Run();
370 EXPECT_EQ(max_zoom_value,
371 image_capture_client_->capabilities()->zoom->current);
372
373 device->StopAndDeAllocate();
374 }
375
376 TEST_F(FakeVideoCaptureDeviceTest, TakePhoto) {
377 std::unique_ptr<VideoCaptureDevice> device(new FakeVideoCaptureDevice(
378 FakeVideoCaptureDevice::BufferOwnership::OWN_BUFFERS, 30.0));
379 ASSERT_TRUE(device);
380
381 VideoCaptureParams capture_params;
382 capture_params.requested_format.frame_size.SetSize(640, 480);
383 capture_params.requested_format.frame_rate = 30.0;
384 device->AllocateAndStart(capture_params, std::move(client_));
385
386 VideoCaptureDevice::TakePhotoCallback scoped_callback(
387 base::Bind(&ImageCaptureClient::DoOnPhotoTaken, image_capture_client_),
388 base::Bind(&ImageCaptureClient::OnTakePhotoFailure,
389 image_capture_client_));
390
391 EXPECT_CALL(*image_capture_client_.get(), OnCorrectPhotoTaken()).Times(1);
392 device->TakePhoto(std::move(scoped_callback));
393
394 run_loop_.reset(new base::RunLoop());
395 run_loop_->Run();
396 device->StopAndDeAllocate();
397 }
398
399 TEST_P(FakeVideoCaptureDeviceCommandLineTest, FrameRate) {
400 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
401 switches::kUseFakeDeviceForMediaStream, GetParam().argument);
402 const std::unique_ptr<VideoCaptureDeviceDescriptors> descriptors(
403 EnumerateDevices());
404 ASSERT_FALSE(descriptors->empty());
405
406 for (const auto& descriptors_iterator : *descriptors) {
407 std::unique_ptr<VideoCaptureDevice> device =
408 video_capture_device_factory_->CreateDevice(descriptors_iterator);
409 ASSERT_TRUE(device);
410
411 VideoCaptureParams capture_params;
412 capture_params.requested_format.frame_size.SetSize(1280, 720);
413 capture_params.requested_format.frame_rate = GetParam().fps;
414 device->AllocateAndStart(capture_params, std::move(client_));
415
416 WaitForCapturedFrame();
417 EXPECT_EQ(last_format().frame_size.width(), 1280);
418 EXPECT_EQ(last_format().frame_size.height(), 720);
419 EXPECT_EQ(last_format().frame_rate, GetParam().fps);
420 device->StopAndDeAllocate();
421 }
422 }
423
424 INSTANTIATE_TEST_CASE_P(,
425 FakeVideoCaptureDeviceCommandLineTest,
426 Values(CommandLineTestData{"fps=-1", 5},
427 CommandLineTestData{"fps=29.97", 29.97f},
428 CommandLineTestData{"fps=60", 60},
429 CommandLineTestData{"fps=1000", 60}));
430 }; // namespace media
OLDNEW
« no previous file with comments | « media/capture/video/fake_video_capture_device_factory.cc ('k') | media/capture/video/file_video_capture_device.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698