OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/session_manager.h" | 5 #include "remoting/host/session_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/scoped_ptr.h" | 10 #include "base/scoped_ptr.h" |
11 #include "base/stl_util-inl.h" | 11 #include "base/stl_util-inl.h" |
12 #include "media/base/data_buffer.h" | 12 #include "media/base/data_buffer.h" |
13 #include "remoting/base/capture_data.h" | 13 #include "remoting/base/capture_data.h" |
14 #include "remoting/base/protocol_decoder.h" | 14 #include "remoting/base/protocol_decoder.h" |
| 15 #include "remoting/base/tracer.h" |
15 #include "remoting/host/client_connection.h" | 16 #include "remoting/host/client_connection.h" |
16 | 17 |
17 namespace remoting { | 18 namespace remoting { |
18 | 19 |
19 // By default we capture 20 times a second. This number is obtained by | 20 // By default we capture 20 times a second. This number is obtained by |
20 // experiment to provide good latency. | 21 // experiment to provide good latency. |
21 static const double kDefaultCaptureRate = 20.0; | 22 static const double kDefaultCaptureRate = 20.0; |
22 | 23 |
23 // Interval that we perform rate regulation. | 24 // Interval that we perform rate regulation. |
24 static const base::TimeDelta kRateControlInterval = | 25 static const base::TimeDelta kRateControlInterval = |
(...skipping 29 matching lines...) Expand all Loading... |
54 } | 55 } |
55 | 56 |
56 SessionManager::~SessionManager() { | 57 SessionManager::~SessionManager() { |
57 clients_.clear(); | 58 clients_.clear(); |
58 } | 59 } |
59 | 60 |
60 // Public methods -------------------------------------------------------------- | 61 // Public methods -------------------------------------------------------------- |
61 | 62 |
62 void SessionManager::Start() { | 63 void SessionManager::Start() { |
63 capture_loop_->PostTask( | 64 capture_loop_->PostTask( |
64 FROM_HERE, NewRunnableMethod(this, &SessionManager::DoStart)); | 65 FROM_HERE, NewTracedMethod(this, &SessionManager::DoStart)); |
65 } | 66 } |
66 | 67 |
67 void SessionManager::Pause() { | 68 void SessionManager::Pause() { |
68 capture_loop_->PostTask( | 69 capture_loop_->PostTask( |
69 FROM_HERE, NewRunnableMethod(this, &SessionManager::DoPause)); | 70 FROM_HERE, NewTracedMethod(this, &SessionManager::DoPause)); |
70 } | 71 } |
71 | 72 |
72 void SessionManager::SetMaxRate(double rate) { | 73 void SessionManager::SetMaxRate(double rate) { |
73 capture_loop_->PostTask( | 74 capture_loop_->PostTask( |
74 FROM_HERE, NewRunnableMethod(this, &SessionManager::DoSetMaxRate, rate)); | 75 FROM_HERE, NewTracedMethod(this, &SessionManager::DoSetMaxRate, rate)); |
75 } | 76 } |
76 | 77 |
77 void SessionManager::AddClient(scoped_refptr<ClientConnection> client) { | 78 void SessionManager::AddClient(scoped_refptr<ClientConnection> client) { |
78 // Gets the init information for the client. | 79 // Gets the init information for the client. |
79 capture_loop_->PostTask( | 80 capture_loop_->PostTask( |
80 FROM_HERE, | 81 FROM_HERE, |
81 NewRunnableMethod(this, &SessionManager::DoGetInitInfo, client)); | 82 NewTracedMethod(this, &SessionManager::DoGetInitInfo, client)); |
82 } | 83 } |
83 | 84 |
84 void SessionManager::RemoveClient(scoped_refptr<ClientConnection> client) { | 85 void SessionManager::RemoveClient(scoped_refptr<ClientConnection> client) { |
85 network_loop_->PostTask( | 86 network_loop_->PostTask( |
86 FROM_HERE, | 87 FROM_HERE, |
87 NewRunnableMethod(this, &SessionManager::DoRemoveClient, client)); | 88 NewTracedMethod(this, &SessionManager::DoRemoveClient, client)); |
88 } | 89 } |
89 | 90 |
90 void SessionManager::RemoveAllClients() { | 91 void SessionManager::RemoveAllClients() { |
91 network_loop_->PostTask( | 92 network_loop_->PostTask( |
92 FROM_HERE, | 93 FROM_HERE, |
93 NewRunnableMethod(this, &SessionManager::DoRemoveAllClients)); | 94 NewTracedMethod(this, &SessionManager::DoRemoveAllClients)); |
94 } | 95 } |
95 | 96 |
96 // Private accessors ----------------------------------------------------------- | 97 // Private accessors ----------------------------------------------------------- |
97 | 98 |
98 Capturer* SessionManager::capturer() { | 99 Capturer* SessionManager::capturer() { |
99 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 100 DCHECK_EQ(capture_loop_, MessageLoop::current()); |
100 return capturer_.get(); | 101 return capturer_.get(); |
101 } | 102 } |
102 | 103 |
103 Encoder* SessionManager::encoder() { | 104 Encoder* SessionManager::encoder() { |
(...skipping 10 matching lines...) Expand all Loading... |
114 NOTREACHED() << "Record session already started."; | 115 NOTREACHED() << "Record session already started."; |
115 return; | 116 return; |
116 } | 117 } |
117 | 118 |
118 started_ = true; | 119 started_ = true; |
119 DoCapture(); | 120 DoCapture(); |
120 | 121 |
121 // Starts the rate regulation. | 122 // Starts the rate regulation. |
122 network_loop_->PostTask( | 123 network_loop_->PostTask( |
123 FROM_HERE, | 124 FROM_HERE, |
124 NewRunnableMethod(this, &SessionManager::DoStartRateControl)); | 125 NewTracedMethod(this, &SessionManager::DoStartRateControl)); |
125 } | 126 } |
126 | 127 |
127 void SessionManager::DoPause() { | 128 void SessionManager::DoPause() { |
128 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 129 DCHECK_EQ(capture_loop_, MessageLoop::current()); |
129 | 130 |
130 if (!started_) { | 131 if (!started_) { |
131 NOTREACHED() << "Record session not started."; | 132 NOTREACHED() << "Record session not started."; |
132 return; | 133 return; |
133 } | 134 } |
134 | 135 |
135 started_ = false; | 136 started_ = false; |
136 | 137 |
137 // Pause the rate regulation. | 138 // Pause the rate regulation. |
138 network_loop_->PostTask( | 139 network_loop_->PostTask( |
139 FROM_HERE, | 140 FROM_HERE, |
140 NewRunnableMethod(this, &SessionManager::DoPauseRateControl)); | 141 NewTracedMethod(this, &SessionManager::DoPauseRateControl)); |
141 } | 142 } |
142 | 143 |
143 void SessionManager::DoSetRate(double rate) { | 144 void SessionManager::DoSetRate(double rate) { |
144 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 145 DCHECK_EQ(capture_loop_, MessageLoop::current()); |
145 if (rate == rate_) | 146 if (rate == rate_) |
146 return; | 147 return; |
147 | 148 |
148 // Change the current capture rate. | 149 // Change the current capture rate. |
149 rate_ = rate; | 150 rate_ = rate; |
150 | 151 |
(...skipping 11 matching lines...) Expand all Loading... |
162 max_rate_ = max_rate; | 163 max_rate_ = max_rate; |
163 DoSetRate(max_rate); | 164 DoSetRate(max_rate); |
164 } else { | 165 } else { |
165 NOTREACHED() << "Rate is too small."; | 166 NOTREACHED() << "Rate is too small."; |
166 } | 167 } |
167 } | 168 } |
168 | 169 |
169 void SessionManager::ScheduleNextCapture() { | 170 void SessionManager::ScheduleNextCapture() { |
170 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 171 DCHECK_EQ(capture_loop_, MessageLoop::current()); |
171 | 172 |
| 173 ScopedTracer tracer("capture"); |
| 174 |
| 175 TraceContext::tracer()->PrintString("Capture Scheduled"); |
| 176 |
172 if (rate_ == 0) | 177 if (rate_ == 0) |
173 return; | 178 return; |
174 | 179 |
175 base::TimeDelta interval = base::TimeDelta::FromMilliseconds( | 180 base::TimeDelta interval = base::TimeDelta::FromMilliseconds( |
176 static_cast<int>(base::Time::kMillisecondsPerSecond / rate_)); | 181 static_cast<int>(base::Time::kMillisecondsPerSecond / rate_)); |
177 capture_loop_->PostDelayedTask( | 182 capture_loop_->PostDelayedTask( |
178 FROM_HERE, | 183 FROM_HERE, |
179 NewRunnableMethod(this, &SessionManager::DoCapture), | 184 NewTracedMethod(this, &SessionManager::DoCapture), |
180 interval.InMilliseconds()); | 185 interval.InMilliseconds()); |
181 } | 186 } |
182 | 187 |
183 void SessionManager::DoCapture() { | 188 void SessionManager::DoCapture() { |
184 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 189 DCHECK_EQ(capture_loop_, MessageLoop::current()); |
185 // Make sure we have at most two oustanding recordings. We can simply return | 190 // Make sure we have at most two oustanding recordings. We can simply return |
186 // if we can't make a capture now, the next capture will be started by the | 191 // if we can't make a capture now, the next capture will be started by the |
187 // end of an encode operation. | 192 // end of an encode operation. |
188 if (recordings_ >= 2 || !started_) { | 193 if (recordings_ >= 2 || !started_) { |
189 return; | 194 return; |
190 } | 195 } |
| 196 TraceContext::tracer()->PrintString("Capture Started"); |
191 | 197 |
192 base::Time now = base::Time::Now(); | 198 base::Time now = base::Time::Now(); |
193 base::TimeDelta interval = base::TimeDelta::FromMilliseconds( | 199 base::TimeDelta interval = base::TimeDelta::FromMilliseconds( |
194 static_cast<int>(base::Time::kMillisecondsPerSecond / rate_)); | 200 static_cast<int>(base::Time::kMillisecondsPerSecond / rate_)); |
195 base::TimeDelta elapsed = now - last_capture_time_; | 201 base::TimeDelta elapsed = now - last_capture_time_; |
196 | 202 |
197 // If this method is called sooner than the required interval we return | 203 // If this method is called sooner than the required interval we return |
198 // immediately | 204 // immediately |
199 if (elapsed < interval) { | 205 if (elapsed < interval) { |
200 return; | 206 return; |
201 } | 207 } |
202 | 208 |
203 // At this point we are going to perform one capture so save the current time. | 209 // At this point we are going to perform one capture so save the current time. |
204 last_capture_time_ = now; | 210 last_capture_time_ = now; |
205 ++recordings_; | 211 ++recordings_; |
206 | 212 |
207 // Before we actually do a capture, schedule the next one. | 213 // Before we actually do a capture, schedule the next one. |
208 ScheduleNextCapture(); | 214 ScheduleNextCapture(); |
209 | 215 |
210 // And finally perform one capture. | 216 // And finally perform one capture. |
211 DCHECK(capturer_.get()); | 217 DCHECK(capturer()); |
212 | 218 |
213 capturer_->CaptureInvalidRects( | 219 capturer()->CaptureInvalidRects( |
214 NewCallback(this, &SessionManager::CaptureDoneCallback)); | 220 NewCallback(this, &SessionManager::CaptureDoneCallback)); |
215 } | 221 } |
216 | 222 |
217 void SessionManager::CaptureDoneCallback( | 223 void SessionManager::CaptureDoneCallback( |
218 scoped_refptr<CaptureData> capture_data) { | 224 scoped_refptr<CaptureData> capture_data) { |
219 // TODO(hclam): There is a bug if the capturer doesn't produce any dirty | 225 // TODO(hclam): There is a bug if the capturer doesn't produce any dirty |
220 // rects. | 226 // rects. |
221 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 227 DCHECK_EQ(capture_loop_, MessageLoop::current()); |
| 228 TraceContext::tracer()->PrintString("Capture Done"); |
222 encode_loop_->PostTask( | 229 encode_loop_->PostTask( |
223 FROM_HERE, | 230 FROM_HERE, |
224 NewRunnableMethod(this, &SessionManager::DoEncode, capture_data)); | 231 NewTracedMethod(this, &SessionManager::DoEncode, capture_data)); |
225 } | 232 } |
226 | 233 |
227 void SessionManager::DoFinishEncode() { | 234 void SessionManager::DoFinishEncode() { |
228 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 235 DCHECK_EQ(capture_loop_, MessageLoop::current()); |
229 | 236 |
230 // Decrement the number of recording in process since we have completed | 237 // Decrement the number of recording in process since we have completed |
231 // one cycle. | 238 // one cycle. |
232 --recordings_; | 239 --recordings_; |
233 | 240 |
234 // Try to do a capture again. Note that the following method may do nothing | 241 // Try to do a capture again. Note that the following method may do nothing |
235 // if it is too early to perform a capture. | 242 // if it is too early to perform a capture. |
236 if (rate_ > 0) | 243 if (rate_ > 0) |
237 DoCapture(); | 244 DoCapture(); |
238 } | 245 } |
239 | 246 |
240 void SessionManager::DoGetInitInfo(scoped_refptr<ClientConnection> client) { | 247 void SessionManager::DoGetInitInfo(scoped_refptr<ClientConnection> client) { |
241 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 248 DCHECK_EQ(capture_loop_, MessageLoop::current()); |
242 | 249 |
| 250 ScopedTracer tracer("init"); |
| 251 |
243 // Sends the init message to the client. | 252 // Sends the init message to the client. |
244 network_loop_->PostTask( | 253 network_loop_->PostTask( |
245 FROM_HERE, | 254 FROM_HERE, |
246 NewRunnableMethod(this, &SessionManager::DoSendInit, client, | 255 NewTracedMethod(this, &SessionManager::DoSendInit, client, |
247 capturer()->width(), capturer()->height())); | 256 capturer()->width(), capturer()->height())); |
248 | 257 |
249 // And then add the client to the list so it can receive update stream. | 258 // And then add the client to the list so it can receive update stream. |
250 // It is important we do so in such order or the client will receive | 259 // It is important we do so in such order or the client will receive |
251 // update stream before init message. | 260 // update stream before init message. |
252 network_loop_->PostTask( | 261 network_loop_->PostTask( |
253 FROM_HERE, | 262 FROM_HERE, |
254 NewRunnableMethod(this, &SessionManager::DoAddClient, client)); | 263 NewTracedMethod(this, &SessionManager::DoAddClient, client)); |
255 } | 264 } |
256 | 265 |
257 // Network thread -------------------------------------------------------------- | 266 // Network thread -------------------------------------------------------------- |
258 | 267 |
259 void SessionManager::DoStartRateControl() { | 268 void SessionManager::DoStartRateControl() { |
260 DCHECK_EQ(network_loop_, MessageLoop::current()); | 269 DCHECK_EQ(network_loop_, MessageLoop::current()); |
261 | 270 |
262 if (rate_control_started_) { | 271 if (rate_control_started_) { |
263 NOTREACHED() << "Rate regulation already started"; | 272 NOTREACHED() << "Rate regulation already started"; |
264 return; | 273 return; |
265 } | 274 } |
266 rate_control_started_ = true; | 275 rate_control_started_ = true; |
267 ScheduleNextRateControl(); | 276 ScheduleNextRateControl(); |
268 } | 277 } |
269 | 278 |
270 void SessionManager::DoPauseRateControl() { | 279 void SessionManager::DoPauseRateControl() { |
271 DCHECK_EQ(network_loop_, MessageLoop::current()); | 280 DCHECK_EQ(network_loop_, MessageLoop::current()); |
272 | 281 |
273 if (!rate_control_started_) { | 282 if (!rate_control_started_) { |
274 NOTREACHED() << "Rate regulation not started"; | 283 NOTREACHED() << "Rate regulation not started"; |
275 return; | 284 return; |
276 } | 285 } |
277 rate_control_started_ = false; | 286 rate_control_started_ = false; |
278 } | 287 } |
279 | 288 |
280 void SessionManager::ScheduleNextRateControl() { | 289 void SessionManager::ScheduleNextRateControl() { |
| 290 ScopedTracer tracer("Rate Control"); |
281 network_loop_->PostDelayedTask( | 291 network_loop_->PostDelayedTask( |
282 FROM_HERE, | 292 FROM_HERE, |
283 NewRunnableMethod(this, &SessionManager::DoRateControl), | 293 NewTracedMethod(this, &SessionManager::DoRateControl), |
284 kRateControlInterval.InMilliseconds()); | 294 kRateControlInterval.InMilliseconds()); |
285 } | 295 } |
286 | 296 |
287 void SessionManager::DoRateControl() { | 297 void SessionManager::DoRateControl() { |
288 DCHECK_EQ(network_loop_, MessageLoop::current()); | 298 DCHECK_EQ(network_loop_, MessageLoop::current()); |
289 | 299 |
290 // If we have been paused then shutdown the rate regulation loop. | 300 // If we have been paused then shutdown the rate regulation loop. |
291 if (!rate_control_started_) | 301 if (!rate_control_started_) |
292 return; | 302 return; |
293 | 303 |
(...skipping 14 matching lines...) Expand all Loading... |
308 new_rate = 0; | 318 new_rate = 0; |
309 } else { | 319 } else { |
310 // Slow down the capture rate using the divider. | 320 // Slow down the capture rate using the divider. |
311 new_rate = max_rate_ / kRateDividers[slow_down]; | 321 new_rate = max_rate_ / kRateDividers[slow_down]; |
312 } | 322 } |
313 DCHECK_NE(new_rate, -1.0); | 323 DCHECK_NE(new_rate, -1.0); |
314 | 324 |
315 // Then set the rate. | 325 // Then set the rate. |
316 capture_loop_->PostTask( | 326 capture_loop_->PostTask( |
317 FROM_HERE, | 327 FROM_HERE, |
318 NewRunnableMethod(this, &SessionManager::DoSetRate, new_rate)); | 328 NewTracedMethod(this, &SessionManager::DoSetRate, new_rate)); |
319 ScheduleNextRateControl(); | 329 ScheduleNextRateControl(); |
320 } | 330 } |
321 | 331 |
322 void SessionManager::DoSendUpdate(ChromotingHostMessage* message, | 332 void SessionManager::DoSendUpdate(ChromotingHostMessage* message, |
323 Encoder::EncodingState state) { | 333 Encoder::EncodingState state) { |
324 DCHECK_EQ(network_loop_, MessageLoop::current()); | 334 DCHECK_EQ(network_loop_, MessageLoop::current()); |
325 | 335 |
| 336 // TODO(ajwong): We shouldn't need EncodingState. Just inspect message. |
| 337 bool is_end_of_update = (message->rectangle_update().flags() | |
| 338 RectangleUpdatePacket::LAST_PACKET) != 0; |
| 339 |
| 340 TraceContext::tracer()->PrintString("DoSendUpdate"); |
| 341 |
326 // Create a data buffer in wire format from |message|. | 342 // Create a data buffer in wire format from |message|. |
327 // Note that this takes ownership of |message|. | 343 // Note that this takes ownership of |message|. |
328 scoped_refptr<media::DataBuffer> data = | 344 scoped_refptr<media::DataBuffer> data = |
329 ClientConnection::CreateWireFormatDataBuffer(message); | 345 ClientConnection::CreateWireFormatDataBuffer(message); |
330 | 346 |
331 for (ClientConnectionList::const_iterator i = clients_.begin(); | 347 for (ClientConnectionList::const_iterator i = clients_.begin(); |
332 i < clients_.end(); ++i) { | 348 i < clients_.end(); ++i) { |
333 // TODO(hclam): Merge BeginUpdateStreamMessage into |message|. | |
334 if (state & Encoder::EncodingStarting) { | |
335 (*i)->SendBeginUpdateStreamMessage(); | |
336 } | |
337 | |
338 (*i)->SendUpdateStreamPacketMessage(data); | 349 (*i)->SendUpdateStreamPacketMessage(data); |
339 | 350 |
340 // TODO(hclam): Merge EndUpdateStreamMessage into |message|. | 351 if (is_end_of_update) |
341 if (state & Encoder::EncodingEnded) | 352 (*i)->MarkEndOfUpdate(); |
342 (*i)->SendEndUpdateStreamMessage(); | |
343 } | 353 } |
| 354 TraceContext::tracer()->PrintString("DoSendUpdate done"); |
344 } | 355 } |
345 | 356 |
346 void SessionManager::DoSendInit(scoped_refptr<ClientConnection> client, | 357 void SessionManager::DoSendInit(scoped_refptr<ClientConnection> client, |
347 int width, int height) { | 358 int width, int height) { |
348 DCHECK_EQ(network_loop_, MessageLoop::current()); | 359 DCHECK_EQ(network_loop_, MessageLoop::current()); |
349 | 360 |
350 // Sends the client init information. | 361 // Sends the client init information. |
351 client->SendInitClientMessage(width, height); | 362 client->SendInitClientMessage(width, height); |
352 } | 363 } |
353 | 364 |
(...skipping 20 matching lines...) Expand all Loading... |
374 | 385 |
375 // Clear the list of clients. | 386 // Clear the list of clients. |
376 clients_.clear(); | 387 clients_.clear(); |
377 } | 388 } |
378 | 389 |
379 // Encoder thread -------------------------------------------------------------- | 390 // Encoder thread -------------------------------------------------------------- |
380 | 391 |
381 void SessionManager::DoEncode( | 392 void SessionManager::DoEncode( |
382 scoped_refptr<CaptureData> capture_data) { | 393 scoped_refptr<CaptureData> capture_data) { |
383 DCHECK_EQ(encode_loop_, MessageLoop::current()); | 394 DCHECK_EQ(encode_loop_, MessageLoop::current()); |
| 395 TraceContext::tracer()->PrintString("DoEncode called"); |
384 | 396 |
| 397 // Early out if there's nothing to encode. |
385 if (!capture_data->dirty_rects().size()) { | 398 if (!capture_data->dirty_rects().size()) { |
386 capture_loop_->PostTask( | 399 capture_loop_->PostTask( |
387 FROM_HERE, NewRunnableMethod(this, &SessionManager::DoFinishEncode)); | 400 FROM_HERE, NewTracedMethod(this, &SessionManager::DoFinishEncode)); |
| 401 return; |
388 } | 402 } |
389 | 403 |
390 // TODO(hclam): Enable |force_refresh| if a new client was | 404 // TODO(hclam): Enable |force_refresh| if a new client was |
391 // added. | 405 // added. |
| 406 TraceContext::tracer()->PrintString("Encode start"); |
392 encoder_->Encode(capture_data, false, | 407 encoder_->Encode(capture_data, false, |
393 NewCallback(this, &SessionManager::EncodeDataAvailableTask)); | 408 NewCallback(this, &SessionManager::EncodeDataAvailableTask)); |
| 409 TraceContext::tracer()->PrintString("Encode Done"); |
394 } | 410 } |
395 | 411 |
396 void SessionManager::EncodeDataAvailableTask( | 412 void SessionManager::EncodeDataAvailableTask( |
397 ChromotingHostMessage* message, Encoder::EncodingState state) { | 413 ChromotingHostMessage* message, Encoder::EncodingState state) { |
398 DCHECK_EQ(encode_loop_, MessageLoop::current()); | 414 DCHECK_EQ(encode_loop_, MessageLoop::current()); |
399 | 415 |
400 // Before a new encode task starts, notify clients a new update | 416 // Before a new encode task starts, notify clients a new update |
401 // stream is coming. | 417 // stream is coming. |
402 // Notify this will keep a reference to the DataBuffer in the | 418 // Notify this will keep a reference to the DataBuffer in the |
403 // task. The ownership will eventually pass to the ClientConnections. | 419 // task. The ownership will eventually pass to the ClientConnections. |
404 network_loop_->PostTask( | 420 network_loop_->PostTask( |
405 FROM_HERE, | 421 FROM_HERE, |
406 NewRunnableMethod(this, &SessionManager::DoSendUpdate, message, state)); | 422 NewTracedMethod(this, &SessionManager::DoSendUpdate, message, state)); |
407 | 423 |
408 if (state & Encoder::EncodingEnded) { | 424 if (state & Encoder::EncodingEnded) { |
409 capture_loop_->PostTask( | 425 capture_loop_->PostTask( |
410 FROM_HERE, NewRunnableMethod(this, &SessionManager::DoFinishEncode)); | 426 FROM_HERE, NewTracedMethod(this, &SessionManager::DoFinishEncode)); |
411 } | 427 } |
412 } | 428 } |
413 | 429 |
414 } // namespace remoting | 430 } // namespace remoting |
OLD | NEW |