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.
5 #include "content/browser/renderer_host/media/screen_capture_device.h"
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.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"
20 using ::testing::DoAll
;
21 using ::testing::InvokeWithoutArgs
;
22 using ::testing::SaveArg
;
28 const int kTestFrameWidth1
= 100;
29 const int kTestFrameHeight1
= 100;
30 const int kTestFrameWidth2
= 200;
31 const int kTestFrameHeight2
= 150;
32 const int kBufferSize
= kTestFrameWidth2
* kTestFrameHeight2
* 4;
34 const int kFrameRate
= 30;
36 class MockFrameObserver
: public media::VideoCaptureDevice::EventHandler
{
38 MOCK_METHOD0(ReserveOutputBuffer
, scoped_refptr
<media::VideoFrame
>());
39 MOCK_METHOD0(OnError
, void());
40 MOCK_METHOD1(OnFrameInfo
, void(const media::VideoCaptureCapability
& info
));
41 MOCK_METHOD6(OnIncomingCapturedFrame
, void(const uint8
* data
,
47 MOCK_METHOD2(OnIncomingCapturedVideoFrame
,
48 void(const scoped_refptr
<media::VideoFrame
>& frame
,
49 base::Time timestamp
));
52 // TODO(sergeyu): Move this to a separate file where it can be reused.
53 class FakeScreenCapturer
: public webrtc::ScreenCapturer
{
59 virtual ~FakeScreenCapturer() {}
61 // VideoFrameCapturer interface.
62 virtual void Start(Callback
* callback
) OVERRIDE
{
66 virtual void Capture(const webrtc::DesktopRegion
& region
) OVERRIDE
{
67 webrtc::DesktopSize size
;
68 if (frame_index_
% 2 == 0) {
69 size
= webrtc::DesktopSize(kTestFrameWidth1
, kTestFrameHeight1
);
71 size
= webrtc::DesktopSize(kTestFrameWidth2
, kTestFrameHeight2
);
74 callback_
->OnCaptureCompleted(new webrtc::BasicDesktopFrame(size
));
77 virtual void SetMouseShapeObserver(
78 MouseShapeObserver
* mouse_shape_observer
) OVERRIDE
{
86 class ScreenCaptureDeviceTest
: public testing::Test
{
88 virtual void SetUp() OVERRIDE
{
89 worker_pool_
= new base::SequencedWorkerPool(3, "TestCaptureThread");
93 scoped_refptr
<base::SequencedWorkerPool
> worker_pool_
;
98 TEST_F(ScreenCaptureDeviceTest
, Capture
) {
99 ScreenCaptureDevice
capture_device(
100 worker_pool_
->GetSequencedTaskRunner(worker_pool_
->GetSequenceToken()));
101 media::VideoCaptureCapability caps
;
102 base::WaitableEvent
done_event(false, false);
105 MockFrameObserver frame_observer
;
106 EXPECT_CALL(frame_observer
, OnFrameInfo(_
))
107 .WillOnce(SaveArg
<0>(&caps
));
108 EXPECT_CALL(frame_observer
, OnError())
110 EXPECT_CALL(frame_observer
, OnIncomingCapturedFrame(_
, _
, _
, _
, _
, _
))
111 .WillRepeatedly(DoAll(
112 SaveArg
<1>(&frame_size
),
113 InvokeWithoutArgs(&done_event
, &base::WaitableEvent::Signal
)));
115 capture_device
.Allocate(640, 480, kFrameRate
, &frame_observer
);
116 capture_device
.Start();
117 EXPECT_TRUE(done_event
.TimedWait(TestTimeouts::action_max_timeout()));
118 capture_device
.Stop();
119 capture_device
.DeAllocate();
121 EXPECT_GT(caps
.width
, 0);
122 EXPECT_GT(caps
.height
, 0);
123 EXPECT_EQ(kFrameRate
, caps
.frame_rate
);
124 EXPECT_EQ(media::VideoCaptureCapability::kARGB
, caps
.color
);
125 EXPECT_FALSE(caps
.interlaced
);
127 EXPECT_EQ(caps
.width
* caps
.height
* 4, frame_size
);
130 // Test that screen capturer can handle resolution change without crashing.
131 TEST_F(ScreenCaptureDeviceTest
, ScreenResolutionChange
) {
132 FakeScreenCapturer
* mock_capturer
= new FakeScreenCapturer();
134 ScreenCaptureDevice
capture_device(
135 worker_pool_
->GetSequencedTaskRunner(worker_pool_
->GetSequenceToken()));
136 capture_device
.SetScreenCapturerForTest(
137 scoped_ptr
<webrtc::ScreenCapturer
>(mock_capturer
));
139 media::VideoCaptureCapability caps
;
140 base::WaitableEvent
done_event(false, false);
143 MockFrameObserver frame_observer
;
144 EXPECT_CALL(frame_observer
, OnFrameInfo(_
))
145 .WillOnce(SaveArg
<0>(&caps
));
146 EXPECT_CALL(frame_observer
, OnError())
148 EXPECT_CALL(frame_observer
, OnIncomingCapturedFrame(_
, _
, _
, _
, _
, _
))
149 .WillRepeatedly(DoAll(
150 SaveArg
<1>(&frame_size
),
151 InvokeWithoutArgs(&done_event
, &base::WaitableEvent::Signal
)));
153 capture_device
.Allocate(kTestFrameWidth1
, kTestFrameHeight1
,
154 kFrameRate
, &frame_observer
);
155 capture_device
.Start();
156 // Capture first frame.
157 EXPECT_TRUE(done_event
.TimedWait(TestTimeouts::action_max_timeout()));
159 // Capture second frame.
160 EXPECT_TRUE(done_event
.TimedWait(TestTimeouts::action_max_timeout()));
161 capture_device
.Stop();
162 capture_device
.DeAllocate();
164 EXPECT_EQ(kTestFrameWidth1
, caps
.width
);
165 EXPECT_EQ(kTestFrameHeight1
, caps
.height
);
166 EXPECT_EQ(kFrameRate
, caps
.frame_rate
);
167 EXPECT_EQ(media::VideoCaptureCapability::kARGB
, caps
.color
);
168 EXPECT_FALSE(caps
.interlaced
);
170 EXPECT_EQ(caps
.width
* caps
.height
* 4, frame_size
);
173 } // namespace content