Index: remoting/host/video_scheduler.cc |
diff --git a/remoting/host/video_scheduler.cc b/remoting/host/video_scheduler.cc |
index 75c7c1215910b187b6f06648c26a4f0c255c7759..a82d626b65f59bdf8d6dc9833721797307fec719 100644 |
--- a/remoting/host/video_scheduler.cc |
+++ b/remoting/host/video_scheduler.cc |
@@ -36,7 +36,7 @@ scoped_refptr<VideoScheduler> VideoScheduler::Create( |
scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, |
scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, |
scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, |
- VideoFrameCapturer* capturer, |
+ scoped_ptr<VideoFrameCapturer> capturer, |
scoped_ptr<VideoEncoder> encoder, |
protocol::CursorShapeStub* cursor_stub, |
protocol::VideoStub* video_stub) { |
@@ -48,7 +48,7 @@ scoped_refptr<VideoScheduler> VideoScheduler::Create( |
scoped_refptr<VideoScheduler> scheduler = new VideoScheduler( |
capture_task_runner, encode_task_runner, network_task_runner, |
- capturer, encoder.Pass(), cursor_stub, video_stub); |
+ capturer.Pass(), encoder.Pass(), cursor_stub, video_stub); |
capture_task_runner->PostTask( |
FROM_HERE, base::Bind(&VideoScheduler::StartOnCaptureThread, scheduler)); |
@@ -94,16 +94,15 @@ void VideoScheduler::OnCursorShapeChanged( |
base::Passed(&cursor_proto))); |
} |
-void VideoScheduler::Stop(const base::Closure& done_task) { |
+void VideoScheduler::Stop() { |
DCHECK(network_task_runner_->BelongsToCurrentThread()); |
- DCHECK(!done_task.is_null()); |
// Clear stubs to prevent further updates reaching the client. |
cursor_stub_ = NULL; |
video_stub_ = NULL; |
capture_task_runner_->PostTask(FROM_HERE, |
- base::Bind(&VideoScheduler::StopOnCaptureThread, this, done_task)); |
+ base::Bind(&VideoScheduler::StopOnCaptureThread, this)); |
} |
void VideoScheduler::Pause(bool pause) { |
@@ -141,21 +140,22 @@ VideoScheduler::VideoScheduler( |
scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, |
scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, |
scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, |
- VideoFrameCapturer* capturer, |
+ scoped_ptr<VideoFrameCapturer> capturer, |
scoped_ptr<VideoEncoder> encoder, |
protocol::CursorShapeStub* cursor_stub, |
protocol::VideoStub* video_stub) |
: capture_task_runner_(capture_task_runner), |
encode_task_runner_(encode_task_runner), |
network_task_runner_(network_task_runner), |
- capturer_(capturer), |
+ capturer_(capturer.Pass()), |
encoder_(encoder.Pass()), |
cursor_stub_(cursor_stub), |
video_stub_(video_stub), |
pending_captures_(0), |
did_skip_frame_(false), |
is_paused_(false), |
- sequence_number_(0) { |
+ sequence_number_(0), |
+ size_most_recent_(SkISize::Make(0, 0)) { |
} |
VideoScheduler::~VideoScheduler() { |
@@ -175,22 +175,23 @@ void VideoScheduler::StartOnCaptureThread() { |
CaptureNextFrame(); |
} |
-void VideoScheduler::StopOnCaptureThread(const base::Closure& done_task) { |
+void VideoScheduler::StopOnCaptureThread() { |
DCHECK(capture_task_runner_->BelongsToCurrentThread()); |
// Stop |capturer_| and clear it to prevent pending tasks from using it. |
capturer_->Stop(); |
- capturer_ = NULL; |
// |capture_timer_| must be destroyed on the thread on which it is used. |
capture_timer_.reset(); |
- // Ensure that the encode thread is no longer processing capture data, |
- // otherwise tearing down |capturer_| will crash it. See crbug.com/163641. |
+ // Schedule deletion of |capturer_| once the encode thread is no longer |
+ // processing capture data. See http://crbug.com/163641. This also clears |
+ // |capturer_| pointer to prevent pending tasks from using it. |
// TODO(wez): Make it safe to tear down capturer while buffers remain, and |
// remove this work-around. |
- encode_task_runner_->PostTask(FROM_HERE, |
- base::Bind(&VideoScheduler::StopOnEncodeThread, this, done_task)); |
+ encode_task_runner_->PostTask( |
+ FROM_HERE, base::Bind(&VideoScheduler::StopOnEncodeThread, this, |
+ base::Passed(&capturer_))); |
} |
void VideoScheduler::ScheduleNextCapture() { |
@@ -255,6 +256,13 @@ void VideoScheduler::SendVideoPacket(scoped_ptr<VideoPacket> packet) { |
if ((packet->flags() & VideoPacket::LAST_PARTITION) != 0) |
callback = base::Bind(&VideoScheduler::VideoFrameSentCallback, this); |
+ // Update saved screen size. |
+ if (packet->format().has_screen_width() && |
+ packet->format().has_screen_height()) { |
+ size_most_recent_ = SkISize::Make(packet->format().screen_width(), |
+ packet->format().screen_height()); |
+ } |
+ |
video_stub_->ProcessVideoPacket(packet.Pass(), callback); |
} |
@@ -278,6 +286,14 @@ void VideoScheduler::SendCursorShape( |
cursor_stub_->SetCursorShape(*cursor_shape); |
} |
+void VideoScheduler::StopOnNetworkThread( |
+ scoped_ptr<VideoFrameCapturer> capturer) { |
+ DCHECK(network_task_runner_->BelongsToCurrentThread()); |
+ |
+ // This is posted by StopOnEncodeThread meaning that both capture and encode |
+ // threads are stopped now and it is safe to delete |capturer|. |
+} |
+ |
// Encoder thread -------------------------------------------------------------- |
void VideoScheduler::EncodeFrame( |
@@ -314,12 +330,16 @@ void VideoScheduler::EncodedDataAvailableCallback( |
base::Passed(&packet))); |
} |
-void VideoScheduler::StopOnEncodeThread(const base::Closure& done_task) { |
+void VideoScheduler::StopOnEncodeThread( |
+ scoped_ptr<VideoFrameCapturer> capturer) { |
DCHECK(encode_task_runner_->BelongsToCurrentThread()); |
// This is posted by StopOnCaptureThread, so we know that by the time we |
- // process it there are no more encode tasks queued. |
- network_task_runner_->PostTask(FROM_HERE, done_task); |
+ // process it there are no more encode tasks queued. Schedule deletion of |
+ // |capturer_| on the same thread it was created on. |
Wez
2013/01/11 02:23:41
nit: Suggest "Pass |capturer_| for deletion on the
alexeypa (please no reviews)
2013/01/11 19:59:46
Done.
|
+ network_task_runner_->PostTask( |
+ FROM_HERE, base::Bind(&VideoScheduler::StopOnNetworkThread, this, |
+ base::Passed(&capturer))); |
} |
} // namespace remoting |