Commit 462d699b authored by Ted Meyer's avatar Ted Meyer Committed by Commit Bot

Picture Processing in D3D11PictureBuffer

This refactor sees D3D11PictureBuffer no longer holding a D3D11Texture2D,
instead it holds a wrapper class which is responsible for creating and
owning gpu resources and mailboxes.

The default wrapper behaves exactly like the old implementation.

Bug: 963742
Change-Id: I49c67517203ef6464a6f0f2d3609bd7e484ac4a8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1614937
Commit-Queue: Ted Meyer <tmathmeyer@chromium.org>
Reviewed-by: default avatarFrank Liberato <liberato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#664459}
parent 8f2502b2
......@@ -177,6 +177,8 @@ component("gpu") {
"windows/d3d11_h264_accelerator.h",
"windows/d3d11_picture_buffer.cc",
"windows/d3d11_picture_buffer.h",
"windows/d3d11_texture_wrapper.cc",
"windows/d3d11_texture_wrapper.h",
"windows/d3d11_video_context_wrapper.cc",
"windows/d3d11_video_context_wrapper.h",
"windows/d3d11_video_decoder.cc",
......
......@@ -7,177 +7,71 @@
#include <d3d11.h>
#include <d3d11_1.h>
#include <windows.h>
#include <wrl/client.h>
#include <memory>
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "media/base/media_log.h"
#include "media/gpu/windows/return_on_failure.h"
#include "third_party/angle/include/EGL/egl.h"
#include "third_party/angle/include/EGL/eglext.h"
#include "ui/gfx/color_space.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_image_dxgi.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/scoped_binders.h"
namespace media {
D3D11PictureBuffer::D3D11PictureBuffer(GLenum target,
gfx::Size size,
size_t level)
: target_(target), size_(size), level_(level) {}
D3D11PictureBuffer::D3D11PictureBuffer(
GLenum target,
std::unique_ptr<Texture2DWrapper> texture_wrapper,
gfx::Size size,
size_t level)
: target_(target),
texture_wrapper_(std::move(texture_wrapper)),
size_(size),
level_(level) {}
D3D11PictureBuffer::~D3D11PictureBuffer() {
// TODO(liberato): post destruction of |gpu_resources_| to the gpu thread.
}
bool D3D11PictureBuffer::Init(
base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()> get_helper_cb,
Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device,
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture,
const GUID& decoder_guid,
int textures_per_picture) {
texture_ = texture;
bool D3D11PictureBuffer::Init(GetCommandBufferHelperCB get_helper_cb,
ComD3D11VideoDevice video_device,
const GUID& decoder_guid,
int textures_per_picture,
std::unique_ptr<MediaLog> media_log) {
D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC view_desc = {};
view_desc.DecodeProfile = decoder_guid;
view_desc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D;
view_desc.Texture2D.ArraySlice = (UINT)level_;
HRESULT hr = video_device->CreateVideoDecoderOutputView(
texture.Get(), &view_desc, output_view_.GetAddressOf());
if (!SUCCEEDED(hr))
if (!texture_wrapper_->Init(std::move(get_helper_cb), level_, target_, size_,
textures_per_picture)) {
media_log->AddEvent(
media_log->CreateStringEvent(MediaLogEvent::MEDIA_ERROR_LOG_ENTRY,
"error", "Failed to Init the wrapper"));
return false;
// Generate mailboxes and holders.
std::vector<gpu::Mailbox> mailboxes;
for (int texture_idx = 0; texture_idx < textures_per_picture; texture_idx++) {
mailboxes.push_back(gpu::Mailbox::Generate());
mailbox_holders_[texture_idx] = gpu::MailboxHolder(
mailboxes[texture_idx], gpu::SyncToken(), GL_TEXTURE_EXTERNAL_OES);
}
// Start construction of the GpuResources.
// We send the texture itself, since we assume that we're using the angle
// device for decoding. Sharing seems not to work very well. Otherwise, we
// would create the texture with KEYED_MUTEX and NTHANDLE, then send along
// a handle that we get from |texture| as an IDXGIResource1.
// TODO(liberato): this should happen on the gpu thread.
gpu_resources_ = std::make_unique<GpuResources>();
if (!gpu_resources_->Init(std::move(get_helper_cb), level_,
std::move(mailboxes), target_, size_, texture,
textures_per_picture))
HRESULT hr = video_device->CreateVideoDecoderOutputView(
Texture().Get(), &view_desc, &output_view_);
if (!SUCCEEDED(hr)) {
media_log->AddEvent(media_log->CreateStringEvent(
MediaLogEvent::MEDIA_ERROR_LOG_ENTRY, "error",
"Failed to CreateVideoDecoderOutputView"));
return false;
}
return true;
}
D3D11PictureBuffer::GpuResources::GpuResources() {}
D3D11PictureBuffer::GpuResources::~GpuResources() {
if (helper_ && helper_->MakeContextCurrent()) {
for (uint32_t service_id : service_ids_)
helper_->DestroyTexture(service_id);
}
const MailboxHolderArray& D3D11PictureBuffer::ProcessTexture() const {
return texture_wrapper_->ProcessTexture(this);
}
bool D3D11PictureBuffer::GpuResources::Init(
base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()> get_helper_cb,
int level,
const std::vector<gpu::Mailbox> mailboxes,
GLenum target,
gfx::Size size,
Microsoft::WRL::ComPtr<ID3D11Texture2D> angle_texture,
int textures_per_picture) {
helper_ = get_helper_cb.Run();
if (!helper_ || !helper_->MakeContextCurrent())
return false;
// Create the textures and attach them to the mailboxes.
for (int texture_idx = 0; texture_idx < textures_per_picture; texture_idx++) {
uint32_t service_id =
helper_->CreateTexture(target, GL_RGBA, size.width(), size.height(),
GL_RGBA, GL_UNSIGNED_BYTE);
service_ids_.push_back(service_id);
helper_->ProduceTexture(mailboxes[texture_idx], service_id);
}
// Create the stream for zero-copy use by gl.
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,
};
EGLStreamKHR stream = eglCreateStreamKHR(egl_display, stream_attributes);
RETURN_ON_FAILURE(!!stream, "Could not create stream", false);
// |stream| will be destroyed when the GLImage is.
// TODO(liberato): for tests, it will be destroyed pretty much at the end of
// this function unless |helper_| retains it. Also, this won't work if we
// have a FakeCommandBufferHelper since the service IDs aren't meaningful.
scoped_refptr<gl::GLImage> gl_image =
base::MakeRefCounted<gl::GLImageDXGI>(size, stream);
gl::ScopedActiveTexture texture0(GL_TEXTURE0);
gl::ScopedTextureBinder texture0_binder(GL_TEXTURE_EXTERNAL_OES,
service_ids_[0]);
gl::ScopedActiveTexture texture1(GL_TEXTURE1);
gl::ScopedTextureBinder texture1_binder(GL_TEXTURE_EXTERNAL_OES,
service_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 = eglCreateStreamProducerD3DTextureANGLE(egl_display, stream,
producer_attributes);
RETURN_ON_FAILURE(result, "Could not create stream", false);
EGLAttrib frame_attributes[] = {
EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, level, EGL_NONE,
};
result = eglStreamPostD3DTextureANGLE(egl_display, stream,
static_cast<void*>(angle_texture.Get()),
frame_attributes);
RETURN_ON_FAILURE(result, "Could not post texture", false);
result = eglStreamConsumerAcquireKHR(egl_display, stream);
RETURN_ON_FAILURE(result, "Could not post acquire stream", false);
gl::GLImageDXGI* gl_image_dxgi =
static_cast<gl::GLImageDXGI*>(gl_image.get());
gl_image_dxgi->SetTexture(angle_texture, level);
// Bind the image to each texture.
for (size_t texture_idx = 0; texture_idx < service_ids_.size();
texture_idx++) {
helper_->BindImage(service_ids_[texture_idx], gl_image.get(),
false /* client_managed */);
}
return true;
ComD3D11Texture2D D3D11PictureBuffer::Texture() const {
return texture_wrapper_->Texture();
}
} // namespace media
......@@ -9,15 +9,19 @@
#include <dxva.h>
#include <wrl/client.h>
#include <memory>
#include <vector>
#include "base/memory/ref_counted.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "gpu/ipc/service/command_buffer_stub.h"
#include "media/base/media_log.h"
#include "media/base/video_frame.h"
#include "media/gpu/command_buffer_helper.h"
#include "media/gpu/media_gpu_export.h"
#include "media/gpu/windows/d3d11_texture_wrapper.h"
#include "media/video/picture.h"
#include "third_party/angle/include/EGL/egl.h"
#include "third_party/angle/include/EGL/eglext.h"
......@@ -25,6 +29,8 @@
namespace media {
class Texture2DWrapper;
// PictureBuffer that owns Chrome Textures to display it, and keep a reference
// to the D3D texture that backs the image.
//
......@@ -41,20 +47,26 @@ namespace media {
class MEDIA_GPU_EXPORT D3D11PictureBuffer
: public base::RefCountedThreadSafe<D3D11PictureBuffer> {
public:
using MailboxHolderArray = gpu::MailboxHolder[VideoFrame::kMaxPlanes];
D3D11PictureBuffer(GLenum target, gfx::Size size, size_t level);
bool Init(base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()>
get_helper_cb,
Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device,
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture,
// |texture_wrapper| is responsible for controlling mailbox access to
// the ID3D11Texture2D,
// |level| is the picturebuffer index inside the Array-type ID3D11Texture2D.
D3D11PictureBuffer(GLenum target,
std::unique_ptr<Texture2DWrapper> texture_wrapper,
gfx::Size size,
size_t level);
bool Init(GetCommandBufferHelperCB get_helper_cb,
ComD3D11VideoDevice video_device,
const GUID& decoder_guid,
int textures_per_picture);
int textures_per_picture,
std::unique_ptr<MediaLog> media_log);
// Return the mailbox holders that can be used to create a VideoFrame for us.
const MailboxHolderArray& ProcessTexture() const;
ComD3D11Texture2D Texture() const;
const gfx::Size& size() const { return size_; }
size_t level() const { return level_; }
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture() const { return texture_; }
// Is this PictureBuffer backing a VideoFrame right now?
bool in_client_use() const { return in_client_use_; }
......@@ -65,14 +77,10 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer
void set_in_client_use(bool use) { in_client_use_ = use; }
void set_in_picture_use(bool use) { in_picture_use_ = use; }
const Microsoft::WRL::ComPtr<ID3D11VideoDecoderOutputView>& output_view()
const {
const ComD3D11VideoDecoderOutputView& output_view() const {
return output_view_;
}
// Return the mailbox holders that can be used to create a VideoFrame for us.
const MailboxHolderArray& mailbox_holders() const { return mailbox_holders_; }
// Shouldn't be here, but simpler for now.
base::TimeDelta timestamp_;
......@@ -81,46 +89,13 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer
friend class base::RefCountedThreadSafe<D3D11PictureBuffer>;
GLenum target_;
std::unique_ptr<Texture2DWrapper> texture_wrapper_;
gfx::Size size_;
bool in_picture_use_ = false;
bool in_client_use_ = false;
size_t level_;
// TODO(liberato): I don't think that we need to remember |texture_|. The
// GLImage will do so, so it will last long enough for any VideoFrames that
// reference it.
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture_;
Microsoft::WRL::ComPtr<ID3D11VideoDecoderOutputView> output_view_;
MailboxHolderArray mailbox_holders_;
// Things that are to be accessed / freed only on the main thread. In
// addition to setting up the textures to render from a D3D11 texture,
// these also hold the chrome GL Texture objects so that the client
// can use the mailbox.
class GpuResources {
public:
GpuResources();
~GpuResources();
bool Init(base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()>
get_helper_cb,
int level,
const std::vector<gpu::Mailbox> mailboxes,
GLenum target,
gfx::Size size,
Microsoft::WRL::ComPtr<ID3D11Texture2D> angle_texture,
int textures_per_picture);
std::vector<uint32_t> service_ids_;
private:
scoped_refptr<CommandBufferHelper> helper_;
DISALLOW_COPY_AND_ASSIGN(GpuResources);
};
std::unique_ptr<GpuResources> gpu_resources_;
ComD3D11VideoDecoderOutputView output_view_;
DISALLOW_COPY_AND_ASSIGN(D3D11PictureBuffer);
};
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/gpu/windows/d3d11_texture_wrapper.h"
#include <memory>
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "media/gpu/windows/return_on_failure.h"
namespace media {
Texture2DWrapper::Texture2DWrapper(ComD3D11Texture2D texture)
: texture_(texture) {}
Texture2DWrapper::~Texture2DWrapper() {}
const ComD3D11Texture2D Texture2DWrapper::Texture() const {
return texture_;
}
DefaultTexture2DWrapper::DefaultTexture2DWrapper(ComD3D11Texture2D texture)
: Texture2DWrapper(texture) {}
DefaultTexture2DWrapper::~DefaultTexture2DWrapper() {}
const MailboxHolderArray& DefaultTexture2DWrapper::ProcessTexture(
const D3D11PictureBuffer* owner_pb) {
return mailbox_holders_;
}
bool DefaultTexture2DWrapper::Init(GetCommandBufferHelperCB get_helper_cb,
size_t array_slice,
GLenum target,
gfx::Size size,
int textures_per_picture) {
gpu_resources_ = std::make_unique<GpuResources>();
if (!gpu_resources_)
return false;
// Generate mailboxes and holders.
std::vector<gpu::Mailbox> mailboxes;
for (int texture_idx = 0; texture_idx < textures_per_picture; texture_idx++) {
mailboxes.push_back(gpu::Mailbox::Generate());
mailbox_holders_[texture_idx] = gpu::MailboxHolder(
mailboxes[texture_idx], gpu::SyncToken(), GL_TEXTURE_EXTERNAL_OES);
}
// Start construction of the GpuResources.
// We send the texture itself, since we assume that we're using the angle
// device for decoding. Sharing seems not to work very well. Otherwise, we
// would create the texture with KEYED_MUTEX and NTHANDLE, then send along
// a handle that we get from |texture| as an IDXGIResource1.
// TODO(liberato): this should happen on the gpu thread.
return gpu_resources_->Init(std::move(get_helper_cb), array_slice,
std::move(mailboxes), target, size, Texture(),
textures_per_picture);
return true;
}
DefaultTexture2DWrapper::GpuResources::GpuResources() {}
DefaultTexture2DWrapper::GpuResources::~GpuResources() {
if (helper_ && helper_->MakeContextCurrent()) {
for (uint32_t service_id : service_ids_)
helper_->DestroyTexture(service_id);
}
}
bool DefaultTexture2DWrapper::GpuResources::Init(
GetCommandBufferHelperCB get_helper_cb,
int array_slice,
const std::vector<gpu::Mailbox> mailboxes,
GLenum target,
gfx::Size size,
ComD3D11Texture2D angle_texture,
int textures_per_picture) {
helper_ = get_helper_cb.Run();
if (!helper_ || !helper_->MakeContextCurrent())
return false;
// Create the textures and attach them to the mailboxes.
for (int texture_idx = 0; texture_idx < textures_per_picture; texture_idx++) {
uint32_t service_id =
helper_->CreateTexture(target, GL_RGBA, size.width(), size.height(),
GL_RGBA, GL_UNSIGNED_BYTE);
service_ids_.push_back(service_id);
helper_->ProduceTexture(mailboxes[texture_idx], service_id);
}
// Create the stream for zero-copy use by gl.
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,
};
EGLStreamKHR stream = eglCreateStreamKHR(egl_display, stream_attributes);
RETURN_ON_FAILURE(!!stream, "Could not create stream", false);
// |stream| will be destroyed when the GLImage is.
// TODO(liberato): for tests, it will be destroyed pretty much at the end of
// this function unless |helper_| retains it. Also, this won't work if we
// have a FakeCommandBufferHelper since the service IDs aren't meaningful.
scoped_refptr<gl::GLImage> gl_image =
base::MakeRefCounted<gl::GLImageDXGI>(size, stream);
gl::ScopedActiveTexture texture0(GL_TEXTURE0);
gl::ScopedTextureBinder texture0_binder(GL_TEXTURE_EXTERNAL_OES,
service_ids_[0]);
gl::ScopedActiveTexture texture1(GL_TEXTURE1);
gl::ScopedTextureBinder texture1_binder(GL_TEXTURE_EXTERNAL_OES,
service_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 = eglCreateStreamProducerD3DTextureANGLE(egl_display, stream,
producer_attributes);
RETURN_ON_FAILURE(result, "Could not create stream", false);
EGLAttrib frame_attributes[] = {
EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE,
array_slice,
EGL_NONE,
};
result = eglStreamPostD3DTextureANGLE(egl_display, stream,
static_cast<void*>(angle_texture.Get()),
frame_attributes);
RETURN_ON_FAILURE(result, "Could not post texture", false);
result = eglStreamConsumerAcquireKHR(egl_display, stream);
RETURN_ON_FAILURE(result, "Could not post acquire stream", false);
gl::GLImageDXGI* gl_image_dxgi =
static_cast<gl::GLImageDXGI*>(gl_image.get());
gl_image_dxgi->SetTexture(angle_texture, array_slice);
// Bind the image to each texture.
for (size_t texture_idx = 0; texture_idx < service_ids_.size();
texture_idx++) {
helper_->BindImage(service_ids_[texture_idx], gl_image.get(),
false /* client_managed */);
}
return true;
}
} // namespace media
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_GPU_WINDOWS_D3D11_TEXTURE_WRAPPER_H_
#define MEDIA_GPU_WINDOWS_D3D11_TEXTURE_WRAPPER_H_
#include <d3d11.h>
#include <wrl/client.h>
#include <memory>
#include <vector>
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "media/base/video_frame.h"
#include "media/gpu/command_buffer_helper.h"
#include "media/gpu/media_gpu_export.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_image_dxgi.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/scoped_binders.h"
namespace media {
using CommandBufferHelperPtr = scoped_refptr<CommandBufferHelper>;
using MailboxHolderArray = gpu::MailboxHolder[VideoFrame::kMaxPlanes];
using GetCommandBufferHelperCB =
base::RepeatingCallback<CommandBufferHelperPtr()>;
using ComD3D11VideoDevice = Microsoft::WRL::ComPtr<ID3D11VideoDevice>;
using ComD3D11Texture2D = Microsoft::WRL::ComPtr<ID3D11Texture2D>;
using ComD3D11VideoDecoderOutputView =
Microsoft::WRL::ComPtr<ID3D11VideoDecoderOutputView>;
class D3D11PictureBuffer;
// Support different strategies for processing pictures - some may need copying,
// for example.
class MEDIA_GPU_EXPORT Texture2DWrapper {
public:
Texture2DWrapper(ComD3D11Texture2D texture);
virtual ~Texture2DWrapper();
virtual const ComD3D11Texture2D Texture() const;
// This pointer can be raw, since each Texture2DWrapper is directly owned
// by the D3D11PictureBuffer through a unique_ptr.
virtual const MailboxHolderArray& ProcessTexture(
const D3D11PictureBuffer* owner_pb) = 0;
virtual bool Init(GetCommandBufferHelperCB get_helper_cb,
size_t array_slice,
GLenum target,
gfx::Size size,
int textures_per_picture) = 0;
private:
ComD3D11Texture2D texture_;
};
// The default texture wrapper that uses GPUResources to talk to hardware
// on behalf of a Texture2D.
class MEDIA_GPU_EXPORT DefaultTexture2DWrapper : public Texture2DWrapper {
public:
DefaultTexture2DWrapper(ComD3D11Texture2D texture);
~DefaultTexture2DWrapper() override;
bool Init(GetCommandBufferHelperCB get_helper_cb,
size_t array_slice,
GLenum target,
gfx::Size size,
int textures_per_picture) override;
const MailboxHolderArray& ProcessTexture(
const D3D11PictureBuffer* owner_pb) override;
private:
// Things that are to be accessed / freed only on the main thread. In
// addition to setting up the textures to render from a D3D11 texture,
// these also hold the chrome GL Texture objects so that the client
// can use the mailbox.
class GpuResources {
public:
GpuResources();
~GpuResources();
bool Init(GetCommandBufferHelperCB get_helper_cb,
int array_slice,
const std::vector<gpu::Mailbox> mailboxes,
GLenum target,
gfx::Size size,
ComD3D11Texture2D angle_texture,
int textures_per_picture);
std::vector<uint32_t> service_ids_;
private:
scoped_refptr<CommandBufferHelper> helper_;
DISALLOW_COPY_AND_ASSIGN(GpuResources);
};
std::unique_ptr<GpuResources> gpu_resources_;
MailboxHolderArray mailbox_holders_;
};
} // namespace media
#endif // MEDIA_GPU_WINDOWS_D3D11_TEXTURE_WRAPPER_H_
......@@ -671,11 +671,12 @@ void D3D11VideoDecoder::CreatePictureBuffers() {
// Create each picture buffer.
const int textures_per_picture = 2; // From the VDA
for (size_t i = 0; i < TextureSelector::BUFFER_COUNT; i++) {
picture_buffers_.push_back(
new D3D11PictureBuffer(GL_TEXTURE_EXTERNAL_OES, size, i));
if (!picture_buffers_[i]->Init(get_helper_cb_, video_device_, out_texture,
auto processor = std::make_unique<DefaultTexture2DWrapper>(out_texture);
picture_buffers_.push_back(new D3D11PictureBuffer(
GL_TEXTURE_EXTERNAL_OES, std::move(processor), size, i));
if (!picture_buffers_[i]->Init(get_helper_cb_, video_device_,
texture_selector_->decoder_guid,
textures_per_picture)) {
textures_per_picture, media_log_->Clone())) {
NotifyError("Unable to allocate PictureBuffer");
return;
}
......@@ -713,7 +714,7 @@ void D3D11VideoDecoder::OutputResult(const CodecPicture* picture,
base::TimeDelta timestamp = picture_buffer->timestamp_;
scoped_refptr<VideoFrame> frame = VideoFrame::WrapNativeTextures(
texture_selector_->pixel_format, picture_buffer->mailbox_holders(),
texture_selector_->pixel_format, picture_buffer->ProcessTexture(),
VideoFrame::ReleaseMailboxCB(), picture_buffer->size(), visible_rect,
GetNaturalSize(visible_rect, pixel_aspect_ratio), timestamp);
......
......@@ -151,7 +151,7 @@ void D3D11VP9Accelerator::CopyReferenceFrames(
DXVA_PicParams_VP9* pic_params,
const Vp9ReferenceFrameVector& ref_frames) {
D3D11_TEXTURE2D_DESC texture_descriptor;
pic.picture_buffer()->texture()->GetDesc(&texture_descriptor);
pic.picture_buffer()->Texture()->GetDesc(&texture_descriptor);
for (size_t i = 0; i < base::size(pic_params->ref_frame_map); i++) {
auto ref_pic = ref_frames.GetFrame(i);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment