| 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 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 config_change_detector_.reset(new H264ConfigChangeDetector); | 704 config_change_detector_.reset(new H264ConfigChangeDetector); |
| 705 | 705 |
| 706 SetState(kNormal); | 706 SetState(kNormal); |
| 707 | 707 |
| 708 StartDecoderThread(); | 708 StartDecoderThread(); |
| 709 return true; | 709 return true; |
| 710 } | 710 } |
| 711 | 711 |
| 712 bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() { | 712 bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() { |
| 713 TRACE_EVENT0("gpu", "DXVAVideoDecodeAccelerator_CreateD3DDevManager"); | 713 TRACE_EVENT0("gpu", "DXVAVideoDecodeAccelerator_CreateD3DDevManager"); |
| 714 // The device may exist if the last state was a config change. |
| 715 if (d3d9_.get()) |
| 716 return true; |
| 714 | 717 |
| 715 HRESULT hr = E_FAIL; | 718 HRESULT hr = E_FAIL; |
| 716 | 719 |
| 717 hr = Direct3DCreate9Ex(D3D_SDK_VERSION, d3d9_.Receive()); | 720 hr = Direct3DCreate9Ex(D3D_SDK_VERSION, d3d9_.Receive()); |
| 718 RETURN_ON_HR_FAILURE(hr, "Direct3DCreate9Ex failed", false); | 721 RETURN_ON_HR_FAILURE(hr, "Direct3DCreate9Ex failed", false); |
| 719 | 722 |
| 720 hr = d3d9_->CheckDeviceFormatConversion( | 723 hr = d3d9_->CheckDeviceFormatConversion( |
| 721 D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, | 724 D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, |
| 722 static_cast<D3DFORMAT>(MAKEFOURCC('N', 'V', '1', '2')), D3DFMT_X8R8G8B8); | 725 static_cast<D3DFORMAT>(MAKEFOURCC('N', 'V', '1', '2')), D3DFMT_X8R8G8B8); |
| 723 RETURN_ON_HR_FAILURE(hr, "D3D9 driver does not support H/W format conversion", | 726 RETURN_ON_HR_FAILURE(hr, "D3D9 driver does not support H/W format conversion", |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 hr = d3d9_device_ex_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive()); | 768 hr = d3d9_device_ex_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive()); |
| 766 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device query", false); | 769 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device query", false); |
| 767 // Ensure query_ API works (to avoid an infinite loop later in | 770 // Ensure query_ API works (to avoid an infinite loop later in |
| 768 // CopyOutputSampleDataToPictureBuffer). | 771 // CopyOutputSampleDataToPictureBuffer). |
| 769 hr = query_->Issue(D3DISSUE_END); | 772 hr = query_->Issue(D3DISSUE_END); |
| 770 RETURN_ON_HR_FAILURE(hr, "Failed to issue END test query", false); | 773 RETURN_ON_HR_FAILURE(hr, "Failed to issue END test query", false); |
| 771 return true; | 774 return true; |
| 772 } | 775 } |
| 773 | 776 |
| 774 bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() { | 777 bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() { |
| 778 // The device may exist if the last state was a config change. |
| 779 if (d3d11_device_.get()) |
| 780 return true; |
| 775 HRESULT hr = create_dxgi_device_manager_(&dx11_dev_manager_reset_token_, | 781 HRESULT hr = create_dxgi_device_manager_(&dx11_dev_manager_reset_token_, |
| 776 d3d11_device_manager_.Receive()); | 782 d3d11_device_manager_.Receive()); |
| 777 RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false); | 783 RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false); |
| 778 if (share_nv12_textures_) { | 784 if (share_nv12_textures_) { |
| 779 base::win::ScopedComPtr<ID3D11Device> angle_device = | 785 base::win::ScopedComPtr<ID3D11Device> angle_device = |
| 780 QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE); | 786 QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE); |
| 781 RETURN_ON_FAILURE(angle_device.get(), "Failed to get d3d11 device", false); | 787 RETURN_ON_FAILURE(angle_device.get(), "Failed to get d3d11 device", false); |
| 782 | 788 |
| 783 using_angle_device_ = true; | 789 using_angle_device_ = true; |
| 784 d3d11_device_ = angle_device; | 790 d3d11_device_ = angle_device; |
| (...skipping 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1820 | 1826 |
| 1821 void DXVAVideoDecodeAccelerator::Invalidate() { | 1827 void DXVAVideoDecodeAccelerator::Invalidate() { |
| 1822 if (GetState() == kUninitialized) | 1828 if (GetState() == kUninitialized) |
| 1823 return; | 1829 return; |
| 1824 | 1830 |
| 1825 // Best effort to make the GL context current. | 1831 // Best effort to make the GL context current. |
| 1826 make_context_current_cb_.Run(); | 1832 make_context_current_cb_.Run(); |
| 1827 | 1833 |
| 1828 decoder_thread_.Stop(); | 1834 decoder_thread_.Stop(); |
| 1829 weak_this_factory_.InvalidateWeakPtrs(); | 1835 weak_this_factory_.InvalidateWeakPtrs(); |
| 1830 output_picture_buffers_.clear(); | |
| 1831 stale_output_picture_buffers_.clear(); | |
| 1832 pending_output_samples_.clear(); | 1836 pending_output_samples_.clear(); |
| 1833 // We want to continue processing pending input after detecting a config | |
| 1834 // change. | |
| 1835 if (GetState() != kConfigChange) | |
| 1836 pending_input_buffers_.clear(); | |
| 1837 decoder_.Release(); | 1837 decoder_.Release(); |
| 1838 pictures_requested_ = false; | |
| 1839 | |
| 1840 config_change_detector_.reset(); | 1838 config_change_detector_.reset(); |
| 1841 | 1839 |
| 1842 if (use_dx11_) { | 1840 // If we are processing a config change, then leave the d3d9/d3d11 objects |
| 1843 if (video_format_converter_mft_.get()) { | 1841 // along with the output picture buffers intact as they can be reused. The |
| 1844 video_format_converter_mft_->ProcessMessage( | 1842 // output picture buffers may need to be recreated in case the video |
| 1845 MFT_MESSAGE_NOTIFY_END_STREAMING, 0); | 1843 // resolution changes. We already handle that in the |
| 1846 video_format_converter_mft_.Release(); | 1844 // HandleResolutionChanged() function. |
| 1845 if (GetState() != kConfigChange) { |
| 1846 output_picture_buffers_.clear(); |
| 1847 stale_output_picture_buffers_.clear(); |
| 1848 // We want to continue processing pending input after detecting a config |
| 1849 // change. |
| 1850 pending_input_buffers_.clear(); |
| 1851 pictures_requested_ = false; |
| 1852 if (use_dx11_) { |
| 1853 if (video_format_converter_mft_.get()) { |
| 1854 video_format_converter_mft_->ProcessMessage( |
| 1855 MFT_MESSAGE_NOTIFY_END_STREAMING, 0); |
| 1856 video_format_converter_mft_.Release(); |
| 1857 } |
| 1858 d3d11_device_context_.Release(); |
| 1859 d3d11_device_.Release(); |
| 1860 d3d11_device_manager_.Release(); |
| 1861 d3d11_query_.Release(); |
| 1862 multi_threaded_.Release(); |
| 1863 dx11_video_format_converter_media_type_needs_init_ = true; |
| 1864 } else { |
| 1865 d3d9_.Release(); |
| 1866 d3d9_device_ex_.Release(); |
| 1867 device_manager_.Release(); |
| 1868 query_.Release(); |
| 1847 } | 1869 } |
| 1848 d3d11_device_context_.Release(); | |
| 1849 d3d11_device_.Release(); | |
| 1850 d3d11_device_manager_.Release(); | |
| 1851 d3d11_query_.Release(); | |
| 1852 dx11_video_format_converter_media_type_needs_init_ = true; | |
| 1853 multi_threaded_.Release(); | |
| 1854 } else { | |
| 1855 d3d9_.Release(); | |
| 1856 d3d9_device_ex_.Release(); | |
| 1857 device_manager_.Release(); | |
| 1858 query_.Release(); | |
| 1859 } | 1870 } |
| 1860 sent_drain_message_ = false; | 1871 sent_drain_message_ = false; |
| 1861 SetState(kUninitialized); | 1872 SetState(kUninitialized); |
| 1862 } | 1873 } |
| 1863 | 1874 |
| 1864 void DXVAVideoDecodeAccelerator::NotifyInputBufferRead(int input_buffer_id) { | 1875 void DXVAVideoDecodeAccelerator::NotifyInputBufferRead(int input_buffer_id) { |
| 1865 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); | 1876 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
| 1866 if (client_) | 1877 if (client_) |
| 1867 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); | 1878 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); |
| 1868 } | 1879 } |
| (...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2692 E_FAIL); | 2703 E_FAIL); |
| 2693 } | 2704 } |
| 2694 *config_changed = config_change_detector_->config_changed(); | 2705 *config_changed = config_change_detector_->config_changed(); |
| 2695 return S_OK; | 2706 return S_OK; |
| 2696 } | 2707 } |
| 2697 | 2708 |
| 2698 void DXVAVideoDecodeAccelerator::ConfigChanged(const Config& config) { | 2709 void DXVAVideoDecodeAccelerator::ConfigChanged(const Config& config) { |
| 2699 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); | 2710 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
| 2700 | 2711 |
| 2701 SetState(kConfigChange); | 2712 SetState(kConfigChange); |
| 2702 DismissStaleBuffers(true); | |
| 2703 Invalidate(); | 2713 Invalidate(); |
| 2704 Initialize(config_, client_); | 2714 Initialize(config_, client_); |
| 2705 decoder_thread_task_runner_->PostTask( | 2715 decoder_thread_task_runner_->PostTask( |
| 2706 FROM_HERE, | 2716 FROM_HERE, |
| 2707 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, | 2717 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, |
| 2708 base::Unretained(this))); | 2718 base::Unretained(this))); |
| 2709 } | 2719 } |
| 2710 | 2720 |
| 2711 } // namespace media | 2721 } // namespace media |
| OLD | NEW |