summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/filters/video_renderer_base.cc35
-rw-r--r--media/filters/video_renderer_base.h2
-rw-r--r--webkit/glue/webmediaplayer_impl.cc11
-rw-r--r--webkit/glue/webmediaplayer_impl.h1
4 files changed, 35 insertions, 14 deletions
diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc
index 7c964a6..994a520 100644
--- a/media/filters/video_renderer_base.cc
+++ b/media/filters/video_renderer_base.cc
@@ -33,6 +33,7 @@ VideoRendererBase::VideoRendererBase()
thread_(kNullThreadHandle),
pending_reads_(0),
pending_paint_(false),
+ pending_paint_with_last_available_(false),
playback_rate_(0) {
}
@@ -325,17 +326,28 @@ void VideoRendererBase::ThreadMain() {
void VideoRendererBase::GetCurrentFrame(scoped_refptr<VideoFrame>* frame_out) {
AutoLock auto_lock(lock_);
- DCHECK(!pending_paint_);
+ DCHECK(!pending_paint_ && !pending_paint_with_last_available_);
if (!current_frame_.get() || current_frame_->IsEndOfStream()) {
- *frame_out = NULL;
- return;
+ if (!last_available_frame_.get() ||
+ last_available_frame_->IsEndOfStream()) {
+ *frame_out = NULL;
+ return;
+ }
}
// We should have initialized and have the current frame.
DCHECK(state_ != kUninitialized && state_ != kStopped && state_ != kError);
- *frame_out = current_frame_;
- pending_paint_ = true;
+
+ if (current_frame_) {
+ *frame_out = current_frame_;
+ last_available_frame_ = current_frame_;
+ pending_paint_ = true;
+ } else {
+ DCHECK(last_available_frame_.get() != NULL);
+ *frame_out = last_available_frame_;
+ pending_paint_with_last_available_ = true;
+ }
}
void VideoRendererBase::PutCurrentFrame(scoped_refptr<VideoFrame> frame) {
@@ -343,10 +355,17 @@ void VideoRendererBase::PutCurrentFrame(scoped_refptr<VideoFrame> frame) {
// Note that we do not claim |pending_paint_| when we return NULL frame, in
// that case, |current_frame_| could be changed before PutCurrentFrame.
- DCHECK(pending_paint_ || frame.get() == NULL);
- DCHECK(current_frame_.get() == frame.get() || frame.get() == NULL);
+ if (pending_paint_) {
+ DCHECK(current_frame_.get() == frame.get());
+ DCHECK(pending_paint_with_last_available_ == false);
+ pending_paint_ = false;
+ } else if (pending_paint_with_last_available_) {
+ DCHECK(last_available_frame_.get() == frame.get());
+ pending_paint_with_last_available_ = false;
+ } else {
+ DCHECK(frame.get() == NULL);
+ }
- pending_paint_ = false;
// 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.
diff --git a/media/filters/video_renderer_base.h b/media/filters/video_renderer_base.h
index 10ee2fa..0ded475 100644
--- a/media/filters/video_renderer_base.h
+++ b/media/filters/video_renderer_base.h
@@ -144,6 +144,7 @@ class VideoRendererBase : public VideoRenderer,
VideoFrameQueue frames_queue_ready_;
VideoFrameQueue frames_queue_done_;
scoped_refptr<VideoFrame> current_frame_;
+ scoped_refptr<VideoFrame> last_available_frame_;
// Used to signal |thread_| as frames are added to |frames_|. Rule of thumb:
// always check |state_| to see if it was set to STOPPED after waking up!
@@ -200,6 +201,7 @@ class VideoRendererBase : public VideoRenderer,
// renderer provides buffer, |pending_reads_| is always non-negative.
int pending_reads_;
bool pending_paint_;
+ bool pending_paint_with_last_available_;
float playback_rate_;
diff --git a/webkit/glue/webmediaplayer_impl.cc b/webkit/glue/webmediaplayer_impl.cc
index e13d942..4a64b0f 100644
--- a/webkit/glue/webmediaplayer_impl.cc
+++ b/webkit/glue/webmediaplayer_impl.cc
@@ -233,6 +233,7 @@ WebMediaPlayerImpl::WebMediaPlayerImpl(
pipeline_(NULL),
pipeline_thread_("PipelineThread"),
paused_(true),
+ seeking_(false),
playback_rate_(0.0f),
client_(client),
proxy_(NULL),
@@ -368,11 +369,6 @@ void WebMediaPlayerImpl::seek(float seconds) {
return;
}
- // Drop our ready state if the media file isn't fully loaded.
- if (!pipeline_->IsLoaded()) {
- SetReadyState(WebKit::WebMediaPlayer::HaveMetadata);
- }
-
// Try to preserve as much accuracy as possible.
float microseconds = seconds * base::Time::kMicrosecondsPerSecond;
base::TimeDelta seek_time =
@@ -383,6 +379,8 @@ void WebMediaPlayerImpl::seek(float seconds) {
paused_time_ = seek_time;
}
+ seeking_ = true;
+
// Kick off the asynchronous seek!
pipeline_->Seek(
seek_time,
@@ -476,7 +474,7 @@ bool WebMediaPlayerImpl::seeking() const {
if (ready_state_ == WebKit::WebMediaPlayer::HaveNothing)
return false;
- return ready_state_ == WebKit::WebMediaPlayer::HaveMetadata;
+ return seeking_;
}
float WebMediaPlayerImpl::duration() const {
@@ -705,6 +703,7 @@ void WebMediaPlayerImpl::OnPipelineSeek() {
}
SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData);
+ seeking_ = false;
GetClient()->timeChanged();
}
}
diff --git a/webkit/glue/webmediaplayer_impl.h b/webkit/glue/webmediaplayer_impl.h
index 8aa6661..bae0d9b 100644
--- a/webkit/glue/webmediaplayer_impl.h
+++ b/webkit/glue/webmediaplayer_impl.h
@@ -303,6 +303,7 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer,
// clock can creep forward a little bit while the asynchronous
// SetPlaybackRate(0) is being executed.
bool paused_;
+ bool seeking_;
float playback_rate_;
base::TimeDelta paused_time_;