blob: c72fe1365d8f61581e9b959bafc02932291a6a27 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/filters/video_frame_generator.h"
#include "base/bind.h"
#include "base/message_loop.h"
#include "media/base/demuxer_stream.h"
#include "media/base/video_frame.h"
namespace media {
VideoFrameGenerator::VideoFrameGenerator(
const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
const gfx::Size& size,
const base::TimeDelta& frame_duration)
: message_loop_proxy_(message_loop_proxy),
size_(size),
stopped_(true),
frame_duration_(frame_duration) {
}
void VideoFrameGenerator::Initialize(
const scoped_refptr<DemuxerStream>& stream,
const PipelineStatusCB& status_cb,
const StatisticsCB& statistics_cb) {
message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&VideoFrameGenerator::InitializeOnDecoderThread,
this, stream, status_cb, statistics_cb));
}
void VideoFrameGenerator::Read(const ReadCB& read_cb) {
message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&VideoFrameGenerator::ReadOnDecoderThread, this, read_cb));
}
void VideoFrameGenerator::Reset(const base::Closure& closure) {
message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&VideoFrameGenerator::ResetOnDecoderThread, this, closure));
}
void VideoFrameGenerator::Stop(const base::Closure& closure) {
message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&VideoFrameGenerator::StopOnDecoderThread, this, closure));
}
VideoFrameGenerator::~VideoFrameGenerator() {}
void VideoFrameGenerator::InitializeOnDecoderThread(
const scoped_refptr<DemuxerStream>& /* stream */,
const PipelineStatusCB& status_cb,
const StatisticsCB& statistics_cb) {
DVLOG(1) << "InitializeOnDecoderThread";
DCHECK(message_loop_proxy_->BelongsToCurrentThread());
status_cb.Run(PIPELINE_OK);
stopped_ = false;
}
void VideoFrameGenerator::ReadOnDecoderThread(const ReadCB& read_cb) {
DCHECK(message_loop_proxy_->BelongsToCurrentThread());
CHECK(!read_cb.is_null());
if (stopped_)
return;
// Always allocate a new frame.
//
// TODO(scherkus): migrate this to proper buffer recycling.
scoped_refptr<VideoFrame> video_frame =
VideoFrame::CreateFrame(VideoFrame::YV12, size_, gfx::Rect(size_), size_,
current_time_);
current_time_ += frame_duration_;
// TODO(wjia): set pixel data to pre-defined patterns if it's desired to
// verify frame content.
read_cb.Run(kOk, video_frame);
}
void VideoFrameGenerator::ResetOnDecoderThread(const base::Closure& closure) {
DVLOG(1) << "ResetOnDecoderThread";
DCHECK(message_loop_proxy_->BelongsToCurrentThread());
current_time_ = base::TimeDelta();
closure.Run();
}
void VideoFrameGenerator::StopOnDecoderThread(const base::Closure& closure) {
DVLOG(1) << "StopOnDecoderThread";
DCHECK(message_loop_proxy_->BelongsToCurrentThread());
stopped_ = true;
current_time_ = base::TimeDelta();
closure.Run();
}
} // namespace media