Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / content / renderer / media / video_capture_impl_unittest.cc
blob37c2c5055003709bfa63f863bc1b1bb255b0f9e6
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/shared_memory.h"
6 #include "base/message_loop/message_loop.h"
7 #include "content/child/child_process.h"
8 #include "content/common/media/video_capture_messages.h"
9 #include "content/renderer/media/video_capture_impl.h"
10 #include "media/base/bind_to_current_loop.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 using ::testing::_;
15 using ::testing::AtLeast;
16 using ::testing::InvokeWithoutArgs;
17 using ::testing::Return;
18 using ::testing::SaveArg;
20 namespace content {
22 // TODO(ajose): http://crbug.com/522145 Improve and expand these tests.
23 // In particular, exercise VideoCaptureHostMsg_BufferReady.
24 class MockVideoCaptureMessageFilter : public VideoCaptureMessageFilter {
25 public:
26 MockVideoCaptureMessageFilter() : VideoCaptureMessageFilter() {}
28 // Filter implementation.
29 MOCK_METHOD1(Send, bool(IPC::Message* message));
31 protected:
32 virtual ~MockVideoCaptureMessageFilter() {}
34 private:
35 DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureMessageFilter);
38 struct BufferReceivedTestArg {
39 BufferReceivedTestArg(media::VideoPixelFormat pixel_format,
40 const std::vector<gpu::MailboxHolder>& mailbox_holders)
41 : pixel_format(pixel_format), mailbox_holders(mailbox_holders) {}
43 BufferReceivedTestArg(media::VideoPixelFormat pixel_format)
44 : pixel_format(pixel_format) {}
46 media::VideoPixelFormat pixel_format;
47 std::vector<gpu::MailboxHolder> mailbox_holders;
50 static const BufferReceivedTestArg kBufferFormats[] = {
51 BufferReceivedTestArg(media::PIXEL_FORMAT_I420),
52 BufferReceivedTestArg(
53 media::PIXEL_FORMAT_ARGB,
54 std::vector<gpu::MailboxHolder>(
55 1, gpu::MailboxHolder(gpu::Mailbox::Generate(), 0, 0)))};
57 class VideoCaptureImplTest :
58 public ::testing::TestWithParam<BufferReceivedTestArg> {
59 public:
60 class MockVideoCaptureImpl : public VideoCaptureImpl {
61 public:
62 MockVideoCaptureImpl(const media::VideoCaptureSessionId id,
63 VideoCaptureMessageFilter* filter)
64 : VideoCaptureImpl(id, filter), received_buffer_count_(0) {
66 ~MockVideoCaptureImpl() override {}
68 // Override Send() to mimic device to send events.
69 void Send(IPC::Message* message) override {
70 CHECK(message);
72 // In this method, messages are sent to the according handlers as if
73 // we are the device.
74 bool handled = true;
75 IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureImpl, *message)
76 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, DeviceStartCapture)
77 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, DevicePauseCapture)
78 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, DeviceStopCapture)
79 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady,
80 DeviceReceiveEmptyBuffer)
81 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceSupportedFormats,
82 DeviceGetSupportedFormats)
83 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceFormatsInUse,
84 DeviceGetFormatsInUse)
85 IPC_MESSAGE_UNHANDLED(handled = false)
86 IPC_END_MESSAGE_MAP()
87 EXPECT_TRUE(handled);
88 delete message;
91 void DeviceStartCapture(int device_id,
92 media::VideoCaptureSessionId session_id,
93 const media::VideoCaptureParams& params) {
94 // Do not call OnStateChanged(VIDEO_CAPTURE_STATE_STARTED) here, as this
95 // does not accurately reflect the behavior of the VideoCaptureHost.
98 void DevicePauseCapture(int device_id) {}
100 void DeviceStopCapture(int device_id) {
101 OnStateChanged(VIDEO_CAPTURE_STATE_STOPPED);
104 void DeviceReceiveEmptyBuffer(int device_id,
105 int buffer_id,
106 uint32 sync_point,
107 double consumer_resource_utilization) {
108 received_buffer_count_++;
111 void DeviceGetSupportedFormats(int device_id,
112 media::VideoCaptureSessionId session_id) {
113 // When the mock message filter receives a request for the device
114 // supported formats, replies immediately with an empty format list.
115 OnDeviceSupportedFormatsEnumerated(media::VideoCaptureFormats());
118 void DeviceGetFormatsInUse(int device_id,
119 media::VideoCaptureSessionId session_id) {
120 OnDeviceFormatsInUseReceived(media::VideoCaptureFormats());
123 void ReceiveStateChangeMessage(VideoCaptureState state) {
124 OnStateChanged(state);
127 int received_buffer_count() const { return received_buffer_count_; }
129 private:
130 int received_buffer_count_;
133 VideoCaptureImplTest() {
134 params_small_.requested_format = media::VideoCaptureFormat(
135 gfx::Size(176, 144), 30, media::PIXEL_FORMAT_I420);
137 params_large_.requested_format = media::VideoCaptureFormat(
138 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420);
140 child_process_.reset(new ChildProcess());
142 message_filter_ = new MockVideoCaptureMessageFilter;
143 session_id_ = 1;
145 video_capture_impl_.reset(new MockVideoCaptureImpl(
146 session_id_, message_filter_.get()));
148 video_capture_impl_->device_id_ = 2;
151 virtual ~VideoCaptureImplTest() {
154 protected:
155 MOCK_METHOD2(OnFrameReady,
156 void(const scoped_refptr<media::VideoFrame>&, base::TimeTicks));
157 MOCK_METHOD1(OnStateUpdate, void(VideoCaptureState));
158 MOCK_METHOD1(OnDeviceFormatsInUse,
159 void(const media::VideoCaptureFormats&));
160 MOCK_METHOD1(OnDeviceSupportedFormats,
161 void(const media::VideoCaptureFormats&));
163 void Init() {
164 video_capture_impl_->Init();
167 void StartCapture(const media::VideoCaptureParams& params) {
168 video_capture_impl_->StartCapture(
169 params, base::Bind(&VideoCaptureImplTest::OnStateUpdate,
170 base::Unretained(this)),
171 base::Bind(&VideoCaptureImplTest::OnFrameReady,
172 base::Unretained(this)));
175 void StopCapture() { video_capture_impl_->StopCapture(); }
177 void NewBuffer(int buffer_id, const base::SharedMemory& shm) {
178 video_capture_impl_->OnBufferCreated(
179 base::SharedMemory::DuplicateHandle(shm.handle()),
180 shm.mapped_size(), buffer_id);
183 void BufferReceived(int buffer_id, const gfx::Size& size,
184 media::VideoPixelFormat pixel_format,
185 const std::vector<gpu::MailboxHolder>& mailbox_holders) {
186 video_capture_impl_->OnBufferReceived(
187 buffer_id, base::TimeTicks::Now(), base::DictionaryValue(),
188 pixel_format, media::VideoFrame::STORAGE_SHMEM, size,
189 gfx::Rect(size), mailbox_holders);
192 void BufferDestroyed(int buffer_id) {
193 video_capture_impl_->OnBufferDestroyed(buffer_id);
196 void DeInit() {
197 video_capture_impl_->DeInit();
200 void GetDeviceSupportedFormats() {
201 const base::Callback<void(const media::VideoCaptureFormats&)>
202 callback = base::Bind(
203 &VideoCaptureImplTest::OnDeviceSupportedFormats,
204 base::Unretained(this));
205 video_capture_impl_->GetDeviceSupportedFormats(callback);
208 void GetDeviceFormatsInUse() {
209 const base::Callback<void(const media::VideoCaptureFormats&)>
210 callback = base::Bind(
211 &VideoCaptureImplTest::OnDeviceFormatsInUse,
212 base::Unretained(this));
213 video_capture_impl_->GetDeviceFormatsInUse(callback);
216 base::MessageLoop message_loop_;
217 scoped_ptr<ChildProcess> child_process_;
218 scoped_refptr<MockVideoCaptureMessageFilter> message_filter_;
219 media::VideoCaptureSessionId session_id_;
220 scoped_ptr<MockVideoCaptureImpl> video_capture_impl_;
221 media::VideoCaptureParams params_small_;
222 media::VideoCaptureParams params_large_;
224 private:
225 DISALLOW_COPY_AND_ASSIGN(VideoCaptureImplTest);
228 // Execute SetCapture() and StopCapture() for one client.
229 TEST_F(VideoCaptureImplTest, Simple) {
230 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED));
231 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED));
233 Init();
234 StartCapture(params_small_);
235 StopCapture();
236 DeInit();
239 // Check that a request to GetDeviceSupportedFormats() ends up eventually in the
240 // provided callback.
241 TEST_F(VideoCaptureImplTest, GetDeviceFormats) {
242 EXPECT_CALL(*this, OnDeviceSupportedFormats(_));
244 Init();
245 GetDeviceSupportedFormats();
246 DeInit();
249 // Check that two requests to GetDeviceSupportedFormats() end up eventually
250 // calling the provided callbacks.
251 TEST_F(VideoCaptureImplTest, TwoClientsGetDeviceFormats) {
252 EXPECT_CALL(*this, OnDeviceSupportedFormats(_)).Times(2);
254 Init();
255 GetDeviceSupportedFormats();
256 GetDeviceSupportedFormats();
257 DeInit();
260 // Check that a request to GetDeviceFormatsInUse() ends up eventually in the
261 // provided callback.
262 TEST_F(VideoCaptureImplTest, GetDeviceFormatsInUse) {
263 EXPECT_CALL(*this, OnDeviceFormatsInUse(_));
265 Init();
266 GetDeviceFormatsInUse();
267 DeInit();
270 TEST_P(VideoCaptureImplTest, BufferReceivedWithFormat) {
271 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED)).Times(1);
272 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED)).Times(1);
273 EXPECT_CALL(*this, OnFrameReady(_, _)).Times(1);
275 const BufferReceivedTestArg& buffer_arg = GetParam();
276 const gfx::Size size(1280, 720);
278 // Create a fake shared memory for buffer.
279 base::SharedMemory shm;
280 const size_t frame_size = media::VideoFrame::AllocationSize(
281 buffer_arg.pixel_format, size);
282 ASSERT_TRUE(shm.CreateAndMapAnonymous(frame_size));
284 media::VideoCaptureParams params;
285 params.requested_format = media::VideoCaptureFormat(
286 size, 30, buffer_arg.pixel_format);
288 Init();
289 StartCapture(params);
290 NewBuffer(0, shm);
291 BufferReceived(0, size, buffer_arg.pixel_format, buffer_arg.mailbox_holders);
292 StopCapture();
293 BufferDestroyed(0);
294 DeInit();
297 INSTANTIATE_TEST_CASE_P(I420AndARGB,
298 VideoCaptureImplTest,
299 testing::ValuesIn(kBufferFormats));
301 TEST_F(VideoCaptureImplTest, BufferReceivedAfterStop) {
302 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED)).Times(1);
303 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED)).Times(1);
304 EXPECT_CALL(*this, OnFrameReady(_, _)).Times(0);
306 // Create a fake shared memory for buffer.
307 base::SharedMemory shm;
308 const size_t i420_frame_size = media::VideoFrame::AllocationSize(
309 media::PIXEL_FORMAT_I420, params_large_.requested_format.frame_size);
310 ASSERT_TRUE(shm.CreateAndMapAnonymous(i420_frame_size));
312 Init();
313 StartCapture(params_large_);
314 NewBuffer(0, shm);
315 StopCapture();
316 BufferReceived(0, params_large_.requested_format.frame_size,
317 media::PIXEL_FORMAT_I420, std::vector<gpu::MailboxHolder>());
318 BufferDestroyed(0);
319 DeInit();
321 EXPECT_EQ(this->video_capture_impl_->received_buffer_count(), 1);
324 TEST_F(VideoCaptureImplTest, EndedBeforeStop) {
325 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED));
326 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED));
328 Init();
329 StartCapture(params_small_);
331 // Receive state change message from browser.
332 video_capture_impl_->ReceiveStateChangeMessage(VIDEO_CAPTURE_STATE_ENDED);
334 StopCapture();
335 DeInit();
338 TEST_F(VideoCaptureImplTest, ErrorBeforeStop) {
339 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED));
340 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_ERROR));
342 Init();
343 StartCapture(params_small_);
345 // Receive state change message from browser.
346 video_capture_impl_->ReceiveStateChangeMessage(VIDEO_CAPTURE_STATE_ERROR);
348 StopCapture();
349 DeInit();
352 } // namespace content