| Index: content/renderer/media/capture_video_decoder.cc
|
| diff --git a/content/renderer/media/capture_video_decoder.cc b/content/renderer/media/capture_video_decoder.cc
|
| index fadcac75a81275187ea6132785b6db2d7bc706db..680dd8fcd3d1981a15e39718df0f847e963728d5 100644
|
| --- a/content/renderer/media/capture_video_decoder.cc
|
| +++ b/content/renderer/media/capture_video_decoder.cc
|
| @@ -41,12 +41,11 @@ void CaptureVideoDecoder::Initialize(
|
| filter_callback, stat_callback));
|
| }
|
|
|
| -void CaptureVideoDecoder::ProduceVideoFrame(
|
| - scoped_refptr<media::VideoFrame> video_frame) {
|
| +void CaptureVideoDecoder::Read(const FrameReadyCB& callback) {
|
| message_loop_proxy_->PostTask(
|
| FROM_HERE,
|
| - base::Bind(&CaptureVideoDecoder::ProduceVideoFrameOnDecoderThread,
|
| - this, video_frame));
|
| + base::Bind(&CaptureVideoDecoder::ReadOnDecoderThread,
|
| + this, callback));
|
| }
|
|
|
| gfx::Size CaptureVideoDecoder::natural_size() {
|
| @@ -131,17 +130,15 @@ void CaptureVideoDecoder::InitializeOnDecoderThread(
|
|
|
| capture_engine_ = vc_manager_->AddDevice(video_stream_id_, this);
|
|
|
| - available_frames_.clear();
|
| -
|
| statistics_callback_ = stat_callback;
|
| filter_callback.Run();
|
| state_ = kNormal;
|
| }
|
|
|
| -void CaptureVideoDecoder::ProduceVideoFrameOnDecoderThread(
|
| - scoped_refptr<media::VideoFrame> video_frame) {
|
| +void CaptureVideoDecoder::ReadOnDecoderThread(const FrameReadyCB& callback) {
|
| DCHECK(message_loop_proxy_->BelongsToCurrentThread());
|
| - available_frames_.push_back(video_frame);
|
| + CHECK(frame_ready_cb_.is_null());
|
| + frame_ready_cb_ = callback;
|
| }
|
|
|
| void CaptureVideoDecoder::PlayOnDecoderThread(const base::Closure& callback) {
|
| @@ -170,15 +167,6 @@ void CaptureVideoDecoder::SeekOnDecoderThread(base::TimeDelta time,
|
| VLOG(1) << "SeekOnDecoderThread.";
|
| DCHECK(message_loop_proxy_->BelongsToCurrentThread());
|
|
|
| - state_ = kSeeking;
|
| - // Create output buffer pool and pass the frames to renderer
|
| - // so that the renderer can complete the seeking
|
| - for (size_t i = 0; i < media::Limits::kMaxVideoFrames; ++i) {
|
| - VideoFrameReady(media::VideoFrame::CreateBlackFrame(capability_.width,
|
| - capability_.height));
|
| - }
|
| -
|
| - cb.Run(media::PIPELINE_OK);
|
| state_ = kNormal;
|
| capture_engine_->StartCapture(this, capability_);
|
| }
|
| @@ -197,14 +185,11 @@ void CaptureVideoDecoder::OnBufferReadyOnDecoderThread(
|
| scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) {
|
| DCHECK(message_loop_proxy_->BelongsToCurrentThread());
|
|
|
| - if (available_frames_.size() == 0 || kNormal != state_) {
|
| + if (frame_ready_cb_.is_null() || kNormal != state_) {
|
| capture->FeedBuffer(buf);
|
| return;
|
| }
|
|
|
| - scoped_refptr<media::VideoFrame> video_frame = available_frames_.front();
|
| - available_frames_.pop_front();
|
| -
|
| if (buf->width != capability_.width || buf->height != capability_.height) {
|
| capability_.width = buf->width;
|
| capability_.height = buf->height;
|
| @@ -212,19 +197,15 @@ void CaptureVideoDecoder::OnBufferReadyOnDecoderThread(
|
| gfx::Size(capability_.width, capability_.height));
|
| }
|
|
|
| - // Check if there's a size change.
|
| - if (static_cast<int>(video_frame->width()) != capability_.width ||
|
| - static_cast<int>(video_frame->height()) != capability_.height) {
|
| - // Allocate new buffer based on the new size.
|
| - video_frame = media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
|
| - capability_.width,
|
| - capability_.height,
|
| - media::kNoTimestamp,
|
| - media::kNoTimestamp);
|
| - }
|
| -
|
| - video_frame->SetTimestamp(buf->timestamp - start_time_);
|
| - video_frame->SetDuration(base::TimeDelta::FromMilliseconds(33));
|
| + // Always allocate a new frame.
|
| + //
|
| + // TODO(scherkus): migrate this to proper buffer recycling.
|
| + scoped_refptr<media::VideoFrame> video_frame =
|
| + media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
|
| + capability_.width,
|
| + capability_.height,
|
| + buf->timestamp - start_time_,
|
| + base::TimeDelta::FromMilliseconds(33));
|
|
|
| uint8* buffer = buf->memory_pointer;
|
|
|
| @@ -241,6 +222,14 @@ void CaptureVideoDecoder::OnBufferReadyOnDecoderThread(
|
| buffer += uv_width * uv_height;
|
| CopyVPlane(buffer, uv_width, uv_height, video_frame);
|
|
|
| - VideoFrameReady(video_frame);
|
| + DeliverFrame(video_frame);
|
| capture->FeedBuffer(buf);
|
| }
|
| +
|
| +void CaptureVideoDecoder::DeliverFrame(
|
| + const scoped_refptr<media::VideoFrame>& video_frame) {
|
| + // Reset the callback before running to protect against reentrancy.
|
| + FrameReadyCB frame_ready_cb = frame_ready_cb_;
|
| + frame_ready_cb_.Reset();
|
| + frame_ready_cb.Run(video_frame);
|
| +}
|
|
|