| Index: media/filters/vpx_video_decoder.cc
|
| diff --git a/media/filters/vpx_video_decoder.cc b/media/filters/vpx_video_decoder.cc
|
| index 40623527062518fcc32ef28a483f273844569548..1754f0230e9eb8f44defb3b77c4e3f6a8223290c 100644
|
| --- a/media/filters/vpx_video_decoder.cc
|
| +++ b/media/filters/vpx_video_decoder.cc
|
| @@ -4,6 +4,9 @@
|
|
|
| #include "media/filters/vpx_video_decoder.h"
|
|
|
| +#include <algorithm>
|
| +#include <string>
|
| +
|
| #include "base/bind.h"
|
| #include "base/callback_helpers.h"
|
| #include "base/command_line.h"
|
| @@ -61,7 +64,6 @@ VpxVideoDecoder::VpxVideoDecoder(
|
| : message_loop_(message_loop),
|
| weak_factory_(this),
|
| state_(kUninitialized),
|
| - demuxer_stream_(NULL),
|
| vpx_codec_(NULL),
|
| vpx_codec_alpha_(NULL) {
|
| }
|
| @@ -71,26 +73,25 @@ VpxVideoDecoder::~VpxVideoDecoder() {
|
| CloseDecoder();
|
| }
|
|
|
| -void VpxVideoDecoder::Initialize(
|
| - DemuxerStream* stream,
|
| - const PipelineStatusCB& status_cb,
|
| - const StatisticsCB& statistics_cb) {
|
| +void VpxVideoDecoder::Initialize(const VideoDecoderConfig& config,
|
| + const PipelineStatusCB& status_cb,
|
| + const StatisticsCB& statistics_cb) {
|
| DCHECK(message_loop_->BelongsToCurrentThread());
|
| - DCHECK(stream);
|
| + DCHECK(config.IsValidConfig());
|
| + DCHECK(!config.is_encrypted());
|
| DCHECK(read_cb_.is_null());
|
| DCHECK(reset_cb_.is_null());
|
|
|
| weak_this_ = weak_factory_.GetWeakPtr();
|
|
|
| - demuxer_stream_ = stream;
|
| - statistics_cb_ = statistics_cb;
|
| -
|
| - if (!ConfigureDecoder()) {
|
| + if (!ConfigureDecoder(config)) {
|
| status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
|
| return;
|
| }
|
|
|
| // Success!
|
| + config_ = config;
|
| + statistics_cb_ = statistics_cb;
|
| state_ = kNormal;
|
| status_cb.Run(PIPELINE_OK);
|
| }
|
| @@ -117,10 +118,7 @@ static vpx_codec_ctx* InitializeVpxContext(vpx_codec_ctx* context,
|
| return context;
|
| }
|
|
|
| -bool VpxVideoDecoder::ConfigureDecoder() {
|
| - const VideoDecoderConfig& config = demuxer_stream_->video_decoder_config();
|
| - DCHECK(config.IsValidConfig());
|
| -
|
| +bool VpxVideoDecoder::ConfigureDecoder(const VideoDecoderConfig& config) {
|
| const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
|
| bool can_handle = false;
|
| if (config.codec() == kCodecVP9)
|
| @@ -160,25 +158,27 @@ void VpxVideoDecoder::CloseDecoder() {
|
| }
|
| }
|
|
|
| -void VpxVideoDecoder::Read(const ReadCB& read_cb) {
|
| +void VpxVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
|
| + const ReadCB& read_cb) {
|
| DCHECK(message_loop_->BelongsToCurrentThread());
|
| DCHECK(!read_cb.is_null());
|
| CHECK_NE(state_, kUninitialized);
|
| CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported.";
|
| +
|
| read_cb_ = BindToCurrentLoop(read_cb);
|
|
|
| if (state_ == kError) {
|
| - read_cb.Run(kDecodeError, NULL);
|
| + base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
|
| return;
|
| }
|
|
|
| // Return empty frames if decoding has finished.
|
| if (state_ == kDecodeFinished) {
|
| - read_cb.Run(kOk, VideoFrame::CreateEmptyFrame());
|
| + base::ResetAndReturn(&read_cb_).Run(kOk, VideoFrame::CreateEmptyFrame());
|
| return;
|
| }
|
|
|
| - ReadFromDemuxerStream();
|
| + DecodeBuffer(buffer);
|
| }
|
|
|
| void VpxVideoDecoder::Reset(const base::Closure& closure) {
|
| @@ -210,57 +210,18 @@ void VpxVideoDecoder::Stop(const base::Closure& closure) {
|
| state_ = kUninitialized;
|
| }
|
|
|
| -void VpxVideoDecoder::ReadFromDemuxerStream() {
|
| - DCHECK_NE(state_, kUninitialized);
|
| - DCHECK_NE(state_, kDecodeFinished);
|
| - DCHECK_NE(state_, kError);
|
| - DCHECK(!read_cb_.is_null());
|
| -
|
| - demuxer_stream_->Read(base::Bind(
|
| - &VpxVideoDecoder::DoDecryptOrDecodeBuffer, weak_this_));
|
| -}
|
| -
|
| bool VpxVideoDecoder::HasAlpha() const {
|
| return vpx_codec_alpha_ != NULL;
|
| }
|
|
|
| -void VpxVideoDecoder::DoDecryptOrDecodeBuffer(
|
| - DemuxerStream::Status status,
|
| - const scoped_refptr<DecoderBuffer>& buffer) {
|
| - DCHECK(message_loop_->BelongsToCurrentThread());
|
| - DCHECK_NE(state_, kDecodeFinished);
|
| - DCHECK_EQ(status != DemuxerStream::kOk, !buffer.get()) << status;
|
| -
|
| - if (state_ == kUninitialized)
|
| - return;
|
| -
|
| - DCHECK(!read_cb_.is_null());
|
| -
|
| - if (!reset_cb_.is_null()) {
|
| - base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
|
| - DoReset();
|
| - return;
|
| - }
|
| -
|
| - if (status == DemuxerStream::kAborted) {
|
| - base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
|
| - return;
|
| - }
|
| -
|
| - // VideoFrameStream ensures no kConfigChanged is passed to VideoDecoders.
|
| - DCHECK_EQ(status, DemuxerStream::kOk) << status;
|
| - DecodeBuffer(buffer);
|
| -}
|
| -
|
| -void VpxVideoDecoder::DecodeBuffer(
|
| - const scoped_refptr<DecoderBuffer>& buffer) {
|
| +void VpxVideoDecoder::DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) {
|
| DCHECK(message_loop_->BelongsToCurrentThread());
|
| DCHECK_NE(state_, kUninitialized);
|
| DCHECK_NE(state_, kDecodeFinished);
|
| DCHECK_NE(state_, kError);
|
| DCHECK(reset_cb_.is_null());
|
| DCHECK(!read_cb_.is_null());
|
| - DCHECK(buffer.get());
|
| + DCHECK(buffer);
|
|
|
| // Transition to kDecodeFinished on the first end of stream buffer.
|
| if (state_ == kNormal && buffer->IsEndOfStream()) {
|
| @@ -270,7 +231,7 @@ void VpxVideoDecoder::DecodeBuffer(
|
| }
|
|
|
| scoped_refptr<VideoFrame> video_frame;
|
| - if (!Decode(buffer, &video_frame)) {
|
| + if (!VpxDecode(buffer, &video_frame)) {
|
| state_ = kError;
|
| base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
|
| return;
|
| @@ -283,18 +244,16 @@ void VpxVideoDecoder::DecodeBuffer(
|
| statistics_cb_.Run(statistics);
|
| }
|
|
|
| - // If we didn't get a frame we need more data.
|
| if (!video_frame.get()) {
|
| - ReadFromDemuxerStream();
|
| + base::ResetAndReturn(&read_cb_).Run(kNotEnoughData, NULL);
|
| return;
|
| }
|
|
|
| base::ResetAndReturn(&read_cb_).Run(kOk, video_frame);
|
| }
|
|
|
| -bool VpxVideoDecoder::Decode(
|
| - const scoped_refptr<DecoderBuffer>& buffer,
|
| - scoped_refptr<VideoFrame>* video_frame) {
|
| +bool VpxVideoDecoder::VpxDecode(const scoped_refptr<DecoderBuffer>& buffer,
|
| + scoped_refptr<VideoFrame>* video_frame) {
|
| DCHECK(video_frame);
|
| DCHECK(!buffer->IsEndOfStream());
|
|
|
| @@ -374,10 +333,9 @@ void VpxVideoDecoder::DoReset() {
|
| reset_cb_.Reset();
|
| }
|
|
|
| -void VpxVideoDecoder::CopyVpxImageTo(
|
| - const vpx_image* vpx_image,
|
| - const struct vpx_image* vpx_image_alpha,
|
| - scoped_refptr<VideoFrame>* video_frame) {
|
| +void VpxVideoDecoder::CopyVpxImageTo(const vpx_image* vpx_image,
|
| + const struct vpx_image* vpx_image_alpha,
|
| + scoped_refptr<VideoFrame>* video_frame) {
|
| CHECK(vpx_image);
|
| CHECK_EQ(vpx_image->d_w % 2, 0U);
|
| CHECK_EQ(vpx_image->d_h % 2, 0U);
|
| @@ -385,16 +343,13 @@ void VpxVideoDecoder::CopyVpxImageTo(
|
| vpx_image->fmt == VPX_IMG_FMT_YV12);
|
|
|
| gfx::Size size(vpx_image->d_w, vpx_image->d_h);
|
| - gfx::Size natural_size =
|
| - demuxer_stream_->video_decoder_config().natural_size();
|
| -
|
| - *video_frame = VideoFrame::CreateFrame(vpx_codec_alpha_ ?
|
| - VideoFrame::YV12A :
|
| - VideoFrame::YV12,
|
| - size,
|
| - gfx::Rect(size),
|
| - natural_size,
|
| - kNoTimestamp());
|
| +
|
| + *video_frame = VideoFrame::CreateFrame(
|
| + vpx_codec_alpha_ ? VideoFrame::YV12A : VideoFrame::YV12,
|
| + size,
|
| + gfx::Rect(size),
|
| + config_.natural_size(),
|
| + kNoTimestamp());
|
|
|
| CopyYPlane(vpx_image->planes[VPX_PLANE_Y],
|
| vpx_image->stride[VPX_PLANE_Y],
|
|
|