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

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

Issue 7635005: Properly handle screen recorder shutdown in ChromotingHost. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: - Created 9 years, 4 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/logging.h" 10 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
11 #include "base/stl_util.h" 12 #include "base/stl_util.h"
12 #include "base/task.h" 13 #include "base/task.h"
13 #include "base/time.h" 14 #include "base/time.h"
14 #include "remoting/base/capture_data.h" 15 #include "remoting/base/capture_data.h"
15 #include "remoting/base/tracer.h" 16 #include "remoting/base/tracer.h"
16 #include "remoting/proto/control.pb.h" 17 #include "remoting/proto/control.pb.h"
17 #include "remoting/proto/video.pb.h" 18 #include "remoting/proto/video.pb.h"
18 #include "remoting/protocol/client_stub.h" 19 #include "remoting/protocol/client_stub.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 ScreenRecorder::~ScreenRecorder() { 61 ScreenRecorder::~ScreenRecorder() {
61 } 62 }
62 63
63 // Public methods -------------------------------------------------------------- 64 // Public methods --------------------------------------------------------------
64 65
65 void ScreenRecorder::Start() { 66 void ScreenRecorder::Start() {
66 capture_loop_->PostTask( 67 capture_loop_->PostTask(
67 FROM_HERE, NewTracedMethod(this, &ScreenRecorder::DoStart)); 68 FROM_HERE, NewTracedMethod(this, &ScreenRecorder::DoStart));
68 } 69 }
69 70
70 void ScreenRecorder::Stop(Task* done_task) { 71 void ScreenRecorder::Stop(const base::Closure& done_task) {
71 capture_loop_->PostTask( 72 if (MessageLoop::current() != capture_loop_) {
72 FROM_HERE, NewTracedMethod(this, &ScreenRecorder::DoStop, done_task)); 73 capture_loop_->PostTask(FROM_HERE, base::Bind(
74 &ScreenRecorder::Stop, this, done_task));
75 return;
76 }
77
78 DCHECK(!done_task.is_null());
79
80 capture_timer_.Stop();
81 is_recording_ = false;
82
83 network_loop_->PostTask(FROM_HERE, base::Bind(
84 &ScreenRecorder::DoStopOnNetworkThread, this, done_task));
73 } 85 }
74 86
75 void ScreenRecorder::SetMaxRate(double rate) { 87 void ScreenRecorder::SetMaxRate(double rate) {
76 capture_loop_->PostTask( 88 capture_loop_->PostTask(
77 FROM_HERE, NewTracedMethod(this, &ScreenRecorder::DoSetMaxRate, rate)); 89 FROM_HERE, NewTracedMethod(this, &ScreenRecorder::DoSetMaxRate, rate));
78 } 90 }
79 91
80 void ScreenRecorder::AddConnection( 92 void ScreenRecorder::AddConnection(
81 scoped_refptr<ConnectionToClient> connection) { 93 scoped_refptr<ConnectionToClient> connection) {
82 ScopedTracer tracer("AddConnection"); 94 ScopedTracer tracer("AddConnection");
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 return; 153 return;
142 } 154 }
143 155
144 is_recording_ = true; 156 is_recording_ = true;
145 StartCaptureTimer(); 157 StartCaptureTimer();
146 158
147 // Capture first frame immedately. 159 // Capture first frame immedately.
148 DoCapture(); 160 DoCapture();
149 } 161 }
150 162
151 void ScreenRecorder::DoStop(Task* done_task) {
152 DCHECK_EQ(capture_loop_, MessageLoop::current());
153
154 base::ScopedTaskRunner done_runner(done_task);
155
156 // We might have not started when we receive a stop command, simply run the
157 // task and then return.
158 if (!is_recording_)
159 return;
160
161 capture_timer_.Stop();
162 is_recording_ = false;
163
164 DCHECK_GE(recordings_, 0);
165 if (recordings_) {
166 network_loop_->PostTask(
167 FROM_HERE,
168 NewTracedMethod(this,
169 &ScreenRecorder::DoStopOnNetworkThread,
170 done_runner.Release()));
171 return;
172 }
173 }
174
175 void ScreenRecorder::DoSetMaxRate(double max_rate) { 163 void ScreenRecorder::DoSetMaxRate(double max_rate) {
176 DCHECK_EQ(capture_loop_, MessageLoop::current()); 164 DCHECK_EQ(capture_loop_, MessageLoop::current());
177 165
178 // TODO(hclam): Should also check for small epsilon. 166 // TODO(hclam): Should also check for small epsilon.
179 DCHECK_GT(max_rate, 0.0) << "Rate is too small."; 167 DCHECK_GT(max_rate, 0.0) << "Rate is too small.";
180 168
181 max_rate_ = max_rate; 169 max_rate_ = max_rate;
182 170
183 // Restart the timer with the new rate. 171 // Restart the timer with the new rate.
184 if (is_recording_) { 172 if (is_recording_) {
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 } 322 }
335 } 323 }
336 324
337 void ScreenRecorder::DoRemoveAllClients() { 325 void ScreenRecorder::DoRemoveAllClients() {
338 DCHECK_EQ(network_loop_, MessageLoop::current()); 326 DCHECK_EQ(network_loop_, MessageLoop::current());
339 327
340 // Clear the list of connections. 328 // Clear the list of connections.
341 connections_.clear(); 329 connections_.clear();
342 } 330 }
343 331
344 void ScreenRecorder::DoStopOnNetworkThread(Task* done_task) { 332 void ScreenRecorder::DoStopOnNetworkThread(const base::Closure& done_task) {
345 DCHECK_EQ(network_loop_, MessageLoop::current()); 333 DCHECK_EQ(network_loop_, MessageLoop::current());
346 334
347 // There could be tasks on the network thread when this method is being 335 // There could be tasks on the network thread when this method is being
348 // executed. By setting the flag we'll not post anymore tasks from network 336 // executed. By setting the flag we'll not post anymore tasks from network
349 // thread. 337 // thread.
350 // 338 //
351 // After that a task is posted on encode thread to continue the stop 339 // After that a task is posted on encode thread to continue the stop
352 // sequence. 340 // sequence.
353 network_stopped_ = true; 341 network_stopped_ = true;
354 342
(...skipping 23 matching lines...) Expand all
378 } 366 }
379 367
380 TraceContext::tracer()->PrintString("Encode start"); 368 TraceContext::tracer()->PrintString("Encode start");
381 encode_start_time_ = base::Time::Now(); 369 encode_start_time_ = base::Time::Now();
382 encoder()->Encode( 370 encoder()->Encode(
383 capture_data, false, 371 capture_data, false,
384 NewCallback(this, &ScreenRecorder::EncodedDataAvailableCallback)); 372 NewCallback(this, &ScreenRecorder::EncodedDataAvailableCallback));
385 TraceContext::tracer()->PrintString("Encode Done"); 373 TraceContext::tracer()->PrintString("Encode Done");
386 } 374 }
387 375
388 void ScreenRecorder::DoStopOnEncodeThread(Task* done_task) { 376 void ScreenRecorder::DoStopOnEncodeThread(const base::Closure& done_task) {
389 DCHECK_EQ(encode_loop_, MessageLoop::current()); 377 DCHECK_EQ(encode_loop_, MessageLoop::current());
390 378
391 encoder_stopped_ = true; 379 encoder_stopped_ = true;
392 380
393 // When this method is being executed there are no more tasks on encode thread 381 // When this method is being executed there are no more tasks on encode thread
394 // for this object. We can then post a task to capture thread to finish the 382 // for this object. We can then post a task to capture thread to finish the
395 // stop sequence. 383 // stop sequence.
396 if (done_task) 384 capture_loop_->PostTask(FROM_HERE, done_task);
397 capture_loop_->PostTask(FROM_HERE, done_task);
398 } 385 }
399 386
400 void ScreenRecorder::EncodedDataAvailableCallback(VideoPacket* packet) { 387 void ScreenRecorder::EncodedDataAvailableCallback(VideoPacket* packet) {
401 DCHECK_EQ(encode_loop_, MessageLoop::current()); 388 DCHECK_EQ(encode_loop_, MessageLoop::current());
402 389
403 if (encoder_stopped_) 390 if (encoder_stopped_)
404 return; 391 return;
405 392
406 bool last = (packet->flags() & VideoPacket::LAST_PACKET) != 0; 393 bool last = (packet->flags() & VideoPacket::LAST_PACKET) != 0;
407 if (last) { 394 if (last) {
408 int encode_time = static_cast<int>( 395 int encode_time = static_cast<int>(
409 (base::Time::Now() - encode_start_time_).InMilliseconds()); 396 (base::Time::Now() - encode_start_time_).InMilliseconds());
410 packet->set_encode_time_ms(encode_time); 397 packet->set_encode_time_ms(encode_time);
411 } 398 }
412 399
413 network_loop_->PostTask( 400 network_loop_->PostTask(
414 FROM_HERE, 401 FROM_HERE,
415 NewTracedMethod(this, &ScreenRecorder::DoSendVideoPacket, packet)); 402 NewTracedMethod(this, &ScreenRecorder::DoSendVideoPacket, packet));
416 } 403 }
417 404
418 } // namespace remoting 405 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698