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

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

Issue 10572005: Use SingleThreadTaskRunner instead of MessageLoopProxy in remoting/host. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 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
« no previous file with comments | « remoting/host/screen_recorder.h ('k') | remoting/host/screen_recorder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/screen_recorder.h" 5 #include "remoting/host/screen_recorder.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 14 matching lines...) Expand all
25 25
26 using remoting::protocol::ConnectionToClient; 26 using remoting::protocol::ConnectionToClient;
27 27
28 namespace remoting { 28 namespace remoting {
29 29
30 // Maximum number of frames that can be processed similtaneously. 30 // Maximum number of frames that can be processed similtaneously.
31 // TODO(hclam): Move this value to CaptureScheduler. 31 // TODO(hclam): Move this value to CaptureScheduler.
32 static const int kMaxRecordings = 2; 32 static const int kMaxRecordings = 2;
33 33
34 ScreenRecorder::ScreenRecorder( 34 ScreenRecorder::ScreenRecorder(
35 MessageLoop* capture_loop, 35 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,
36 MessageLoop* encode_loop, 36 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner,
37 base::MessageLoopProxy* network_loop, 37 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
38 Capturer* capturer, 38 Capturer* capturer,
39 Encoder* encoder) 39 Encoder* encoder)
40 : capture_loop_(capture_loop), 40 : capture_task_runner_(capture_task_runner),
41 encode_loop_(encode_loop), 41 encode_task_runner_(encode_task_runner),
42 network_loop_(network_loop), 42 network_task_runner_(network_task_runner),
43 capturer_(capturer), 43 capturer_(capturer),
44 encoder_(encoder), 44 encoder_(encoder),
45 network_stopped_(false), 45 network_stopped_(false),
46 encoder_stopped_(false), 46 encoder_stopped_(false),
47 max_recordings_(kMaxRecordings), 47 max_recordings_(kMaxRecordings),
48 recordings_(0), 48 recordings_(0),
49 frame_skipped_(false), 49 frame_skipped_(false),
50 sequence_number_(0) { 50 sequence_number_(0) {
51 DCHECK(capture_loop_); 51 DCHECK(capture_task_runner_);
52 DCHECK(encode_loop_); 52 DCHECK(encode_task_runner_);
53 DCHECK(network_loop_); 53 DCHECK(network_task_runner_);
54 } 54 }
55 55
56 // Public methods -------------------------------------------------------------- 56 // Public methods --------------------------------------------------------------
57 57
58 void ScreenRecorder::Start() { 58 void ScreenRecorder::Start() {
59 capture_loop_->PostTask( 59 capture_task_runner_->PostTask(
60 FROM_HERE, base::Bind(&ScreenRecorder::DoStart, this)); 60 FROM_HERE, base::Bind(&ScreenRecorder::DoStart, this));
61 } 61 }
62 62
63 void ScreenRecorder::Stop(const base::Closure& done_task) { 63 void ScreenRecorder::Stop(const base::Closure& done_task) {
64 if (MessageLoop::current() != capture_loop_) { 64 if (!capture_task_runner_->BelongsToCurrentThread()) {
65 capture_loop_->PostTask(FROM_HERE, base::Bind( 65 capture_task_runner_->PostTask(FROM_HERE, base::Bind(
66 &ScreenRecorder::Stop, this, done_task)); 66 &ScreenRecorder::Stop, this, done_task));
67 return; 67 return;
68 } 68 }
69 69
70 DCHECK(!done_task.is_null()); 70 DCHECK(!done_task.is_null());
71 71
72 capturer()->Stop(); 72 capturer()->Stop();
73 capture_timer_.reset(); 73 capture_timer_.reset();
74 74
75 network_loop_->PostTask(FROM_HERE, base::Bind( 75 network_task_runner_->PostTask(FROM_HERE, base::Bind(
76 &ScreenRecorder::DoStopOnNetworkThread, this, done_task)); 76 &ScreenRecorder::DoStopOnNetworkThread, this, done_task));
77 } 77 }
78 78
79 void ScreenRecorder::AddConnection(ConnectionToClient* connection) { 79 void ScreenRecorder::AddConnection(ConnectionToClient* connection) {
80 DCHECK(network_loop_->BelongsToCurrentThread()); 80 DCHECK(network_task_runner_->BelongsToCurrentThread());
81 connections_.push_back(connection); 81 connections_.push_back(connection);
82 82
83 capture_loop_->PostTask( 83 capture_task_runner_->PostTask(
84 FROM_HERE, base::Bind(&ScreenRecorder::DoInvalidateFullScreen, this)); 84 FROM_HERE, base::Bind(&ScreenRecorder::DoInvalidateFullScreen, this));
85 } 85 }
86 86
87 void ScreenRecorder::RemoveConnection(ConnectionToClient* connection) { 87 void ScreenRecorder::RemoveConnection(ConnectionToClient* connection) {
88 DCHECK(network_loop_->BelongsToCurrentThread()); 88 DCHECK(network_task_runner_->BelongsToCurrentThread());
89 89
90 ConnectionToClientList::iterator it = 90 ConnectionToClientList::iterator it =
91 std::find(connections_.begin(), connections_.end(), connection); 91 std::find(connections_.begin(), connections_.end(), connection);
92 if (it != connections_.end()) { 92 if (it != connections_.end()) {
93 connections_.erase(it); 93 connections_.erase(it);
94 } 94 }
95 } 95 }
96 96
97 void ScreenRecorder::RemoveAllConnections() { 97 void ScreenRecorder::RemoveAllConnections() {
98 DCHECK(network_loop_->BelongsToCurrentThread()); 98 DCHECK(network_task_runner_->BelongsToCurrentThread());
99 connections_.clear(); 99 connections_.clear();
100 } 100 }
101 101
102 void ScreenRecorder::UpdateSequenceNumber(int64 sequence_number) { 102 void ScreenRecorder::UpdateSequenceNumber(int64 sequence_number) {
103 // Sequence number is used and written only on the capture thread. 103 // Sequence number is used and written only on the capture thread.
104 if (MessageLoop::current() != capture_loop_) { 104 if (!capture_task_runner_->BelongsToCurrentThread()) {
105 capture_loop_->PostTask( 105 capture_task_runner_->PostTask(
106 FROM_HERE, base::Bind(&ScreenRecorder::UpdateSequenceNumber, 106 FROM_HERE, base::Bind(&ScreenRecorder::UpdateSequenceNumber,
107 this, sequence_number)); 107 this, sequence_number));
108 return; 108 return;
109 } 109 }
110 110
111 sequence_number_ = sequence_number; 111 sequence_number_ = sequence_number;
112 } 112 }
113 113
114 // Private methods ----------------------------------------------------------- 114 // Private methods -----------------------------------------------------------
115 115
116 ScreenRecorder::~ScreenRecorder() { 116 ScreenRecorder::~ScreenRecorder() {
117 } 117 }
118 118
119 Capturer* ScreenRecorder::capturer() { 119 Capturer* ScreenRecorder::capturer() {
120 DCHECK_EQ(capture_loop_, MessageLoop::current()); 120 DCHECK(capture_task_runner_->BelongsToCurrentThread());
121 DCHECK(capturer_); 121 DCHECK(capturer_);
122 return capturer_; 122 return capturer_;
123 } 123 }
124 124
125 Encoder* ScreenRecorder::encoder() { 125 Encoder* ScreenRecorder::encoder() {
126 DCHECK_EQ(encode_loop_, MessageLoop::current()); 126 DCHECK(encode_task_runner_->BelongsToCurrentThread());
127 DCHECK(encoder_.get()); 127 DCHECK(encoder_.get());
128 return encoder_.get(); 128 return encoder_.get();
129 } 129 }
130 130
131 bool ScreenRecorder::is_recording() { 131 bool ScreenRecorder::is_recording() {
132 DCHECK_EQ(capture_loop_, MessageLoop::current()); 132 DCHECK(capture_task_runner_->BelongsToCurrentThread());
133 return capture_timer_.get() != NULL; 133 return capture_timer_.get() != NULL;
134 } 134 }
135 135
136 // Capturer thread ------------------------------------------------------------- 136 // Capturer thread -------------------------------------------------------------
137 137
138 void ScreenRecorder::DoStart() { 138 void ScreenRecorder::DoStart() {
139 DCHECK_EQ(capture_loop_, MessageLoop::current()); 139 DCHECK(capture_task_runner_->BelongsToCurrentThread());
140 140
141 if (is_recording()) { 141 if (is_recording()) {
142 NOTREACHED() << "Record session already started."; 142 NOTREACHED() << "Record session already started.";
143 return; 143 return;
144 } 144 }
145 145
146 capturer()->Start( 146 capturer()->Start(
147 base::Bind(&ScreenRecorder::CursorShapeChangedCallback, this)); 147 base::Bind(&ScreenRecorder::CursorShapeChangedCallback, this));
148 148
149 capture_timer_.reset(new base::OneShotTimer<ScreenRecorder>()); 149 capture_timer_.reset(new base::OneShotTimer<ScreenRecorder>());
150 150
151 // Capture first frame immedately. 151 // Capture first frame immedately.
152 DoCapture(); 152 DoCapture();
153 } 153 }
154 154
155 void ScreenRecorder::StartCaptureTimer() { 155 void ScreenRecorder::StartCaptureTimer() {
156 DCHECK_EQ(capture_loop_, MessageLoop::current()); 156 DCHECK(capture_task_runner_->BelongsToCurrentThread());
157 157
158 capture_timer_->Start(FROM_HERE, 158 capture_timer_->Start(FROM_HERE,
159 scheduler_.NextCaptureDelay(), 159 scheduler_.NextCaptureDelay(),
160 this, 160 this,
161 &ScreenRecorder::DoCapture); 161 &ScreenRecorder::DoCapture);
162 } 162 }
163 163
164 void ScreenRecorder::DoCapture() { 164 void ScreenRecorder::DoCapture() {
165 DCHECK_EQ(capture_loop_, MessageLoop::current()); 165 DCHECK(capture_task_runner_->BelongsToCurrentThread());
166 // Make sure we have at most two oustanding recordings. We can simply return 166 // Make sure we have at most two oustanding recordings. We can simply return
167 // if we can't make a capture now, the next capture will be started by the 167 // if we can't make a capture now, the next capture will be started by the
168 // end of an encode operation. 168 // end of an encode operation.
169 if (recordings_ >= max_recordings_ || !is_recording()) { 169 if (recordings_ >= max_recordings_ || !is_recording()) {
170 frame_skipped_ = true; 170 frame_skipped_ = true;
171 return; 171 return;
172 } 172 }
173 173
174 if (frame_skipped_) 174 if (frame_skipped_)
175 frame_skipped_ = false; 175 frame_skipped_ = false;
(...skipping 10 matching lines...) Expand all
186 &ScreenRecorder::DoCapture); 186 &ScreenRecorder::DoCapture);
187 187
188 // And finally perform one capture. 188 // And finally perform one capture.
189 capture_start_time_ = base::Time::Now(); 189 capture_start_time_ = base::Time::Now();
190 capturer()->CaptureInvalidRegion( 190 capturer()->CaptureInvalidRegion(
191 base::Bind(&ScreenRecorder::CaptureDoneCallback, this)); 191 base::Bind(&ScreenRecorder::CaptureDoneCallback, this));
192 } 192 }
193 193
194 void ScreenRecorder::CaptureDoneCallback( 194 void ScreenRecorder::CaptureDoneCallback(
195 scoped_refptr<CaptureData> capture_data) { 195 scoped_refptr<CaptureData> capture_data) {
196 DCHECK_EQ(capture_loop_, MessageLoop::current()); 196 DCHECK(capture_task_runner_->BelongsToCurrentThread());
197 197
198 if (!is_recording()) 198 if (!is_recording())
199 return; 199 return;
200 200
201 if (capture_data) { 201 if (capture_data) {
202 base::TimeDelta capture_time = base::Time::Now() - capture_start_time_; 202 base::TimeDelta capture_time = base::Time::Now() - capture_start_time_;
203 int capture_time_ms = 203 int capture_time_ms =
204 static_cast<int>(capture_time.InMilliseconds()); 204 static_cast<int>(capture_time.InMilliseconds());
205 capture_data->set_capture_time_ms(capture_time_ms); 205 capture_data->set_capture_time_ms(capture_time_ms);
206 scheduler_.RecordCaptureTime(capture_time); 206 scheduler_.RecordCaptureTime(capture_time);
207 207
208 // The best way to get this value is by binding the sequence number to 208 // The best way to get this value is by binding the sequence number to
209 // the callback when calling CaptureInvalidRects(). However the callback 209 // the callback when calling CaptureInvalidRects(). However the callback
210 // system doesn't allow this. Reading from the member variable is 210 // system doesn't allow this. Reading from the member variable is
211 // accurate as long as capture is synchronous as the following statement 211 // accurate as long as capture is synchronous as the following statement
212 // will obtain the most recent sequence number received. 212 // will obtain the most recent sequence number received.
213 capture_data->set_client_sequence_number(sequence_number_); 213 capture_data->set_client_sequence_number(sequence_number_);
214 } 214 }
215 215
216 encode_loop_->PostTask( 216 encode_task_runner_->PostTask(
217 FROM_HERE, base::Bind(&ScreenRecorder::DoEncode, this, capture_data)); 217 FROM_HERE, base::Bind(&ScreenRecorder::DoEncode, this, capture_data));
218 } 218 }
219 219
220 void ScreenRecorder::CursorShapeChangedCallback( 220 void ScreenRecorder::CursorShapeChangedCallback(
221 scoped_ptr<protocol::CursorShapeInfo> cursor_shape) { 221 scoped_ptr<protocol::CursorShapeInfo> cursor_shape) {
222 DCHECK_EQ(capture_loop_, MessageLoop::current()); 222 DCHECK(capture_task_runner_->BelongsToCurrentThread());
223 223
224 if (!is_recording()) 224 if (!is_recording())
225 return; 225 return;
226 226
227 network_loop_->PostTask( 227 network_task_runner_->PostTask(
228 FROM_HERE, base::Bind(&ScreenRecorder::DoSendCursorShape, this, 228 FROM_HERE, base::Bind(&ScreenRecorder::DoSendCursorShape, this,
229 base::Passed(cursor_shape.Pass()))); 229 base::Passed(cursor_shape.Pass())));
230 } 230 }
231 231
232 void ScreenRecorder::DoFinishOneRecording() { 232 void ScreenRecorder::DoFinishOneRecording() {
233 DCHECK_EQ(capture_loop_, MessageLoop::current()); 233 DCHECK(capture_task_runner_->BelongsToCurrentThread());
234 234
235 if (!is_recording()) 235 if (!is_recording())
236 return; 236 return;
237 237
238 // Decrement the number of recording in process since we have completed 238 // Decrement the number of recording in process since we have completed
239 // one cycle. 239 // one cycle.
240 --recordings_; 240 --recordings_;
241 DCHECK_GE(recordings_, 0); 241 DCHECK_GE(recordings_, 0);
242 242
243 // Try to do a capture again only if |frame_skipped_| is set to true by 243 // Try to do a capture again only if |frame_skipped_| is set to true by
244 // capture timer. 244 // capture timer.
245 if (frame_skipped_) 245 if (frame_skipped_)
246 DoCapture(); 246 DoCapture();
247 } 247 }
248 248
249 void ScreenRecorder::DoInvalidateFullScreen() { 249 void ScreenRecorder::DoInvalidateFullScreen() {
250 DCHECK_EQ(capture_loop_, MessageLoop::current()); 250 DCHECK(capture_task_runner_->BelongsToCurrentThread());
251 251
252 capturer_->InvalidateFullScreen(); 252 capturer_->InvalidateFullScreen();
253 } 253 }
254 254
255 // Network thread -------------------------------------------------------------- 255 // Network thread --------------------------------------------------------------
256 256
257 void ScreenRecorder::DoSendVideoPacket(scoped_ptr<VideoPacket> packet) { 257 void ScreenRecorder::DoSendVideoPacket(scoped_ptr<VideoPacket> packet) {
258 DCHECK(network_loop_->BelongsToCurrentThread()); 258 DCHECK(network_task_runner_->BelongsToCurrentThread());
259 259
260 if (network_stopped_ || connections_.empty()) 260 if (network_stopped_ || connections_.empty())
261 return; 261 return;
262 262
263 base::Closure callback; 263 base::Closure callback;
264 if ((packet->flags() & VideoPacket::LAST_PARTITION) != 0) 264 if ((packet->flags() & VideoPacket::LAST_PARTITION) != 0)
265 callback = base::Bind(&ScreenRecorder::VideoFrameSentCallback, this); 265 callback = base::Bind(&ScreenRecorder::VideoFrameSentCallback, this);
266 266
267 // TODO(sergeyu): Currently we send the data only to the first 267 // TODO(sergeyu): Currently we send the data only to the first
268 // connection. Send it to all connections if necessary. 268 // connection. Send it to all connections if necessary.
269 connections_.front()->video_stub()->ProcessVideoPacket( 269 connections_.front()->video_stub()->ProcessVideoPacket(
270 packet.Pass(), callback); 270 packet.Pass(), callback);
271 } 271 }
272 272
273 void ScreenRecorder::VideoFrameSentCallback() { 273 void ScreenRecorder::VideoFrameSentCallback() {
274 DCHECK(network_loop_->BelongsToCurrentThread()); 274 DCHECK(network_task_runner_->BelongsToCurrentThread());
275 275
276 if (network_stopped_) 276 if (network_stopped_)
277 return; 277 return;
278 278
279 capture_loop_->PostTask( 279 capture_task_runner_->PostTask(
280 FROM_HERE, base::Bind(&ScreenRecorder::DoFinishOneRecording, this)); 280 FROM_HERE, base::Bind(&ScreenRecorder::DoFinishOneRecording, this));
281 } 281 }
282 282
283 void ScreenRecorder::DoStopOnNetworkThread(const base::Closure& done_task) { 283 void ScreenRecorder::DoStopOnNetworkThread(const base::Closure& done_task) {
284 DCHECK(network_loop_->BelongsToCurrentThread()); 284 DCHECK(network_task_runner_->BelongsToCurrentThread());
285 285
286 // There could be tasks on the network thread when this method is being 286 // There could be tasks on the network thread when this method is being
287 // executed. By setting the flag we'll not post anymore tasks from network 287 // executed. By setting the flag we'll not post anymore tasks from network
288 // thread. 288 // thread.
289 // 289 //
290 // After that a task is posted on encode thread to continue the stop 290 // After that a task is posted on encode thread to continue the stop
291 // sequence. 291 // sequence.
292 network_stopped_ = true; 292 network_stopped_ = true;
293 293
294 encode_loop_->PostTask( 294 encode_task_runner_->PostTask(
295 FROM_HERE, base::Bind(&ScreenRecorder::DoStopOnEncodeThread, 295 FROM_HERE, base::Bind(&ScreenRecorder::DoStopOnEncodeThread,
296 this, done_task)); 296 this, done_task));
297 } 297 }
298 298
299 void ScreenRecorder::DoSendCursorShape( 299 void ScreenRecorder::DoSendCursorShape(
300 scoped_ptr<protocol::CursorShapeInfo> cursor_shape) { 300 scoped_ptr<protocol::CursorShapeInfo> cursor_shape) {
301 DCHECK(network_loop_->BelongsToCurrentThread()); 301 DCHECK(network_task_runner_->BelongsToCurrentThread());
302 302
303 if (network_stopped_ || connections_.empty()) 303 if (network_stopped_ || connections_.empty())
304 return; 304 return;
305 305
306 // TODO(sergeyu): Currently we send the data only to the first 306 // TODO(sergeyu): Currently we send the data only to the first
307 // connection. Send it to all connections if necessary. 307 // connection. Send it to all connections if necessary.
308 connections_.front()->client_stub()->SetCursorShape(*cursor_shape); 308 connections_.front()->client_stub()->SetCursorShape(*cursor_shape);
309 } 309 }
310 310
311 // Encoder thread -------------------------------------------------------------- 311 // Encoder thread --------------------------------------------------------------
312 312
313 void ScreenRecorder::DoEncode( 313 void ScreenRecorder::DoEncode(
314 scoped_refptr<CaptureData> capture_data) { 314 scoped_refptr<CaptureData> capture_data) {
315 DCHECK_EQ(encode_loop_, MessageLoop::current()); 315 DCHECK(encode_task_runner_->BelongsToCurrentThread());
316 316
317 if (encoder_stopped_) 317 if (encoder_stopped_)
318 return; 318 return;
319 319
320 // Early out if there's nothing to encode. 320 // Early out if there's nothing to encode.
321 if (!capture_data || capture_data->dirty_region().isEmpty()) { 321 if (!capture_data || capture_data->dirty_region().isEmpty()) {
322 // Send an empty video packet to keep network active. 322 // Send an empty video packet to keep network active.
323 scoped_ptr<VideoPacket> packet(new VideoPacket()); 323 scoped_ptr<VideoPacket> packet(new VideoPacket());
324 packet->set_flags(VideoPacket::LAST_PARTITION); 324 packet->set_flags(VideoPacket::LAST_PARTITION);
325 network_loop_->PostTask( 325 network_task_runner_->PostTask(
326 FROM_HERE, base::Bind(&ScreenRecorder::DoSendVideoPacket, 326 FROM_HERE, base::Bind(&ScreenRecorder::DoSendVideoPacket,
327 this, base::Passed(packet.Pass()))); 327 this, base::Passed(packet.Pass())));
328 return; 328 return;
329 } 329 }
330 330
331 encode_start_time_ = base::Time::Now(); 331 encode_start_time_ = base::Time::Now();
332 encoder()->Encode( 332 encoder()->Encode(
333 capture_data, false, 333 capture_data, false,
334 base::Bind(&ScreenRecorder::EncodedDataAvailableCallback, this)); 334 base::Bind(&ScreenRecorder::EncodedDataAvailableCallback, this));
335 } 335 }
336 336
337 void ScreenRecorder::DoStopOnEncodeThread(const base::Closure& done_task) { 337 void ScreenRecorder::DoStopOnEncodeThread(const base::Closure& done_task) {
338 DCHECK_EQ(encode_loop_, MessageLoop::current()); 338 DCHECK(encode_task_runner_->BelongsToCurrentThread());
339 339
340 encoder_stopped_ = true; 340 encoder_stopped_ = true;
341 341
342 // When this method is being executed there are no more tasks on encode thread 342 // When this method is being executed there are no more tasks on encode thread
343 // for this object. We can then post a task to capture thread to finish the 343 // for this object. We can then post a task to capture thread to finish the
344 // stop sequence. 344 // stop sequence.
345 capture_loop_->PostTask(FROM_HERE, done_task); 345 capture_task_runner_->PostTask(FROM_HERE, done_task);
346 } 346 }
347 347
348 void ScreenRecorder::EncodedDataAvailableCallback( 348 void ScreenRecorder::EncodedDataAvailableCallback(
349 scoped_ptr<VideoPacket> packet) { 349 scoped_ptr<VideoPacket> packet) {
350 DCHECK_EQ(encode_loop_, MessageLoop::current()); 350 DCHECK(encode_task_runner_->BelongsToCurrentThread());
351 351
352 if (encoder_stopped_) 352 if (encoder_stopped_)
353 return; 353 return;
354 354
355 bool last = (packet->flags() & VideoPacket::LAST_PACKET) != 0; 355 bool last = (packet->flags() & VideoPacket::LAST_PACKET) != 0;
356 if (last) { 356 if (last) {
357 base::TimeDelta encode_time = base::Time::Now() - encode_start_time_; 357 base::TimeDelta encode_time = base::Time::Now() - encode_start_time_;
358 int encode_time_ms = 358 int encode_time_ms =
359 static_cast<int>(encode_time.InMilliseconds()); 359 static_cast<int>(encode_time.InMilliseconds());
360 packet->set_encode_time_ms(encode_time_ms); 360 packet->set_encode_time_ms(encode_time_ms);
361 scheduler_.RecordEncodeTime(encode_time); 361 scheduler_.RecordEncodeTime(encode_time);
362 } 362 }
363 363
364 network_loop_->PostTask( 364 network_task_runner_->PostTask(
365 FROM_HERE, base::Bind(&ScreenRecorder::DoSendVideoPacket, this, 365 FROM_HERE, base::Bind(&ScreenRecorder::DoSendVideoPacket, this,
366 base::Passed(packet.Pass()))); 366 base::Passed(packet.Pass())));
367 } 367 }
368 368
369 } // namespace remoting 369 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/screen_recorder.h ('k') | remoting/host/screen_recorder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698