OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |