Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Unified Diff: media/filters/gpu_video_decoder.cc

Issue 16274005: Separate DemuxerStream and VideoDecoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: VideoFrameStream ready for review. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/filters/gpu_video_decoder.cc
diff --git a/media/filters/gpu_video_decoder.cc b/media/filters/gpu_video_decoder.cc
index 8ea4fc68e179e7e819630686061479fb6eced39f..a76a714b399a39211895dcf2f9372e9555f8de92 100644
--- a/media/filters/gpu_video_decoder.cc
+++ b/media/filters/gpu_video_decoder.cc
@@ -12,7 +12,6 @@
#include "base/task_runner_util.h"
#include "media/base/bind_to_loop.h"
#include "media/base/decoder_buffer.h"
-#include "media/base/demuxer_stream.h"
#include "media/base/pipeline.h"
#include "media/base/pipeline_status.h"
#include "media/base/video_decoder_config.h"
@@ -160,19 +159,18 @@ GpuVideoDecoder::BufferData::~BufferData() {}
GpuVideoDecoder::GpuVideoDecoder(
const scoped_refptr<base::MessageLoopProxy>& message_loop,
const scoped_refptr<Factories>& factories)
- : demuxer_stream_(NULL),
- needs_bitstream_conversion_(false),
+ : needs_bitstream_conversion_(false),
gvd_loop_proxy_(message_loop),
weak_factory_(this),
vda_loop_proxy_(factories->GetMessageLoop()),
factories_(factories),
state_(kNormal),
- demuxer_read_in_progress_(false),
decoder_texture_target_(0),
next_picture_buffer_id_(0),
next_bitstream_buffer_id_(0),
available_pictures_(-1) {
DCHECK(factories_);
+ DCHECK(!config_.IsValidConfig());
}
void GpuVideoDecoder::Reset(const base::Closure& closure) {
@@ -214,7 +212,6 @@ void GpuVideoDecoder::Stop(const base::Closure& closure) {
EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
if (!pending_reset_cb_.is_null())
base::ResetAndReturn(&pending_reset_cb_).Run();
- demuxer_stream_ = NULL;
BindToCurrentLoop(closure).Run();
}
@@ -234,11 +231,12 @@ static bool IsCodedSizeSupported(const gfx::Size& coded_size) {
return os_large_video_support && hw_large_video_support;
}
-void GpuVideoDecoder::Initialize(DemuxerStream* stream,
+void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config,
const PipelineStatusCB& orig_status_cb,
const StatisticsCB& statistics_cb) {
DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
- DCHECK(stream);
+ DCHECK(config.IsValidConfig());
+ DCHECK(!config.is_encrypted());
weak_this_ = weak_factory_.GetWeakPtr();
@@ -246,7 +244,7 @@ void GpuVideoDecoder::Initialize(DemuxerStream* stream,
"Media.GpuVideoDecoderInitializeStatus",
BindToCurrentLoop(orig_status_cb));
- if (demuxer_stream_) {
+ if (config_.IsValidConfig()) {
// TODO(xhwang): Make GpuVideoDecoder reinitializable.
// See http://crbug.com/233608
DVLOG(1) << "GpuVideoDecoder reinitialization not supported.";
@@ -254,10 +252,6 @@ void GpuVideoDecoder::Initialize(DemuxerStream* stream,
return;
}
- const VideoDecoderConfig& config = stream->video_decoder_config();
- DCHECK(config.IsValidConfig());
- DCHECK(!config.is_encrypted());
-
if (!IsCodedSizeSupported(config.coded_size())) {
status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
return;
@@ -271,7 +265,6 @@ void GpuVideoDecoder::Initialize(DemuxerStream* stream,
return;
}
- demuxer_stream_ = stream;
statistics_cb_ = statistics_cb;
needs_bitstream_conversion_ = (config.codec() == kCodecH264);
@@ -295,8 +288,9 @@ void GpuVideoDecoder::SetVDA(
void GpuVideoDecoder::DestroyTextures() {
for (std::map<int32, PictureBuffer>::iterator it =
- picture_buffers_in_decoder_.begin();
- it != picture_buffers_in_decoder_.end(); ++it) {
+ picture_buffers_in_decoder_.begin();
+ it != picture_buffers_in_decoder_.end();
+ ++it) {
factories_->DeleteTexture(it->second.texture_id());
}
picture_buffers_in_decoder_.clear();
@@ -325,10 +319,12 @@ void GpuVideoDecoder::DestroyVDA() {
DestroyTextures();
}
-void GpuVideoDecoder::Read(const ReadCB& read_cb) {
+void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
+ const ReadCB& read_cb) {
DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
DCHECK(pending_reset_cb_.is_null());
DCHECK(pending_read_cb_.is_null());
+
pending_read_cb_ = BindToCurrentLoop(read_cb);
if (state_ == kError) {
@@ -336,19 +332,50 @@ void GpuVideoDecoder::Read(const ReadCB& read_cb) {
return;
}
- // TODO(xhwang): It's odd that we return kOk after VDA has been released.
- // Fix this and simplify cases.
if (!vda_) {
base::ResetAndReturn(&pending_read_cb_).Run(
- kOk, VideoFrame::CreateEmptyFrame());
+ kDecodeError, VideoFrame::CreateEmptyFrame());
return;
}
- if (!ready_video_frames_.empty()) {
+ if (!ready_video_frames_.empty())
EnqueueFrameAndTriggerFrameDelivery(NULL);
- return;
+
+ if (buffer->IsEndOfStream()) {
+ if (state_ == kNormal) {
+ state_ = kDrainingDecoder;
+ vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
+ &VideoDecodeAccelerator::Flush, weak_vda_));
+ }
+ } else {
+ size_t size = buffer->GetDataSize();
+ SHMBuffer* shm_buffer = GetSHM(size);
+ if (!shm_buffer) {
+ state_ = kError;
+ return;
+ }
+
+ memcpy(shm_buffer->shm->memory(), buffer->GetData(), size);
+ BitstreamBuffer bitstream_buffer(
+ next_bitstream_buffer_id_, shm_buffer->shm->handle(), size);
+ // Mask against 30 bits, to avoid (undefined) wraparound on signed integer.
+ next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF;
+ bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair(
+ bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second;
+ DCHECK(inserted);
+ RecordBufferData(bitstream_buffer, *buffer);
+
+ vda_loop_proxy_->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer));
+ }
+
+ if (CanMoreDecodeWorkBeDone()) {
+ base::ResetAndReturn(&pending_read_cb_).Run(kNotEnoughData, NULL);
}
+/*
switch (state_) {
case kDecoderDrained:
state_ = kNormal;
@@ -364,78 +391,19 @@ void GpuVideoDecoder::Read(const ReadCB& read_cb) {
NOTREACHED();
break;
}
+*/
}
bool GpuVideoDecoder::CanMoreDecodeWorkBeDone() {
return bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes;
}
-void GpuVideoDecoder::RequestBufferDecode(
- DemuxerStream::Status status,
- const scoped_refptr<DecoderBuffer>& buffer) {
- DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
- DCHECK_EQ(status != DemuxerStream::kOk, !buffer) << status;
-
- demuxer_read_in_progress_ = false;
-
- if (status == DemuxerStream::kAborted) {
- if (pending_read_cb_.is_null())
- return;
- base::ResetAndReturn(&pending_read_cb_).Run(kOk, NULL);
- return;
- }
-
- // VideoFrameStream ensures no kConfigChanged is passed to VideoDecoders.
- DCHECK_EQ(status, DemuxerStream::kOk) << status;
-
- if (!vda_) {
- EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
- return;
- }
-
- if (buffer->IsEndOfStream()) {
- if (state_ == kNormal) {
- state_ = kDrainingDecoder;
- vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
- &VideoDecodeAccelerator::Flush, weak_vda_));
- }
- return;
- }
-
- if (!pending_reset_cb_.is_null())
- return;
-
- size_t size = buffer->GetDataSize();
- SHMBuffer* shm_buffer = GetSHM(size);
- if (!shm_buffer)
- return;
-
- memcpy(shm_buffer->shm->memory(), buffer->GetData(), size);
- BitstreamBuffer bitstream_buffer(
- next_bitstream_buffer_id_, shm_buffer->shm->handle(), size);
- // Mask against 30 bits, to avoid (undefined) wraparound on signed integer.
- next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF;
- bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair(
- bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second;
- DCHECK(inserted);
- RecordBufferData(bitstream_buffer, *buffer);
-
- vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
- &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer));
-
- if (CanMoreDecodeWorkBeDone()) {
- // Force post here to prevent reentrancy into DemuxerStream.
- gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
- &GpuVideoDecoder::EnsureDemuxOrDecode, weak_this_));
- }
-}
-
-void GpuVideoDecoder::RecordBufferData(
- const BitstreamBuffer& bitstream_buffer, const DecoderBuffer& buffer) {
- input_buffer_data_.push_front(BufferData(
- bitstream_buffer.id(), buffer.GetTimestamp(),
- demuxer_stream_->video_decoder_config().visible_rect(),
- demuxer_stream_->video_decoder_config().natural_size()));
+void GpuVideoDecoder::RecordBufferData(const BitstreamBuffer& bitstream_buffer,
+ const DecoderBuffer& buffer) {
+ input_buffer_data_.push_front(BufferData(bitstream_buffer.id(),
+ buffer.GetTimestamp(),
+ config_.visible_rect(),
+ config_.natural_size()));
// Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but
// that's too small for some pathological B-frame test videos. The cost of
// using too-high a value is low (192 bits per extra slot).
@@ -449,8 +417,8 @@ void GpuVideoDecoder::RecordBufferData(
void GpuVideoDecoder::GetBufferData(int32 id, base::TimeDelta* timestamp,
gfx::Rect* visible_rect,
gfx::Size* natural_size) {
- for (std::list<BufferData>::const_iterator it =
- input_buffer_data_.begin(); it != input_buffer_data_.end();
+ for (std::list<BufferData>::const_iterator it = input_buffer_data_.begin();
+ it != input_buffer_data_.end();
++it) {
if (it->bitstream_buffer_id != id)
continue;
@@ -659,21 +627,6 @@ GpuVideoDecoder::~GpuVideoDecoder() {
DestroyTextures();
}
-void GpuVideoDecoder::EnsureDemuxOrDecode() {
- DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
-
- // The second condition can happen during the tear-down process.
- // GpuVideoDecoder::Stop() returns the |pending_read_cb_| immediately without
- // waiting for the demuxer read to be returned. Therefore, this function could
- // be called even after the decoder has been stopped.
- if (demuxer_read_in_progress_ || !demuxer_stream_)
- return;
-
- demuxer_read_in_progress_ = true;
- demuxer_stream_->Read(base::Bind(
- &GpuVideoDecoder::RequestBufferDecode, weak_this_));
-}
-
void GpuVideoDecoder::NotifyFlushDone() {
DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
DCHECK_EQ(state_, kDrainingDecoder);

Powered by Google App Engine
This is Rietveld 408576698