| 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.
|
| + network_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&VideoScheduler::StopOnNetworkThread, this,
|
| + base::Passed(&capturer)));
|
| }
|
|
|
| } // namespace remoting
|
|
|