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

Side by Side Diff: media/filters/video_renderer_base.cc

Issue 10173012: Fix VideoRendererBase to allow the decoder to be flushed with a pending read. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Minor fixes based on comments. Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « media/filters/video_renderer_base.h ('k') | media/filters/video_renderer_base_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/bind.h" 5 #include "base/bind.h"
6 #include "base/callback.h" 6 #include "base/callback.h"
7 #include "base/callback_helpers.h" 7 #include "base/callback_helpers.h"
8 #include "base/threading/platform_thread.h" 8 #include "base/threading/platform_thread.h"
9 #include "media/base/buffers.h" 9 #include "media/base/buffers.h"
10 #include "media/base/filter_host.h" 10 #include "media/base/filter_host.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 base::AutoLock auto_lock(lock_); 47 base::AutoLock auto_lock(lock_);
48 DCHECK(state_ != kUninitialized || state_ == kError); 48 DCHECK(state_ != kUninitialized || state_ == kError);
49 state_ = kPaused; 49 state_ = kPaused;
50 callback.Run(); 50 callback.Run();
51 } 51 }
52 52
53 void VideoRendererBase::Flush(const base::Closure& callback) { 53 void VideoRendererBase::Flush(const base::Closure& callback) {
54 base::AutoLock auto_lock(lock_); 54 base::AutoLock auto_lock(lock_);
55 DCHECK_EQ(state_, kPaused); 55 DCHECK_EQ(state_, kPaused);
56 flush_cb_ = callback; 56 flush_cb_ = callback;
57 state_ = kFlushing; 57 state_ = kFlushingDecoder;
58 58
59 AttemptFlush_Locked(); 59 // We must unlock here because the callback might run within the Flush()
60 // call.
61 // TODO: Remove this line when fixing http://crbug.com/125020
62 base::AutoUnlock auto_unlock(lock_);
63 decoder_->Flush(base::Bind(&VideoRendererBase::OnDecoderFlushDone, this));
60 } 64 }
61 65
62 void VideoRendererBase::Stop(const base::Closure& callback) { 66 void VideoRendererBase::Stop(const base::Closure& callback) {
63 if (state_ == kStopped) { 67 if (state_ == kStopped) {
64 callback.Run(); 68 callback.Run();
65 return; 69 return;
66 } 70 }
67 71
68 base::PlatformThreadHandle thread_to_join = base::kNullThreadHandle; 72 base::PlatformThreadHandle thread_to_join = base::kNullThreadHandle;
69 { 73 {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 DCHECK(!pending_paint_); 339 DCHECK(!pending_paint_);
336 pending_paint_with_last_available_ = false; 340 pending_paint_with_last_available_ = false;
337 } else { 341 } else {
338 DCHECK(!frame); 342 DCHECK(!frame);
339 } 343 }
340 344
341 // We had cleared the |pending_paint_| flag, there are chances that current 345 // We had cleared the |pending_paint_| flag, there are chances that current
342 // frame is timed-out. We will wake up our main thread to advance the current 346 // frame is timed-out. We will wake up our main thread to advance the current
343 // frame when this is true. 347 // frame when this is true.
344 frame_available_.Signal(); 348 frame_available_.Signal();
349 if (state_ == kFlushingDecoder)
350 return;
351
345 if (state_ == kFlushing) { 352 if (state_ == kFlushing) {
346 AttemptFlush_Locked(); 353 AttemptFlush_Locked();
347 } else if (state_ == kError || state_ == kStopped) { 354 return;
355 }
356
357 if (state_ == kError || state_ == kStopped) {
348 DoStopOrError_Locked(); 358 DoStopOrError_Locked();
349 } 359 }
350 } 360 }
351 361
352 void VideoRendererBase::FrameReady(scoped_refptr<VideoFrame> frame) { 362 void VideoRendererBase::FrameReady(scoped_refptr<VideoFrame> frame) {
353 base::AutoLock auto_lock(lock_); 363 base::AutoLock auto_lock(lock_);
354 DCHECK_NE(state_, kUninitialized); 364 DCHECK_NE(state_, kUninitialized);
355 365
356 CHECK(pending_read_); 366 CHECK(pending_read_);
357 pending_read_ = false; 367 pending_read_ = false;
358 368
359 // Already-queued Decoder ReadCB's can fire after various state transitions 369 // Already-queued Decoder ReadCB's can fire after various state transitions
360 // have happened; in that case just drop those frames immediately. 370 // have happened; in that case just drop those frames immediately.
361 if (state_ == kStopped || state_ == kError || state_ == kFlushed) 371 if (state_ == kStopped || state_ == kError || state_ == kFlushed ||
372 state_ == kFlushingDecoder)
362 return; 373 return;
363 374
364 if (state_ == kFlushing) { 375 if (state_ == kFlushing) {
365 AttemptFlush_Locked(); 376 AttemptFlush_Locked();
366 return; 377 return;
367 } 378 }
368 379
369 if (!frame) { 380 if (!frame) {
370 if (state_ != kSeeking) 381 if (state_ != kSeeking)
371 return; 382 return;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 paint_cb_.Run(); 450 paint_cb_.Run();
440 } 451 }
441 } 452 }
442 453
443 void VideoRendererBase::AttemptRead_Locked() { 454 void VideoRendererBase::AttemptRead_Locked() {
444 lock_.AssertAcquired(); 455 lock_.AssertAcquired();
445 DCHECK_NE(kEnded, state_); 456 DCHECK_NE(kEnded, state_);
446 457
447 if (pending_read_ || 458 if (pending_read_ ||
448 NumFrames_Locked() == limits::kMaxVideoFrames || 459 NumFrames_Locked() == limits::kMaxVideoFrames ||
449 (!ready_frames_.empty() && ready_frames_.back()->IsEndOfStream())) { 460 (!ready_frames_.empty() && ready_frames_.back()->IsEndOfStream()) ||
450 return; 461 state_ == kFlushingDecoder ||
451 } 462 state_ == kFlushing) {
463 return;
464 }
452 465
453 pending_read_ = true; 466 pending_read_ = true;
454 decoder_->Read(base::Bind(&VideoRendererBase::FrameReady, this)); 467 decoder_->Read(base::Bind(&VideoRendererBase::FrameReady, this));
455 } 468 }
456 469
470 void VideoRendererBase::OnDecoderFlushDone() {
471 base::AutoLock auto_lock(lock_);
472 DCHECK_EQ(kFlushingDecoder, state_);
473 DCHECK(!pending_read_);
474
475 state_ = kFlushing;
476 AttemptFlush_Locked();
477 }
478
457 void VideoRendererBase::AttemptFlush_Locked() { 479 void VideoRendererBase::AttemptFlush_Locked() {
458 lock_.AssertAcquired(); 480 lock_.AssertAcquired();
459 DCHECK_EQ(kFlushing, state_); 481 DCHECK_EQ(kFlushing, state_);
460 482
461 // Get rid of any ready frames. 483 // Get rid of any ready frames.
462 ready_frames_.clear(); 484 ready_frames_.clear();
463 485
464 if (!pending_paint_ && !pending_read_) { 486 if (!pending_paint_ && !pending_read_) {
465 state_ = kFlushed; 487 state_ = kFlushed;
466 current_frame_ = NULL; 488 current_frame_ = NULL;
467 489 base::ResetAndReturn(&flush_cb_).Run();
468 base::Closure flush_cb = flush_cb_;
469 flush_cb_.Reset();
470 decoder_->Flush(flush_cb);
471 } 490 }
472 } 491 }
473 492
474 base::TimeDelta VideoRendererBase::CalculateSleepDuration( 493 base::TimeDelta VideoRendererBase::CalculateSleepDuration(
475 const scoped_refptr<VideoFrame>& next_frame, 494 const scoped_refptr<VideoFrame>& next_frame,
476 float playback_rate) { 495 float playback_rate) {
477 // Determine the current and next presentation timestamps. 496 // Determine the current and next presentation timestamps.
478 base::TimeDelta now = host()->GetTime(); 497 base::TimeDelta now = host()->GetTime();
479 base::TimeDelta this_pts = current_frame_->GetTimestamp(); 498 base::TimeDelta this_pts = current_frame_->GetTimestamp();
480 base::TimeDelta next_pts; 499 base::TimeDelta next_pts;
(...skipping 20 matching lines...) Expand all
501 520
502 int VideoRendererBase::NumFrames_Locked() const { 521 int VideoRendererBase::NumFrames_Locked() const {
503 lock_.AssertAcquired(); 522 lock_.AssertAcquired();
504 int outstanding_frames = 523 int outstanding_frames =
505 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) + 524 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) +
506 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0); 525 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0);
507 return ready_frames_.size() + outstanding_frames; 526 return ready_frames_.size() + outstanding_frames;
508 } 527 }
509 528
510 } // namespace media 529 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/video_renderer_base.h ('k') | media/filters/video_renderer_base_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698