| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/gpu/dxva_video_decode_accelerator_win.h" | 5 #include "media/gpu/dxva_video_decode_accelerator_win.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #if !defined(OS_WIN) | 9 #if !defined(OS_WIN) |
| 10 #error This file should only be built on Windows. | 10 #error This file should only be built on Windows. |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 pictures_requested_(false), | 489 pictures_requested_(false), |
| 490 inputs_before_decode_(0), | 490 inputs_before_decode_(0), |
| 491 sent_drain_message_(false), | 491 sent_drain_message_(false), |
| 492 get_gl_context_cb_(get_gl_context_cb), | 492 get_gl_context_cb_(get_gl_context_cb), |
| 493 make_context_current_cb_(make_context_current_cb), | 493 make_context_current_cb_(make_context_current_cb), |
| 494 bind_image_cb_(bind_image_cb), | 494 bind_image_cb_(bind_image_cb), |
| 495 codec_(kUnknownVideoCodec), | 495 codec_(kUnknownVideoCodec), |
| 496 decoder_thread_("DXVAVideoDecoderThread"), | 496 decoder_thread_("DXVAVideoDecoderThread"), |
| 497 pending_flush_(false), | 497 pending_flush_(false), |
| 498 enable_low_latency_(gpu_preferences.enable_low_latency_dxva), | 498 enable_low_latency_(gpu_preferences.enable_low_latency_dxva), |
| 499 share_nv12_textures_(gpu_preferences.enable_zero_copy_dxgi_video && | 499 support_share_nv12_textures_( |
| 500 !workarounds.disable_dxgi_zero_copy_video), | 500 gpu_preferences.enable_zero_copy_dxgi_video && |
| 501 copy_nv12_textures_(gpu_preferences.enable_nv12_dxgi_video && | 501 !workarounds.disable_dxgi_zero_copy_video), |
| 502 !workarounds.disable_nv12_dxgi_video), | 502 support_copy_nv12_textures_(gpu_preferences.enable_nv12_dxgi_video && |
| 503 !workarounds.disable_nv12_dxgi_video), |
| 503 use_dx11_(false), | 504 use_dx11_(false), |
| 504 use_keyed_mutex_(false), | 505 use_keyed_mutex_(false), |
| 505 using_angle_device_(false), | 506 using_angle_device_(false), |
| 506 enable_accelerated_vpx_decode_( | 507 enable_accelerated_vpx_decode_( |
| 507 workarounds.disable_accelerated_vpx_decode | 508 workarounds.disable_accelerated_vpx_decode |
| 508 ? gpu::GpuPreferences::VpxDecodeVendors::VPX_VENDOR_NONE | 509 ? gpu::GpuPreferences::VpxDecodeVendors::VPX_VENDOR_NONE |
| 509 : gpu_preferences.enable_accelerated_vpx_decode), | 510 : gpu_preferences.enable_accelerated_vpx_decode), |
| 510 processing_config_changed_(false), | 511 processing_config_changed_(false), |
| 511 weak_this_factory_(this) { | 512 weak_this_factory_(this) { |
| 512 weak_ptr_ = weak_this_factory_.GetWeakPtr(); | 513 weak_ptr_ = weak_this_factory_.GetWeakPtr(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 536 return false; | 537 return false; |
| 537 } | 538 } |
| 538 | 539 |
| 539 client_ = client; | 540 client_ = client; |
| 540 | 541 |
| 541 main_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 542 main_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 542 | 543 |
| 543 if (!config.supported_output_formats.empty() && | 544 if (!config.supported_output_formats.empty() && |
| 544 !base::ContainsValue(config.supported_output_formats, | 545 !base::ContainsValue(config.supported_output_formats, |
| 545 PIXEL_FORMAT_NV12)) { | 546 PIXEL_FORMAT_NV12)) { |
| 546 share_nv12_textures_ = false; | 547 support_share_nv12_textures_ = false; |
| 547 copy_nv12_textures_ = false; | 548 support_copy_nv12_textures_ = false; |
| 548 } | 549 } |
| 549 | 550 |
| 550 bool profile_supported = false; | 551 bool profile_supported = false; |
| 551 for (const auto& supported_profile : kSupportedProfiles) { | 552 for (const auto& supported_profile : kSupportedProfiles) { |
| 552 if (config.profile == supported_profile) { | 553 if (config.profile == supported_profile) { |
| 553 profile_supported = true; | 554 profile_supported = true; |
| 554 break; | 555 break; |
| 555 } | 556 } |
| 556 } | 557 } |
| 557 if (!profile_supported) { | 558 if (!profile_supported) { |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 799 | 800 |
| 800 bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() { | 801 bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() { |
| 801 // The device may exist if the last state was a config change. | 802 // The device may exist if the last state was a config change. |
| 802 if (D3D11Device()) | 803 if (D3D11Device()) |
| 803 return true; | 804 return true; |
| 804 HRESULT hr = create_dxgi_device_manager_( | 805 HRESULT hr = create_dxgi_device_manager_( |
| 805 &dx11_dev_manager_reset_token_, d3d11_device_manager_.GetAddressOf()); | 806 &dx11_dev_manager_reset_token_, d3d11_device_manager_.GetAddressOf()); |
| 806 RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false); | 807 RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false); |
| 807 | 808 |
| 808 angle_device_ = gl::QueryD3D11DeviceObjectFromANGLE(); | 809 angle_device_ = gl::QueryD3D11DeviceObjectFromANGLE(); |
| 809 if (!angle_device_) | 810 if (!angle_device_) { |
| 810 copy_nv12_textures_ = false; | 811 support_copy_nv12_textures_ = false; |
| 811 if (share_nv12_textures_) { | 812 } |
| 813 if (ShouldUseANGLEDevice()) { |
| 812 RETURN_ON_FAILURE(angle_device_.Get(), "Failed to get d3d11 device", false); | 814 RETURN_ON_FAILURE(angle_device_.Get(), "Failed to get d3d11 device", false); |
| 813 | 815 |
| 814 using_angle_device_ = true; | 816 using_angle_device_ = true; |
| 815 } | 817 DCHECK(!use_fp16_); |
| 818 angle_device_->GetImmediateContext(d3d11_device_context_.GetAddressOf()); |
| 816 | 819 |
| 817 if (use_fp16_ || !share_nv12_textures_) { | 820 hr = angle_device_.CopyTo(video_device_.GetAddressOf()); |
| 821 RETURN_ON_HR_FAILURE(hr, "Failed to get video device", false); |
| 822 } else { |
| 818 // This array defines the set of DirectX hardware feature levels we support. | 823 // This array defines the set of DirectX hardware feature levels we support. |
| 819 // The ordering MUST be preserved. All applications are assumed to support | 824 // The ordering MUST be preserved. All applications are assumed to support |
| 820 // 9.1 unless otherwise stated by the application. | 825 // 9.1 unless otherwise stated by the application. |
| 821 D3D_FEATURE_LEVEL feature_levels[] = { | 826 D3D_FEATURE_LEVEL feature_levels[] = { |
| 822 D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, | 827 D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, |
| 823 D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, | 828 D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, |
| 824 D3D_FEATURE_LEVEL_9_1}; | 829 D3D_FEATURE_LEVEL_9_1}; |
| 825 | 830 |
| 826 UINT flags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; | 831 UINT flags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; |
| 827 | 832 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 846 hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, | 851 hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, |
| 847 feature_levels, arraysize(feature_levels), | 852 feature_levels, arraysize(feature_levels), |
| 848 D3D11_SDK_VERSION, d3d11_device_.GetAddressOf(), | 853 D3D11_SDK_VERSION, d3d11_device_.GetAddressOf(), |
| 849 &feature_level_out, | 854 &feature_level_out, |
| 850 d3d11_device_context_.GetAddressOf()); | 855 d3d11_device_context_.GetAddressOf()); |
| 851 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device", false); | 856 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device", false); |
| 852 } | 857 } |
| 853 | 858 |
| 854 hr = d3d11_device_.CopyTo(video_device_.GetAddressOf()); | 859 hr = d3d11_device_.CopyTo(video_device_.GetAddressOf()); |
| 855 RETURN_ON_HR_FAILURE(hr, "Failed to get video device", false); | 860 RETURN_ON_HR_FAILURE(hr, "Failed to get video device", false); |
| 861 } |
| 856 | 862 |
| 857 hr = d3d11_device_context_.CopyTo(video_context_.GetAddressOf()); | 863 hr = d3d11_device_context_.CopyTo(video_context_.GetAddressOf()); |
| 858 RETURN_ON_HR_FAILURE(hr, "Failed to get video context", false); | 864 RETURN_ON_HR_FAILURE(hr, "Failed to get video context", false); |
| 859 } | |
| 860 | 865 |
| 861 D3D11_FEATURE_DATA_D3D11_OPTIONS options; | 866 D3D11_FEATURE_DATA_D3D11_OPTIONS options; |
| 862 hr = D3D11Device()->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &options, | 867 hr = D3D11Device()->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &options, |
| 863 sizeof(options)); | 868 sizeof(options)); |
| 864 RETURN_ON_HR_FAILURE(hr, "Failed to retrieve D3D11 options", false); | 869 RETURN_ON_HR_FAILURE(hr, "Failed to retrieve D3D11 options", false); |
| 865 | 870 |
| 866 // Need extended resource sharing so we can share the NV12 texture between | 871 // Need extended resource sharing so we can share the NV12 texture between |
| 867 // ANGLE and the decoder context. | 872 // ANGLE and the decoder context. |
| 868 if (!options.ExtendedResourceSharing) | 873 if (!options.ExtendedResourceSharing) |
| 869 copy_nv12_textures_ = false; | 874 support_copy_nv12_textures_ = false; |
| 870 | 875 |
| 871 UINT nv12_format_support = 0; | 876 UINT nv12_format_support = 0; |
| 872 hr = | 877 hr = |
| 873 D3D11Device()->CheckFormatSupport(DXGI_FORMAT_NV12, &nv12_format_support); | 878 D3D11Device()->CheckFormatSupport(DXGI_FORMAT_NV12, &nv12_format_support); |
| 874 RETURN_ON_HR_FAILURE(hr, "Failed to check NV12 format support", false); | 879 RETURN_ON_HR_FAILURE(hr, "Failed to check NV12 format support", false); |
| 875 | 880 |
| 876 if (!(nv12_format_support & D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT)) | 881 if (!(nv12_format_support & D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT)) |
| 877 copy_nv12_textures_ = false; | 882 support_copy_nv12_textures_ = false; |
| 878 | 883 |
| 879 UINT fp16_format_support = 0; | 884 UINT fp16_format_support = 0; |
| 880 hr = D3D11Device()->CheckFormatSupport(DXGI_FORMAT_R16G16B16A16_FLOAT, | 885 hr = D3D11Device()->CheckFormatSupport(DXGI_FORMAT_R16G16B16A16_FLOAT, |
| 881 &fp16_format_support); | 886 &fp16_format_support); |
| 882 if (FAILED(hr) || | 887 if (FAILED(hr) || |
| 883 !(fp16_format_support & D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT)) | 888 !(fp16_format_support & D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT)) |
| 884 use_fp16_ = false; | 889 use_fp16_ = false; |
| 885 | 890 |
| 886 // Enable multithreaded mode on the device. This ensures that accesses to | 891 // Enable multithreaded mode on the device. This ensures that accesses to |
| 887 // context are synchronized across threads. We have multiple threads | 892 // context are synchronized across threads. We have multiple threads |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 DXVAPictureBuffer::Create(*this, buffers[buffer_index], egl_config_); | 977 DXVAPictureBuffer::Create(*this, buffers[buffer_index], egl_config_); |
| 973 RETURN_AND_NOTIFY_ON_FAILURE(picture_buffer.get(), | 978 RETURN_AND_NOTIFY_ON_FAILURE(picture_buffer.get(), |
| 974 "Failed to allocate picture buffer", | 979 "Failed to allocate picture buffer", |
| 975 PLATFORM_FAILURE, ); | 980 PLATFORM_FAILURE, ); |
| 976 if (bind_image_cb_) { | 981 if (bind_image_cb_) { |
| 977 for (uint32_t client_id : buffers[buffer_index].client_texture_ids()) { | 982 for (uint32_t client_id : buffers[buffer_index].client_texture_ids()) { |
| 978 // The picture buffer handles the actual binding of its contents to | 983 // The picture buffer handles the actual binding of its contents to |
| 979 // texture ids. This call just causes the texture manager to hold a | 984 // texture ids. This call just causes the texture manager to hold a |
| 980 // reference to the GLImage as long as either texture exists. | 985 // reference to the GLImage as long as either texture exists. |
| 981 bind_image_cb_.Run(client_id, GetTextureTarget(), | 986 bind_image_cb_.Run(client_id, GetTextureTarget(), |
| 982 picture_buffer->gl_image(), true); | 987 picture_buffer->gl_image(), false); |
| 983 } | 988 } |
| 984 } | 989 } |
| 985 | 990 |
| 986 bool inserted = | 991 bool inserted = |
| 987 output_picture_buffers_ | 992 output_picture_buffers_ |
| 988 .insert(std::make_pair(buffers[buffer_index].id(), picture_buffer)) | 993 .insert(std::make_pair(buffers[buffer_index].id(), picture_buffer)) |
| 989 .second; | 994 .second; |
| 990 DCHECK(inserted); | 995 DCHECK(inserted); |
| 991 } | 996 } |
| 992 | 997 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1033 if (it->second->available() || it->second->waiting_to_reuse()) | 1038 if (it->second->available() || it->second->waiting_to_reuse()) |
| 1034 return; | 1039 return; |
| 1035 | 1040 |
| 1036 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), | 1041 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), |
| 1037 "Failed to make context current", | 1042 "Failed to make context current", |
| 1038 PLATFORM_FAILURE, ); | 1043 PLATFORM_FAILURE, ); |
| 1039 if (use_keyed_mutex_ || using_angle_device_) { | 1044 if (use_keyed_mutex_ || using_angle_device_) { |
| 1040 RETURN_AND_NOTIFY_ON_FAILURE(it->second->ReusePictureBuffer(), | 1045 RETURN_AND_NOTIFY_ON_FAILURE(it->second->ReusePictureBuffer(), |
| 1041 "Failed to reuse picture buffer", | 1046 "Failed to reuse picture buffer", |
| 1042 PLATFORM_FAILURE, ); | 1047 PLATFORM_FAILURE, ); |
| 1048 if (bind_image_cb_ && (GetPictureBufferMechanism() == |
| 1049 PictureBufferMechanism::DELAYED_COPY_TO_NV12)) { |
| 1050 // Unbind the image to ensure it will be copied again the next time it's |
| 1051 // needed. |
| 1052 for (uint32_t client_id : |
| 1053 it->second->picture_buffer().client_texture_ids()) { |
| 1054 bind_image_cb_.Run(client_id, GetTextureTarget(), |
| 1055 it->second->gl_image(), false); |
| 1056 } |
| 1057 } |
| 1043 | 1058 |
| 1044 ProcessPendingSamples(); | 1059 ProcessPendingSamples(); |
| 1045 if (pending_flush_) { | 1060 if (pending_flush_) { |
| 1046 decoder_thread_task_runner_->PostTask( | 1061 decoder_thread_task_runner_->PostTask( |
| 1047 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, | 1062 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, |
| 1048 base::Unretained(this))); | 1063 base::Unretained(this))); |
| 1049 } | 1064 } |
| 1050 } else { | 1065 } else { |
| 1051 it->second->ResetReuseFence(); | 1066 it->second->ResetReuseFence(); |
| 1052 | 1067 |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1583 } | 1598 } |
| 1584 return false; | 1599 return false; |
| 1585 } | 1600 } |
| 1586 } | 1601 } |
| 1587 | 1602 |
| 1588 break; | 1603 break; |
| 1589 } | 1604 } |
| 1590 | 1605 |
| 1591 if (use_fp16_) { | 1606 if (use_fp16_) { |
| 1592 // TODO(hubbe): Share/copy P010/P016 textures. | 1607 // TODO(hubbe): Share/copy P010/P016 textures. |
| 1593 share_nv12_textures_ = false; | 1608 support_share_nv12_textures_ = false; |
| 1594 copy_nv12_textures_ = false; | 1609 support_copy_nv12_textures_ = false; |
| 1595 } | 1610 } |
| 1596 | 1611 |
| 1597 return SetDecoderMediaTypes(); | 1612 return SetDecoderMediaTypes(); |
| 1598 } | 1613 } |
| 1599 | 1614 |
| 1600 bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() { | 1615 bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() { |
| 1601 base::win::ScopedComPtr<IMFAttributes> attributes; | 1616 base::win::ScopedComPtr<IMFAttributes> attributes; |
| 1602 HRESULT hr = decoder_->GetAttributes(attributes.GetAddressOf()); | 1617 HRESULT hr = decoder_->GetAttributes(attributes.GetAddressOf()); |
| 1603 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder attributes", false); | 1618 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder attributes", false); |
| 1604 | 1619 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1636 } | 1651 } |
| 1637 | 1652 |
| 1638 use_keyed_mutex_ = | 1653 use_keyed_mutex_ = |
| 1639 use_dx11_ && gl::GLSurfaceEGL::HasEGLExtension("EGL_ANGLE_keyed_mutex"); | 1654 use_dx11_ && gl::GLSurfaceEGL::HasEGLExtension("EGL_ANGLE_keyed_mutex"); |
| 1640 | 1655 |
| 1641 if (!use_dx11_ || | 1656 if (!use_dx11_ || |
| 1642 !gl::g_driver_egl.ext.b_EGL_ANGLE_stream_producer_d3d_texture_nv12 || | 1657 !gl::g_driver_egl.ext.b_EGL_ANGLE_stream_producer_d3d_texture_nv12 || |
| 1643 !gl::g_driver_egl.ext.b_EGL_KHR_stream || | 1658 !gl::g_driver_egl.ext.b_EGL_KHR_stream || |
| 1644 !gl::g_driver_egl.ext.b_EGL_KHR_stream_consumer_gltexture || | 1659 !gl::g_driver_egl.ext.b_EGL_KHR_stream_consumer_gltexture || |
| 1645 !gl::g_driver_egl.ext.b_EGL_NV_stream_consumer_gltexture_yuv) { | 1660 !gl::g_driver_egl.ext.b_EGL_NV_stream_consumer_gltexture_yuv) { |
| 1646 share_nv12_textures_ = false; | 1661 support_share_nv12_textures_ = false; |
| 1647 copy_nv12_textures_ = false; | 1662 support_copy_nv12_textures_ = false; |
| 1648 } | 1663 } |
| 1649 | 1664 |
| 1650 // The MS VP9 MFT doesn't pass through the bind flags we specify, so | 1665 // The MS VP9 MFT doesn't pass through the bind flags we specify, so |
| 1651 // textures aren't created with D3D11_BIND_SHADER_RESOURCE and can't be used | 1666 // textures aren't created with D3D11_BIND_SHADER_RESOURCE and can't be used |
| 1652 // from ANGLE. | 1667 // from ANGLE. |
| 1653 if (using_ms_vp9_mft_) | 1668 if (using_ms_vp9_mft_) |
| 1654 share_nv12_textures_ = false; | 1669 support_share_nv12_textures_ = false; |
| 1655 | 1670 |
| 1656 return true; | 1671 return true; |
| 1657 } | 1672 } |
| 1658 | 1673 |
| 1659 bool DXVAVideoDecodeAccelerator::SetDecoderMediaTypes() { | 1674 bool DXVAVideoDecodeAccelerator::SetDecoderMediaTypes() { |
| 1660 RETURN_ON_FAILURE(SetDecoderInputMediaType(), | 1675 RETURN_ON_FAILURE(SetDecoderInputMediaType(), |
| 1661 "Failed to set decoder input media type", false); | 1676 "Failed to set decoder input media type", false); |
| 1662 return SetDecoderOutputMediaType(MFVideoFormat_NV12) || | 1677 return SetDecoderOutputMediaType(MFVideoFormat_NV12) || |
| 1663 SetDecoderOutputMediaType(MFVideoFormat_P010) || | 1678 SetDecoderOutputMediaType(MFVideoFormat_P010) || |
| 1664 SetDecoderOutputMediaType(MFVideoFormat_P016); | 1679 SetDecoderOutputMediaType(MFVideoFormat_P016); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1703 | 1718 |
| 1704 hr = decoder_->SetInputType(0, media_type.Get(), 0); // No flags | 1719 hr = decoder_->SetInputType(0, media_type.Get(), 0); // No flags |
| 1705 RETURN_ON_HR_FAILURE(hr, "Failed to set decoder input type", false); | 1720 RETURN_ON_HR_FAILURE(hr, "Failed to set decoder input type", false); |
| 1706 return true; | 1721 return true; |
| 1707 } | 1722 } |
| 1708 | 1723 |
| 1709 bool DXVAVideoDecodeAccelerator::SetDecoderOutputMediaType( | 1724 bool DXVAVideoDecodeAccelerator::SetDecoderOutputMediaType( |
| 1710 const GUID& subtype) { | 1725 const GUID& subtype) { |
| 1711 bool result = SetTransformOutputType(decoder_.Get(), subtype, 0, 0); | 1726 bool result = SetTransformOutputType(decoder_.Get(), subtype, 0, 0); |
| 1712 | 1727 |
| 1713 if (share_nv12_textures_) { | 1728 if (GetPictureBufferMechanism() == PictureBufferMechanism::BIND) { |
| 1714 base::win::ScopedComPtr<IMFAttributes> out_attributes; | 1729 base::win::ScopedComPtr<IMFAttributes> out_attributes; |
| 1715 HRESULT hr = | 1730 HRESULT hr = |
| 1716 decoder_->GetOutputStreamAttributes(0, out_attributes.GetAddressOf()); | 1731 decoder_->GetOutputStreamAttributes(0, out_attributes.GetAddressOf()); |
| 1717 RETURN_ON_HR_FAILURE(hr, "Failed to get stream attributes", false); | 1732 RETURN_ON_HR_FAILURE(hr, "Failed to get stream attributes", false); |
| 1718 out_attributes->SetUINT32(MF_SA_D3D11_BINDFLAGS, | 1733 out_attributes->SetUINT32(MF_SA_D3D11_BINDFLAGS, |
| 1719 D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DECODER); | 1734 D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DECODER); |
| 1720 // For some reason newer Intel drivers need D3D11_BIND_DECODER textures to | 1735 // For some reason newer Intel drivers need D3D11_BIND_DECODER textures to |
| 1721 // be created with a share handle or they'll crash in | 1736 // be created with a share handle or they'll crash in |
| 1722 // CreateShaderResourceView. Technically MF_SA_D3D11_SHARED_WITHOUT_MUTEX | 1737 // CreateShaderResourceView. Technically MF_SA_D3D11_SHARED_WITHOUT_MUTEX |
| 1723 // is only honored by the sample allocator, not by the media foundation | 1738 // is only honored by the sample allocator, not by the media foundation |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1931 if (width != index->second->size().width() || | 1946 if (width != index->second->size().width() || |
| 1932 height != index->second->size().height()) { | 1947 height != index->second->size().height()) { |
| 1933 HandleResolutionChanged(width, height); | 1948 HandleResolutionChanged(width, height); |
| 1934 return; | 1949 return; |
| 1935 } | 1950 } |
| 1936 | 1951 |
| 1937 pending_sample->picture_buffer_id = index->second->id(); | 1952 pending_sample->picture_buffer_id = index->second->id(); |
| 1938 index->second->set_bound(); | 1953 index->second->set_bound(); |
| 1939 index->second->set_color_space(pending_sample->color_space); | 1954 index->second->set_color_space(pending_sample->color_space); |
| 1940 | 1955 |
| 1941 if (share_nv12_textures_) { | 1956 if (index->second->CanBindSamples()) { |
| 1942 main_thread_task_runner_->PostTask( | 1957 main_thread_task_runner_->PostTask( |
| 1943 FROM_HERE, | 1958 FROM_HERE, |
| 1944 base::Bind(&DXVAVideoDecodeAccelerator::BindPictureBufferToSample, | 1959 base::Bind(&DXVAVideoDecodeAccelerator::BindPictureBufferToSample, |
| 1945 weak_ptr_, pending_sample->output_sample, | 1960 weak_ptr_, pending_sample->output_sample, |
| 1946 pending_sample->picture_buffer_id, | 1961 pending_sample->picture_buffer_id, |
| 1947 pending_sample->input_buffer_id)); | 1962 pending_sample->input_buffer_id)); |
| 1948 continue; | 1963 continue; |
| 1949 } | 1964 } |
| 1950 | 1965 |
| 1951 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; | 1966 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2102 } | 2117 } |
| 2103 | 2118 |
| 2104 void DXVAVideoDecodeAccelerator::RequestPictureBuffers(int width, int height) { | 2119 void DXVAVideoDecodeAccelerator::RequestPictureBuffers(int width, int height) { |
| 2105 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); | 2120 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
| 2106 // This task could execute after the decoder has been torn down. | 2121 // This task could execute after the decoder has been torn down. |
| 2107 if (GetState() != kUninitialized && client_) { | 2122 if (GetState() != kUninitialized && client_) { |
| 2108 // When sharing NV12 textures, the client needs to provide 2 texture IDs | 2123 // When sharing NV12 textures, the client needs to provide 2 texture IDs |
| 2109 // per picture buffer, 1 for the Y channel and 1 for the UV channels. | 2124 // per picture buffer, 1 for the Y channel and 1 for the UV channels. |
| 2110 // They're shared to ANGLE using EGL_NV_stream_consumer_gltexture_yuv, so | 2125 // They're shared to ANGLE using EGL_NV_stream_consumer_gltexture_yuv, so |
| 2111 // they need to be GL_TEXTURE_EXTERNAL_OES. | 2126 // they need to be GL_TEXTURE_EXTERNAL_OES. |
| 2112 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; | 2127 bool provide_nv12_textures = |
| 2128 GetPictureBufferMechanism() != PictureBufferMechanism::COPY_TO_RGB; |
| 2113 client_->ProvidePictureBuffers( | 2129 client_->ProvidePictureBuffers( |
| 2114 kNumPictureBuffers, | 2130 kNumPictureBuffers, |
| 2115 provide_nv12_textures ? PIXEL_FORMAT_NV12 : PIXEL_FORMAT_UNKNOWN, | 2131 provide_nv12_textures ? PIXEL_FORMAT_NV12 : PIXEL_FORMAT_UNKNOWN, |
| 2116 provide_nv12_textures ? 2 : 1, gfx::Size(width, height), | 2132 provide_nv12_textures ? 2 : 1, gfx::Size(width, height), |
| 2117 GetTextureTarget()); | 2133 GetTextureTarget()); |
| 2118 } | 2134 } |
| 2119 } | 2135 } |
| 2120 | 2136 |
| 2121 void DXVAVideoDecodeAccelerator::NotifyPictureReady( | 2137 void DXVAVideoDecodeAccelerator::NotifyPictureReady( |
| 2122 int picture_buffer_id, | 2138 int picture_buffer_id, |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2582 DXVAPictureBuffer* picture_buffer = it->second.get(); | 2598 DXVAPictureBuffer* picture_buffer = it->second.get(); |
| 2583 if (picture_buffer->available()) | 2599 if (picture_buffer->available()) |
| 2584 return; | 2600 return; |
| 2585 | 2601 |
| 2586 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), | 2602 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), |
| 2587 "Failed to make context current", | 2603 "Failed to make context current", |
| 2588 PLATFORM_FAILURE, ); | 2604 PLATFORM_FAILURE, ); |
| 2589 | 2605 |
| 2590 DCHECK(!output_picture_buffers_.empty()); | 2606 DCHECK(!output_picture_buffers_.empty()); |
| 2591 | 2607 |
| 2592 bool result = picture_buffer->BindSampleToTexture(sample); | 2608 bool result = picture_buffer->BindSampleToTexture(this, sample); |
| 2593 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface", | 2609 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface", |
| 2594 PLATFORM_FAILURE, ); | 2610 PLATFORM_FAILURE, ); |
| 2595 | 2611 |
| 2596 NotifyPictureReady(picture_buffer->id(), input_buffer_id, | 2612 NotifyPictureReady(picture_buffer->id(), input_buffer_id, |
| 2597 picture_buffer->color_space(), | 2613 picture_buffer->color_space(), |
| 2598 picture_buffer->AllowOverlay()); | 2614 picture_buffer->AllowOverlay()); |
| 2599 | 2615 |
| 2600 { | 2616 { |
| 2601 base::AutoLock lock(decoder_lock_); | 2617 base::AutoLock lock(decoder_lock_); |
| 2602 if (!pending_output_samples_.empty()) | 2618 if (!pending_output_samples_.empty()) |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2840 hr = video_device_->CreateVideoProcessor(enumerator_.Get(), 0, | 2856 hr = video_device_->CreateVideoProcessor(enumerator_.Get(), 0, |
| 2841 d3d11_processor_.GetAddressOf()); | 2857 d3d11_processor_.GetAddressOf()); |
| 2842 RETURN_ON_HR_FAILURE(hr, "Failed to create video processor.", false); | 2858 RETURN_ON_HR_FAILURE(hr, "Failed to create video processor.", false); |
| 2843 processor_width_ = width; | 2859 processor_width_ = width; |
| 2844 processor_height_ = height; | 2860 processor_height_ = height; |
| 2845 | 2861 |
| 2846 video_context_->VideoProcessorSetStreamAutoProcessingMode( | 2862 video_context_->VideoProcessorSetStreamAutoProcessingMode( |
| 2847 d3d11_processor_.Get(), 0, false); | 2863 d3d11_processor_.Get(), 0, false); |
| 2848 } | 2864 } |
| 2849 | 2865 |
| 2850 if (copy_nv12_textures_) { | 2866 if (GetPictureBufferMechanism() == PictureBufferMechanism::COPY_TO_NV12 || |
| 2867 GetPictureBufferMechanism() == |
| 2868 PictureBufferMechanism::DELAYED_COPY_TO_NV12) { |
| 2851 // If we're copying NV12 textures, make sure we set the same | 2869 // If we're copying NV12 textures, make sure we set the same |
| 2852 // color space on input and output. | 2870 // color space on input and output. |
| 2853 D3D11_VIDEO_PROCESSOR_COLOR_SPACE d3d11_color_space = {0}; | 2871 D3D11_VIDEO_PROCESSOR_COLOR_SPACE d3d11_color_space = {0}; |
| 2854 d3d11_color_space.RGB_Range = 1; | 2872 d3d11_color_space.RGB_Range = 1; |
| 2855 d3d11_color_space.Nominal_Range = D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_0_255; | 2873 d3d11_color_space.Nominal_Range = D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_0_255; |
| 2856 | 2874 |
| 2857 video_context_->VideoProcessorSetOutputColorSpace(d3d11_processor_.Get(), | 2875 video_context_->VideoProcessorSetOutputColorSpace(d3d11_processor_.Get(), |
| 2858 &d3d11_color_space); | 2876 &d3d11_color_space); |
| 2859 | 2877 |
| 2860 video_context_->VideoProcessorSetStreamColorSpace(d3d11_processor_.Get(), 0, | 2878 video_context_->VideoProcessorSetStreamColorSpace(d3d11_processor_.Get(), 0, |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3015 SetState(kConfigChange); | 3033 SetState(kConfigChange); |
| 3016 Invalidate(); | 3034 Invalidate(); |
| 3017 Initialize(config_, client_); | 3035 Initialize(config_, client_); |
| 3018 decoder_thread_task_runner_->PostTask( | 3036 decoder_thread_task_runner_->PostTask( |
| 3019 FROM_HERE, | 3037 FROM_HERE, |
| 3020 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, | 3038 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, |
| 3021 base::Unretained(this))); | 3039 base::Unretained(this))); |
| 3022 } | 3040 } |
| 3023 | 3041 |
| 3024 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const { | 3042 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const { |
| 3025 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; | 3043 switch (GetPictureBufferMechanism()) { |
| 3026 return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; | 3044 case PictureBufferMechanism::BIND: |
| 3045 case PictureBufferMechanism::DELAYED_COPY_TO_NV12: |
| 3046 case PictureBufferMechanism::COPY_TO_NV12: |
| 3047 return GL_TEXTURE_EXTERNAL_OES; |
| 3048 case PictureBufferMechanism::COPY_TO_RGB: |
| 3049 return GL_TEXTURE_2D; |
| 3050 } |
| 3051 NOTREACHED(); |
| 3052 return 0; |
| 3027 } | 3053 } |
| 3028 | 3054 |
| 3055 DXVAVideoDecodeAccelerator::PictureBufferMechanism |
| 3056 DXVAVideoDecodeAccelerator::GetPictureBufferMechanism() const { |
| 3057 if (use_fp16_) |
| 3058 return PictureBufferMechanism::COPY_TO_RGB; |
| 3059 if (support_share_nv12_textures_) |
| 3060 return PictureBufferMechanism::BIND; |
| 3061 if (base::FeatureList::IsEnabled(kDelayCopyNV12Textures) && |
| 3062 support_copy_nv12_textures_) |
| 3063 return PictureBufferMechanism::DELAYED_COPY_TO_NV12; |
| 3064 if (support_copy_nv12_textures_) |
| 3065 return PictureBufferMechanism::COPY_TO_NV12; |
| 3066 return PictureBufferMechanism::COPY_TO_RGB; |
| 3067 } |
| 3068 |
| 3069 bool DXVAVideoDecodeAccelerator::ShouldUseANGLEDevice() const { |
| 3070 switch (GetPictureBufferMechanism()) { |
| 3071 case PictureBufferMechanism::BIND: |
| 3072 case PictureBufferMechanism::DELAYED_COPY_TO_NV12: |
| 3073 return true; |
| 3074 case PictureBufferMechanism::COPY_TO_NV12: |
| 3075 case PictureBufferMechanism::COPY_TO_RGB: |
| 3076 return false; |
| 3077 } |
| 3078 NOTREACHED(); |
| 3079 return false; |
| 3080 } |
| 3029 ID3D11Device* DXVAVideoDecodeAccelerator::D3D11Device() const { | 3081 ID3D11Device* DXVAVideoDecodeAccelerator::D3D11Device() const { |
| 3030 return share_nv12_textures_ ? angle_device_.Get() : d3d11_device_.Get(); | 3082 return ShouldUseANGLEDevice() ? angle_device_.Get() : d3d11_device_.Get(); |
| 3031 } | 3083 } |
| 3032 | 3084 |
| 3033 } // namespace media | 3085 } // namespace media |
| OLD | NEW |