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

Side by Side Diff: media/renderers/video_renderer_impl.cc

Issue 2273033003: Invalidate VideoRendererImpl's weak ptrs before resetting the decoder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 3 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "media/renderers/video_renderer_impl.h" 5 #include "media/renderers/video_renderer_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 DCHECK(task_runner_->BelongsToCurrentThread()); 86 DCHECK(task_runner_->BelongsToCurrentThread());
87 87
88 if (sink_started_) 88 if (sink_started_)
89 StopSink(); 89 StopSink();
90 90
91 base::AutoLock auto_lock(lock_); 91 base::AutoLock auto_lock(lock_);
92 DCHECK_EQ(state_, kPlaying); 92 DCHECK_EQ(state_, kPlaying);
93 flush_cb_ = callback; 93 flush_cb_ = callback;
94 state_ = kFlushing; 94 state_ = kFlushing;
95 95
96 // This is necessary if the |video_frame_stream_| has already seen an end of
97 // stream and needs to drain it before flushing it.
98 if (buffering_state_ != BUFFERING_HAVE_NOTHING) { 96 if (buffering_state_ != BUFFERING_HAVE_NOTHING) {
99 buffering_state_ = BUFFERING_HAVE_NOTHING; 97 buffering_state_ = BUFFERING_HAVE_NOTHING;
100 task_runner_->PostTask( 98 task_runner_->PostTask(
101 FROM_HERE, base::Bind(&VideoRendererImpl::OnBufferingStateChange, 99 FROM_HERE, base::Bind(&VideoRendererImpl::OnBufferingStateChange,
102 weak_factory_.GetWeakPtr(), buffering_state_)); 100 weak_factory_.GetWeakPtr(), buffering_state_));
103 } 101 }
104 received_end_of_stream_ = false; 102 received_end_of_stream_ = false;
105 rendered_end_of_stream_ = false; 103 rendered_end_of_stream_ = false;
106 104
107 algorithm_->Reset(); 105 // Reset |video_frame_stream_| and drop any pending read callbacks from it.
108 106 pending_read_ = false;
107 frame_callback_weak_factory_.InvalidateWeakPtrs();
109 video_frame_stream_->Reset( 108 video_frame_stream_->Reset(
110 base::Bind(&VideoRendererImpl::OnVideoFrameStreamResetDone, 109 base::Bind(&VideoRendererImpl::OnVideoFrameStreamResetDone,
111 weak_factory_.GetWeakPtr())); 110 weak_factory_.GetWeakPtr()));
111
112 // To avoid unnecessary work by VDAs, only delete queued frames after
113 // resetting |video_frame_stream_|. If this is done in the opposite order VDAs
114 // will get a bunch of ReusePictureBuffer() calls before the Reset(), which
115 // they may use to output more frames that won't be used.
116 algorithm_->Reset();
112 } 117 }
113 118
114 void VideoRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) { 119 void VideoRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) {
115 DVLOG(1) << __func__ << "(" << timestamp.InMicroseconds() << ")"; 120 DVLOG(1) << __func__ << "(" << timestamp.InMicroseconds() << ")";
116 DCHECK(task_runner_->BelongsToCurrentThread()); 121 DCHECK(task_runner_->BelongsToCurrentThread());
117 base::AutoLock auto_lock(lock_); 122 base::AutoLock auto_lock(lock_);
118 DCHECK_EQ(state_, kFlushed); 123 DCHECK_EQ(state_, kFlushed);
119 DCHECK(!pending_read_); 124 DCHECK(!pending_read_);
120 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); 125 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
121 126
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( 335 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
331 frame, base::Bind(&VideoRendererImpl::FrameReady, 336 frame, base::Bind(&VideoRendererImpl::FrameReady,
332 frame_callback_weak_factory_.GetWeakPtr(), status)); 337 frame_callback_weak_factory_.GetWeakPtr(), status));
333 } 338 }
334 339
335 void VideoRendererImpl::FrameReady(VideoFrameStream::Status status, 340 void VideoRendererImpl::FrameReady(VideoFrameStream::Status status,
336 const scoped_refptr<VideoFrame>& frame) { 341 const scoped_refptr<VideoFrame>& frame) {
337 DCHECK(task_runner_->BelongsToCurrentThread()); 342 DCHECK(task_runner_->BelongsToCurrentThread());
338 base::AutoLock auto_lock(lock_); 343 base::AutoLock auto_lock(lock_);
339 344
340 DCHECK_NE(state_, kUninitialized); 345 DCHECK_EQ(state_, kPlaying);
341 DCHECK_NE(state_, kFlushed);
342
343 CHECK(pending_read_); 346 CHECK(pending_read_);
344 pending_read_ = false; 347 pending_read_ = false;
345 348
346 if (status == VideoFrameStream::DECODE_ERROR) { 349 if (status == VideoFrameStream::DECODE_ERROR) {
347 DCHECK(!frame); 350 DCHECK(!frame);
348 task_runner_->PostTask( 351 task_runner_->PostTask(
349 FROM_HERE, 352 FROM_HERE,
350 base::Bind(&VideoRendererImpl::OnPlaybackError, 353 base::Bind(&VideoRendererImpl::OnPlaybackError,
351 weak_factory_.GetWeakPtr(), PIPELINE_ERROR_DECODE)); 354 weak_factory_.GetWeakPtr(), PIPELINE_ERROR_DECODE));
352 return; 355 return;
353 } 356 }
354 357
355 // Already-queued VideoFrameStream ReadCB's can fire after various state
356 // transitions have happened; in that case just drop those frames
357 // immediately.
358 if (state_ == kFlushing)
359 return;
360
361 DCHECK_EQ(state_, kPlaying);
362
363 // Can happen when demuxers are preparing for a new Seek(). 358 // Can happen when demuxers are preparing for a new Seek().
364 if (!frame) { 359 if (!frame) {
365 DCHECK_EQ(status, VideoFrameStream::DEMUXER_READ_ABORTED); 360 DCHECK_EQ(status, VideoFrameStream::DEMUXER_READ_ABORTED);
366 return; 361 return;
367 } 362 }
368 363
369 if (frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)) { 364 if (frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)) {
370 DCHECK(!received_end_of_stream_); 365 DCHECK(!received_end_of_stream_);
371 received_end_of_stream_ = true; 366 received_end_of_stream_ = true;
372 } else if ((low_delay_ || !video_frame_stream_->CanReadWithoutStalling()) && 367 } else if ((low_delay_ || !video_frame_stream_->CanReadWithoutStalling()) &&
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 void VideoRendererImpl::OnVideoFrameStreamResetDone() { 508 void VideoRendererImpl::OnVideoFrameStreamResetDone() {
514 // We don't need to acquire the |lock_| here, because we can only get here 509 // We don't need to acquire the |lock_| here, because we can only get here
515 // when Flush is in progress, so rendering and video sink must be stopped. 510 // when Flush is in progress, so rendering and video sink must be stopped.
516 DCHECK(task_runner_->BelongsToCurrentThread()); 511 DCHECK(task_runner_->BelongsToCurrentThread());
517 DCHECK(!sink_started_); 512 DCHECK(!sink_started_);
518 DCHECK_EQ(kFlushing, state_); 513 DCHECK_EQ(kFlushing, state_);
519 DCHECK(!received_end_of_stream_); 514 DCHECK(!received_end_of_stream_);
520 DCHECK(!rendered_end_of_stream_); 515 DCHECK(!rendered_end_of_stream_);
521 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); 516 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
522 517
523 // Pending read might be true if an async video frame copy is in flight.
524 pending_read_ = false;
525 // Drop any pending calls to FrameReady() and
526 // FrameReadyForCopyingToGpuMemoryBuffers()
527 frame_callback_weak_factory_.InvalidateWeakPtrs();
528 state_ = kFlushed; 518 state_ = kFlushed;
529 base::ResetAndReturn(&flush_cb_).Run(); 519 base::ResetAndReturn(&flush_cb_).Run();
530 } 520 }
531 521
532 void VideoRendererImpl::UpdateStats_Locked() { 522 void VideoRendererImpl::UpdateStats_Locked() {
533 lock_.AssertAcquired(); 523 lock_.AssertAcquired();
534 DCHECK_GE(frames_decoded_, 0); 524 DCHECK_GE(frames_decoded_, 0);
535 DCHECK_GE(frames_dropped_, 0); 525 DCHECK_GE(frames_dropped_, 0);
536 526
537 if (frames_decoded_ || frames_dropped_) { 527 if (frames_decoded_ || frames_dropped_) {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 680
691 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges( 681 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges(
692 VideoPixelFormat pixel_format, 682 VideoPixelFormat pixel_format,
693 const gfx::Size& natural_size) { 683 const gfx::Size& natural_size) {
694 base::AutoLock auto_lock(lock_); 684 base::AutoLock auto_lock(lock_);
695 CheckForMetadataChanges(pixel_format, natural_size); 685 CheckForMetadataChanges(pixel_format, natural_size);
696 AttemptRead_Locked(); 686 AttemptRead_Locked();
697 } 687 }
698 688
699 } // namespace media 689 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698