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

Side by Side Diff: remoting/host/video_frame_pump_unittest.cc

Issue 883673004: Cleanup VideoFramePump. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@rename_scheduler
Patch Set: Created 5 years, 10 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/video_frame_pump.h" 5 #include "remoting/host/video_frame_pump.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
11 #include "remoting/base/auto_thread.h" 11 #include "remoting/base/auto_thread.h"
12 #include "remoting/base/auto_thread_task_runner.h" 12 #include "remoting/base/auto_thread_task_runner.h"
13 #include "remoting/codec/video_encoder.h" 13 #include "remoting/codec/video_encoder.h"
14 #include "remoting/codec/video_encoder_verbatim.h" 14 #include "remoting/codec/video_encoder_verbatim.h"
15 #include "remoting/host/desktop_capturer_proxy.h"
15 #include "remoting/host/fake_desktop_capturer.h" 16 #include "remoting/host/fake_desktop_capturer.h"
16 #include "remoting/host/fake_mouse_cursor_monitor.h"
17 #include "remoting/host/host_mock_objects.h" 17 #include "remoting/host/host_mock_objects.h"
18 #include "remoting/proto/control.pb.h" 18 #include "remoting/proto/control.pb.h"
19 #include "remoting/proto/video.pb.h" 19 #include "remoting/proto/video.pb.h"
20 #include "remoting/protocol/protocol_mock_objects.h" 20 #include "remoting/protocol/protocol_mock_objects.h"
21 #include "testing/gmock/include/gmock/gmock.h" 21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 23 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
24 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h"
25 #include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_object s.h" 24 #include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_object s.h"
26 25
27 using ::remoting::protocol::MockClientStub; 26 using ::remoting::protocol::MockClientStub;
28 using ::remoting::protocol::MockVideoStub; 27 using ::remoting::protocol::MockVideoStub;
29 28
30 using ::testing::_; 29 using ::testing::_;
31 using ::testing::AtLeast;
32 using ::testing::AnyNumber;
33 using ::testing::DeleteArg;
34 using ::testing::DoAll; 30 using ::testing::DoAll;
35 using ::testing::Expectation; 31 using ::testing::Expectation;
36 using ::testing::InSequence;
37 using ::testing::InvokeWithoutArgs; 32 using ::testing::InvokeWithoutArgs;
38 using ::testing::Return;
39 using ::testing::ReturnRef;
40 using ::testing::SaveArg;
41 33
42 namespace remoting { 34 namespace remoting {
43 35
44 namespace { 36 namespace {
45 37
46 ACTION(FinishEncode) { 38 ACTION(FinishEncode) {
47 scoped_ptr<VideoPacket> packet(new VideoPacket()); 39 scoped_ptr<VideoPacket> packet(new VideoPacket());
48 return packet.release(); 40 return packet.release();
49 } 41 }
50 42
51 ACTION(FinishSend) { 43 ACTION(FinishSend) {
52 arg1.Run(); 44 arg1.Run();
53 } 45 }
54 46
55 } // namespace 47 } // namespace
56 48
57 static const int kWidth = 640; 49 static const int kWidth = 640;
58 static const int kHeight = 480; 50 static const int kHeight = 480;
59 static const int kCursorWidth = 64;
60 static const int kCursorHeight = 32;
61 static const int kHotspotX = 11;
62 static const int kHotspotY = 12;
63 51
64 class MockVideoEncoder : public VideoEncoder { 52 class MockVideoEncoder : public VideoEncoder {
65 public: 53 public:
66 MockVideoEncoder() {} 54 MockVideoEncoder() {}
67 virtual ~MockVideoEncoder() {} 55 virtual ~MockVideoEncoder() {}
68 56
69 scoped_ptr<VideoPacket> Encode(const webrtc::DesktopFrame& frame) { 57 scoped_ptr<VideoPacket> Encode(const webrtc::DesktopFrame& frame) {
70 return make_scoped_ptr(EncodePtr(frame)); 58 return make_scoped_ptr(EncodePtr(frame));
71 } 59 }
72 MOCK_METHOD1(EncodePtr, VideoPacket*(const webrtc::DesktopFrame& frame)); 60 MOCK_METHOD1(EncodePtr, VideoPacket*(const webrtc::DesktopFrame& frame));
(...skipping 27 matching lines...) Expand all
100 ~ThreadCheckDesktopCapturer() override { 88 ~ThreadCheckDesktopCapturer() override {
101 EXPECT_TRUE(task_runner_->BelongsToCurrentThread()); 89 EXPECT_TRUE(task_runner_->BelongsToCurrentThread());
102 } 90 }
103 91
104 private: 92 private:
105 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 93 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
106 94
107 DISALLOW_COPY_AND_ASSIGN(ThreadCheckDesktopCapturer); 95 DISALLOW_COPY_AND_ASSIGN(ThreadCheckDesktopCapturer);
108 }; 96 };
109 97
110 class ThreadCheckMouseCursorMonitor : public FakeMouseCursorMonitor {
111 public:
112 ThreadCheckMouseCursorMonitor(
113 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
114 : task_runner_(task_runner) {
115 }
116 ~ThreadCheckMouseCursorMonitor() override {
117 EXPECT_TRUE(task_runner_->BelongsToCurrentThread());
118 }
119
120 private:
121 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
122
123 DISALLOW_COPY_AND_ASSIGN(ThreadCheckMouseCursorMonitor);
124 };
125
126 class VideoFramePumpTest : public testing::Test { 98 class VideoFramePumpTest : public testing::Test {
127 public: 99 public:
128 VideoFramePumpTest(); 100 VideoFramePumpTest();
129 101
130 void SetUp() override; 102 void SetUp() override;
131 void TearDown() override; 103 void TearDown() override;
132 104
133 void StartVideoFramePump( 105 void StartVideoFramePump(
134 scoped_ptr<webrtc::DesktopCapturer> capturer, 106 scoped_ptr<webrtc::DesktopCapturer> capturer,
135 scoped_ptr<VideoEncoder> encoder, 107 scoped_ptr<VideoEncoder> encoder);
136 scoped_ptr<webrtc::MouseCursorMonitor> mouse_monitor);
137 void StopVideoFramePump(); 108 void StopVideoFramePump();
138 109
139 // webrtc::DesktopCapturer mocks. 110 // webrtc::DesktopCapturer mocks.
140 void OnCapturerStart(webrtc::DesktopCapturer::Callback* callback); 111 void OnCapturerStart(webrtc::DesktopCapturer::Callback* callback);
141 void OnCaptureFrame(const webrtc::DesktopRegion& region); 112 void OnCaptureFrame(const webrtc::DesktopRegion& region);
142 113
143 // webrtc::MouseCursorMonitor mocks.
144 void OnMouseCursorMonitorInit(
145 webrtc::MouseCursorMonitor::Callback* callback,
146 webrtc::MouseCursorMonitor::Mode mode);
147 void OnCaptureMouse();
148 void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape);
149
150 protected: 114 protected:
151 base::MessageLoop message_loop_; 115 base::MessageLoop message_loop_;
152 base::RunLoop run_loop_; 116 base::RunLoop run_loop_;
153 scoped_refptr<AutoThreadTaskRunner> capture_task_runner_; 117 scoped_refptr<AutoThreadTaskRunner> capture_task_runner_;
154 scoped_refptr<AutoThreadTaskRunner> encode_task_runner_; 118 scoped_refptr<AutoThreadTaskRunner> encode_task_runner_;
155 scoped_refptr<AutoThreadTaskRunner> main_task_runner_; 119 scoped_refptr<AutoThreadTaskRunner> main_task_runner_;
156 scoped_refptr<VideoFramePump> scheduler_; 120 scoped_ptr<VideoFramePump> pump_;
157 121
158 MockClientStub client_stub_;
159 MockVideoStub video_stub_; 122 MockVideoStub video_stub_;
160 123
161 // Points to the callback passed to webrtc::DesktopCapturer::Start(). 124 // Points to the callback passed to webrtc::DesktopCapturer::Start().
162 webrtc::DesktopCapturer::Callback* capturer_callback_; 125 webrtc::DesktopCapturer::Callback* capturer_callback_;
163 126
164 // Points to the callback passed to webrtc::MouseCursor::Init().
165 webrtc::MouseCursorMonitor::Callback* mouse_monitor_callback_;
166
167 private: 127 private:
168 DISALLOW_COPY_AND_ASSIGN(VideoFramePumpTest); 128 DISALLOW_COPY_AND_ASSIGN(VideoFramePumpTest);
169 }; 129 };
170 130
171 VideoFramePumpTest::VideoFramePumpTest() 131 VideoFramePumpTest::VideoFramePumpTest() : capturer_callback_(nullptr) {
172 : capturer_callback_(nullptr),
173 mouse_monitor_callback_(nullptr) {
174 } 132 }
175 133
176 void VideoFramePumpTest::SetUp() { 134 void VideoFramePumpTest::SetUp() {
177 main_task_runner_ = new AutoThreadTaskRunner( 135 main_task_runner_ = new AutoThreadTaskRunner(
178 message_loop_.message_loop_proxy(), run_loop_.QuitClosure()); 136 message_loop_.message_loop_proxy(), run_loop_.QuitClosure());
179 capture_task_runner_ = main_task_runner_; 137 capture_task_runner_ = main_task_runner_;
180 encode_task_runner_ = main_task_runner_; 138 encode_task_runner_ = main_task_runner_;
181 } 139 }
182 140
183 void VideoFramePumpTest::TearDown() { 141 void VideoFramePumpTest::TearDown() {
184 // Release the task runners, so that the test can quit. 142 // Release the task runners, so that the test can quit.
185 capture_task_runner_ = nullptr; 143 capture_task_runner_ = nullptr;
186 encode_task_runner_ = nullptr; 144 encode_task_runner_ = nullptr;
187 main_task_runner_ = nullptr; 145 main_task_runner_ = nullptr;
188 146
189 // Run the MessageLoop until everything has torn down. 147 // Run the MessageLoop until everything has torn down.
190 run_loop_.Run(); 148 run_loop_.Run();
191 } 149 }
192 150
193 void VideoFramePumpTest::StartVideoFramePump( 151 void VideoFramePumpTest::StartVideoFramePump(
194 scoped_ptr<webrtc::DesktopCapturer> capturer, 152 scoped_ptr<webrtc::DesktopCapturer> capturer,
195 scoped_ptr<VideoEncoder> encoder, 153 scoped_ptr<VideoEncoder> encoder) {
196 scoped_ptr<webrtc::MouseCursorMonitor> mouse_monitor) { 154 pump_.reset(new VideoFramePump(encode_task_runner_,
197 scheduler_ = new VideoFramePump( 155 make_scoped_ptr(new DesktopCapturerProxy(
198 capture_task_runner_, 156 capture_task_runner_, capturer.Pass())),
199 encode_task_runner_, 157 encoder.Pass(), &video_stub_));
200 main_task_runner_,
201 capturer.Pass(),
202 mouse_monitor.Pass(),
203 encoder.Pass(),
204 &client_stub_,
205 &video_stub_);
206 scheduler_->Start();
207 } 158 }
208 159
209 void VideoFramePumpTest::StopVideoFramePump() { 160 void VideoFramePumpTest::StopVideoFramePump() {
210 scheduler_->Stop(); 161 pump_.reset();
211 scheduler_ = nullptr;
212 } 162 }
213 163
214 void VideoFramePumpTest::OnCapturerStart( 164 void VideoFramePumpTest::OnCapturerStart(
215 webrtc::DesktopCapturer::Callback* callback) { 165 webrtc::DesktopCapturer::Callback* callback) {
216 EXPECT_FALSE(capturer_callback_); 166 EXPECT_FALSE(capturer_callback_);
217 EXPECT_TRUE(callback); 167 EXPECT_TRUE(callback);
218 168
219 capturer_callback_ = callback; 169 capturer_callback_ = callback;
220 } 170 }
221 171
222 void VideoFramePumpTest::OnCaptureFrame(const webrtc::DesktopRegion& region) { 172 void VideoFramePumpTest::OnCaptureFrame(const webrtc::DesktopRegion& region) {
223 scoped_ptr<webrtc::DesktopFrame> frame( 173 scoped_ptr<webrtc::DesktopFrame> frame(
224 new webrtc::BasicDesktopFrame(webrtc::DesktopSize(kWidth, kHeight))); 174 new webrtc::BasicDesktopFrame(webrtc::DesktopSize(kWidth, kHeight)));
225 frame->mutable_updated_region()->SetRect( 175 frame->mutable_updated_region()->SetRect(
226 webrtc::DesktopRect::MakeXYWH(0, 0, 10, 10)); 176 webrtc::DesktopRect::MakeXYWH(0, 0, 10, 10));
227 capturer_callback_->OnCaptureCompleted(frame.release()); 177 capturer_callback_->OnCaptureCompleted(frame.release());
228 } 178 }
229 179
230 void VideoFramePumpTest::OnCaptureMouse() {
231 EXPECT_TRUE(mouse_monitor_callback_);
232
233 scoped_ptr<webrtc::MouseCursor> mouse_cursor(
234 new webrtc::MouseCursor(
235 new webrtc::BasicDesktopFrame(
236 webrtc::DesktopSize(kCursorWidth, kCursorHeight)),
237 webrtc::DesktopVector(kHotspotX, kHotspotY)));
238
239 mouse_monitor_callback_->OnMouseCursor(mouse_cursor.release());
240 }
241
242 void VideoFramePumpTest::OnMouseCursorMonitorInit(
243 webrtc::MouseCursorMonitor::Callback* callback,
244 webrtc::MouseCursorMonitor::Mode mode) {
245 EXPECT_FALSE(mouse_monitor_callback_);
246 EXPECT_TRUE(callback);
247
248 mouse_monitor_callback_ = callback;
249 }
250
251 void VideoFramePumpTest::SetCursorShape(
252 const protocol::CursorShapeInfo& cursor_shape) {
253 EXPECT_TRUE(cursor_shape.has_width());
254 EXPECT_EQ(kCursorWidth, cursor_shape.width());
255 EXPECT_TRUE(cursor_shape.has_height());
256 EXPECT_EQ(kCursorHeight, cursor_shape.height());
257 EXPECT_TRUE(cursor_shape.has_hotspot_x());
258 EXPECT_EQ(kHotspotX, cursor_shape.hotspot_x());
259 EXPECT_TRUE(cursor_shape.has_hotspot_y());
260 EXPECT_EQ(kHotspotY, cursor_shape.hotspot_y());
261 EXPECT_TRUE(cursor_shape.has_data());
262 EXPECT_EQ(kCursorWidth * kCursorHeight * webrtc::DesktopFrame::kBytesPerPixel,
263 static_cast<int>(cursor_shape.data().size()));
264 }
265
266 // This test mocks capturer, encoder and network layer to simulate one capture 180 // This test mocks capturer, encoder and network layer to simulate one capture
267 // cycle. When the first encoded packet is submitted to the network 181 // cycle.
268 // VideoFramePump is instructed to come to a complete stop. We expect the stop
269 // sequence to be executed successfully.
270 TEST_F(VideoFramePumpTest, StartAndStop) { 182 TEST_F(VideoFramePumpTest, StartAndStop) {
271 scoped_ptr<webrtc::MockScreenCapturer> capturer( 183 scoped_ptr<webrtc::MockScreenCapturer> capturer(
272 new webrtc::MockScreenCapturer()); 184 new webrtc::MockScreenCapturer());
273 scoped_ptr<MockMouseCursorMonitor> cursor_monitor(
274 new MockMouseCursorMonitor());
275
276 {
277 InSequence s;
278
279 EXPECT_CALL(*cursor_monitor, Init(_, _))
280 .WillOnce(
281 Invoke(this, &VideoFramePumpTest::OnMouseCursorMonitorInit));
282
283 EXPECT_CALL(*cursor_monitor, Capture())
284 .WillRepeatedly(Invoke(this, &VideoFramePumpTest::OnCaptureMouse));
285 }
286 185
287 Expectation capturer_start = 186 Expectation capturer_start =
288 EXPECT_CALL(*capturer, Start(_)) 187 EXPECT_CALL(*capturer, Start(_))
289 .WillOnce(Invoke(this, &VideoFramePumpTest::OnCapturerStart)); 188 .WillOnce(Invoke(this, &VideoFramePumpTest::OnCapturerStart));
290 189
291 // First the capturer is called. 190 // First the capturer is called.
292 Expectation capturer_capture = EXPECT_CALL(*capturer, Capture(_)) 191 Expectation capturer_capture = EXPECT_CALL(*capturer, Capture(_))
293 .After(capturer_start) 192 .After(capturer_start)
294 .WillRepeatedly(Invoke(this, &VideoFramePumpTest::OnCaptureFrame)); 193 .WillRepeatedly(Invoke(this, &VideoFramePumpTest::OnCaptureFrame));
295 194
296 scoped_ptr<MockVideoEncoder> encoder(new MockVideoEncoder()); 195 scoped_ptr<MockVideoEncoder> encoder(new MockVideoEncoder());
297 196
298 // Expect the encoder be called. 197 // Expect the encoder be called.
299 EXPECT_CALL(*encoder, EncodePtr(_)) 198 EXPECT_CALL(*encoder, EncodePtr(_))
300 .WillRepeatedly(FinishEncode()); 199 .WillRepeatedly(FinishEncode());
301 200
302 // By default delete the arguments when ProcessVideoPacket is received. 201 // By default delete the arguments when ProcessVideoPacket is received.
303 EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _)) 202 EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _))
304 .WillRepeatedly(FinishSend()); 203 .WillRepeatedly(FinishSend());
305 204
306 // When the first ProcessVideoPacket is received we stop the VideoFramePump. 205 // When the first ProcessVideoPacket is received we stop the VideoFramePump.
307 EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _)) 206 EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _))
308 .WillOnce(DoAll( 207 .WillOnce(DoAll(
309 FinishSend(), 208 FinishSend(),
310 InvokeWithoutArgs(this, &VideoFramePumpTest::StopVideoFramePump))) 209 InvokeWithoutArgs(this, &VideoFramePumpTest::StopVideoFramePump)))
311 .RetiresOnSaturation(); 210 .RetiresOnSaturation();
312 211
313 EXPECT_CALL(client_stub_, SetCursorShape(_))
314 .WillOnce(Invoke(this, &VideoFramePumpTest::SetCursorShape));
315
316 // Start video frame capture. 212 // Start video frame capture.
317 scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor( 213 StartVideoFramePump(capturer.Pass(), encoder.Pass());
318 new FakeMouseCursorMonitor());
319 StartVideoFramePump(capturer.Pass(), encoder.Pass(), cursor_monitor.Pass());
320 214
321 // Run until there are no more pending tasks from the VideoFramePump. 215 // Run until there are no more pending tasks from the VideoFramePump.
322 // Otherwise, a lingering frame capture might attempt to trigger a capturer 216 // Otherwise, a lingering frame capture might attempt to trigger a capturer
323 // expectation action and crash. 217 // expectation action and crash.
324 base::RunLoop().RunUntilIdle(); 218 base::RunLoop().RunUntilIdle();
325 } 219 }
326 220
327 // Verify that the capturer, encoder and mouse monitor are torn down on the 221 // Verify that the capturer and encoder are torn down on the correct threads.
328 // correct threads.
329 TEST_F(VideoFramePumpTest, DeleteOnThreads) { 222 TEST_F(VideoFramePumpTest, DeleteOnThreads) {
Wez 2015/02/12 21:59:15 Add a test for actually capturing across threads?
Sergey Ulanov 2015/02/13 08:39:45 Done.
330 capture_task_runner_ = AutoThread::Create("capture", main_task_runner_); 223 capture_task_runner_ = AutoThread::Create("capture", main_task_runner_);
331 encode_task_runner_ = AutoThread::Create("encode", main_task_runner_); 224 encode_task_runner_ = AutoThread::Create("encode", main_task_runner_);
332 225
333 scoped_ptr<webrtc::DesktopCapturer> capturer( 226 scoped_ptr<webrtc::DesktopCapturer> capturer(
334 new ThreadCheckDesktopCapturer(capture_task_runner_)); 227 new ThreadCheckDesktopCapturer(capture_task_runner_));
335 scoped_ptr<VideoEncoder> encoder( 228 scoped_ptr<VideoEncoder> encoder(
336 new ThreadCheckVideoEncoder(encode_task_runner_)); 229 new ThreadCheckVideoEncoder(encode_task_runner_));
337 scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor(
338 new ThreadCheckMouseCursorMonitor(capture_task_runner_));
339 230
340 // Start and stop the scheduler, so it will tear down the screen capturer, 231 // Start and stop the scheduler, so it will tear down the screen capturer and
341 // video encoder and mouse monitor. 232 // video encoder.
342 StartVideoFramePump(capturer.Pass(), encoder.Pass(), 233 StartVideoFramePump(capturer.Pass(), encoder.Pass());
343 mouse_cursor_monitor.Pass());
344 StopVideoFramePump(); 234 StopVideoFramePump();
345 } 235 }
346 236
347 } // namespace remoting 237 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698