| Index: media/gpu/dxva_video_decode_accelerator_win.cc
|
| diff --git a/media/gpu/dxva_video_decode_accelerator_win.cc b/media/gpu/dxva_video_decode_accelerator_win.cc
|
| index 13e3af05bd14f0b51a00fb94baf9706c9349d889..01d2655876620a0465db015d220fd891cd83eae6 100644
|
| --- a/media/gpu/dxva_video_decode_accelerator_win.cc
|
| +++ b/media/gpu/dxva_video_decode_accelerator_win.cc
|
| @@ -496,10 +496,11 @@ DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator(
|
| decoder_thread_("DXVAVideoDecoderThread"),
|
| pending_flush_(false),
|
| enable_low_latency_(gpu_preferences.enable_low_latency_dxva),
|
| - share_nv12_textures_(gpu_preferences.enable_zero_copy_dxgi_video &&
|
| - !workarounds.disable_dxgi_zero_copy_video),
|
| - copy_nv12_textures_(gpu_preferences.enable_nv12_dxgi_video &&
|
| - !workarounds.disable_nv12_dxgi_video),
|
| + support_share_nv12_textures_(
|
| + gpu_preferences.enable_zero_copy_dxgi_video &&
|
| + !workarounds.disable_dxgi_zero_copy_video),
|
| + support_copy_nv12_textures_(gpu_preferences.enable_nv12_dxgi_video &&
|
| + !workarounds.disable_nv12_dxgi_video),
|
| use_dx11_(false),
|
| use_keyed_mutex_(false),
|
| using_angle_device_(false),
|
| @@ -543,8 +544,8 @@ bool DXVAVideoDecodeAccelerator::Initialize(const Config& config,
|
| if (!config.supported_output_formats.empty() &&
|
| !base::ContainsValue(config.supported_output_formats,
|
| PIXEL_FORMAT_NV12)) {
|
| - share_nv12_textures_ = false;
|
| - copy_nv12_textures_ = false;
|
| + support_share_nv12_textures_ = false;
|
| + support_copy_nv12_textures_ = false;
|
| }
|
|
|
| bool profile_supported = false;
|
| @@ -806,15 +807,19 @@ bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() {
|
| RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false);
|
|
|
| angle_device_ = gl::QueryD3D11DeviceObjectFromANGLE();
|
| - if (!angle_device_)
|
| - copy_nv12_textures_ = false;
|
| - if (share_nv12_textures_) {
|
| + if (!angle_device_) {
|
| + support_copy_nv12_textures_ = false;
|
| + }
|
| + if (ShouldUseANGLEDevice()) {
|
| RETURN_ON_FAILURE(angle_device_.Get(), "Failed to get d3d11 device", false);
|
|
|
| using_angle_device_ = true;
|
| - }
|
| + DCHECK(!use_fp16_);
|
| + angle_device_->GetImmediateContext(d3d11_device_context_.GetAddressOf());
|
|
|
| - if (use_fp16_ || !share_nv12_textures_) {
|
| + hr = angle_device_.CopyTo(video_device_.GetAddressOf());
|
| + RETURN_ON_HR_FAILURE(hr, "Failed to get video device", false);
|
| + } else {
|
| // This array defines the set of DirectX hardware feature levels we support.
|
| // The ordering MUST be preserved. All applications are assumed to support
|
| // 9.1 unless otherwise stated by the application.
|
| @@ -853,11 +858,11 @@ bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() {
|
|
|
| hr = d3d11_device_.CopyTo(video_device_.GetAddressOf());
|
| RETURN_ON_HR_FAILURE(hr, "Failed to get video device", false);
|
| -
|
| - hr = d3d11_device_context_.CopyTo(video_context_.GetAddressOf());
|
| - RETURN_ON_HR_FAILURE(hr, "Failed to get video context", false);
|
| }
|
|
|
| + hr = d3d11_device_context_.CopyTo(video_context_.GetAddressOf());
|
| + RETURN_ON_HR_FAILURE(hr, "Failed to get video context", false);
|
| +
|
| D3D11_FEATURE_DATA_D3D11_OPTIONS options;
|
| hr = D3D11Device()->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &options,
|
| sizeof(options));
|
| @@ -866,7 +871,7 @@ bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() {
|
| // Need extended resource sharing so we can share the NV12 texture between
|
| // ANGLE and the decoder context.
|
| if (!options.ExtendedResourceSharing)
|
| - copy_nv12_textures_ = false;
|
| + support_copy_nv12_textures_ = false;
|
|
|
| UINT nv12_format_support = 0;
|
| hr =
|
| @@ -874,7 +879,7 @@ bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() {
|
| RETURN_ON_HR_FAILURE(hr, "Failed to check NV12 format support", false);
|
|
|
| if (!(nv12_format_support & D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT))
|
| - copy_nv12_textures_ = false;
|
| + support_copy_nv12_textures_ = false;
|
|
|
| UINT fp16_format_support = 0;
|
| hr = D3D11Device()->CheckFormatSupport(DXGI_FORMAT_R16G16B16A16_FLOAT,
|
| @@ -979,7 +984,7 @@ void DXVAVideoDecodeAccelerator::AssignPictureBuffers(
|
| // texture ids. This call just causes the texture manager to hold a
|
| // reference to the GLImage as long as either texture exists.
|
| bind_image_cb_.Run(client_id, GetTextureTarget(),
|
| - picture_buffer->gl_image(), true);
|
| + picture_buffer->gl_image(), false);
|
| }
|
| }
|
|
|
| @@ -1040,6 +1045,16 @@ void DXVAVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_buffer_id) {
|
| RETURN_AND_NOTIFY_ON_FAILURE(it->second->ReusePictureBuffer(),
|
| "Failed to reuse picture buffer",
|
| PLATFORM_FAILURE, );
|
| + if (bind_image_cb_ && (GetPictureBufferMechanism() ==
|
| + PictureBufferMechanism::DELAYED_COPY_TO_NV12)) {
|
| + // Unbind the image to ensure it will be copied again the next time it's
|
| + // needed.
|
| + for (uint32_t client_id :
|
| + it->second->picture_buffer().client_texture_ids()) {
|
| + bind_image_cb_.Run(client_id, GetTextureTarget(),
|
| + it->second->gl_image(), false);
|
| + }
|
| + }
|
|
|
| ProcessPendingSamples();
|
| if (pending_flush_) {
|
| @@ -1590,8 +1605,8 @@ bool DXVAVideoDecodeAccelerator::InitDecoder(VideoCodecProfile profile) {
|
|
|
| if (use_fp16_) {
|
| // TODO(hubbe): Share/copy P010/P016 textures.
|
| - share_nv12_textures_ = false;
|
| - copy_nv12_textures_ = false;
|
| + support_share_nv12_textures_ = false;
|
| + support_copy_nv12_textures_ = false;
|
| }
|
|
|
| return SetDecoderMediaTypes();
|
| @@ -1643,15 +1658,15 @@ bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() {
|
| !gl::g_driver_egl.ext.b_EGL_KHR_stream ||
|
| !gl::g_driver_egl.ext.b_EGL_KHR_stream_consumer_gltexture ||
|
| !gl::g_driver_egl.ext.b_EGL_NV_stream_consumer_gltexture_yuv) {
|
| - share_nv12_textures_ = false;
|
| - copy_nv12_textures_ = false;
|
| + support_share_nv12_textures_ = false;
|
| + support_copy_nv12_textures_ = false;
|
| }
|
|
|
| // The MS VP9 MFT doesn't pass through the bind flags we specify, so
|
| // textures aren't created with D3D11_BIND_SHADER_RESOURCE and can't be used
|
| // from ANGLE.
|
| if (using_ms_vp9_mft_)
|
| - share_nv12_textures_ = false;
|
| + support_share_nv12_textures_ = false;
|
|
|
| return true;
|
| }
|
| @@ -1710,7 +1725,7 @@ bool DXVAVideoDecodeAccelerator::SetDecoderOutputMediaType(
|
| const GUID& subtype) {
|
| bool result = SetTransformOutputType(decoder_.Get(), subtype, 0, 0);
|
|
|
| - if (share_nv12_textures_) {
|
| + if (GetPictureBufferMechanism() == PictureBufferMechanism::BIND) {
|
| base::win::ScopedComPtr<IMFAttributes> out_attributes;
|
| HRESULT hr =
|
| decoder_->GetOutputStreamAttributes(0, out_attributes.GetAddressOf());
|
| @@ -1938,7 +1953,7 @@ void DXVAVideoDecodeAccelerator::ProcessPendingSamples() {
|
| index->second->set_bound();
|
| index->second->set_color_space(pending_sample->color_space);
|
|
|
| - if (share_nv12_textures_) {
|
| + if (index->second->CanBindSamples()) {
|
| main_thread_task_runner_->PostTask(
|
| FROM_HERE,
|
| base::Bind(&DXVAVideoDecodeAccelerator::BindPictureBufferToSample,
|
| @@ -2109,7 +2124,8 @@ void DXVAVideoDecodeAccelerator::RequestPictureBuffers(int width, int height) {
|
| // per picture buffer, 1 for the Y channel and 1 for the UV channels.
|
| // They're shared to ANGLE using EGL_NV_stream_consumer_gltexture_yuv, so
|
| // they need to be GL_TEXTURE_EXTERNAL_OES.
|
| - bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_;
|
| + bool provide_nv12_textures =
|
| + GetPictureBufferMechanism() != PictureBufferMechanism::COPY_TO_RGB;
|
| client_->ProvidePictureBuffers(
|
| kNumPictureBuffers,
|
| provide_nv12_textures ? PIXEL_FORMAT_NV12 : PIXEL_FORMAT_UNKNOWN,
|
| @@ -2589,7 +2605,7 @@ void DXVAVideoDecodeAccelerator::BindPictureBufferToSample(
|
|
|
| DCHECK(!output_picture_buffers_.empty());
|
|
|
| - bool result = picture_buffer->BindSampleToTexture(sample);
|
| + bool result = picture_buffer->BindSampleToTexture(this, sample);
|
| RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface",
|
| PLATFORM_FAILURE, );
|
|
|
| @@ -2847,7 +2863,9 @@ bool DXVAVideoDecodeAccelerator::InitializeID3D11VideoProcessor(
|
| d3d11_processor_.Get(), 0, false);
|
| }
|
|
|
| - if (copy_nv12_textures_) {
|
| + if (GetPictureBufferMechanism() == PictureBufferMechanism::COPY_TO_NV12 ||
|
| + GetPictureBufferMechanism() ==
|
| + PictureBufferMechanism::DELAYED_COPY_TO_NV12) {
|
| // If we're copying NV12 textures, make sure we set the same
|
| // color space on input and output.
|
| D3D11_VIDEO_PROCESSOR_COLOR_SPACE d3d11_color_space = {0};
|
| @@ -3022,12 +3040,46 @@ void DXVAVideoDecodeAccelerator::ConfigChanged(const Config& config) {
|
| }
|
|
|
| uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const {
|
| - bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_;
|
| - return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D;
|
| + switch (GetPictureBufferMechanism()) {
|
| + case PictureBufferMechanism::BIND:
|
| + case PictureBufferMechanism::DELAYED_COPY_TO_NV12:
|
| + case PictureBufferMechanism::COPY_TO_NV12:
|
| + return GL_TEXTURE_EXTERNAL_OES;
|
| + case PictureBufferMechanism::COPY_TO_RGB:
|
| + return GL_TEXTURE_2D;
|
| + }
|
| + NOTREACHED();
|
| + return 0;
|
| +}
|
| +
|
| +DXVAVideoDecodeAccelerator::PictureBufferMechanism
|
| +DXVAVideoDecodeAccelerator::GetPictureBufferMechanism() const {
|
| + if (use_fp16_)
|
| + return PictureBufferMechanism::COPY_TO_RGB;
|
| + if (support_share_nv12_textures_)
|
| + return PictureBufferMechanism::BIND;
|
| + if (base::FeatureList::IsEnabled(kDelayCopyNV12Textures) &&
|
| + support_copy_nv12_textures_)
|
| + return PictureBufferMechanism::DELAYED_COPY_TO_NV12;
|
| + if (support_copy_nv12_textures_)
|
| + return PictureBufferMechanism::COPY_TO_NV12;
|
| + return PictureBufferMechanism::COPY_TO_RGB;
|
| +}
|
| +
|
| +bool DXVAVideoDecodeAccelerator::ShouldUseANGLEDevice() const {
|
| + switch (GetPictureBufferMechanism()) {
|
| + case PictureBufferMechanism::BIND:
|
| + case PictureBufferMechanism::DELAYED_COPY_TO_NV12:
|
| + return true;
|
| + case PictureBufferMechanism::COPY_TO_NV12:
|
| + case PictureBufferMechanism::COPY_TO_RGB:
|
| + return false;
|
| + }
|
| + NOTREACHED();
|
| + return false;
|
| }
|
| -
|
| ID3D11Device* DXVAVideoDecodeAccelerator::D3D11Device() const {
|
| - return share_nv12_textures_ ? angle_device_.Get() : d3d11_device_.Get();
|
| + return ShouldUseANGLEDevice() ? angle_device_.Get() : d3d11_device_.Get();
|
| }
|
|
|
| } // namespace media
|
|
|