| 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 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 DCHECK(task_runner_->BelongsToCurrentThread()); | 230 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 231 base::AutoLock auto_lock(lock_); | 231 base::AutoLock auto_lock(lock_); |
| 232 DCHECK_EQ(state_, kInitializing); | 232 DCHECK_EQ(state_, kInitializing); |
| 233 | 233 |
| 234 if (!success) { | 234 if (!success) { |
| 235 state_ = kUninitialized; | 235 state_ = kUninitialized; |
| 236 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 236 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
| 237 return; | 237 return; |
| 238 } | 238 } |
| 239 | 239 |
| 240 // We're all good! Consider ourselves flushed. (ThreadMain() should never | 240 // We're all good! Consider ourselves flushed because we have not read any |
| 241 // see us in the kUninitialized state). | 241 // frames yet. |
| 242 // Since we had an initial Preroll(), we consider ourself flushed, because we | |
| 243 // have not populated any buffers yet. | |
| 244 state_ = kFlushed; | 242 state_ = kFlushed; |
| 245 | 243 |
| 246 algorithm_.reset(new VideoRendererAlgorithm(wall_clock_time_cb_)); | 244 algorithm_.reset(new VideoRendererAlgorithm(wall_clock_time_cb_)); |
| 247 if (!drop_frames_) | 245 if (!drop_frames_) |
| 248 algorithm_->disable_frame_dropping(); | 246 algorithm_->disable_frame_dropping(); |
| 249 | 247 |
| 250 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); | 248 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
| 251 } | 249 } |
| 252 | 250 |
| 253 void VideoRendererImpl::OnPlaybackError(PipelineStatus error) { | 251 void VideoRendererImpl::OnPlaybackError(PipelineStatus error) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 278 void VideoRendererImpl::SetTickClockForTesting( | 276 void VideoRendererImpl::SetTickClockForTesting( |
| 279 std::unique_ptr<base::TickClock> tick_clock) { | 277 std::unique_ptr<base::TickClock> tick_clock) { |
| 280 tick_clock_.swap(tick_clock); | 278 tick_clock_.swap(tick_clock); |
| 281 } | 279 } |
| 282 | 280 |
| 283 void VideoRendererImpl::SetGpuMemoryBufferVideoForTesting( | 281 void VideoRendererImpl::SetGpuMemoryBufferVideoForTesting( |
| 284 std::unique_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool) { | 282 std::unique_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool) { |
| 285 gpu_memory_buffer_pool_.swap(gpu_memory_buffer_pool); | 283 gpu_memory_buffer_pool_.swap(gpu_memory_buffer_pool); |
| 286 } | 284 } |
| 287 | 285 |
| 288 void VideoRendererImpl::OnTimeStateChanged(bool time_progressing) { | 286 void VideoRendererImpl::TimeStartedProgressing() { |
| 289 DCHECK(task_runner_->BelongsToCurrentThread()); | 287 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 290 time_progressing_ = time_progressing; | 288 time_progressing_ = true; |
| 291 | 289 |
| 292 // WARNING: Do not attempt to use |lock_| here as this may be a reentrant call | 290 if (sink_started_) |
| 293 // in response to callbacks firing above. | |
| 294 | |
| 295 if (sink_started_ == time_progressing_) | |
| 296 return; | 291 return; |
| 297 | 292 |
| 298 if (time_progressing_) { | 293 // If only an EOS frame came in after a seek, the renderer may not have |
| 299 // If only an EOS frame came in after a seek, the renderer may not have | 294 // received the ended event yet though we've posted it. |
| 300 // received the ended event yet though we've posted it. | 295 if (rendered_end_of_stream_) |
| 301 if (rendered_end_of_stream_) | 296 return; |
| 302 return; | |
| 303 | 297 |
| 304 // If we have no frames queued, there is a pending buffering state change in | 298 // If we have no frames queued, there is a pending buffering state change in |
| 305 // flight and we should ignore the start attempt. | 299 // flight and we should ignore the start attempt. |
| 306 if (!algorithm_->frames_queued()) { | 300 if (!algorithm_->frames_queued()) { |
| 307 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); | 301 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); |
| 308 return; | 302 return; |
| 309 } | 303 } |
| 310 | 304 |
| 311 StartSink(); | 305 StartSink(); |
| 312 } else { | 306 } |
| 313 StopSink(); | |
| 314 | 307 |
| 315 // Make sure we expire everything we can if we can't read anymore currently, | 308 void VideoRendererImpl::TimeStoppedProgressing() { |
| 316 // otherwise playback may hang indefinitely. Note: There are no effective | 309 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 317 // frames queued at this point, otherwise FrameReady() would have canceled | 310 time_progressing_ = false; |
| 318 // the underflow state before reaching this point. | 311 |
| 319 if (buffering_state_ == BUFFERING_HAVE_NOTHING) { | 312 if (!sink_started_) |
| 320 base::AutoLock al(lock_); | 313 return; |
| 321 RemoveFramesForUnderflowOrBackgroundRendering(); | 314 |
| 322 } | 315 StopSink(); |
| 316 |
| 317 // Make sure we expire everything we can if we can't read any more currently, |
| 318 // otherwise playback may hang indefinitely. Note: There are no effective |
| 319 // frames queued at this point, otherwise FrameReady() would have canceled |
| 320 // the underflow state before reaching this point. |
| 321 if (buffering_state_ == BUFFERING_HAVE_NOTHING) { |
| 322 base::AutoLock al(lock_); |
| 323 RemoveFramesForUnderflowOrBackgroundRendering(); |
| 323 } | 324 } |
| 324 } | 325 } |
| 325 | 326 |
| 326 void VideoRendererImpl::FrameReadyForCopyingToGpuMemoryBuffers( | 327 void VideoRendererImpl::FrameReadyForCopyingToGpuMemoryBuffers( |
| 327 VideoFrameStream::Status status, | 328 VideoFrameStream::Status status, |
| 328 const scoped_refptr<VideoFrame>& frame) { | 329 const scoped_refptr<VideoFrame>& frame) { |
| 329 if (status != VideoFrameStream::OK || IsBeforeStartTime(frame->timestamp())) { | 330 if (status != VideoFrameStream::OK || IsBeforeStartTime(frame->timestamp())) { |
| 330 VideoRendererImpl::FrameReady(status, frame); | 331 VideoRendererImpl::FrameReady(status, frame); |
| 331 return; | 332 return; |
| 332 } | 333 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 scoped_refptr<VideoFrame> frame = algorithm_->first_frame(); | 409 scoped_refptr<VideoFrame> frame = algorithm_->first_frame(); |
| 409 CheckForMetadataChanges(frame->format(), frame->natural_size()); | 410 CheckForMetadataChanges(frame->format(), frame->natural_size()); |
| 410 sink_->PaintSingleFrame(frame); | 411 sink_->PaintSingleFrame(frame); |
| 411 } | 412 } |
| 412 } | 413 } |
| 413 | 414 |
| 414 // Signal buffering state if we've met our conditions. | 415 // Signal buffering state if we've met our conditions. |
| 415 if (buffering_state_ == BUFFERING_HAVE_NOTHING && HaveEnoughData_Locked()) | 416 if (buffering_state_ == BUFFERING_HAVE_NOTHING && HaveEnoughData_Locked()) |
| 416 TransitionToHaveEnough_Locked(); | 417 TransitionToHaveEnough_Locked(); |
| 417 | 418 |
| 418 // Always request more decoded video if we have capacity. This serves two | 419 // Always request more decoded video if we have capacity. |
| 419 // purposes: | |
| 420 // 1) Prerolling while paused | |
| 421 // 2) Keeps decoding going if video rendering thread starts falling behind | |
| 422 AttemptRead_Locked(); | 420 AttemptRead_Locked(); |
| 423 } | 421 } |
| 424 | 422 |
| 425 bool VideoRendererImpl::HaveEnoughData_Locked() { | 423 bool VideoRendererImpl::HaveEnoughData_Locked() { |
| 426 DCHECK_EQ(state_, kPlaying); | 424 DCHECK_EQ(state_, kPlaying); |
| 427 lock_.AssertAcquired(); | 425 lock_.AssertAcquired(); |
| 428 | 426 |
| 429 if (received_end_of_stream_) | 427 if (received_end_of_stream_) |
| 430 return true; | 428 return true; |
| 431 | 429 |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 | 696 |
| 699 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges( | 697 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges( |
| 700 VideoPixelFormat pixel_format, | 698 VideoPixelFormat pixel_format, |
| 701 const gfx::Size& natural_size) { | 699 const gfx::Size& natural_size) { |
| 702 base::AutoLock auto_lock(lock_); | 700 base::AutoLock auto_lock(lock_); |
| 703 CheckForMetadataChanges(pixel_format, natural_size); | 701 CheckForMetadataChanges(pixel_format, natural_size); |
| 704 AttemptRead_Locked(); | 702 AttemptRead_Locked(); |
| 705 } | 703 } |
| 706 | 704 |
| 707 } // namespace media | 705 } // namespace media |
| OLD | NEW |