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

Unified Diff: content/common/gpu/media/vt_video_decode_accelerator.cc

Issue 491163002: Implement flushing in VTVideoDecodeAccelerator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 4 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
« no previous file with comments | « content/common/gpu/media/vt_video_decode_accelerator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/gpu/media/vt_video_decode_accelerator.cc
diff --git a/content/common/gpu/media/vt_video_decode_accelerator.cc b/content/common/gpu/media/vt_video_decode_accelerator.cc
index 5b916501b1b3fdbb532014842e48422584976874..3da6562fad7efed25c7d7964eeb673dfa8ebaa0e 100644
--- a/content/common/gpu/media/vt_video_decode_accelerator.cc
+++ b/content/common/gpu/media/vt_video_decode_accelerator.cc
@@ -39,7 +39,6 @@ static void OutputThunk(
CVImageBufferRef image_buffer,
CMTime presentation_time_stamp,
CMTime presentation_duration) {
- // TODO(sandersd): Implement flush-before-delete to guarantee validity.
VTVideoDecodeAccelerator* vda =
reinterpret_cast<VTVideoDecodeAccelerator*>(decompression_output_refcon);
int32_t bitstream_id = reinterpret_cast<intptr_t>(source_frame_refcon);
@@ -59,6 +58,8 @@ VTVideoDecodeAccelerator::DecodedFrame::~DecodedFrame() {
VTVideoDecodeAccelerator::VTVideoDecodeAccelerator(CGLContextObj cgl_context)
: cgl_context_(cgl_context),
client_(NULL),
+ state_(NORMAL),
+ frames_pending_decode_(0),
format_(NULL),
session_(NULL),
gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()),
@@ -159,7 +160,6 @@ void VTVideoDecodeAccelerator::ConfigureDecoder(
image_config, kCVPixelBufferOpenGLCompatibilityKey, kCFBooleanTrue);
// TODO(sandersd): Check if the session is already compatible.
- // TODO(sandersd): Flush.
session_.reset();
CHECK(!VTDecompressionSessionCreate(
kCFAllocatorDefault,
@@ -182,8 +182,7 @@ void VTVideoDecodeAccelerator::ConfigureDecoder(
void VTVideoDecodeAccelerator::Decode(const media::BitstreamBuffer& bitstream) {
DCHECK(CalledOnValidThread());
- // TODO(sandersd): Test what happens if bitstream buffers are passed to VT out
- // of order.
+ frames_pending_decode_++;
Pawel Osciak 2014/08/27 08:25:20 Client will keep calling Decode()s after it calls
sandersd (OOO until July 31) 2014/08/27 21:40:43 video_decoder.h specifies that no decode calls are
Pawel Osciak 2014/08/28 12:09:12 This class implements VideoDecodeAccelerator, not
decoder_thread_.message_loop_proxy()->PostTask(FROM_HERE, base::Bind(
&VTVideoDecodeAccelerator::DecodeTask, base::Unretained(this),
bitstream));
@@ -309,8 +308,16 @@ void VTVideoDecodeAccelerator::Output(
void VTVideoDecodeAccelerator::OutputTask(DecodedFrame frame) {
DCHECK(CalledOnValidThread());
- decoded_frames_.push(frame);
- SendPictures();
+ if (state_ == RESETTING || state_ == DESTROYING) {
+ // Drop all decoded frames when resetting or destroying.
+ client_->NotifyEndOfBitstreamBuffer(frame.bitstream_id);
+ frames_pending_decode_--;
+ if (!frames_pending_decode_)
+ FlushDone();
+ } else {
+ decoded_frames_.push(frame);
+ SendPictures();
+ }
}
void VTVideoDecodeAccelerator::SizeChangedTask(gfx::Size coded_size) {
@@ -332,7 +339,8 @@ void VTVideoDecodeAccelerator::AssignPictureBuffers(
}
// Pictures are not marked as uncleared until this method returns. They will
- // become broken if they are used before that happens.
+ // become broken if they are used before that happens. So, instead of calling
+ // SendPictures(), arrange for it to be called later.
gpu_task_runner_->PostTask(FROM_HERE, base::Bind(
&VTVideoDecodeAccelerator::SendPictures,
weak_this_factory_.GetWeakPtr()));
@@ -362,6 +370,7 @@ void VTVideoDecodeAccelerator::SendPictures() {
decoded_frames_.pop();
IOSurfaceRef surface = CVPixelBufferGetIOSurface(frame.image_buffer);
+ // TODO(sandersd): Find out why this fails due to no GL context sometimes.
gfx::ScopedTextureBinder
texture_binder(GL_TEXTURE_RECTANGLE_ARB, texture_ids_[picture_id]);
CHECK(!CGLTexImageIOSurface2D(
@@ -378,25 +387,76 @@ void VTVideoDecodeAccelerator::SendPictures() {
picture_bindings_[picture_id] = frame.image_buffer;
client_->PictureReady(media::Picture(picture_id, frame.bitstream_id));
client_->NotifyEndOfBitstreamBuffer(frame.bitstream_id);
+ frames_pending_decode_--;
}
glDisable(GL_TEXTURE_RECTANGLE_ARB);
+
+ if (state_ != NORMAL && !frames_pending_decode_)
+ FlushDone();
+}
+
+void VTVideoDecodeAccelerator::FlushStart(State state) {
+ DCHECK(CalledOnValidThread());
+ state_ = state;
+
+ // If resetting or destroying, drop all pending frames.
+ if (state_ == RESETTING || state_ == DESTROYING) {
+ while (!decoded_frames_.empty()) {
+ DecodedFrame frame = decoded_frames_.front();
+ decoded_frames_.pop();
+ client_->NotifyEndOfBitstreamBuffer(frame.bitstream_id);
+ frames_pending_decode_--;
+ }
+ }
+
+ if (frames_pending_decode_) {
+ decoder_thread_.message_loop_proxy()->PostTask(FROM_HERE, base::Bind(
+ &VTVideoDecodeAccelerator::FlushTask, base::Unretained(this)));
+ } else {
+ FlushDone();
+ }
+}
+
+void VTVideoDecodeAccelerator::FlushTask() {
+ DCHECK(decoder_thread_.message_loop_proxy()->BelongsToCurrentThread());
+ if (session_)
+ CHECK(!VTDecompressionSessionFinishDelayedFrames(session_));
+}
+
+void VTVideoDecodeAccelerator::FlushDone() {
+ DCHECK(CalledOnValidThread());
+ switch (state_) {
+ case NORMAL:
+ NOTREACHED();
+ break;
+ case FLUSHING:
+ client_->NotifyFlushDone();
+ state_ = NORMAL;
+ break;
+ case RESETTING:
+ client_->NotifyResetDone();
+ state_ = NORMAL;
+ break;
+ case DESTROYING:
+ delete this;
+ break;
+ }
}
void VTVideoDecodeAccelerator::Flush() {
DCHECK(CalledOnValidThread());
- // TODO(sandersd): Trigger flush, sending frames.
+ FlushStart(FLUSHING);
}
void VTVideoDecodeAccelerator::Reset() {
DCHECK(CalledOnValidThread());
- // TODO(sandersd): Trigger flush, discarding frames.
+ FlushStart(RESETTING);
}
void VTVideoDecodeAccelerator::Destroy() {
DCHECK(CalledOnValidThread());
- // TODO(sandersd): Trigger flush, discarding frames, and wait for them.
- delete this;
+ FlushStart(DESTROYING);
}
bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() {
« no previous file with comments | « content/common/gpu/media/vt_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698