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

Side by Side Diff: content/browser/renderer_host/media/desktop_capture_device_unittest.cc

Issue 172003004: Fixit: Move tab and desktop capture code to new location. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 "content/browser/renderer_host/media/desktop_capture_device.h"
6
7 #include "base/basictypes.h"
8 #include "base/sequenced_task_runner.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "base/test/test_timeouts.h"
11 #include "base/threading/sequenced_worker_pool.h"
12 #include "base/time/time.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
16 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
17 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
18
19 using ::testing::_;
20 using ::testing::AnyNumber;
21 using ::testing::DoAll;
22 using ::testing::Expectation;
23 using ::testing::InvokeWithoutArgs;
24 using ::testing::SaveArg;
25
26 namespace content {
27
28 namespace {
29
30 MATCHER_P2(EqualsCaptureCapability, width, height, "") {
31 return arg.width == width && arg.height == height;
32 }
33
34 const int kTestFrameWidth1 = 100;
35 const int kTestFrameHeight1 = 100;
36 const int kTestFrameWidth2 = 200;
37 const int kTestFrameHeight2 = 150;
38
39 const int kFrameRate = 30;
40
41 class MockDeviceClient : public media::VideoCaptureDevice::Client {
42 public:
43 MOCK_METHOD2(ReserveOutputBuffer,
44 scoped_refptr<Buffer>(media::VideoFrame::Format format,
45 const gfx::Size& dimensions));
46 MOCK_METHOD1(OnError, void(const std::string& reason));
47 MOCK_METHOD5(OnIncomingCapturedFrame,
48 void(const uint8* data,
49 int length,
50 base::TimeTicks timestamp,
51 int rotation,
52 const media::VideoCaptureFormat& frame_format));
53 MOCK_METHOD5(OnIncomingCapturedBuffer,
54 void(const scoped_refptr<Buffer>& buffer,
55 media::VideoFrame::Format format,
56 const gfx::Size& dimensions,
57 base::TimeTicks timestamp,
58 int frame_rate));
59 };
60
61 // DesktopFrame wrapper that flips wrapped frame upside down by inverting
62 // stride.
63 class InvertedDesktopFrame : public webrtc::DesktopFrame {
64 public:
65 // Takes ownership of |frame|.
66 InvertedDesktopFrame(webrtc::DesktopFrame* frame)
67 : webrtc::DesktopFrame(
68 frame->size(), -frame->stride(),
69 frame->data() + (frame->size().height() - 1) * frame->stride(),
70 frame->shared_memory()),
71 original_frame_(frame) {
72 set_dpi(frame->dpi());
73 set_capture_time_ms(frame->capture_time_ms());
74 mutable_updated_region()->Swap(frame->mutable_updated_region());
75 }
76 virtual ~InvertedDesktopFrame() {}
77
78 private:
79 scoped_ptr<webrtc::DesktopFrame> original_frame_;
80
81 DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame);
82 };
83
84 // TODO(sergeyu): Move this to a separate file where it can be reused.
85 class FakeScreenCapturer : public webrtc::ScreenCapturer {
86 public:
87 FakeScreenCapturer()
88 : callback_(NULL),
89 frame_index_(0),
90 generate_inverted_frames_(false) {
91 }
92 virtual ~FakeScreenCapturer() {}
93
94 void set_generate_inverted_frames(bool generate_inverted_frames) {
95 generate_inverted_frames_ = generate_inverted_frames;
96 }
97
98 // VideoFrameCapturer interface.
99 virtual void Start(Callback* callback) OVERRIDE {
100 callback_ = callback;
101 }
102
103 virtual void Capture(const webrtc::DesktopRegion& region) OVERRIDE {
104 webrtc::DesktopSize size;
105 if (frame_index_ % 2 == 0) {
106 size = webrtc::DesktopSize(kTestFrameWidth1, kTestFrameHeight1);
107 } else {
108 size = webrtc::DesktopSize(kTestFrameWidth2, kTestFrameHeight2);
109 }
110 frame_index_++;
111
112 webrtc::DesktopFrame* frame = new webrtc::BasicDesktopFrame(size);
113 if (generate_inverted_frames_)
114 frame = new InvertedDesktopFrame(frame);
115 callback_->OnCaptureCompleted(frame);
116 }
117
118 virtual void SetMouseShapeObserver(
119 MouseShapeObserver* mouse_shape_observer) OVERRIDE {
120 }
121
122 virtual bool GetScreenList(ScreenList* screens) OVERRIDE {
123 return false;
124 }
125
126 virtual bool SelectScreen(webrtc::ScreenId id) OVERRIDE {
127 return false;
128 }
129
130 private:
131 Callback* callback_;
132 int frame_index_;
133 bool generate_inverted_frames_;
134 };
135
136 class DesktopCaptureDeviceTest : public testing::Test {
137 public:
138 virtual void SetUp() OVERRIDE {
139 worker_pool_ = new base::SequencedWorkerPool(3, "TestCaptureThread");
140 }
141
142 protected:
143 scoped_refptr<base::SequencedWorkerPool> worker_pool_;
144 };
145
146 } // namespace
147
148 // There is currently no screen capturer implementation for ozone. So disable
149 // the test that uses a real screen-capturer instead of FakeScreenCapturer.
150 // http://crbug.com/260318
151 #if defined(USE_OZONE)
152 #define MAYBE_Capture DISABLED_Capture
153 #else
154 #define MAYBE_Capture Capture
155 #endif
156 TEST_F(DesktopCaptureDeviceTest, MAYBE_Capture) {
157 scoped_ptr<webrtc::DesktopCapturer> capturer(
158 webrtc::ScreenCapturer::Create());
159 DesktopCaptureDevice capture_device(
160 worker_pool_->GetSequencedTaskRunner(worker_pool_->GetSequenceToken()),
161 capturer.Pass());
162 media::VideoCaptureFormat format;
163 base::WaitableEvent done_event(false, false);
164 int frame_size;
165
166 scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
167 EXPECT_CALL(*client, OnError(_)).Times(0);
168 EXPECT_CALL(*client, OnIncomingCapturedFrame(_, _, _, _, _))
169 .WillRepeatedly(
170 DoAll(SaveArg<1>(&frame_size),
171 SaveArg<4>(&format),
172 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
173
174 media::VideoCaptureParams capture_params;
175 capture_params.requested_format.frame_size.SetSize(640, 480);
176 capture_params.requested_format.frame_rate = kFrameRate;
177 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
178 capture_params.allow_resolution_change = false;
179 capture_device.AllocateAndStart(
180 capture_params, client.PassAs<media::VideoCaptureDevice::Client>());
181 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
182 capture_device.StopAndDeAllocate();
183
184 EXPECT_GT(format.frame_size.width(), 0);
185 EXPECT_GT(format.frame_size.height(), 0);
186 EXPECT_EQ(kFrameRate, format.frame_rate);
187 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format);
188
189 EXPECT_EQ(format.frame_size.GetArea() * 4, frame_size);
190 worker_pool_->FlushForTesting();
191 }
192
193 // Test that screen capturer behaves correctly if the source frame size changes
194 // but the caller cannot cope with variable resolution output.
195 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeConstantResolution) {
196 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer();
197
198 DesktopCaptureDevice capture_device(
199 worker_pool_->GetSequencedTaskRunner(worker_pool_->GetSequenceToken()),
200 scoped_ptr<webrtc::DesktopCapturer>(mock_capturer));
201
202 media::VideoCaptureFormat format;
203 base::WaitableEvent done_event(false, false);
204 int frame_size;
205
206 scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
207 EXPECT_CALL(*client, OnError(_)).Times(0);
208 EXPECT_CALL(*client, OnIncomingCapturedFrame(_, _, _, _, _))
209 .WillRepeatedly(
210 DoAll(SaveArg<1>(&frame_size),
211 SaveArg<4>(&format),
212 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
213
214 media::VideoCaptureParams capture_params;
215 capture_params.requested_format.frame_size.SetSize(kTestFrameWidth1,
216 kTestFrameHeight1);
217 capture_params.requested_format.frame_rate = kFrameRate;
218 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
219 capture_params.allow_resolution_change = false;
220
221 capture_device.AllocateAndStart(
222 capture_params, client.PassAs<media::VideoCaptureDevice::Client>());
223
224 // Capture at least two frames, to ensure that the source frame size has
225 // changed while capturing.
226 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
227 done_event.Reset();
228 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
229
230 capture_device.StopAndDeAllocate();
231
232 EXPECT_EQ(kTestFrameWidth1, format.frame_size.width());
233 EXPECT_EQ(kTestFrameHeight1, format.frame_size.height());
234 EXPECT_EQ(kFrameRate, format.frame_rate);
235 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format);
236
237 EXPECT_EQ(format.frame_size.GetArea() * 4, frame_size);
238 worker_pool_->FlushForTesting();
239 }
240
241 // Test that screen capturer behaves correctly if the source frame size changes
242 // and the caller can cope with variable resolution output.
243 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeVariableResolution) {
244 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer();
245
246 DesktopCaptureDevice capture_device(
247 worker_pool_->GetSequencedTaskRunner(worker_pool_->GetSequenceToken()),
248 scoped_ptr<webrtc::DesktopCapturer>(mock_capturer));
249
250 media::VideoCaptureFormat format;
251 base::WaitableEvent done_event(false, false);
252
253 scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
254 EXPECT_CALL(*client, OnError(_)).Times(0);
255 EXPECT_CALL(*client, OnIncomingCapturedFrame(_, _, _, _, _))
256 .WillRepeatedly(
257 DoAll(SaveArg<4>(&format),
258 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
259
260 media::VideoCaptureParams capture_params;
261 capture_params.requested_format.frame_size.SetSize(kTestFrameWidth2,
262 kTestFrameHeight2);
263 capture_params.requested_format.frame_rate = kFrameRate;
264 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
265 capture_params.allow_resolution_change = false;
266
267 capture_device.AllocateAndStart(
268 capture_params, client.PassAs<media::VideoCaptureDevice::Client>());
269
270 // Capture at least three frames, to ensure that the source frame size has
271 // changed at least twice while capturing.
272 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
273 done_event.Reset();
274 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
275 done_event.Reset();
276 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
277
278 capture_device.StopAndDeAllocate();
279
280 EXPECT_EQ(kTestFrameWidth1, format.frame_size.width());
281 EXPECT_EQ(kTestFrameHeight1, format.frame_size.height());
282 EXPECT_EQ(kFrameRate, format.frame_rate);
283 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format);
284 worker_pool_->FlushForTesting();
285 }
286
287 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698