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 |