| 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" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 | 32 |
| 33 // We divide the pending update stream number by this value to determine the | 33 // We divide the pending update stream number by this value to determine the |
| 34 // rate divider. | 34 // rate divider. |
| 35 static const int kSlowDownFactor = 10; | 35 static const int kSlowDownFactor = 10; |
| 36 | 36 |
| 37 // A list of dividers used to divide the max rate to determine the current | 37 // A list of dividers used to divide the max rate to determine the current |
| 38 // capture rate. | 38 // capture rate. |
| 39 static const int kRateDividers[] = {1, 2, 4, 8, 16}; | 39 static const int kRateDividers[] = {1, 2, 4, 8, 16}; |
| 40 | 40 |
| 41 SessionManager::SessionManager( | 41 SessionManager::SessionManager( |
| 42 MessageLoop* capture_loop, | 42 scoped_refptr<base::MessageLoopProxy> capture_loop, |
| 43 MessageLoop* encode_loop, | 43 MessageLoop* encode_loop, |
| 44 MessageLoop* network_loop, | 44 MessageLoop* network_loop, |
| 45 Capturer* capturer, | 45 Capturer* capturer, |
| 46 Encoder* encoder) | 46 Encoder* encoder) |
| 47 : capture_loop_(capture_loop), | 47 : capture_loop_(capture_loop), |
| 48 encode_loop_(encode_loop), | 48 encode_loop_(encode_loop), |
| 49 network_loop_(network_loop), | 49 network_loop_(network_loop), |
| 50 capturer_(capturer), | 50 capturer_(capturer), |
| 51 encoder_(encoder), | 51 encoder_(encoder), |
| 52 rate_(kDefaultCaptureRate), | 52 rate_(kDefaultCaptureRate), |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 | 97 |
| 98 void SessionManager::RemoveAllConnections() { | 98 void SessionManager::RemoveAllConnections() { |
| 99 network_loop_->PostTask( | 99 network_loop_->PostTask( |
| 100 FROM_HERE, | 100 FROM_HERE, |
| 101 NewTracedMethod(this, &SessionManager::DoRemoveAllClients)); | 101 NewTracedMethod(this, &SessionManager::DoRemoveAllClients)); |
| 102 } | 102 } |
| 103 | 103 |
| 104 // Private accessors ----------------------------------------------------------- | 104 // Private accessors ----------------------------------------------------------- |
| 105 | 105 |
| 106 Capturer* SessionManager::capturer() { | 106 Capturer* SessionManager::capturer() { |
| 107 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 107 DCHECK(capture_loop_->BelongsToCurrentThread()); |
| 108 return capturer_.get(); | 108 return capturer_.get(); |
| 109 } | 109 } |
| 110 | 110 |
| 111 Encoder* SessionManager::encoder() { | 111 Encoder* SessionManager::encoder() { |
| 112 DCHECK_EQ(encode_loop_, MessageLoop::current()); | 112 DCHECK_EQ(encode_loop_, MessageLoop::current()); |
| 113 return encoder_.get(); | 113 return encoder_.get(); |
| 114 } | 114 } |
| 115 | 115 |
| 116 // Capturer thread ------------------------------------------------------------- | 116 // Capturer thread ------------------------------------------------------------- |
| 117 | 117 |
| 118 void SessionManager::DoStart() { | 118 void SessionManager::DoStart() { |
| 119 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 119 DCHECK(capture_loop_->BelongsToCurrentThread()); |
| 120 | 120 |
| 121 if (started_) { | 121 if (started_) { |
| 122 NOTREACHED() << "Record session already started."; | 122 NOTREACHED() << "Record session already started."; |
| 123 return; | 123 return; |
| 124 } | 124 } |
| 125 | 125 |
| 126 started_ = true; | 126 started_ = true; |
| 127 DoCapture(); | 127 DoCapture(); |
| 128 | 128 |
| 129 // Starts the rate regulation. | 129 // Starts the rate regulation. |
| 130 network_loop_->PostTask( | 130 network_loop_->PostTask( |
| 131 FROM_HERE, | 131 FROM_HERE, |
| 132 NewTracedMethod(this, &SessionManager::DoStartRateControl)); | 132 NewTracedMethod(this, &SessionManager::DoStartRateControl)); |
| 133 } | 133 } |
| 134 | 134 |
| 135 void SessionManager::DoPause() { | 135 void SessionManager::DoPause() { |
| 136 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 136 DCHECK(capture_loop_->BelongsToCurrentThread()); |
| 137 | 137 |
| 138 if (!started_) { | 138 if (!started_) { |
| 139 NOTREACHED() << "Record session not started."; | 139 NOTREACHED() << "Record session not started."; |
| 140 return; | 140 return; |
| 141 } | 141 } |
| 142 | 142 |
| 143 started_ = false; | 143 started_ = false; |
| 144 | 144 |
| 145 // Pause the rate regulation. | 145 // Pause the rate regulation. |
| 146 network_loop_->PostTask( | 146 network_loop_->PostTask( |
| 147 FROM_HERE, | 147 FROM_HERE, |
| 148 NewTracedMethod(this, &SessionManager::DoPauseRateControl)); | 148 NewTracedMethod(this, &SessionManager::DoPauseRateControl)); |
| 149 } | 149 } |
| 150 | 150 |
| 151 void SessionManager::DoSetRate(double rate) { | 151 void SessionManager::DoSetRate(double rate) { |
| 152 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 152 DCHECK(capture_loop_->BelongsToCurrentThread()); |
| 153 if (rate == rate_) | 153 if (rate == rate_) |
| 154 return; | 154 return; |
| 155 | 155 |
| 156 // Change the current capture rate. | 156 // Change the current capture rate. |
| 157 rate_ = rate; | 157 rate_ = rate; |
| 158 | 158 |
| 159 // If we have already started then schedule the next capture with the new | 159 // If we have already started then schedule the next capture with the new |
| 160 // rate. | 160 // rate. |
| 161 if (started_) | 161 if (started_) |
| 162 ScheduleNextCapture(); | 162 ScheduleNextCapture(); |
| 163 } | 163 } |
| 164 | 164 |
| 165 void SessionManager::DoSetMaxRate(double max_rate) { | 165 void SessionManager::DoSetMaxRate(double max_rate) { |
| 166 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 166 DCHECK(capture_loop_->BelongsToCurrentThread()); |
| 167 | 167 |
| 168 // TODO(hclam): Should also check for small epsilon. | 168 // TODO(hclam): Should also check for small epsilon. |
| 169 if (max_rate != 0) { | 169 if (max_rate != 0) { |
| 170 max_rate_ = max_rate; | 170 max_rate_ = max_rate; |
| 171 DoSetRate(max_rate); | 171 DoSetRate(max_rate); |
| 172 } else { | 172 } else { |
| 173 NOTREACHED() << "Rate is too small."; | 173 NOTREACHED() << "Rate is too small."; |
| 174 } | 174 } |
| 175 } | 175 } |
| 176 | 176 |
| 177 void SessionManager::ScheduleNextCapture() { | 177 void SessionManager::ScheduleNextCapture() { |
| 178 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 178 DCHECK(capture_loop_->BelongsToCurrentThread()); |
| 179 | 179 |
| 180 ScopedTracer tracer("capture"); | 180 ScopedTracer tracer("capture"); |
| 181 | 181 |
| 182 TraceContext::tracer()->PrintString("Capture Scheduled"); | 182 TraceContext::tracer()->PrintString("Capture Scheduled"); |
| 183 | 183 |
| 184 if (rate_ == 0) | 184 if (rate_ == 0) |
| 185 return; | 185 return; |
| 186 | 186 |
| 187 base::TimeDelta interval = base::TimeDelta::FromMilliseconds( | 187 base::TimeDelta interval = base::TimeDelta::FromMilliseconds( |
| 188 static_cast<int>(base::Time::kMillisecondsPerSecond / rate_)); | 188 static_cast<int>(base::Time::kMillisecondsPerSecond / rate_)); |
| 189 capture_loop_->PostDelayedTask( | 189 capture_loop_->PostDelayedTask( |
| 190 FROM_HERE, | 190 FROM_HERE, |
| 191 NewTracedMethod(this, &SessionManager::DoCapture), | 191 NewTracedMethod(this, &SessionManager::DoCapture), |
| 192 interval.InMilliseconds()); | 192 interval.InMilliseconds()); |
| 193 } | 193 } |
| 194 | 194 |
| 195 void SessionManager::DoCapture() { | 195 void SessionManager::DoCapture() { |
| 196 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 196 DCHECK(capture_loop_->BelongsToCurrentThread()); |
| 197 // Make sure we have at most two oustanding recordings. We can simply return | 197 // Make sure we have at most two oustanding recordings. We can simply return |
| 198 // if we can't make a capture now, the next capture will be started by the | 198 // if we can't make a capture now, the next capture will be started by the |
| 199 // end of an encode operation. | 199 // end of an encode operation. |
| 200 if (recordings_ >= 2 || !started_) { | 200 if (recordings_ >= 2 || !started_) { |
| 201 return; | 201 return; |
| 202 } | 202 } |
| 203 TraceContext::tracer()->PrintString("Capture Started"); | 203 TraceContext::tracer()->PrintString("Capture Started"); |
| 204 | 204 |
| 205 base::Time now = base::Time::Now(); | 205 base::Time now = base::Time::Now(); |
| 206 base::TimeDelta interval = base::TimeDelta::FromMilliseconds( | 206 base::TimeDelta interval = base::TimeDelta::FromMilliseconds( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 224 DCHECK(capturer()); | 224 DCHECK(capturer()); |
| 225 | 225 |
| 226 capturer()->CaptureInvalidRects( | 226 capturer()->CaptureInvalidRects( |
| 227 NewCallback(this, &SessionManager::CaptureDoneCallback)); | 227 NewCallback(this, &SessionManager::CaptureDoneCallback)); |
| 228 } | 228 } |
| 229 | 229 |
| 230 void SessionManager::CaptureDoneCallback( | 230 void SessionManager::CaptureDoneCallback( |
| 231 scoped_refptr<CaptureData> capture_data) { | 231 scoped_refptr<CaptureData> capture_data) { |
| 232 // TODO(hclam): There is a bug if the capturer doesn't produce any dirty | 232 // TODO(hclam): There is a bug if the capturer doesn't produce any dirty |
| 233 // rects. | 233 // rects. |
| 234 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 234 DCHECK(capture_loop_->BelongsToCurrentThread()); |
| 235 TraceContext::tracer()->PrintString("Capture Done"); | 235 TraceContext::tracer()->PrintString("Capture Done"); |
| 236 encode_loop_->PostTask( | 236 encode_loop_->PostTask( |
| 237 FROM_HERE, | 237 FROM_HERE, |
| 238 NewTracedMethod(this, &SessionManager::DoEncode, capture_data)); | 238 NewTracedMethod(this, &SessionManager::DoEncode, capture_data)); |
| 239 } | 239 } |
| 240 | 240 |
| 241 void SessionManager::DoFinishEncode() { | 241 void SessionManager::DoFinishEncode() { |
| 242 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 242 DCHECK(capture_loop_->BelongsToCurrentThread()); |
| 243 | 243 |
| 244 // Decrement the number of recording in process since we have completed | 244 // Decrement the number of recording in process since we have completed |
| 245 // one cycle. | 245 // one cycle. |
| 246 --recordings_; | 246 --recordings_; |
| 247 | 247 |
| 248 // Try to do a capture again. Note that the following method may do nothing | 248 // Try to do a capture again. Note that the following method may do nothing |
| 249 // if it is too early to perform a capture. | 249 // if it is too early to perform a capture. |
| 250 if (rate_ > 0) | 250 if (rate_ > 0) |
| 251 DoCapture(); | 251 DoCapture(); |
| 252 } | 252 } |
| 253 | 253 |
| 254 void SessionManager::DoGetInitInfo( | 254 void SessionManager::DoGetInitInfo( |
| 255 scoped_refptr<ConnectionToClient> connection) { | 255 scoped_refptr<ConnectionToClient> connection) { |
| 256 DCHECK_EQ(capture_loop_, MessageLoop::current()); | 256 DCHECK(capture_loop_->BelongsToCurrentThread()); |
| 257 | 257 |
| 258 ScopedTracer tracer("init"); | 258 ScopedTracer tracer("init"); |
| 259 | 259 |
| 260 // Add the client to the list so it can receive update stream. | 260 // Add the client to the list so it can receive update stream. |
| 261 network_loop_->PostTask( | 261 network_loop_->PostTask( |
| 262 FROM_HERE, | 262 FROM_HERE, |
| 263 NewTracedMethod(this, &SessionManager::DoAddClient, connection)); | 263 NewTracedMethod(this, &SessionManager::DoAddClient, connection)); |
| 264 } | 264 } |
| 265 | 265 |
| 266 // Network thread -------------------------------------------------------------- | 266 // Network thread -------------------------------------------------------------- |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 FROM_HERE, | 404 FROM_HERE, |
| 405 NewTracedMethod(this, &SessionManager::DoSendVideoPacket, packet)); | 405 NewTracedMethod(this, &SessionManager::DoSendVideoPacket, packet)); |
| 406 | 406 |
| 407 if (last) { | 407 if (last) { |
| 408 capture_loop_->PostTask( | 408 capture_loop_->PostTask( |
| 409 FROM_HERE, NewTracedMethod(this, &SessionManager::DoFinishEncode)); | 409 FROM_HERE, NewTracedMethod(this, &SessionManager::DoFinishEncode)); |
| 410 } | 410 } |
| 411 } | 411 } |
| 412 | 412 |
| 413 } // namespace remoting | 413 } // namespace remoting |
| OLD | NEW |