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

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

Issue 1688993002: Wait on fence before reusing DXVA picture buffer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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/dxva_video_decode_accelerator_win.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/dxva_video_decode_accelerator_win.cc
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator_win.cc b/content/common/gpu/media/dxva_video_decode_accelerator_win.cc
index a2f28f23374aaae70f7f3f3bbad64cae77ef1b65..21c77a3b851dd4fac53b2ff8ab33d8a094326135 100644
--- a/content/common/gpu/media/dxva_video_decode_accelerator_win.cc
+++ b/content/common/gpu/media/dxva_video_decode_accelerator_win.cc
@@ -41,6 +41,7 @@
#include "third_party/angle/include/EGL/eglext.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_fence.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/gl_switches.h"
@@ -162,6 +163,9 @@ enum {
kFlushDecoderSurfaceTimeoutMs = 1,
// Maximum iterations where we try to flush the d3d device.
kMaxIterationsForD3DFlush = 4,
+ // Maximum iterations where we try to flush the ANGLE device before reusing
+ // the texture.
+ kMaxIterationsForANGLEReuseFlush = 16,
// We only request 5 picture buffers from the client which are used to hold
// the decoded samples. These buffers are then reused when the client tells
// us that it is done with the buffer.
@@ -360,6 +364,7 @@ struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer {
bool use_rgb);
bool ReusePictureBuffer();
+ void ResetReuseFence();
// Copies the output sample data to the picture buffer provided by the
// client.
// The dest_surface parameter contains the decoded bits.
@@ -385,6 +390,10 @@ struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer {
return picture_buffer_.size();
}
+ bool waiting_to_reuse() const { return waiting_to_reuse_; }
+
+ gfx::GLFence* reuse_fence() { return reuse_fence_.get(); }
+
// Called when the source surface |src_surface| is copied to the destination
// |dest_surface|
bool CopySurfaceComplete(IDirect3DSurface9* src_surface,
@@ -394,8 +403,13 @@ struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer {
explicit DXVAPictureBuffer(const media::PictureBuffer& buffer);
bool available_;
+
+ // This is true if the decoder is currently waiting on the fence before
+ // reusing the buffer.
+ bool waiting_to_reuse_;
media::PictureBuffer picture_buffer_;
EGLSurface decoding_surface_;
+ scoped_ptr<gfx::GLFence> reuse_fence_;
HANDLE texture_share_handle_;
base::win::ScopedComPtr<IDirect3DTexture9> decoding_texture_;
@@ -523,6 +537,7 @@ bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::InitializeTexture(
DXVAVideoDecodeAccelerator::DXVAPictureBuffer::DXVAPictureBuffer(
const media::PictureBuffer& buffer)
: available_(true),
+ waiting_to_reuse_(false),
picture_buffer_(buffer),
decoding_surface_(NULL),
texture_share_handle_(nullptr),
@@ -555,6 +570,7 @@ bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ReusePictureBuffer() {
decoder_surface_.Release();
target_surface_.Release();
decoder_dx11_texture_.Release();
+ waiting_to_reuse_ = false;
set_available(true);
if (egl_keyed_mutex_) {
HRESULT hr = egl_keyed_mutex_->ReleaseSync(++keyed_mutex_value_);
@@ -563,6 +579,14 @@ bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ReusePictureBuffer() {
return true;
}
+void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ResetReuseFence() {
+ if (!reuse_fence_ || !reuse_fence_->ResetSupported())
+ reuse_fence_.reset(gfx::GLFence::Create());
+ else
+ reuse_fence_->ResetState();
+ waiting_to_reuse_ = true;
+}
+
bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::
CopyOutputSampleDataToPictureBuffer(
DXVAVideoDecodeAccelerator* decoder,
@@ -754,6 +778,10 @@ bool DXVAVideoDecodeAccelerator::Initialize(const Config& config,
PLATFORM_FAILURE,
false);
+ RETURN_AND_NOTIFY_ON_FAILURE(gfx::GLFence::IsSupported(),
+ "GL fences are unsupported", PLATFORM_FAILURE,
+ false);
+
State state = GetState();
RETURN_AND_NOTIFY_ON_FAILURE((state == kUninitialized),
"Initialize: invalid state: " << state, ILLEGAL_STATE, false);
@@ -1025,7 +1053,55 @@ void DXVAVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_buffer_id) {
return;
}
- RETURN_AND_NOTIFY_ON_FAILURE(it->second->ReusePictureBuffer(),
+ if (it->second->available() || it->second->waiting_to_reuse())
+ return;
+
+ if (use_keyed_mutex_ || using_angle_device_) {
+ RETURN_AND_NOTIFY_ON_FAILURE(it->second->ReusePictureBuffer(),
+ "Failed to reuse picture buffer",
+ PLATFORM_FAILURE, );
+
+ ProcessPendingSamples();
+ if (pending_flush_) {
+ decoder_thread_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal,
+ base::Unretained(this)));
+ }
+ } else {
+ RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(),
+ "Failed to make context current",
+ PLATFORM_FAILURE, );
+ it->second->ResetReuseFence();
+
+ WaitForOutputBuffer(picture_buffer_id, 0);
+ }
+}
+
+void DXVAVideoDecodeAccelerator::WaitForOutputBuffer(int32_t picture_buffer_id,
+ int count) {
+ DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
+ OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id);
+ if (it == output_picture_buffers_.end())
+ return;
+
+ DXVAPictureBuffer* picture_buffer = it->second.get();
+
+ DCHECK(!picture_buffer->available());
+ DCHECK(picture_buffer->waiting_to_reuse());
+
+ gfx::GLFence* fence = picture_buffer->reuse_fence();
+ RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(),
+ "Failed to make context current",
+ PLATFORM_FAILURE, );
+ if (count <= kMaxIterationsForANGLEReuseFlush && !fence->HasCompleted()) {
+ main_thread_task_runner_->PostDelayedTask(
+ FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::WaitForOutputBuffer,
+ weak_this_factory_.GetWeakPtr(),
+ picture_buffer_id, count + 1),
+ base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs));
+ return;
+ }
+ RETURN_AND_NOTIFY_ON_FAILURE(picture_buffer->ReusePictureBuffer(),
"Failed to reuse picture buffer",
PLATFORM_FAILURE, );
« no previous file with comments | « content/common/gpu/media/dxva_video_decode_accelerator_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698