Index: content/renderer/media/capture_video_decoder.cc |
=================================================================== |
--- content/renderer/media/capture_video_decoder.cc (revision 109978) |
+++ content/renderer/media/capture_video_decoder.cc (working copy) |
@@ -67,6 +67,13 @@ |
this, callback)); |
} |
+void CaptureVideoDecoder::Flush(const base::Closure& callback) { |
+ message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&CaptureVideoDecoder::FlushOnDecoderThread, |
+ this, callback)); |
+} |
+ |
void CaptureVideoDecoder::Stop(const base::Closure& callback) { |
message_loop_proxy_->PostTask( |
FROM_HERE, |
@@ -141,8 +148,12 @@ |
void CaptureVideoDecoder::ReadOnDecoderThread(const ReadCB& callback) { |
DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
- CHECK(read_cb_.is_null()); |
- read_cb_ = callback; |
+ CHECK(!callback.is_null()); |
+ if (state_ != kNormal) { |
+ DeliverBlackFrame(callback); |
+ return; |
+ } |
+ read_cbs_.push(callback); |
} |
void CaptureVideoDecoder::PlayOnDecoderThread(const base::Closure& callback) { |
@@ -158,6 +169,16 @@ |
media::VideoDecoder::Pause(callback); |
} |
+void CaptureVideoDecoder::FlushOnDecoderThread(const base::Closure& callback) { |
+ DVLOG(1) << "FlushOnDecoderThread"; |
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
+ while (!read_cbs_.empty()) { |
+ DeliverBlackFrame(read_cbs_.front()); |
+ read_cbs_.pop(); |
+ } |
+ media::VideoDecoder::Flush(callback); |
+} |
+ |
void CaptureVideoDecoder::StopOnDecoderThread(const base::Closure& callback) { |
DVLOG(1) << "StopOnDecoderThread"; |
DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
@@ -201,7 +222,7 @@ |
scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) { |
DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
- if (read_cb_.is_null() || kNormal != state_) { |
+ if (read_cbs_.empty() || kNormal != state_) { |
capture->FeedBuffer(buf); |
return; |
} |
@@ -240,14 +261,16 @@ |
buffer += uv_width * uv_height; |
CopyVPlane(buffer, uv_width, uv_height, video_frame); |
- DeliverFrame(video_frame); |
+ read_cbs_.front().Run(video_frame); |
+ read_cbs_.pop(); |
capture->FeedBuffer(buf); |
} |
-void CaptureVideoDecoder::DeliverFrame( |
- const scoped_refptr<media::VideoFrame>& video_frame) { |
- // Reset the callback before running to protect against reentrancy. |
- ReadCB read_cb = read_cb_; |
- read_cb_.Reset(); |
+void CaptureVideoDecoder::DeliverBlackFrame( |
+ const ReadCB& read_cb) { |
+ CHECK(!read_cb.is_null()); |
+ scoped_refptr<media::VideoFrame> video_frame = |
+ media::VideoFrame::CreateBlackFrame(natural_size_.width(), |
+ natural_size_.height()); |
read_cb.Run(video_frame); |
} |