| 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 |