Chromium Code Reviews| 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 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 549 profile_supported = true; | 549 profile_supported = true; |
| 550 break; | 550 break; |
| 551 } | 551 } |
| 552 } | 552 } |
| 553 if (!profile_supported) { | 553 if (!profile_supported) { |
| 554 RETURN_AND_NOTIFY_ON_FAILURE(false, | 554 RETURN_AND_NOTIFY_ON_FAILURE(false, |
| 555 "Unsupported h.264, vp8, or vp9 profile", | 555 "Unsupported h.264, vp8, or vp9 profile", |
| 556 PLATFORM_FAILURE, false); | 556 PLATFORM_FAILURE, false); |
| 557 } | 557 } |
| 558 | 558 |
| 559 if (config.profile == VP9PROFILE_PROFILE2 || | |
| 560 config.profile == VP9PROFILE_PROFILE3 || | |
| 561 config.profile == H264PROFILE_HIGH10PROFILE) { | |
| 562 // Input file has more than 8 bits per channel. | |
| 563 use_fp16_ = true; | |
| 564 } | |
| 565 | |
| 559 // Not all versions of Windows 7 and later include Media Foundation DLLs. | 566 // Not all versions of Windows 7 and later include Media Foundation DLLs. |
| 560 // Instead of crashing while delay loading the DLL when calling MFStartup() | 567 // Instead of crashing while delay loading the DLL when calling MFStartup() |
| 561 // below, probe whether we can successfully load the DLL now. | 568 // below, probe whether we can successfully load the DLL now. |
| 562 // See http://crbug.com/339678 for details. | 569 // See http://crbug.com/339678 for details. |
| 563 HMODULE dxgi_manager_dll = ::GetModuleHandle(L"MFPlat.dll"); | 570 HMODULE dxgi_manager_dll = ::GetModuleHandle(L"MFPlat.dll"); |
| 564 RETURN_ON_FAILURE(dxgi_manager_dll, "MFPlat.dll is required for decoding", | 571 RETURN_ON_FAILURE(dxgi_manager_dll, "MFPlat.dll is required for decoding", |
| 565 false); | 572 false); |
| 566 | 573 |
| 567 // On Windows 8+ mfplat.dll provides the MFCreateDXGIDeviceManager API. | 574 // On Windows 8+ mfplat.dll provides the MFCreateDXGIDeviceManager API. |
| 568 // On Windows 7 mshtmlmedia.dll provides it. | 575 // On Windows 7 mshtmlmedia.dll provides it. |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 848 copy_nv12_textures_ = false; | 855 copy_nv12_textures_ = false; |
| 849 | 856 |
| 850 UINT nv12_format_support = 0; | 857 UINT nv12_format_support = 0; |
| 851 hr = | 858 hr = |
| 852 d3d11_device_->CheckFormatSupport(DXGI_FORMAT_NV12, &nv12_format_support); | 859 d3d11_device_->CheckFormatSupport(DXGI_FORMAT_NV12, &nv12_format_support); |
| 853 RETURN_ON_HR_FAILURE(hr, "Failed to check NV12 format support", false); | 860 RETURN_ON_HR_FAILURE(hr, "Failed to check NV12 format support", false); |
| 854 | 861 |
| 855 if (!(nv12_format_support & D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT)) | 862 if (!(nv12_format_support & D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT)) |
| 856 copy_nv12_textures_ = false; | 863 copy_nv12_textures_ = false; |
| 857 | 864 |
| 865 UINT fp16_format_support = 0; | |
| 866 hr = d3d11_device_->CheckFormatSupport(DXGI_FORMAT_R16G16B16A16_FLOAT, | |
| 867 &fp16_format_support); | |
| 868 if (FAILED(hr) || | |
| 869 !(fp16_format_support & D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT)) | |
| 870 use_fp16_ = false; | |
| 871 | |
| 858 // Enable multithreaded mode on the device. This ensures that accesses to | 872 // Enable multithreaded mode on the device. This ensures that accesses to |
| 859 // context are synchronized across threads. We have multiple threads | 873 // context are synchronized across threads. We have multiple threads |
| 860 // accessing the context, the media foundation decoder threads and the | 874 // accessing the context, the media foundation decoder threads and the |
| 861 // decoder thread via the video format conversion transform. | 875 // decoder thread via the video format conversion transform. |
| 862 hr = multi_threaded_.QueryFrom(d3d11_device_.get()); | 876 hr = multi_threaded_.QueryFrom(d3d11_device_.get()); |
| 863 RETURN_ON_HR_FAILURE(hr, "Failed to query ID3D10Multithread", false); | 877 RETURN_ON_HR_FAILURE(hr, "Failed to query ID3D10Multithread", false); |
| 864 multi_threaded_->SetMultithreadProtected(TRUE); | 878 multi_threaded_->SetMultithreadProtected(TRUE); |
| 865 | 879 |
| 866 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(), | 880 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(), |
| 867 dx11_dev_manager_reset_token_); | 881 dx11_dev_manager_reset_token_); |
| (...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1510 hr = decoder_->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, | 1524 hr = decoder_->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, |
| 1511 device_manager_to_use); | 1525 device_manager_to_use); |
| 1512 if (use_dx11_) { | 1526 if (use_dx11_) { |
| 1513 RETURN_ON_HR_FAILURE(hr, "Failed to pass DX11 manager to decoder", false); | 1527 RETURN_ON_HR_FAILURE(hr, "Failed to pass DX11 manager to decoder", false); |
| 1514 } else { | 1528 } else { |
| 1515 RETURN_ON_HR_FAILURE(hr, "Failed to pass D3D manager to decoder", false); | 1529 RETURN_ON_HR_FAILURE(hr, "Failed to pass D3D manager to decoder", false); |
| 1516 } | 1530 } |
| 1517 | 1531 |
| 1518 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); | 1532 EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); |
| 1519 | 1533 |
| 1520 EGLint config_attribs[] = {EGL_BUFFER_SIZE, 32, | 1534 LOG(ERROR) << "EGL..."; |
|
jbauman
2017/02/23 02:01:46
Remove.
hubbe
2017/02/23 19:26:09
Done.
| |
| 1521 EGL_RED_SIZE, 8, | 1535 while (true) { |
| 1522 EGL_GREEN_SIZE, 8, | 1536 EGLint config_attribs[] = {EGL_BUFFER_SIZE, 32, |
| 1523 EGL_BLUE_SIZE, 8, | 1537 EGL_RED_SIZE, use_fp16_ ? 16 : 8, |
| 1524 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, | 1538 EGL_GREEN_SIZE, use_fp16_ ? 16 : 8, |
| 1525 EGL_ALPHA_SIZE, 0, | 1539 EGL_BLUE_SIZE, use_fp16_ ? 16 : 8, |
| 1526 EGL_NONE}; | 1540 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, |
| 1541 EGL_ALPHA_SIZE, 0, | |
| 1542 EGL_NONE}; | |
| 1527 | 1543 |
| 1528 EGLint num_configs; | 1544 EGLint num_configs; |
| 1529 | 1545 |
| 1530 if (!eglChooseConfig(egl_display, config_attribs, &egl_config_, 1, | 1546 if (!eglChooseConfig(egl_display, config_attribs, &egl_config_, 1, |
|
jbauman
2017/02/23 02:01:46
I think this should check if num_configs == 0 as w
hubbe
2017/02/23 19:26:09
Done.
| |
| 1531 &num_configs)) | 1547 &num_configs)) { |
| 1532 return false; | 1548 if (use_fp16_) { |
| 1549 // Try again, but without use_fp16_ | |
| 1550 use_fp16_ = false; | |
| 1551 continue; | |
| 1552 } | |
| 1553 return false; | |
| 1554 } | |
| 1555 | |
| 1556 break; | |
| 1557 } | |
| 1558 | |
| 1559 if (use_fp16_) { | |
| 1560 // TODO(hubbe): Share/copy P010/P016 textures. | |
| 1561 share_nv12_textures_ = false; | |
| 1562 copy_nv12_textures_ = false; | |
| 1563 } | |
| 1533 | 1564 |
| 1534 return SetDecoderMediaTypes(); | 1565 return SetDecoderMediaTypes(); |
| 1535 } | 1566 } |
| 1536 | 1567 |
| 1537 bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() { | 1568 bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() { |
| 1538 base::win::ScopedComPtr<IMFAttributes> attributes; | 1569 base::win::ScopedComPtr<IMFAttributes> attributes; |
| 1539 HRESULT hr = decoder_->GetAttributes(attributes.Receive()); | 1570 HRESULT hr = decoder_->GetAttributes(attributes.Receive()); |
| 1540 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder attributes", false); | 1571 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder attributes", false); |
| 1541 | 1572 |
| 1542 UINT32 dxva = 0; | 1573 UINT32 dxva = 0; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1590 if (using_ms_vp9_mft_) | 1621 if (using_ms_vp9_mft_) |
| 1591 share_nv12_textures_ = false; | 1622 share_nv12_textures_ = false; |
| 1592 | 1623 |
| 1593 return true; | 1624 return true; |
| 1594 } | 1625 } |
| 1595 | 1626 |
| 1596 bool DXVAVideoDecodeAccelerator::SetDecoderMediaTypes() { | 1627 bool DXVAVideoDecodeAccelerator::SetDecoderMediaTypes() { |
| 1597 RETURN_ON_FAILURE(SetDecoderInputMediaType(), | 1628 RETURN_ON_FAILURE(SetDecoderInputMediaType(), |
| 1598 "Failed to set decoder input media type", false); | 1629 "Failed to set decoder input media type", false); |
| 1599 return SetDecoderOutputMediaType(MFVideoFormat_NV12) || | 1630 return SetDecoderOutputMediaType(MFVideoFormat_NV12) || |
| 1600 SetDecoderOutputMediaType(MFVideoFormat_P010); | 1631 SetDecoderOutputMediaType(MFVideoFormat_P010) || |
| 1632 SetDecoderOutputMediaType(MFVideoFormat_P016); | |
| 1601 } | 1633 } |
| 1602 | 1634 |
| 1603 bool DXVAVideoDecodeAccelerator::SetDecoderInputMediaType() { | 1635 bool DXVAVideoDecodeAccelerator::SetDecoderInputMediaType() { |
| 1604 base::win::ScopedComPtr<IMFMediaType> media_type; | 1636 base::win::ScopedComPtr<IMFMediaType> media_type; |
| 1605 HRESULT hr = MFCreateMediaType(media_type.Receive()); | 1637 HRESULT hr = MFCreateMediaType(media_type.Receive()); |
| 1606 RETURN_ON_HR_FAILURE(hr, "MFCreateMediaType failed", false); | 1638 RETURN_ON_HR_FAILURE(hr, "MFCreateMediaType failed", false); |
| 1607 | 1639 |
| 1608 hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); | 1640 hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); |
| 1609 RETURN_ON_HR_FAILURE(hr, "Failed to set major input type", false); | 1641 RETURN_ON_HR_FAILURE(hr, "Failed to set major input type", false); |
| 1610 | 1642 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1735 DVLOG(1) << "Got events from ProcessOuput, but discarding"; | 1767 DVLOG(1) << "Got events from ProcessOuput, but discarding"; |
| 1736 events->Release(); | 1768 events->Release(); |
| 1737 } | 1769 } |
| 1738 base::win::ScopedComPtr<IMFSample> output_sample; | 1770 base::win::ScopedComPtr<IMFSample> output_sample; |
| 1739 output_sample.Attach(output_data_buffer.pSample); | 1771 output_sample.Attach(output_data_buffer.pSample); |
| 1740 if (FAILED(hr)) { | 1772 if (FAILED(hr)) { |
| 1741 // A stream change needs further ProcessInput calls to get back decoder | 1773 // A stream change needs further ProcessInput calls to get back decoder |
| 1742 // output which is why we need to set the state to stopped. | 1774 // output which is why we need to set the state to stopped. |
| 1743 if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { | 1775 if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { |
| 1744 if (!SetDecoderOutputMediaType(MFVideoFormat_NV12) && | 1776 if (!SetDecoderOutputMediaType(MFVideoFormat_NV12) && |
| 1745 !SetDecoderOutputMediaType(MFVideoFormat_P010)) { | 1777 !SetDecoderOutputMediaType(MFVideoFormat_P010) && |
| 1778 !SetDecoderOutputMediaType(MFVideoFormat_P016)) { | |
| 1746 // Decoder didn't let us set NV12 output format. Not sure as to why | 1779 // Decoder didn't let us set NV12 output format. Not sure as to why |
| 1747 // this can happen. Give up in disgust. | 1780 // this can happen. Give up in disgust. |
| 1748 NOTREACHED() << "Failed to set decoder output media type to NV12"; | 1781 NOTREACHED() << "Failed to set decoder output media type to NV12"; |
| 1749 SetState(kStopped); | 1782 SetState(kStopped); |
| 1750 } else { | 1783 } else { |
| 1751 DVLOG(1) << "Received output format change from the decoder." | 1784 DVLOG(1) << "Received output format change from the decoder." |
| 1752 " Recursively invoking DoDecode"; | 1785 " Recursively invoking DoDecode"; |
| 1753 DoDecode(color_space); | 1786 DoDecode(color_space); |
| 1754 } | 1787 } |
| 1755 return; | 1788 return; |
| (...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2903 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, | 2936 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, |
| 2904 base::Unretained(this))); | 2937 base::Unretained(this))); |
| 2905 } | 2938 } |
| 2906 | 2939 |
| 2907 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const { | 2940 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const { |
| 2908 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; | 2941 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; |
| 2909 return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; | 2942 return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; |
| 2910 } | 2943 } |
| 2911 | 2944 |
| 2912 } // namespace media | 2945 } // namespace media |
| OLD | NEW |