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

Unified Diff: media/gpu/dxva_picture_buffer_win.cc

Issue 2859723002: Copy NV12 picture buffers on demand on the main thread. (Closed)
Patch Set: change comment Created 3 years, 7 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 | « media/gpu/dxva_picture_buffer_win.h ('k') | media/gpu/dxva_video_decode_accelerator_win.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/gpu/dxva_picture_buffer_win.cc
diff --git a/media/gpu/dxva_picture_buffer_win.cc b/media/gpu/dxva_picture_buffer_win.cc
index 9aa8ea54ab80f47865d2253ac1a875c91ae0941a..d7df906d922f5184bd97c93d34db7270097154fd 100644
--- a/media/gpu/dxva_picture_buffer_win.cc
+++ b/media/gpu/dxva_picture_buffer_win.cc
@@ -32,7 +32,9 @@ class DummyGLImage : public gl::GLImage {
// gl::GLImage implementation.
gfx::Size GetSize() override { return size_; }
unsigned GetInternalFormat() override { return GL_BGRA_EXT; }
- bool BindTexImage(unsigned target) override { return false; }
+ // PbufferPictureBuffer::CopySurfaceComplete does the actual binding, so
+ // this doesn't do anything and always succeeds.
+ bool BindTexImage(unsigned target) override { return true; }
void ReleaseTexImage(unsigned target) override {}
bool CopyTexImage(unsigned target) override { return false; }
bool CopyTexSubImage(unsigned target,
@@ -102,29 +104,44 @@ linked_ptr<DXVAPictureBuffer> DXVAPictureBuffer::Create(
const DXVAVideoDecodeAccelerator& decoder,
const PictureBuffer& buffer,
EGLConfig egl_config) {
- if (decoder.share_nv12_textures_) {
- linked_ptr<EGLStreamPictureBuffer> picture_buffer(
- new EGLStreamPictureBuffer(buffer));
- if (!picture_buffer->Initialize())
- return linked_ptr<DXVAPictureBuffer>(nullptr);
-
- return picture_buffer;
- }
- if (decoder.copy_nv12_textures_) {
- linked_ptr<EGLStreamCopyPictureBuffer> picture_buffer(
- new EGLStreamCopyPictureBuffer(buffer));
- if (!picture_buffer->Initialize(decoder))
- return linked_ptr<DXVAPictureBuffer>(nullptr);
+ switch (decoder.GetPictureBufferMechanism()) {
+ case DXVAVideoDecodeAccelerator::PictureBufferMechanism::BIND: {
+ linked_ptr<EGLStreamPictureBuffer> picture_buffer(
+ new EGLStreamPictureBuffer(buffer));
+ if (!picture_buffer->Initialize())
+ return linked_ptr<DXVAPictureBuffer>(nullptr);
+
+ return picture_buffer;
+ }
+ case DXVAVideoDecodeAccelerator::PictureBufferMechanism::
+ DELAYED_COPY_TO_NV12: {
+ linked_ptr<EGLStreamDelayedCopyPictureBuffer> picture_buffer(
+ new EGLStreamDelayedCopyPictureBuffer(buffer));
+ if (!picture_buffer->Initialize(decoder))
+ return linked_ptr<DXVAPictureBuffer>(nullptr);
+
+ return picture_buffer;
+ }
+ case DXVAVideoDecodeAccelerator::PictureBufferMechanism::COPY_TO_NV12: {
+ linked_ptr<EGLStreamCopyPictureBuffer> picture_buffer(
+ new EGLStreamCopyPictureBuffer(buffer));
+ if (!picture_buffer->Initialize(decoder))
+ return linked_ptr<DXVAPictureBuffer>(nullptr);
- return picture_buffer;
- }
- linked_ptr<PbufferPictureBuffer> picture_buffer(
- new PbufferPictureBuffer(buffer));
+ return picture_buffer;
+ }
+ case DXVAVideoDecodeAccelerator::PictureBufferMechanism::COPY_TO_RGB: {
+ linked_ptr<PbufferPictureBuffer> picture_buffer(
+ new PbufferPictureBuffer(buffer));
- if (!picture_buffer->Initialize(decoder, egl_config))
- return linked_ptr<DXVAPictureBuffer>(nullptr);
+ if (!picture_buffer->Initialize(decoder, egl_config))
+ return linked_ptr<DXVAPictureBuffer>(nullptr);
- return picture_buffer;
+ return picture_buffer;
+ }
+ }
+ NOTREACHED();
+ return linked_ptr<DXVAPictureBuffer>(nullptr);
}
DXVAPictureBuffer::~DXVAPictureBuffer() {}
@@ -161,6 +178,7 @@ DXVAPictureBuffer::DXVAPictureBuffer(const PictureBuffer& buffer)
: picture_buffer_(buffer) {}
bool DXVAPictureBuffer::BindSampleToTexture(
+ DXVAVideoDecodeAccelerator* decoder,
base::win::ScopedComPtr<IMFSample> sample) {
NOTREACHED();
return false;
@@ -375,6 +393,10 @@ bool PbufferPictureBuffer::AllowOverlay() const {
return false;
}
+bool PbufferPictureBuffer::CanBindSamples() const {
+ return false;
+}
+
PbufferPictureBuffer::PbufferPictureBuffer(const PictureBuffer& buffer)
: DXVAPictureBuffer(buffer),
decoding_surface_(NULL),
@@ -474,6 +496,7 @@ bool EGLStreamPictureBuffer::ReusePictureBuffer() {
}
bool EGLStreamPictureBuffer::BindSampleToTexture(
+ DXVAVideoDecodeAccelerator* decoder,
base::win::ScopedComPtr<IMFSample> sample) {
DCHECK_EQ(BOUND, state_);
state_ = IN_CLIENT;
@@ -518,6 +541,129 @@ bool EGLStreamPictureBuffer::AllowOverlay() const {
return true;
}
+bool EGLStreamPictureBuffer::CanBindSamples() const {
+ return true;
+}
+
+EGLStreamDelayedCopyPictureBuffer::EGLStreamDelayedCopyPictureBuffer(
+ const PictureBuffer& buffer)
+ : DXVAPictureBuffer(buffer), stream_(nullptr) {}
+
+EGLStreamDelayedCopyPictureBuffer::~EGLStreamDelayedCopyPictureBuffer() {
+ // stream_ will be deleted by gl_image_.
+}
+
+bool EGLStreamDelayedCopyPictureBuffer::Initialize(
+ const DXVAVideoDecodeAccelerator& decoder) {
+ RETURN_ON_FAILURE(picture_buffer_.service_texture_ids().size() >= 2,
+ "Not enough texture ids provided", false);
+
+ EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
+ const EGLint stream_attributes[] = {
+ EGL_CONSUMER_LATENCY_USEC_KHR,
+ 0,
+ EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR,
+ 0,
+ EGL_NONE,
+ };
+ stream_ = eglCreateStreamKHR(egl_display, stream_attributes);
+ RETURN_ON_FAILURE(!!stream_, "Could not create stream", false);
+ gl::ScopedActiveTexture texture0(GL_TEXTURE0);
+ gl::ScopedTextureBinder texture0_binder(
+ GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[0]);
+ gl::ScopedActiveTexture texture1(GL_TEXTURE1);
+ gl::ScopedTextureBinder texture1_binder(
+ GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[1]);
+
+ EGLAttrib consumer_attributes[] = {
+ EGL_COLOR_BUFFER_TYPE,
+ EGL_YUV_BUFFER_EXT,
+ EGL_YUV_NUMBER_OF_PLANES_EXT,
+ 2,
+ EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
+ 0,
+ EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
+ 1,
+ EGL_NONE,
+ };
+ EGLBoolean result = eglStreamConsumerGLTextureExternalAttribsNV(
+ egl_display, stream_, consumer_attributes);
+ RETURN_ON_FAILURE(result, "Could not set stream consumer", false);
+
+ EGLAttrib producer_attributes[] = {
+ EGL_NONE,
+ };
+
+ result = eglCreateStreamProducerD3DTextureNV12ANGLE(egl_display, stream_,
+ producer_attributes);
+ RETURN_ON_FAILURE(result, "Could not create stream producer", false);
+ scoped_refptr<gl::CopyingGLImageDXGI> copying_image_ =
+ make_scoped_refptr(new gl::CopyingGLImageDXGI(
+ base::win::ScopedComPtr<ID3D11Device>(decoder.D3D11Device()), size(),
+ stream_));
+ gl_image_ = copying_image_;
+ return copying_image_->Initialize();
+}
+
+bool EGLStreamDelayedCopyPictureBuffer::ReusePictureBuffer() {
+ DCHECK_NE(UNUSED, state_);
+
+ static_cast<gl::CopyingGLImageDXGI*>(gl_image_.get())->UnbindFromTexture();
+ if (current_d3d_sample_) {
+ dx11_decoding_texture_.Reset();
+ current_d3d_sample_.Reset();
+ }
+ state_ = UNUSED;
+ return true;
+}
+
+bool EGLStreamDelayedCopyPictureBuffer::BindSampleToTexture(
+ DXVAVideoDecodeAccelerator* decoder,
+ base::win::ScopedComPtr<IMFSample> sample) {
+ DCHECK_EQ(BOUND, state_);
+ state_ = IN_CLIENT;
+
+ current_d3d_sample_ = sample;
+
+ base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
+ HRESULT hr =
+ current_d3d_sample_->GetBufferByIndex(0, output_buffer.GetAddressOf());
+ RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false);
+
+ base::win::ScopedComPtr<IMFDXGIBuffer> dxgi_buffer;
+ hr = output_buffer.CopyTo(dxgi_buffer.GetAddressOf());
+ RETURN_ON_HR_FAILURE(hr, "Failed to get DXGIBuffer from output sample",
+ false);
+ hr = dxgi_buffer->GetResource(
+ IID_PPV_ARGS(dx11_decoding_texture_.GetAddressOf()));
+ RETURN_ON_HR_FAILURE(hr, "Failed to get texture from output sample", false);
+ UINT subresource;
+ dxgi_buffer->GetSubresourceIndex(&subresource);
+ if (!decoder->InitializeID3D11VideoProcessor(size().width(), size().height(),
+ color_space_))
+ return false;
+
+ DCHECK(decoder->d3d11_processor_);
+ DCHECK(decoder->enumerator_);
+
+ gl::GLImageDXGI* gl_image_dxgi =
+ gl::GLImageDXGI::FromGLImage(gl_image_.get());
+ DCHECK(gl_image_dxgi);
+
+ gl_image_dxgi->SetTexture(dx11_decoding_texture_, subresource);
+ return static_cast<gl::CopyingGLImageDXGI*>(gl_image_dxgi)
+ ->InitializeVideoProcessor(decoder->d3d11_processor_,
+ decoder->enumerator_);
+}
+
+bool EGLStreamDelayedCopyPictureBuffer::AllowOverlay() const {
+ return true;
+}
+
+bool EGLStreamDelayedCopyPictureBuffer::CanBindSamples() const {
+ return true;
+}
+
EGLStreamCopyPictureBuffer::EGLStreamCopyPictureBuffer(
const PictureBuffer& buffer)
: DXVAPictureBuffer(buffer), stream_(nullptr) {}
@@ -685,4 +831,8 @@ bool EGLStreamCopyPictureBuffer::AllowOverlay() const {
return true;
}
+bool EGLStreamCopyPictureBuffer::CanBindSamples() const {
+ return false;
+}
+
} // namespace media
« no previous file with comments | « media/gpu/dxva_picture_buffer_win.h ('k') | media/gpu/dxva_video_decode_accelerator_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698