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

Unified Diff: media/filters/video_renderer_base.cc

Issue 12096081: Replace VideoRendererBase Get/PutCurrentFrame() with a VideoFrame-containing callback. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: media/filters/video_renderer_base.cc
diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc
index 5a17940771120c543902274a13cf15f3011e43c5..178cbc7ccdb8f5c7ca32ef89e79e1559c7d44a6b 100644
--- a/media/filters/video_renderer_base.cc
+++ b/media/filters/video_renderer_base.cc
@@ -25,7 +25,7 @@ base::TimeDelta VideoRendererBase::kMaxLastFrameDuration() {
VideoRendererBase::VideoRendererBase(
const scoped_refptr<base::MessageLoopProxy>& message_loop,
const SetDecryptorReadyCB& set_decryptor_ready_cb,
- const base::Closure& paint_cb,
+ const PaintCB& paint_cb,
const SetOpaqueCB& set_opaque_cb,
bool drop_frames)
: message_loop_(message_loop),
@@ -34,12 +34,11 @@ VideoRendererBase::VideoRendererBase(
state_(kUninitialized),
thread_(base::kNullThreadHandle),
pending_read_(false),
- pending_paint_(false),
- pending_paint_with_last_available_(false),
drop_frames_(drop_frames),
playback_rate_(0),
paint_cb_(paint_cb),
- set_opaque_cb_(set_opaque_cb) {
+ set_opaque_cb_(set_opaque_cb),
+ last_timestamp_(kNoTimestamp()) {
DCHECK(!paint_cb_.is_null());
}
@@ -95,8 +94,7 @@ void VideoRendererBase::Stop(const base::Closure& callback) {
statistics_cb_.Reset();
max_time_cb_.Reset();
- if (!pending_paint_ && !pending_paint_with_last_available_)
- DoStopOrError_Locked();
+ DoStopOrError_Locked();
// Clean up our thread if present.
if (thread_ != base::kNullThreadHandle) {
@@ -281,19 +279,13 @@ void VideoRendererBase::ThreadMain() {
continue;
}
- // Remain idle until we've initialized |current_frame_| via prerolling.
- if (!current_frame_) {
- // This can happen if our preroll only contains end of stream frames.
- if (ready_frames_.front()->IsEndOfStream()) {
- state_ = kEnded;
- ended_cb_.Run();
- ready_frames_.clear();
-
- // No need to sleep here as we idle when |state_ != kPlaying|.
- continue;
- }
+ // This can happen if our preroll only contains end of stream frames.
+ if (ready_frames_.front()->IsEndOfStream()) {
+ state_ = kEnded;
+ ended_cb_.Run();
+ ready_frames_.clear();
- frame_available_.TimedWait(kIdleTimeDelta);
+ // No need to sleep here as we idle when |state_ != kPlaying|.
continue;
}
@@ -311,144 +303,28 @@ void VideoRendererBase::ThreadMain() {
continue;
}
-
- // We're almost there!
- //
- // At this point we've rendered |current_frame_| for the proper amount
- // of time and also have the next frame that ready for rendering.
-
-
- // If the next frame is end of stream then we are truly at the end of the
- // video stream.
- //
- // TODO(scherkus): deduplicate this end of stream check after we get rid of
- // |current_frame_|.
- if (ready_frames_.front()->IsEndOfStream()) {
- state_ = kEnded;
- ended_cb_.Run();
- ready_frames_.clear();
-
- // No need to sleep here as we idle when |state_ != kPlaying|.
- continue;
- }
-
- // We cannot update |current_frame_| until we've completed the pending
- // paint. Furthermore, the pending paint might be really slow: check to
- // see if we have any ready frames that we can drop if they've already
- // expired.
- if (pending_paint_) {
- while (!ready_frames_.empty()) {
- // Can't drop anything if we're at the end.
- if (ready_frames_.front()->IsEndOfStream())
- break;
-
- base::TimeDelta remaining_time =
- ready_frames_.front()->GetTimestamp() - get_time_cb_.Run();
-
- // Still a chance we can render the frame!
- if (remaining_time.InMicroseconds() > 0)
- break;
-
- if (!drop_frames_)
- break;
-
- // Frame dropped: read again.
- ++frames_dropped;
- ready_frames_.pop_front();
- message_loop_->PostTask(FROM_HERE, base::Bind(
- &VideoRendererBase::AttemptRead, this));
- }
- // Continue waiting for the current paint to finish.
- frame_available_.TimedWait(kIdleTimeDelta);
- continue;
- }
-
-
// Congratulations! You've made it past the video frame timing gauntlet.
//
- // We can now safely update the current frame, request another frame, and
- // signal to the client that a new frame is available.
- DCHECK(!pending_paint_);
- DCHECK(!ready_frames_.empty());
- SetCurrentFrameToNextReadyFrame();
+ // At this point enough time has passed that the next frame that ready for
+ // rendering.
+ PaintWithNextReadyFrame();
message_loop_->PostTask(FROM_HERE, base::Bind(
&VideoRendererBase::AttemptRead, this));
-
- base::AutoUnlock auto_unlock(lock_);
- paint_cb_.Run();
}
}
-void VideoRendererBase::SetCurrentFrameToNextReadyFrame() {
- current_frame_ = ready_frames_.front();
+void VideoRendererBase::PaintWithNextReadyFrame() {
acolwell GONE FROM CHROMIUM 2013/02/01 00:24:34 nit: Add _Locked() & corresponding assert since th
scherkus (not reviewing) 2013/02/01 22:45:25 Done.
+ scoped_refptr<VideoFrame> next_frame = ready_frames_.front();
ready_frames_.pop_front();
// Notify the pipeline of natural_size() changes.
- const gfx::Size& natural_size = current_frame_->natural_size();
+ const gfx::Size& natural_size = next_frame->natural_size();
if (natural_size != last_natural_size_) {
size_changed_cb_.Run(natural_size);
last_natural_size_ = natural_size;
}
-}
-
-void VideoRendererBase::GetCurrentFrame(scoped_refptr<VideoFrame>* frame_out) {
- base::AutoLock auto_lock(lock_);
- DCHECK(!pending_paint_ && !pending_paint_with_last_available_);
-
- if ((!current_frame_ || current_frame_->IsEndOfStream()) &&
- (!last_available_frame_ || last_available_frame_->IsEndOfStream())) {
- *frame_out = NULL;
- return;
- }
-
- // We should have initialized and have the current frame.
- DCHECK_NE(state_, kUninitialized);
- DCHECK_NE(state_, kStopped);
- DCHECK_NE(state_, kError);
-
- if (current_frame_) {
- *frame_out = current_frame_;
- last_available_frame_ = current_frame_;
- pending_paint_ = true;
- } else {
- DCHECK(last_available_frame_);
- *frame_out = last_available_frame_;
- pending_paint_with_last_available_ = true;
- }
-}
-
-void VideoRendererBase::PutCurrentFrame(scoped_refptr<VideoFrame> frame) {
- base::AutoLock auto_lock(lock_);
- // Note that we do not claim |pending_paint_| when we return NULL frame, in
- // that case, |current_frame_| could be changed before PutCurrentFrame.
- if (pending_paint_) {
- DCHECK_EQ(current_frame_, frame);
- DCHECK(!pending_paint_with_last_available_);
- pending_paint_ = false;
- } else if (pending_paint_with_last_available_) {
- DCHECK_EQ(last_available_frame_, frame);
- DCHECK(!pending_paint_);
- pending_paint_with_last_available_ = false;
- } else {
- DCHECK(!frame);
- }
-
- // We had cleared the |pending_paint_| flag, there are chances that current
- // frame is timed-out. We will wake up our main thread to advance the current
- // frame when this is true.
- frame_available_.Signal();
- if (state_ == kFlushingDecoder)
- return;
-
- if (state_ == kFlushing) {
- AttemptFlush_Locked();
- return;
- }
-
- if (state_ == kError || state_ == kStopped) {
- DoStopOrError_Locked();
- }
+ paint_cb_.Run(next_frame);
acolwell GONE FROM CHROMIUM 2013/02/01 00:24:34 This calls the callback under lock now. Are you su
scherkus (not reviewing) 2013/02/01 22:45:25 Yes. Previously it was terrifying because the most
}
VideoRendererBase::~VideoRendererBase() {
@@ -533,21 +409,22 @@ void VideoRendererBase::FrameReady(VideoDecoder::Status status,
// If we're at capacity or end of stream while prerolling we need to
// transition to prerolled.
if (state_ == kPrerolling) {
acolwell GONE FROM CHROMIUM 2013/02/01 00:24:34 nit: reverse check and unindent?
scherkus (not reviewing) 2013/02/01 22:45:25 Done.
- DCHECK(!current_frame_);
state_ = kPrerolled;
// Because we might remain in the prerolled state for an undetermined amount
// of time (i.e., we were not playing before we started prerolling), we'll
// manually update the current frame and notify the subclass below.
if (!ready_frames_.front()->IsEndOfStream())
- SetCurrentFrameToNextReadyFrame();
+ PaintWithNextReadyFrame();
// ...and we're done prerolling!
- DCHECK(!preroll_cb_.is_null());
base::ResetAndReturn(&preroll_cb_).Run(PIPELINE_OK);
+#if 0
+ // XXX do we still need this!?
scherkus (not reviewing) 2013/01/31 17:54:05 PWNRF() fires the paint_cb_ ... I suppose this mig
acolwell GONE FROM CHROMIUM 2013/02/01 00:24:34 Not sure. What did we use to paint in the case whe
scherkus (not reviewing) 2013/02/01 22:45:25 current_frame_ would have been null, so SkCanvasVi
base::AutoUnlock ul(lock_);
paint_cb_.Run();
+#endif
}
}
@@ -564,10 +441,9 @@ void VideoRendererBase::AddReadyFrame(const scoped_refptr<VideoFrame>& frame) {
end_timestamp = std::min(
duration,
ready_frames_.back()->GetTimestamp() + kMaxLastFrameDuration());
- } else if (current_frame_) {
+ } else if (last_timestamp_ != kNoTimestamp()) {
end_timestamp =
- std::min(duration,
- current_frame_->GetTimestamp() + kMaxLastFrameDuration());
+ std::min(duration, last_timestamp_ + kMaxLastFrameDuration());
}
frame->SetTimestamp(end_timestamp);
} else if (frame->GetTimestamp() > duration) {
@@ -636,9 +512,9 @@ void VideoRendererBase::AttemptFlush_Locked() {
prerolling_delayed_frame_ = NULL;
ready_frames_.clear();
- if (!pending_paint_ && !pending_read_) {
+ if (!pending_read_) {
state_ = kFlushed;
- current_frame_ = NULL;
+ last_timestamp_ = kNoTimestamp();
base::ResetAndReturn(&flush_cb_).Run();
}
}
@@ -657,20 +533,14 @@ base::TimeDelta VideoRendererBase::CalculateSleepDuration(
}
void VideoRendererBase::DoStopOrError_Locked() {
- DCHECK(!pending_paint_);
- DCHECK(!pending_paint_with_last_available_);
lock_.AssertAcquired();
- current_frame_ = NULL;
- last_available_frame_ = NULL;
+ last_timestamp_ = kNoTimestamp();
ready_frames_.clear();
}
int VideoRendererBase::NumFrames_Locked() const {
lock_.AssertAcquired();
- int outstanding_frames =
- (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) +
- (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0);
acolwell GONE FROM CHROMIUM 2013/02/01 00:24:34 o.O I'm not going to miss this.
- return ready_frames_.size() + outstanding_frames;
+ return ready_frames_.size();
}
} // namespace media

Powered by Google App Engine
This is Rietveld 408576698