Commit 8a11a6d0 authored by Ted Meyer's avatar Ted Meyer Committed by Commit Bot

Support different D3D11VideoContext levels

Newer hardware supports, and encrypted media requires D3D11VideoContext1
usage, while older hardware might only have support for
D3D11VideoContext. We should support both of these seamlessly. There are
also other levels of video context, and this should make it easy to add
support should we ever require that.

This should hopefully help mitigate some crashes we are seeing on older hardware.

Bug: 897785
Change-Id: I46c913ba64036c2bc6ef655026f1cd90d0ab4684
Reviewed-on: https://chromium-review.googlesource.com/c/1298636
Commit-Queue: Ted Meyer <tmathmeyer@chromium.org>
Reviewed-by: default avatarFrank Liberato <liberato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605124}
parent fd1d5501
...@@ -268,6 +268,8 @@ component("gpu") { ...@@ -268,6 +268,8 @@ component("gpu") {
"windows/d3d11_h264_accelerator.h", "windows/d3d11_h264_accelerator.h",
"windows/d3d11_picture_buffer.cc", "windows/d3d11_picture_buffer.cc",
"windows/d3d11_picture_buffer.h", "windows/d3d11_picture_buffer.h",
"windows/d3d11_video_context_wrapper.cc",
"windows/d3d11_video_context_wrapper.h",
"windows/d3d11_video_decoder.cc", "windows/d3d11_video_decoder.cc",
"windows/d3d11_video_decoder.h", "windows/d3d11_video_decoder.h",
"windows/d3d11_video_decoder_client.h", "windows/d3d11_video_decoder_client.h",
......
...@@ -67,13 +67,13 @@ D3D11H264Accelerator::D3D11H264Accelerator( ...@@ -67,13 +67,13 @@ D3D11H264Accelerator::D3D11H264Accelerator(
CdmProxyContext* cdm_proxy_context, CdmProxyContext* cdm_proxy_context,
Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder, Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder,
Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device, Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device,
Microsoft::WRL::ComPtr<ID3D11VideoContext1> video_context) std::unique_ptr<VideoContextWrapper> video_context)
: client_(client), : client_(client),
media_log_(media_log), media_log_(media_log),
cdm_proxy_context_(cdm_proxy_context), cdm_proxy_context_(cdm_proxy_context),
video_decoder_(video_decoder), video_decoder_(video_decoder),
video_device_(video_device), video_device_(video_device),
video_context_(video_context) {} video_context_(std::move(video_context)) {}
D3D11H264Accelerator::~D3D11H264Accelerator() {} D3D11H264Accelerator::~D3D11H264Accelerator() {}
...@@ -473,7 +473,7 @@ bool D3D11H264Accelerator::SubmitSliceData() { ...@@ -473,7 +473,7 @@ bool D3D11H264Accelerator::SubmitSliceData() {
return false; return false;
} }
D3D11_VIDEO_DECODER_BUFFER_DESC1 buffers[4] = {}; VideoContextWrapper::VideoBufferWrapper buffers[4] = {};
buffers[0].BufferType = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS; buffers[0].BufferType = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS;
buffers[0].DataOffset = 0; buffers[0].DataOffset = 0;
buffers[0].DataSize = sizeof(DXVA_PicParams_H264); buffers[0].DataSize = sizeof(DXVA_PicParams_H264);
...@@ -498,8 +498,8 @@ bool D3D11H264Accelerator::SubmitSliceData() { ...@@ -498,8 +498,8 @@ bool D3D11H264Accelerator::SubmitSliceData() {
} }
} }
hr = video_context_->SubmitDecoderBuffers1(video_decoder_.Get(), hr = video_context_->SubmitDecoderBuffers(video_decoder_.Get(),
base::size(buffers), buffers); base::size(buffers), buffers);
current_offset_ = 0; current_offset_ = 0;
slice_info_.clear(); slice_info_.clear();
bitstream_buffer_bytes_ = nullptr; bitstream_buffer_bytes_ = nullptr;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "media/base/video_frame.h" #include "media/base/video_frame.h"
#include "media/gpu/h264_decoder.h" #include "media/gpu/h264_decoder.h"
#include "media/gpu/h264_dpb.h" #include "media/gpu/h264_dpb.h"
#include "media/gpu/windows/d3d11_video_context_wrapper.h"
#include "media/gpu/windows/d3d11_video_decoder_client.h" #include "media/gpu/windows/d3d11_video_decoder_client.h"
#include "media/gpu/windows/return_on_failure.h" #include "media/gpu/windows/return_on_failure.h"
#include "media/video/picture.h" #include "media/video/picture.h"
...@@ -32,13 +33,12 @@ class MediaLog; ...@@ -32,13 +33,12 @@ class MediaLog;
class D3D11H264Accelerator : public H264Decoder::H264Accelerator { class D3D11H264Accelerator : public H264Decoder::H264Accelerator {
public: public:
// |cdm_proxy_context| may be null for clear content. // |cdm_proxy_context| may be null for clear content.
D3D11H264Accelerator( D3D11H264Accelerator(D3D11VideoDecoderClient* client,
D3D11VideoDecoderClient* client, MediaLog* media_log,
MediaLog* media_log, CdmProxyContext* cdm_proxy_context,
CdmProxyContext* cdm_proxy_context, Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder,
Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder, Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device,
Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device, std::unique_ptr<VideoContextWrapper> video_context);
Microsoft::WRL::ComPtr<ID3D11VideoContext1> video_context);
~D3D11H264Accelerator() override; ~D3D11H264Accelerator() override;
// H264Decoder::H264Accelerator implementation. // H264Decoder::H264Accelerator implementation.
...@@ -75,7 +75,7 @@ class D3D11H264Accelerator : public H264Decoder::H264Accelerator { ...@@ -75,7 +75,7 @@ class D3D11H264Accelerator : public H264Decoder::H264Accelerator {
Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder_; Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder_;
Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device_; Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device_;
Microsoft::WRL::ComPtr<ID3D11VideoContext1> video_context_; std::unique_ptr<VideoContextWrapper> video_context_;
// This information set at the beginning of a frame and saved for processing // This information set at the beginning of a frame and saved for processing
// all the slices. // all the slices.
......
// Copyright 2018 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_video_context_wrapper.h"
#include <memory>
#include "base/memory/weak_ptr.h"
namespace media {
VideoContextWrapper::~VideoContextWrapper() = default;
// Specialization for sample submission
template <typename CTX>
struct BufferSubmitter;
template <>
struct BufferSubmitter<ID3D11VideoContext1> {
static HRESULT SubmitDecoderBuffers(
Microsoft::WRL::ComPtr<ID3D11VideoContext1> context,
ID3D11VideoDecoder* decoder,
const UINT num_buffers,
const VideoContextWrapper::VideoBufferWrapper* src) {
constexpr UINT max_buffers = 4;
DCHECK_LE(num_buffers, max_buffers);
D3D11_VIDEO_DECODER_BUFFER_DESC1 buffers[max_buffers] = {};
for (size_t i = 0; i < num_buffers; i++) {
buffers[i].BufferType = src[i].BufferType;
buffers[i].DataOffset = src[i].DataOffset;
buffers[i].DataSize = src[i].DataSize;
buffers[i].pIV = src[i].pIV;
buffers[i].IVSize = src[i].IVSize;
buffers[i].pSubSampleMappingBlock = src[i].pSubSampleMappingBlock;
buffers[i].SubSampleMappingCount = src[i].SubSampleMappingCount;
}
return context->SubmitDecoderBuffers1(decoder, num_buffers, buffers);
}
};
template <>
struct BufferSubmitter<ID3D11VideoContext> {
static HRESULT SubmitDecoderBuffers(
Microsoft::WRL::ComPtr<ID3D11VideoContext> context,
ID3D11VideoDecoder* decoder,
const UINT num_buffers,
const VideoContextWrapper::VideoBufferWrapper* src) {
constexpr UINT max_buffers = 4;
DCHECK_LE(num_buffers, max_buffers);
D3D11_VIDEO_DECODER_BUFFER_DESC buffers[max_buffers] = {};
for (size_t i = 0; i < num_buffers; i++) {
buffers[i].BufferType = src[i].BufferType;
buffers[i].DataOffset = src[i].DataOffset;
buffers[i].DataSize = src[i].DataSize;
DCHECK_EQ(src[i].pIV, nullptr);
DCHECK_EQ(src[i].IVSize, 0u);
DCHECK_EQ(src[i].pSubSampleMappingBlock, nullptr);
DCHECK_EQ(src[i].SubSampleMappingCount, 0u);
}
return context->SubmitDecoderBuffers(decoder, num_buffers, buffers);
}
};
// CTX is The type of D3D11VideoContext* that we are wrapping, whether that
// be D3D11VideoContext or D3D11VideoContext1. Only these types will work
// since the BufferSubmitter struct is only specialized for these two types.
template <typename CTX>
class VideoContextWrapperImpl : public VideoContextWrapper {
public:
explicit VideoContextWrapperImpl(Microsoft::WRL::ComPtr<CTX> video_context)
: video_context_(video_context) {}
~VideoContextWrapperImpl() {}
HRESULT DecoderBeginFrame(ID3D11VideoDecoder* video_decoder,
ID3D11VideoDecoderOutputView* output_view,
UINT content_key_size,
const void* content_key) override {
return video_context_->DecoderBeginFrame(video_decoder, output_view,
content_key_size, content_key);
}
HRESULT GetDecoderBuffer(ID3D11VideoDecoder* video_decoder,
D3D11_VIDEO_DECODER_BUFFER_TYPE type,
UINT* buffer_size,
void** buffer) override {
return video_context_->GetDecoderBuffer(video_decoder, type, buffer_size,
buffer);
}
HRESULT ReleaseDecoderBuffer(ID3D11VideoDecoder* video_decoder,
D3D11_VIDEO_DECODER_BUFFER_TYPE type) override {
return video_context_->ReleaseDecoderBuffer(video_decoder, type);
}
HRESULT DecoderEndFrame(ID3D11VideoDecoder* video_decoder) override {
return video_context_->DecoderEndFrame(video_decoder);
}
HRESULT SubmitDecoderBuffers(ID3D11VideoDecoder* video_decoder,
UINT num_buffers,
const VideoBufferWrapper* buffers) override {
return BufferSubmitter<CTX>::SubmitDecoderBuffers(
video_context_, video_decoder, num_buffers, buffers);
}
private:
Microsoft::WRL::ComPtr<CTX> video_context_;
};
std::unique_ptr<VideoContextWrapper> VideoContextWrapper::CreateWrapper(
D3D_FEATURE_LEVEL supported_d3d11_version,
Microsoft::WRL::ComPtr<ID3D11DeviceContext> device_context,
HRESULT* status) {
if (supported_d3d11_version == D3D_FEATURE_LEVEL_11_0) {
Microsoft::WRL::ComPtr<ID3D11VideoContext> video_context;
*status = device_context.CopyTo(video_context.ReleaseAndGetAddressOf());
return std::make_unique<VideoContextWrapperImpl<ID3D11VideoContext>>(
video_context);
}
if (supported_d3d11_version == D3D_FEATURE_LEVEL_11_1) {
Microsoft::WRL::ComPtr<ID3D11VideoContext1> video_context;
*status = device_context.CopyTo(video_context.ReleaseAndGetAddressOf());
return std::make_unique<VideoContextWrapperImpl<ID3D11VideoContext1>>(
video_context);
}
*status = E_FAIL;
return nullptr;
}
} // namespace media
// Copyright 2018 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_VIDEO_CONTEXT_WRAPPER_H_
#define MEDIA_GPU_WINDOWS_D3D11_VIDEO_CONTEXT_WRAPPER_H_
#include <d3d11_1.h>
#include <wrl/client.h>
#include <memory>
#include "base/macros.h"
#include "media/gpu/media_gpu_export.h"
namespace media {
class MEDIA_GPU_EXPORT VideoContextWrapper {
public:
VideoContextWrapper() = default;
virtual ~VideoContextWrapper();
// D3D11_VIDEO_DECODER_BUFFER_DESC1 and D3D11_VIDEO_DECODER_BUFFER_DESC
// have radically different sets of member variables, which means that in
// order to have a converter class, we need to support all fields. They are
// also in different orders, which prevents using a simple memcpy.
// It seems we don't currently use any of the D3D11_VIDEO_DECODER_BUFFER_DESC
// specific fields right now.
// Fields are named as they appear in the D3D11 Structs.
struct VideoBufferWrapper {
// Shared Fields
D3D11_VIDEO_DECODER_BUFFER_TYPE BufferType;
UINT DataOffset;
UINT DataSize;
void* pIV;
UINT IVSize;
// DESC1-specific fields
D3D11_VIDEO_DECODER_SUB_SAMPLE_MAPPING_BLOCK* pSubSampleMappingBlock;
UINT SubSampleMappingCount;
};
static std::unique_ptr<VideoContextWrapper> CreateWrapper(
D3D_FEATURE_LEVEL supported_d3d11_version,
Microsoft::WRL::ComPtr<ID3D11DeviceContext> device_context,
HRESULT* status);
// This method signiture is defined to match exactly that of
// |ID3D11VideoContext::DecoderBeginFrame|.
virtual HRESULT DecoderBeginFrame(ID3D11VideoDecoder* video_decoder,
ID3D11VideoDecoderOutputView* output_view,
UINT content_key_size,
const void* content_key) = 0;
// This method signiture is defined to match exactly that of
// |ID3D11VideoContext::GetDecoderBuffer|.
virtual HRESULT GetDecoderBuffer(ID3D11VideoDecoder* video_decoder,
D3D11_VIDEO_DECODER_BUFFER_TYPE type,
UINT* buffer_size,
void** buffer) = 0;
// This method signiture is defined to match exactly that of
// |ID3D11VideoContext::ReleaseDecoderBuffer|.
virtual HRESULT ReleaseDecoderBuffer(
ID3D11VideoDecoder* video_decoder,
D3D11_VIDEO_DECODER_BUFFER_TYPE type) = 0;
// This method signiture is defined to match exactly that of
// |ID3D11VideoContext::DecoderEndFrame|.
virtual HRESULT DecoderEndFrame(ID3D11VideoDecoder* video_decoder) = 0;
// This method signiture is defined to match exactly that of
// |ID3D11VideoContext::SubmitDecoderBuffers|.
virtual HRESULT SubmitDecoderBuffers(ID3D11VideoDecoder* video_decoder,
UINT num_buffers,
const VideoBufferWrapper* buffers) = 0;
DISALLOW_COPY_AND_ASSIGN(VideoContextWrapper);
}; // VideoContextWrapper
} // namespace media
#endif // MEDIA_GPU_WINDOWS_D3D11_VIDEO_CONTEXT_WRAPPER_H_
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "media/base/video_frame.h" #include "media/base/video_frame.h"
#include "media/base/video_util.h" #include "media/base/video_util.h"
#include "media/gpu/windows/d3d11_picture_buffer.h" #include "media/gpu/windows/d3d11_picture_buffer.h"
#include "media/gpu/windows/d3d11_video_context_wrapper.h"
#include "media/gpu/windows/d3d11_video_decoder_impl.h" #include "media/gpu/windows/d3d11_video_decoder_impl.h"
#include "ui/gl/gl_angle_util_win.h" #include "ui/gl/gl_angle_util_win.h"
...@@ -108,30 +109,41 @@ std::string D3D11VideoDecoder::GetDisplayName() const { ...@@ -108,30 +109,41 @@ std::string D3D11VideoDecoder::GetDisplayName() const {
return "D3D11VideoDecoder"; return "D3D11VideoDecoder";
} }
void D3D11VideoDecoder::InitializeAcceleratedDecoder( HRESULT D3D11VideoDecoder::InitializeAcceleratedDecoder(
const VideoDecoderConfig& config, const VideoDecoderConfig& config,
CdmProxyContext* proxy_context, CdmProxyContext* proxy_context,
Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder) { Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder) {
// If we got an 11.1 D3D11 Device, we can use a |ID3D11VideoContext1|,
// otherwise we have to make sure we only use a |ID3D11VideoContext|.
HRESULT hr;
// |device_context_| is the primary display context, but currently
// we share it for decoding purposes.
auto video_context = VideoContextWrapper::CreateWrapper(usable_feature_level_,
device_context_, &hr);
if (!SUCCEEDED(hr))
return hr;
if (IsVP9(config)) { if (IsVP9(config)) {
accelerated_video_decoder_ = std::make_unique<VP9Decoder>( accelerated_video_decoder_ = std::make_unique<VP9Decoder>(
std::make_unique<D3D11VP9Accelerator>(this, media_log_.get(), std::make_unique<D3D11VP9Accelerator>(
proxy_context, video_decoder, this, media_log_.get(), proxy_context, video_decoder, video_device_,
video_device_, video_context_), std::move(video_context)),
config.color_space_info()); config.color_space_info());
return; return hr;
} }
if (IsH264(config)) { if (IsH264(config)) {
accelerated_video_decoder_ = std::make_unique<H264Decoder>( accelerated_video_decoder_ = std::make_unique<H264Decoder>(
std::make_unique<D3D11H264Accelerator>(this, media_log_.get(), std::make_unique<D3D11H264Accelerator>(
proxy_context, video_decoder, this, media_log_.get(), proxy_context, video_decoder, video_device_,
video_device_, video_context_), std::move(video_context)),
config.color_space_info()); config.color_space_info());
return; return hr;
} }
// No other type of config should make it this far due to earlier checks. return E_FAIL;
NOTREACHED();
} }
bool D3D11VideoDecoder::DeviceHasDecoderID(GUID decoder_guid) { bool D3D11VideoDecoder::DeviceHasDecoderID(GUID decoder_guid) {
...@@ -203,11 +215,6 @@ void D3D11VideoDecoder::Initialize( ...@@ -203,11 +215,6 @@ void D3D11VideoDecoder::Initialize(
// TODO(liberato): Handle cleanup better. Also consider being less chatty in // TODO(liberato): Handle cleanup better. Also consider being less chatty in
// the logs, since this will fall back. // the logs, since this will fall back.
hr = device_context_.CopyTo(video_context_.ReleaseAndGetAddressOf());
if (!SUCCEEDED(hr)) {
NotifyError("Failed to get device context");
return;
}
hr = device_.CopyTo(video_device_.ReleaseAndGetAddressOf()); hr = device_.CopyTo(video_device_.ReleaseAndGetAddressOf());
if (!SUCCEEDED(hr)) { if (!SUCCEEDED(hr)) {
...@@ -285,7 +292,12 @@ void D3D11VideoDecoder::Initialize( ...@@ -285,7 +292,12 @@ void D3D11VideoDecoder::Initialize(
return; return;
} }
InitializeAcceleratedDecoder(config, proxy_context, video_decoder); hr = InitializeAcceleratedDecoder(config, proxy_context, video_decoder);
if (!SUCCEEDED(hr)) {
NotifyError("Failed to get device context");
return;
}
// |cdm_context| could be null for clear playback. // |cdm_context| could be null for clear playback.
// TODO(liberato): On re-init, should this still happen? // TODO(liberato): On re-init, should this still happen?
...@@ -654,30 +666,17 @@ void D3D11VideoDecoder::SetWasSupportedReason( ...@@ -654,30 +666,17 @@ void D3D11VideoDecoder::SetWasSupportedReason(
bool D3D11VideoDecoder::IsPotentiallySupported( bool D3D11VideoDecoder::IsPotentiallySupported(
const VideoDecoderConfig& config) { const VideoDecoderConfig& config) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// TODO(liberato): All of this could be moved into MojoVideoDecoder, so that // TODO(liberato): All of this could be moved into MojoVideoDecoder, so that
// it could run on the client side and save the IPC hop. // it could run on the client side and save the IPC hop.
if (config.is_encrypted() && // Must allow zero-copy of nv12 textures.
!base::FeatureList::IsEnabled(kD3D11EncryptedMedia)) { if (!gpu_preferences_.enable_zero_copy_dxgi_video) {
SetWasSupportedReason(D3D11VideoNotSupportedReason::kEncryptedMedia); SetWasSupportedReason(D3D11VideoNotSupportedReason::kZeroCopyNv12Required);
return false; return false;
} }
// TODO(liberato): It would be nice to QueryD3D11DeviceObjectFromANGLE, but if (gpu_workarounds_.disable_dxgi_zero_copy_video) {
// we don't know what thread we're on. SetWasSupportedReason(D3D11VideoNotSupportedReason::kZeroCopyVideoRequired);
// Make sure that we support at least 11.0.
D3D_FEATURE_LEVEL levels[] = {
D3D_FEATURE_LEVEL_11_0,
};
HRESULT hr = create_device_func_.Run(
nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, levels, ARRAYSIZE(levels),
D3D11_SDK_VERSION, nullptr, nullptr, nullptr);
if (FAILED(hr)) {
SetWasSupportedReason(
D3D11VideoNotSupportedReason::kInsufficientD3D11FeatureLevel);
return false; return false;
} }
...@@ -692,6 +691,13 @@ bool D3D11VideoDecoder::IsPotentiallySupported( ...@@ -692,6 +691,13 @@ bool D3D11VideoDecoder::IsPotentiallySupported(
return false; return false;
} }
bool encrypted_stream = config.is_encrypted();
if (encrypted_stream && !base::FeatureList::IsEnabled(kD3D11EncryptedMedia)) {
SetWasSupportedReason(D3D11VideoNotSupportedReason::kEncryptedMedia);
return false;
}
// Converts one of chromium's VideoCodecProfile options to a dxguid value. // Converts one of chromium's VideoCodecProfile options to a dxguid value.
// If this GUID comes back empty then the profile is not supported. // If this GUID comes back empty then the profile is not supported.
GUID decoder_GUID = GetD3D11DecoderGUID(config); GUID decoder_GUID = GetD3D11DecoderGUID(config);
...@@ -703,21 +709,33 @@ bool D3D11VideoDecoder::IsPotentiallySupported( ...@@ -703,21 +709,33 @@ bool D3D11VideoDecoder::IsPotentiallySupported(
return false; return false;
} }
// TODO(liberato): dxva checks IsHDR() in the target colorspace, but we don't // TODO(liberato): It would be nice to QueryD3D11DeviceObjectFromANGLE, but
// have the target colorspace. It's commented as being for vpx, though, so // we don't know what thread we're on.
// we skip it here for now. D3D_FEATURE_LEVEL levels[] = {
D3D_FEATURE_LEVEL_11_1, // We need 11.1 for encrypted playback,
D3D_FEATURE_LEVEL_11_0, // but make sure we have at least 11.0 for clear.
};
// Must allow zero-copy of nv12 textures. // This is also the most expensive check, so make sure it is last.
if (!gpu_preferences_.enable_zero_copy_dxgi_video) { HRESULT hr = create_device_func_.Run(
SetWasSupportedReason(D3D11VideoNotSupportedReason::kZeroCopyNv12Required); nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, levels, ARRAYSIZE(levels),
D3D11_SDK_VERSION, nullptr, &usable_feature_level_, nullptr);
if (FAILED(hr)) {
SetWasSupportedReason(
D3D11VideoNotSupportedReason::kInsufficientD3D11FeatureLevel);
return false; return false;
} }
if (gpu_workarounds_.disable_dxgi_zero_copy_video) { if (encrypted_stream && usable_feature_level_ == D3D_FEATURE_LEVEL_11_0) {
SetWasSupportedReason(D3D11VideoNotSupportedReason::kZeroCopyVideoRequired); SetWasSupportedReason(
D3D11VideoNotSupportedReason::kInsufficientD3D11FeatureLevel);
return false; return false;
} }
// TODO(liberato): dxva checks IsHDR() in the target colorspace, but we don't
// have the target colorspace. It's commented as being for vpx, though, so
// we skip it here for now.
SetWasSupportedReason(D3D11VideoNotSupportedReason::kVideoIsSupported); SetWasSupportedReason(D3D11VideoNotSupportedReason::kVideoIsSupported);
return true; return true;
} }
......
...@@ -103,7 +103,7 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoder : public VideoDecoder, ...@@ -103,7 +103,7 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoder : public VideoDecoder,
void DoDecode(); void DoDecode();
// instantiate |accelerated_video_decoder_| based on the video profile // instantiate |accelerated_video_decoder_| based on the video profile
void InitializeAcceleratedDecoder( HRESULT InitializeAcceleratedDecoder(
const VideoDecoderConfig& config, const VideoDecoderConfig& config,
CdmProxyContext* proxy_context, CdmProxyContext* proxy_context,
Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder); Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder);
...@@ -198,7 +198,8 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoder : public VideoDecoder, ...@@ -198,7 +198,8 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoder : public VideoDecoder,
Microsoft::WRL::ComPtr<ID3D11Device> device_; Microsoft::WRL::ComPtr<ID3D11Device> device_;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> device_context_; Microsoft::WRL::ComPtr<ID3D11DeviceContext> device_context_;
Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device_; Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device_;
Microsoft::WRL::ComPtr<ID3D11VideoContext1> video_context_;
D3D_FEATURE_LEVEL usable_feature_level_;
std::unique_ptr<AcceleratedVideoDecoder> accelerated_video_decoder_; std::unique_ptr<AcceleratedVideoDecoder> accelerated_video_decoder_;
......
...@@ -40,7 +40,7 @@ D3D11VP9Accelerator::D3D11VP9Accelerator( ...@@ -40,7 +40,7 @@ D3D11VP9Accelerator::D3D11VP9Accelerator(
CdmProxyContext* cdm_proxy_context, CdmProxyContext* cdm_proxy_context,
Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder, Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder,
Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device, Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device,
Microsoft::WRL::ComPtr<ID3D11VideoContext1> video_context) std::unique_ptr<VideoContextWrapper> video_context)
: client_(client), : client_(client),
media_log_(media_log), media_log_(media_log),
cdm_proxy_context_(cdm_proxy_context), cdm_proxy_context_(cdm_proxy_context),
...@@ -315,7 +315,7 @@ bool D3D11VP9Accelerator::SubmitDecoderBuffer( ...@@ -315,7 +315,7 @@ bool D3D11VP9Accelerator::SubmitDecoderBuffer(
RELEASE_BUFFER(D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL); RELEASE_BUFFER(D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL);
constexpr int buffers_count = 3; constexpr int buffers_count = 3;
D3D11_VIDEO_DECODER_BUFFER_DESC1 buffers[buffers_count] = {}; VideoContextWrapper::VideoBufferWrapper buffers[buffers_count] = {};
buffers[0].BufferType = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS; buffers[0].BufferType = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS;
buffers[0].DataOffset = 0; buffers[0].DataOffset = 0;
buffers[0].DataSize = sizeof(pic_params); buffers[0].DataSize = sizeof(pic_params);
...@@ -338,8 +338,8 @@ bool D3D11VP9Accelerator::SubmitDecoderBuffer( ...@@ -338,8 +338,8 @@ bool D3D11VP9Accelerator::SubmitDecoderBuffer(
} }
} }
RETURN_ON_HR_FAILURE(SubmitDecoderBuffers1, RETURN_ON_HR_FAILURE(SubmitDecoderBuffers,
video_context_->SubmitDecoderBuffers1( video_context_->SubmitDecoderBuffers(
video_decoder_.Get(), buffers_count, buffers)); video_decoder_.Get(), buffers_count, buffers));
buffer_offset += copy_size; buffer_offset += copy_size;
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "media/base/media_log.h" #include "media/base/media_log.h"
#include "media/gpu/vp9_decoder.h" #include "media/gpu/vp9_decoder.h"
#include "media/gpu/windows/d3d11_video_context_wrapper.h"
#include "media/gpu/windows/d3d11_video_decoder_client.h" #include "media/gpu/windows/d3d11_video_decoder_client.h"
#include "media/gpu/windows/d3d11_vp9_picture.h" #include "media/gpu/windows/d3d11_vp9_picture.h"
...@@ -20,13 +21,12 @@ class CdmProxyContext; ...@@ -20,13 +21,12 @@ class CdmProxyContext;
class D3D11VP9Accelerator : public VP9Decoder::VP9Accelerator { class D3D11VP9Accelerator : public VP9Decoder::VP9Accelerator {
public: public:
D3D11VP9Accelerator( D3D11VP9Accelerator(D3D11VideoDecoderClient* client,
D3D11VideoDecoderClient* client, MediaLog* media_log,
MediaLog* media_log, CdmProxyContext* cdm_proxy_context,
CdmProxyContext* cdm_proxy_context, Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder,
Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder, Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device,
Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device, std::unique_ptr<VideoContextWrapper> video_context);
Microsoft::WRL::ComPtr<ID3D11VideoContext1> video_context);
~D3D11VP9Accelerator() override; ~D3D11VP9Accelerator() override;
scoped_refptr<VP9Picture> CreateVP9Picture() override; scoped_refptr<VP9Picture> CreateVP9Picture() override;
...@@ -78,7 +78,7 @@ class D3D11VP9Accelerator : public VP9Decoder::VP9Accelerator { ...@@ -78,7 +78,7 @@ class D3D11VP9Accelerator : public VP9Decoder::VP9Accelerator {
UINT status_feedback_; UINT status_feedback_;
Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder_; Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder_;
Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device_; Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device_;
Microsoft::WRL::ComPtr<ID3D11VideoContext1> video_context_; std::unique_ptr<VideoContextWrapper> video_context_;
DISALLOW_COPY_AND_ASSIGN(D3D11VP9Accelerator); DISALLOW_COPY_AND_ASSIGN(D3D11VP9Accelerator);
}; };
......
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