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::OnTimeProgressing() { |
289 DCHECK(task_runner_->BelongsToCurrentThread()); | 287 DCHECK(task_runner_->BelongsToCurrentThread()); |
290 time_progressing_ = time_progressing; | |
291 | 288 |
292 // WARNING: Do not attempt to use |lock_| here as this may be a reentrant call | 289 // WARNING: Do not attempt to use |lock_| here as StartSink() may cause a |
293 // in response to callbacks firing above. | 290 // reentrant call. |
294 | 291 |
295 if (sink_started_ == time_progressing_) | 292 time_progressing_ = true; |
| 293 |
| 294 if (sink_started_) |
296 return; | 295 return; |
297 | 296 |
298 if (time_progressing_) { | 297 // 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 | 298 // received the ended event yet though we've posted it. |
300 // received the ended event yet though we've posted it. | 299 if (rendered_end_of_stream_) |
301 if (rendered_end_of_stream_) | 300 return; |
302 return; | |
303 | 301 |
304 // If we have no frames queued, there is a pending buffering state change in | 302 // If we have no frames queued, there is a pending buffering state change in |
305 // flight and we should ignore the start attempt. | 303 // flight and we should ignore the start attempt. |
306 if (!algorithm_->frames_queued()) { | 304 if (!algorithm_->frames_queued()) { |
307 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); | 305 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); |
308 return; | 306 return; |
309 } | 307 } |
310 | 308 |
311 StartSink(); | 309 StartSink(); |
312 } else { | 310 } |
313 StopSink(); | |
314 | 311 |
315 // Make sure we expire everything we can if we can't read anymore currently, | 312 void VideoRendererImpl::OnTimeStopped() { |
316 // otherwise playback may hang indefinitely. Note: There are no effective | 313 DCHECK(task_runner_->BelongsToCurrentThread()); |
317 // frames queued at this point, otherwise FrameReady() would have canceled | 314 |
318 // the underflow state before reaching this point. | 315 // WARNING: Do not attempt to use |lock_| here as StopSink() may cause a |
319 if (buffering_state_ == BUFFERING_HAVE_NOTHING) { | 316 // reentrant call. |
320 base::AutoLock al(lock_); | 317 |
321 RemoveFramesForUnderflowOrBackgroundRendering(); | 318 time_progressing_ = false; |
322 } | 319 |
| 320 if (!sink_started_) |
| 321 return; |
| 322 |
| 323 StopSink(); |
| 324 |
| 325 // Make sure we expire everything we can if we can't read any more currently, |
| 326 // otherwise playback may hang indefinitely. Note: There are no effective |
| 327 // frames queued at this point, otherwise FrameReady() would have canceled |
| 328 // the underflow state before reaching this point. |
| 329 if (buffering_state_ == BUFFERING_HAVE_NOTHING) { |
| 330 base::AutoLock al(lock_); |
| 331 RemoveFramesForUnderflowOrBackgroundRendering(); |
323 } | 332 } |
324 } | 333 } |
325 | 334 |
326 void VideoRendererImpl::FrameReadyForCopyingToGpuMemoryBuffers( | 335 void VideoRendererImpl::FrameReadyForCopyingToGpuMemoryBuffers( |
327 VideoFrameStream::Status status, | 336 VideoFrameStream::Status status, |
328 const scoped_refptr<VideoFrame>& frame) { | 337 const scoped_refptr<VideoFrame>& frame) { |
329 if (status != VideoFrameStream::OK || IsBeforeStartTime(frame->timestamp())) { | 338 if (status != VideoFrameStream::OK || IsBeforeStartTime(frame->timestamp())) { |
330 VideoRendererImpl::FrameReady(status, frame); | 339 VideoRendererImpl::FrameReady(status, frame); |
331 return; | 340 return; |
332 } | 341 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 scoped_refptr<VideoFrame> frame = algorithm_->first_frame(); | 417 scoped_refptr<VideoFrame> frame = algorithm_->first_frame(); |
409 CheckForMetadataChanges(frame->format(), frame->natural_size()); | 418 CheckForMetadataChanges(frame->format(), frame->natural_size()); |
410 sink_->PaintSingleFrame(frame); | 419 sink_->PaintSingleFrame(frame); |
411 } | 420 } |
412 } | 421 } |
413 | 422 |
414 // Signal buffering state if we've met our conditions. | 423 // Signal buffering state if we've met our conditions. |
415 if (buffering_state_ == BUFFERING_HAVE_NOTHING && HaveEnoughData_Locked()) | 424 if (buffering_state_ == BUFFERING_HAVE_NOTHING && HaveEnoughData_Locked()) |
416 TransitionToHaveEnough_Locked(); | 425 TransitionToHaveEnough_Locked(); |
417 | 426 |
418 // Always request more decoded video if we have capacity. This serves two | 427 // 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(); | 428 AttemptRead_Locked(); |
423 } | 429 } |
424 | 430 |
425 bool VideoRendererImpl::HaveEnoughData_Locked() { | 431 bool VideoRendererImpl::HaveEnoughData_Locked() { |
426 DCHECK_EQ(state_, kPlaying); | 432 DCHECK_EQ(state_, kPlaying); |
427 lock_.AssertAcquired(); | 433 lock_.AssertAcquired(); |
428 | 434 |
429 if (received_end_of_stream_) | 435 if (received_end_of_stream_) |
430 return true; | 436 return true; |
431 | 437 |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 | 704 |
699 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges( | 705 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges( |
700 VideoPixelFormat pixel_format, | 706 VideoPixelFormat pixel_format, |
701 const gfx::Size& natural_size) { | 707 const gfx::Size& natural_size) { |
702 base::AutoLock auto_lock(lock_); | 708 base::AutoLock auto_lock(lock_); |
703 CheckForMetadataChanges(pixel_format, natural_size); | 709 CheckForMetadataChanges(pixel_format, natural_size); |
704 AttemptRead_Locked(); | 710 AttemptRead_Locked(); |
705 } | 711 } |
706 | 712 |
707 } // namespace media | 713 } // namespace media |
OLD | NEW |