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

Unified Diff: remoting/host/screen_recorder.cc

Issue 6282006: Add a done task to ScreenRecorder::Stop() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed comments Created 9 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « remoting/host/screen_recorder.h ('k') | remoting/host/screen_recorder_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/host/screen_recorder.cc
diff --git a/remoting/host/screen_recorder.cc b/remoting/host/screen_recorder.cc
index cf3417ce4129cc102007c17ec40f1244bbfd312c..76ebcc8e4128d177bd74bbf2f198916fa4d9aec2 100644
--- a/remoting/host/screen_recorder.cc
+++ b/remoting/host/screen_recorder.cc
@@ -45,7 +45,8 @@ ScreenRecorder::ScreenRecorder(
network_loop_(network_loop),
capturer_(capturer),
encoder_(encoder),
- started_(false),
+ is_recording_(false),
+ network_stopped_(false),
recordings_(0),
frame_skipped_(false),
max_rate_(kDefaultCaptureRate) {
@@ -55,7 +56,6 @@ ScreenRecorder::ScreenRecorder(
}
ScreenRecorder::~ScreenRecorder() {
- connections_.clear();
}
// Public methods --------------------------------------------------------------
@@ -65,9 +65,9 @@ void ScreenRecorder::Start() {
FROM_HERE, NewTracedMethod(this, &ScreenRecorder::DoStart));
}
-void ScreenRecorder::Pause() {
+void ScreenRecorder::Stop(Task* done_task) {
capture_loop_->PostTask(
- FROM_HERE, NewTracedMethod(this, &ScreenRecorder::DoPause));
+ FROM_HERE, NewTracedMethod(this, &ScreenRecorder::DoStop, done_task));
}
void ScreenRecorder::SetMaxRate(double rate) {
@@ -116,30 +116,49 @@ Encoder* ScreenRecorder::encoder() {
void ScreenRecorder::DoStart() {
DCHECK_EQ(capture_loop_, MessageLoop::current());
- DCHECK(!started_);
- if (started_) {
+ if (is_recording_) {
NOTREACHED() << "Record session already started.";
return;
}
- started_ = true;
+ is_recording_ = true;
StartCaptureTimer();
// Capture first frame immedately.
DoCapture();
}
-void ScreenRecorder::DoPause() {
+void ScreenRecorder::DoStop(Task* done_task) {
DCHECK_EQ(capture_loop_, MessageLoop::current());
- if (!started_) {
+ if (!is_recording_) {
NOTREACHED() << "Record session not started.";
return;
}
capture_timer_.Stop();
- started_ = false;
+ is_recording_ = false;
+
+ DCHECK_GE(recordings_, 0);
+ if (recordings_) {
+ network_loop_->PostTask(
+ FROM_HERE,
+ NewTracedMethod(this,
+ &ScreenRecorder::DoStopOnNetworkThread, done_task));
+ return;
+ }
+
+ DoCompleteStop(done_task);
+}
+
+void ScreenRecorder::DoCompleteStop(Task* done_task) {
+ DCHECK_EQ(capture_loop_, MessageLoop::current());
+
+ if (done_task) {
+ done_task->Run();
+ delete done_task;
+ }
}
void ScreenRecorder::DoSetMaxRate(double max_rate) {
@@ -151,7 +170,7 @@ void ScreenRecorder::DoSetMaxRate(double max_rate) {
max_rate_ = max_rate;
// Restart the timer with the new rate.
- if (started_) {
+ if (is_recording_) {
capture_timer_.Stop();
StartCaptureTimer();
}
@@ -170,7 +189,7 @@ void ScreenRecorder::DoCapture() {
// Make sure we have at most two oustanding recordings. We can simply return
// if we can't make a capture now, the next capture will be started by the
// end of an encode operation.
- if (recordings_ >= kMaxRecordings || !started_) {
+ if (recordings_ >= kMaxRecordings || !is_recording_) {
frame_skipped_ = true;
return;
}
@@ -184,6 +203,7 @@ void ScreenRecorder::DoCapture() {
// At this point we are going to perform one capture so save the current time.
++recordings_;
+ DCHECK_LE(recordings_, kMaxRecordings);
// And finally perform one capture.
capturer()->CaptureInvalidRects(
@@ -192,21 +212,27 @@ void ScreenRecorder::DoCapture() {
void ScreenRecorder::CaptureDoneCallback(
scoped_refptr<CaptureData> capture_data) {
- // TODO(hclam): There is a bug if the capturer doesn't produce any dirty
- // rects.
DCHECK_EQ(capture_loop_, MessageLoop::current());
+
+ if (!is_recording_)
+ return;
+
TraceContext::tracer()->PrintString("Capture Done");
encode_loop_->PostTask(
FROM_HERE,
NewTracedMethod(this, &ScreenRecorder::DoEncode, capture_data));
}
-void ScreenRecorder::DoFinishSend() {
+void ScreenRecorder::DoFinishOneRecording() {
DCHECK_EQ(capture_loop_, MessageLoop::current());
+ if (!is_recording_)
+ return;
+
// Decrement the number of recording in process since we have completed
// one cycle.
--recordings_;
+ DCHECK_GE(recordings_, 0);
// Try to do a capture again. Note that the following method may do nothing
// if it is too early to perform a capture.
@@ -222,14 +248,23 @@ void ScreenRecorder::DoSendVideoPacket(VideoPacket* packet) {
bool last = (packet->flags() & VideoPacket::LAST_PARTITION) != 0;
+ if (network_stopped_) {
+ delete packet;
+ return;
+ }
+
for (ConnectionToClientList::const_iterator i = connections_.begin();
i < connections_.end(); ++i) {
Task* done_task = NULL;
- // Call OnFrameSent() only for the last packet in the first connection.
+ // Call FrameSentCallback() only for the last packet in the first
+ // connection.
if (last && i == connections_.begin()) {
- done_task = NewTracedMethod(this, &ScreenRecorder::OnFrameSent, packet);
+ done_task = NewTracedMethod(this, &ScreenRecorder::FrameSentCallback,
+ packet);
} else {
+ // TODO(hclam): Fix this code since it causes multiple deletion if there's
+ // more than one connection.
done_task = new DeleteTask<VideoPacket>(packet);
}
@@ -239,10 +274,14 @@ void ScreenRecorder::DoSendVideoPacket(VideoPacket* packet) {
TraceContext::tracer()->PrintString("DoSendVideoPacket done");
}
-void ScreenRecorder::OnFrameSent(VideoPacket* packet) {
+void ScreenRecorder::FrameSentCallback(VideoPacket* packet) {
delete packet;
+
+ if (network_stopped_)
+ return;
+
capture_loop_->PostTask(
- FROM_HERE, NewTracedMethod(this, &ScreenRecorder::DoFinishSend));
+ FROM_HERE, NewTracedMethod(this, &ScreenRecorder::DoFinishOneRecording));
}
void ScreenRecorder::DoAddConnection(
@@ -272,6 +311,22 @@ void ScreenRecorder::DoRemoveAllClients() {
connections_.clear();
}
+void ScreenRecorder::DoStopOnNetworkThread(Task* done_task) {
+ DCHECK_EQ(network_loop_, MessageLoop::current());
+
+ // There could be tasks on the network thread when this method is being
+ // executed. By setting the flag we'll not post anymore tasks from network
+ // thread.
+ //
+ // After that a task is posted on encode thread to continue the stop
+ // sequence.
+ network_stopped_ = true;
+
+ encode_loop_->PostTask(
+ FROM_HERE,
+ NewTracedMethod(this, &ScreenRecorder::DoStopOnEncodeThread, done_task));
+}
+
// Encoder thread --------------------------------------------------------------
void ScreenRecorder::DoEncode(
@@ -282,19 +337,31 @@ void ScreenRecorder::DoEncode(
// Early out if there's nothing to encode.
if (!capture_data->dirty_rects().size()) {
capture_loop_->PostTask(
- FROM_HERE, NewTracedMethod(this, &ScreenRecorder::DoFinishSend));
+ FROM_HERE,
+ NewTracedMethod(this, &ScreenRecorder::DoFinishOneRecording));
return;
}
- // TODO(hclam): Enable |force_refresh| if a new connection was
- // added.
+ // TODO(hclam): Invalidate the full screen if there is a new connection added.
TraceContext::tracer()->PrintString("Encode start");
- encoder()->Encode(capture_data, false,
- NewCallback(this, &ScreenRecorder::EncodeDataAvailableTask));
+ encoder()->Encode(
+ capture_data, false,
+ NewCallback(this, &ScreenRecorder::EncodedDataAvailableCallback));
TraceContext::tracer()->PrintString("Encode Done");
}
-void ScreenRecorder::EncodeDataAvailableTask(VideoPacket* packet) {
+void ScreenRecorder::DoStopOnEncodeThread(Task* done_task) {
+ DCHECK_EQ(encode_loop_, MessageLoop::current());
+
+ // When this method is being executed there are no more tasks on encode thread
+ // for this object. We can then post a task to capture thread to finish the
+ // stop sequence.
+ capture_loop_->PostTask(
+ FROM_HERE,
+ NewTracedMethod(this, &ScreenRecorder::DoCompleteStop, done_task));
+}
+
+void ScreenRecorder::EncodedDataAvailableCallback(VideoPacket* packet) {
DCHECK_EQ(encode_loop_, MessageLoop::current());
network_loop_->PostTask(
« 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