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.
4
5#include "base/memory/shared_memory.h"
6#include "content/common/media/video_capture_messages.h"
7#include "content/renderer/media/video_capture_message_filter.h"
8#include "ipc/ipc_test_sink.h"
9#include "media/video/capture/video_capture_types.h"
10#include "testing/gmock/include/gmock/gmock.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13using ::testing::_;
14using ::testing::AnyNumber;
15using ::testing::Mock;
16using ::testing::Return;
17using ::testing::SaveArg;
18using ::testing::StrictMock;
19
20namespace content {
21namespace {
22
23class MockVideoCaptureDelegate : public VideoCaptureMessageFilter::Delegate {
24 public:
25  MockVideoCaptureDelegate() : device_id_(0) {}
26
27  // VideoCaptureMessageFilter::Delegate implementation.
28  MOCK_METHOD3(OnBufferCreated, void(base::SharedMemoryHandle handle,
29                                     int length,
30                                     int buffer_id));
31  MOCK_METHOD1(OnBufferDestroyed, void(int buffer_id));
32  MOCK_METHOD4(OnBufferReceived,
33               void(int buffer_id,
34                    const media::VideoCaptureFormat& format,
35                    const gfx::Rect& visible_rect,
36                    base::TimeTicks timestamp));
37  MOCK_METHOD4(OnMailboxBufferReceived,
38               void(int buffer_id,
39                    const gpu::MailboxHolder& mailbox_holder,
40                    const media::VideoCaptureFormat& format,
41                    base::TimeTicks timestamp));
42  MOCK_METHOD1(OnStateChanged, void(VideoCaptureState state));
43  MOCK_METHOD1(OnDeviceSupportedFormatsEnumerated,
44               void(const media::VideoCaptureFormats& formats));
45  MOCK_METHOD1(OnDeviceFormatsInUseReceived,
46               void(const media::VideoCaptureFormats& formats_in_use));
47
48  virtual void OnDelegateAdded(int32 device_id) OVERRIDE {
49    ASSERT_TRUE(device_id != 0);
50    ASSERT_TRUE(device_id_ == 0);
51    device_id_ = device_id;
52  }
53
54  int device_id() { return device_id_; }
55
56 private:
57  int device_id_;
58};
59
60}  // namespace
61
62TEST(VideoCaptureMessageFilterTest, Basic) {
63  scoped_refptr<VideoCaptureMessageFilter> filter(
64      new VideoCaptureMessageFilter());
65
66  IPC::TestSink channel;
67  filter->OnFilterAdded(&channel);
68  MockVideoCaptureDelegate delegate;
69  filter->AddDelegate(&delegate);
70  ASSERT_EQ(1, delegate.device_id());
71
72  // VideoCaptureMsg_StateChanged
73  EXPECT_CALL(delegate, OnStateChanged(VIDEO_CAPTURE_STATE_STARTED));
74  filter->OnMessageReceived(
75      VideoCaptureMsg_StateChanged(delegate.device_id(),
76                                   VIDEO_CAPTURE_STATE_STARTED));
77  Mock::VerifyAndClearExpectations(&delegate);
78
79  // VideoCaptureMsg_NewBuffer
80  const base::SharedMemoryHandle handle =
81#if defined(OS_WIN)
82      reinterpret_cast<base::SharedMemoryHandle>(10);
83#else
84      base::SharedMemoryHandle(10, true);
85#endif
86  EXPECT_CALL(delegate, OnBufferCreated(handle, 100, 1));
87  filter->OnMessageReceived(VideoCaptureMsg_NewBuffer(
88      delegate.device_id(), handle, 100, 1));
89  Mock::VerifyAndClearExpectations(&delegate);
90
91  // VideoCaptureMsg_BufferReady
92  int buffer_id = 22;
93  base::TimeTicks timestamp = base::TimeTicks::FromInternalValue(1);
94
95  const media::VideoCaptureFormat shm_format(
96      gfx::Size(234, 512), 30, media::PIXEL_FORMAT_I420);
97  media::VideoCaptureFormat saved_format;
98  EXPECT_CALL(delegate, OnBufferReceived(buffer_id, _, _, timestamp))
99      .WillRepeatedly(SaveArg<1>(&saved_format));
100  filter->OnMessageReceived(VideoCaptureMsg_BufferReady(
101      delegate.device_id(), buffer_id, shm_format, gfx::Rect(234, 512),
102      timestamp));
103  Mock::VerifyAndClearExpectations(&delegate);
104  EXPECT_EQ(shm_format.frame_size, saved_format.frame_size);
105  EXPECT_EQ(shm_format.frame_rate, saved_format.frame_rate);
106  EXPECT_EQ(shm_format.pixel_format, saved_format.pixel_format);
107
108  // VideoCaptureMsg_MailboxBufferReady
109  buffer_id = 33;
110  timestamp = base::TimeTicks::FromInternalValue(2);
111
112  const media::VideoCaptureFormat mailbox_format(
113      gfx::Size(234, 512), 30, media::PIXEL_FORMAT_TEXTURE);
114  gpu::Mailbox mailbox;
115  const int8 mailbox_name[arraysize(mailbox.name)] = "TEST MAILBOX";
116  mailbox.SetName(mailbox_name);
117  unsigned int syncpoint = 44;
118  gpu::MailboxHolder saved_mailbox_holder;
119  EXPECT_CALL(delegate, OnMailboxBufferReceived(buffer_id, _, _, timestamp))
120      .WillRepeatedly(
121           DoAll(SaveArg<1>(&saved_mailbox_holder), SaveArg<2>(&saved_format)));
122  gpu::MailboxHolder mailbox_holder(mailbox, 0, syncpoint);
123  filter->OnMessageReceived(
124      VideoCaptureMsg_MailboxBufferReady(delegate.device_id(),
125                                         buffer_id,
126                                         mailbox_holder,
127                                         mailbox_format,
128                                         timestamp));
129  Mock::VerifyAndClearExpectations(&delegate);
130  EXPECT_EQ(mailbox_format.frame_size, saved_format.frame_size);
131  EXPECT_EQ(mailbox_format.frame_rate, saved_format.frame_rate);
132  EXPECT_EQ(mailbox_format.pixel_format, saved_format.pixel_format);
133  EXPECT_EQ(memcmp(mailbox.name,
134                   saved_mailbox_holder.mailbox.name,
135                   sizeof(mailbox.name)),
136            0);
137
138  // VideoCaptureMsg_FreeBuffer
139  EXPECT_CALL(delegate, OnBufferDestroyed(buffer_id));
140  filter->OnMessageReceived(VideoCaptureMsg_FreeBuffer(
141      delegate.device_id(), buffer_id));
142  Mock::VerifyAndClearExpectations(&delegate);
143}
144
145TEST(VideoCaptureMessageFilterTest, Delegates) {
146  scoped_refptr<VideoCaptureMessageFilter> filter(
147      new VideoCaptureMessageFilter());
148
149  IPC::TestSink channel;
150  filter->OnFilterAdded(&channel);
151
152  StrictMock<MockVideoCaptureDelegate> delegate1;
153  StrictMock<MockVideoCaptureDelegate> delegate2;
154
155  filter->AddDelegate(&delegate1);
156  filter->AddDelegate(&delegate2);
157  ASSERT_EQ(1, delegate1.device_id());
158  ASSERT_EQ(2, delegate2.device_id());
159
160  // Send an IPC message. Make sure the correct delegate gets called.
161  EXPECT_CALL(delegate1, OnStateChanged(VIDEO_CAPTURE_STATE_STARTED));
162  filter->OnMessageReceived(
163      VideoCaptureMsg_StateChanged(delegate1.device_id(),
164                                   VIDEO_CAPTURE_STATE_STARTED));
165  Mock::VerifyAndClearExpectations(&delegate1);
166
167  EXPECT_CALL(delegate2, OnStateChanged(VIDEO_CAPTURE_STATE_STARTED));
168  filter->OnMessageReceived(
169      VideoCaptureMsg_StateChanged(delegate2.device_id(),
170                                   VIDEO_CAPTURE_STATE_STARTED));
171  Mock::VerifyAndClearExpectations(&delegate2);
172
173  // Remove the delegates. Make sure they won't get called.
174  filter->RemoveDelegate(&delegate1);
175  filter->OnMessageReceived(
176      VideoCaptureMsg_StateChanged(delegate1.device_id(),
177                                   VIDEO_CAPTURE_STATE_ENDED));
178
179  filter->RemoveDelegate(&delegate2);
180  filter->OnMessageReceived(
181      VideoCaptureMsg_StateChanged(delegate2.device_id(),
182                                   VIDEO_CAPTURE_STATE_ENDED));
183}
184
185TEST(VideoCaptureMessageFilterTest, GetSomeDeviceSupportedFormats) {
186  scoped_refptr<VideoCaptureMessageFilter> filter(
187      new VideoCaptureMessageFilter());
188
189  IPC::TestSink channel;
190  filter->OnFilterAdded(&channel);
191  MockVideoCaptureDelegate delegate;
192  filter->AddDelegate(&delegate);
193  ASSERT_EQ(1, delegate.device_id());
194
195  EXPECT_CALL(delegate, OnDeviceSupportedFormatsEnumerated(_));
196  media::VideoCaptureFormats supported_formats;
197  filter->OnMessageReceived(VideoCaptureMsg_DeviceSupportedFormatsEnumerated(
198      delegate.device_id(), supported_formats));
199}
200
201TEST(VideoCaptureMessageFilterTest, GetSomeDeviceFormatInUse) {
202  scoped_refptr<VideoCaptureMessageFilter> filter(
203      new VideoCaptureMessageFilter());
204
205  IPC::TestSink channel;
206  filter->OnFilterAdded(&channel);
207  MockVideoCaptureDelegate delegate;
208  filter->AddDelegate(&delegate);
209  ASSERT_EQ(1, delegate.device_id());
210
211  EXPECT_CALL(delegate, OnDeviceFormatsInUseReceived(_));
212  media::VideoCaptureFormats formats_in_use;
213  filter->OnMessageReceived(VideoCaptureMsg_DeviceFormatsInUseReceived(
214      delegate.device_id(), formats_in_use));
215}
216}  // namespace content
217