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 |