| 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 "content/common/gpu/media/dxva_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/dxva_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #if !defined(OS_WIN) | 7 #if !defined(OS_WIN) |
| 8 #error This file should only be built on Windows. | 8 #error This file should only be built on Windows. |
| 9 #endif // !defined(OS_WIN) | 9 #endif // !defined(OS_WIN) |
| 10 | 10 |
| (...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 } | 647 } |
| 648 if (!profile_supported) { | 648 if (!profile_supported) { |
| 649 RETURN_AND_NOTIFY_ON_FAILURE(false, | 649 RETURN_AND_NOTIFY_ON_FAILURE(false, |
| 650 "Unsupported h.264, vp8, or vp9 profile", PLATFORM_FAILURE, false); | 650 "Unsupported h.264, vp8, or vp9 profile", PLATFORM_FAILURE, false); |
| 651 } | 651 } |
| 652 | 652 |
| 653 // Not all versions of Windows 7 and later include Media Foundation DLLs. | 653 // Not all versions of Windows 7 and later include Media Foundation DLLs. |
| 654 // Instead of crashing while delay loading the DLL when calling MFStartup() | 654 // Instead of crashing while delay loading the DLL when calling MFStartup() |
| 655 // below, probe whether we can successfully load the DLL now. | 655 // below, probe whether we can successfully load the DLL now. |
| 656 // See http://crbug.com/339678 for details. | 656 // See http://crbug.com/339678 for details. |
| 657 HMODULE dxgi_manager_dll = NULL; | 657 HMODULE dxgi_manager_dll = ::GetModuleHandle(L"MFPlat.dll"); |
| 658 if ((dxgi_manager_dll = ::GetModuleHandle(L"MFPlat.dll")) == NULL) { | 658 RETURN_ON_FAILURE(dxgi_manager_dll, "MFPlat.dll is required for decoding", |
| 659 HMODULE mfplat_dll = ::LoadLibrary(L"MFPlat.dll"); | 659 false); |
| 660 RETURN_ON_FAILURE(mfplat_dll, "MFPlat.dll is required for decoding", | 660 |
| 661 false); | 661 // On Windows 8+ mfplat.dll provides the MFCreateDXGIDeviceManager API. |
| 662 // On Windows 8+ mfplat.dll provides the MFCreateDXGIDeviceManager API. | 662 // On Windows 7 mshtmlmedia.dll provides it. |
| 663 // On Windows 7 mshtmlmedia.dll provides it. | |
| 664 dxgi_manager_dll = mfplat_dll; | |
| 665 } | |
| 666 | 663 |
| 667 // TODO(ananta) | 664 // TODO(ananta) |
| 668 // The code below works, as in we can create the DX11 device manager for | 665 // The code below works, as in we can create the DX11 device manager for |
| 669 // Windows 7. However the IMFTransform we use for texture conversion and | 666 // Windows 7. However the IMFTransform we use for texture conversion and |
| 670 // copy does not exist on Windows 7. Look into an alternate approach | 667 // copy does not exist on Windows 7. Look into an alternate approach |
| 671 // and enable the code below. | 668 // and enable the code below. |
| 672 #if defined ENABLE_DX11_FOR_WIN7 | 669 #if defined(ENABLE_DX11_FOR_WIN7) |
| 673 if ((base::win::GetVersion() == base::win::VERSION_WIN7) && | 670 if (base::win::GetVersion() == base::win::VERSION_WIN7) { |
| 674 ((dxgi_manager_dll = ::GetModuleHandle(L"mshtmlmedia.dll")) == NULL)) { | 671 dxgi_manager_dll = ::GetModuleHandle(L"mshtmlmedia.dll"); |
| 675 HMODULE mshtml_media_dll = ::LoadLibrary(L"mshtmlmedia.dll"); | 672 RETURN_ON_FAILURE(dxgi_manager_dll, |
| 676 if (mshtml_media_dll) | 673 "mshtmlmedia.dll is required for decoding", false); |
| 677 dxgi_manager_dll = mshtml_media_dll; | |
| 678 } | 674 } |
| 679 #endif | 675 #endif |
| 680 // If we don't find the MFCreateDXGIDeviceManager API we fallback to D3D9 | 676 // If we don't find the MFCreateDXGIDeviceManager API we fallback to D3D9 |
| 681 // decoding. | 677 // decoding. |
| 682 if (dxgi_manager_dll && !create_dxgi_device_manager_) { | 678 if (dxgi_manager_dll && !create_dxgi_device_manager_) { |
| 683 create_dxgi_device_manager_ = reinterpret_cast<CreateDXGIDeviceManager>( | 679 create_dxgi_device_manager_ = reinterpret_cast<CreateDXGIDeviceManager>( |
| 684 ::GetProcAddress(dxgi_manager_dll, "MFCreateDXGIDeviceManager")); | 680 ::GetProcAddress(dxgi_manager_dll, "MFCreateDXGIDeviceManager")); |
| 685 } | 681 } |
| 686 | 682 |
| 687 RETURN_AND_NOTIFY_ON_FAILURE( | 683 RETURN_AND_NOTIFY_ON_FAILURE( |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); | 808 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); |
| 813 | 809 |
| 814 D3D11_QUERY_DESC query_desc; | 810 D3D11_QUERY_DESC query_desc; |
| 815 query_desc.Query = D3D11_QUERY_EVENT; | 811 query_desc.Query = D3D11_QUERY_EVENT; |
| 816 query_desc.MiscFlags = 0; | 812 query_desc.MiscFlags = 0; |
| 817 hr = d3d11_device_->CreateQuery( | 813 hr = d3d11_device_->CreateQuery( |
| 818 &query_desc, | 814 &query_desc, |
| 819 d3d11_query_.Receive()); | 815 d3d11_query_.Receive()); |
| 820 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false); | 816 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false); |
| 821 | 817 |
| 822 HMODULE video_processor_dll = ::LoadLibrary(L"msvproc.dll"); | 818 HMODULE video_processor_dll = ::GetModuleHandle(L"msvproc.dll"); |
| 823 RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor", | 819 RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor", |
| 824 false); | 820 false); |
| 825 | 821 |
| 826 hr = CreateCOMObjectFromDll( | 822 hr = CreateCOMObjectFromDll( |
| 827 video_processor_dll, | 823 video_processor_dll, |
| 828 CLSID_VideoProcessorMFT, | 824 CLSID_VideoProcessorMFT, |
| 829 __uuidof(IMFTransform), | 825 __uuidof(IMFTransform), |
| 830 video_format_converter_mft_.ReceiveVoid()); | 826 video_format_converter_mft_.ReceiveVoid()); |
| 831 if (FAILED(hr)) { | 827 if (FAILED(hr)) { |
| 832 base::debug::Alias(&hr); | 828 base::debug::Alias(&hr); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1028 // with any dimension smaller than 48 pixels: | 1024 // with any dimension smaller than 48 pixels: |
| 1029 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815 | 1025 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815 |
| 1030 profile.min_resolution.SetSize(48, 48); | 1026 profile.min_resolution.SetSize(48, 48); |
| 1031 // Use 1088 to account for 16x16 macroblocks. | 1027 // Use 1088 to account for 16x16 macroblocks. |
| 1032 profile.max_resolution.SetSize(1920, 1088); | 1028 profile.max_resolution.SetSize(1920, 1088); |
| 1033 profiles.push_back(profile); | 1029 profiles.push_back(profile); |
| 1034 } | 1030 } |
| 1035 return profiles; | 1031 return profiles; |
| 1036 } | 1032 } |
| 1037 | 1033 |
| 1034 // static |
| 1035 void DXVAVideoDecodeAccelerator::PreSandboxInitialization() { |
| 1036 ::LoadLibrary(L"MFPlat.dll"); |
| 1037 ::LoadLibrary(L"msmpeg2vdec.dll"); |
| 1038 |
| 1039 if (base::win::GetVersion() > base::win::VERSION_WIN7) { |
| 1040 LoadLibrary(L"msvproc.dll"); |
| 1041 } else { |
| 1042 LoadLibrary(L"dxva2.dll"); |
| 1043 #if defined(ENABLE_DX11_FOR_WIN7) |
| 1044 LoadLibrary(L"mshtmlmedia.dll"); |
| 1045 #endif |
| 1046 } |
| 1047 } |
| 1048 |
| 1038 bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) { | 1049 bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) { |
| 1039 HMODULE decoder_dll = NULL; | 1050 HMODULE decoder_dll = NULL; |
| 1040 | 1051 |
| 1041 CLSID clsid = {}; | 1052 CLSID clsid = {}; |
| 1042 | 1053 |
| 1043 // Profile must fall within the valid range for one of the supported codecs. | 1054 // Profile must fall within the valid range for one of the supported codecs. |
| 1044 if (profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX) { | 1055 if (profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX) { |
| 1045 // We mimic the steps CoCreateInstance uses to instantiate the object. This | 1056 // We mimic the steps CoCreateInstance uses to instantiate the object. This |
| 1046 // was previously done because it failed inside the sandbox, and now is done | 1057 // was previously done because it failed inside the sandbox, and now is done |
| 1047 // as a more minimal approach to avoid other side-effects CCI might have (as | 1058 // as a more minimal approach to avoid other side-effects CCI might have (as |
| 1048 // we are still in a reduced sandbox). | 1059 // we are still in a reduced sandbox). |
| 1049 decoder_dll = ::LoadLibrary(L"msmpeg2vdec.dll"); | 1060 decoder_dll = ::GetModuleHandle(L"msmpeg2vdec.dll"); |
| 1050 RETURN_ON_FAILURE(decoder_dll, | 1061 RETURN_ON_FAILURE(decoder_dll, |
| 1051 "msmpeg2vdec.dll required for decoding is not loaded", | 1062 "msmpeg2vdec.dll required for decoding is not loaded", |
| 1052 false); | 1063 false); |
| 1053 | 1064 |
| 1054 // Check version of DLL, version 6.7.7140 is blacklisted due to high crash | 1065 // Check version of DLL, version 6.7.7140 is blacklisted due to high crash |
| 1055 // rates in browsers loading that DLL. If that is the version installed we | 1066 // rates in browsers loading that DLL. If that is the version installed we |
| 1056 // fall back to software decoding. See crbug/403440. | 1067 // fall back to software decoding. See crbug/403440. |
| 1057 FileVersionInfo* version_info = | 1068 FileVersionInfo* version_info = |
| 1058 FileVersionInfo::CreateFileVersionInfoForModule(decoder_dll); | 1069 FileVersionInfo::CreateFileVersionInfoForModule(decoder_dll); |
| 1059 RETURN_ON_FAILURE(version_info, | 1070 RETURN_ON_FAILURE(version_info, |
| (...skipping 1213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2273 D3DSURFACE_DESC surface_desc; | 2284 D3DSURFACE_DESC surface_desc; |
| 2274 hr = surface->GetDesc(&surface_desc); | 2285 hr = surface->GetDesc(&surface_desc); |
| 2275 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false); | 2286 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false); |
| 2276 *width = surface_desc.Width; | 2287 *width = surface_desc.Width; |
| 2277 *height = surface_desc.Height; | 2288 *height = surface_desc.Height; |
| 2278 } | 2289 } |
| 2279 return true; | 2290 return true; |
| 2280 } | 2291 } |
| 2281 | 2292 |
| 2282 } // namespace content | 2293 } // namespace content |
| OLD | NEW |