Chromium Code Reviews| 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 |