| 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 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 config_change_detector_.reset(new H264ConfigChangeDetector); | 703 config_change_detector_.reset(new H264ConfigChangeDetector); |
| 704 | 704 |
| 705 SetState(kNormal); | 705 SetState(kNormal); |
| 706 | 706 |
| 707 StartDecoderThread(); | 707 StartDecoderThread(); |
| 708 return true; | 708 return true; |
| 709 } | 709 } |
| 710 | 710 |
| 711 bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() { | 711 bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() { |
| 712 TRACE_EVENT0("gpu", "DXVAVideoDecodeAccelerator_CreateD3DDevManager"); | 712 TRACE_EVENT0("gpu", "DXVAVideoDecodeAccelerator_CreateD3DDevManager"); |
| 713 // The device may exist if the last state was a config change. |
| 714 if (d3d9_.get()) |
| 715 return true; |
| 713 | 716 |
| 714 HRESULT hr = E_FAIL; | 717 HRESULT hr = E_FAIL; |
| 715 | 718 |
| 716 hr = Direct3DCreate9Ex(D3D_SDK_VERSION, d3d9_.Receive()); | 719 hr = Direct3DCreate9Ex(D3D_SDK_VERSION, d3d9_.Receive()); |
| 717 RETURN_ON_HR_FAILURE(hr, "Direct3DCreate9Ex failed", false); | 720 RETURN_ON_HR_FAILURE(hr, "Direct3DCreate9Ex failed", false); |
| 718 | 721 |
| 719 hr = d3d9_->CheckDeviceFormatConversion( | 722 hr = d3d9_->CheckDeviceFormatConversion( |
| 720 D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, | 723 D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, |
| 721 static_cast<D3DFORMAT>(MAKEFOURCC('N', 'V', '1', '2')), D3DFMT_X8R8G8B8); | 724 static_cast<D3DFORMAT>(MAKEFOURCC('N', 'V', '1', '2')), D3DFMT_X8R8G8B8); |
| 722 RETURN_ON_HR_FAILURE(hr, "D3D9 driver does not support H/W format conversion", | 725 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... |
| 764 hr = d3d9_device_ex_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive()); | 767 hr = d3d9_device_ex_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive()); |
| 765 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device query", false); | 768 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device query", false); |
| 766 // Ensure query_ API works (to avoid an infinite loop later in | 769 // Ensure query_ API works (to avoid an infinite loop later in |
| 767 // CopyOutputSampleDataToPictureBuffer). | 770 // CopyOutputSampleDataToPictureBuffer). |
| 768 hr = query_->Issue(D3DISSUE_END); | 771 hr = query_->Issue(D3DISSUE_END); |
| 769 RETURN_ON_HR_FAILURE(hr, "Failed to issue END test query", false); | 772 RETURN_ON_HR_FAILURE(hr, "Failed to issue END test query", false); |
| 770 return true; | 773 return true; |
| 771 } | 774 } |
| 772 | 775 |
| 773 bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() { | 776 bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() { |
| 777 // The device may exist if the last state was a config change. |
| 778 if (d3d11_device_.get()) |
| 779 return true; |
| 774 HRESULT hr = create_dxgi_device_manager_(&dx11_dev_manager_reset_token_, | 780 HRESULT hr = create_dxgi_device_manager_(&dx11_dev_manager_reset_token_, |
| 775 d3d11_device_manager_.Receive()); | 781 d3d11_device_manager_.Receive()); |
| 776 RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false); | 782 RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false); |
| 777 if (share_nv12_textures_) { | 783 if (share_nv12_textures_) { |
| 778 base::win::ScopedComPtr<ID3D11Device> angle_device = | 784 base::win::ScopedComPtr<ID3D11Device> angle_device = |
| 779 QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE); | 785 QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE); |
| 780 RETURN_ON_FAILURE(angle_device.get(), "Failed to get d3d11 device", false); | 786 RETURN_ON_FAILURE(angle_device.get(), "Failed to get d3d11 device", false); |
| 781 | 787 |
| 782 using_angle_device_ = true; | 788 using_angle_device_ = true; |
| 783 d3d11_device_ = angle_device; | 789 d3d11_device_ = angle_device; |
| (...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1798 | 1804 |
| 1799 void DXVAVideoDecodeAccelerator::Invalidate() { | 1805 void DXVAVideoDecodeAccelerator::Invalidate() { |
| 1800 if (GetState() == kUninitialized) | 1806 if (GetState() == kUninitialized) |
| 1801 return; | 1807 return; |
| 1802 | 1808 |
| 1803 // Best effort to make the GL context current. | 1809 // Best effort to make the GL context current. |
| 1804 make_context_current_cb_.Run(); | 1810 make_context_current_cb_.Run(); |
| 1805 | 1811 |
| 1806 decoder_thread_.Stop(); | 1812 decoder_thread_.Stop(); |
| 1807 weak_this_factory_.InvalidateWeakPtrs(); | 1813 weak_this_factory_.InvalidateWeakPtrs(); |
| 1808 output_picture_buffers_.clear(); | |
| 1809 stale_output_picture_buffers_.clear(); | |
| 1810 pending_output_samples_.clear(); | 1814 pending_output_samples_.clear(); |
| 1811 // We want to continue processing pending input after detecting a config | |
| 1812 // change. | |
| 1813 if (GetState() != kConfigChange) | |
| 1814 pending_input_buffers_.clear(); | |
| 1815 decoder_.Release(); | 1815 decoder_.Release(); |
| 1816 pictures_requested_ = false; | |
| 1817 | |
| 1818 config_change_detector_.reset(); | 1816 config_change_detector_.reset(); |
| 1819 | 1817 |
| 1820 if (use_dx11_) { | 1818 // If we are processing a config change, then leave the d3d9/d3d11 objects |
| 1821 if (video_format_converter_mft_.get()) { | 1819 // along with the output picture buffers intact as they can be reused. The |
| 1822 video_format_converter_mft_->ProcessMessage( | 1820 // output picture buffers may need to be recreated in case the video |
| 1823 MFT_MESSAGE_NOTIFY_END_STREAMING, 0); | 1821 // resolution changes. We already handle that in the |
| 1824 video_format_converter_mft_.Release(); | 1822 // HandleResolutionChanged() function. |
| 1823 if (GetState() != kConfigChange) { |
| 1824 output_picture_buffers_.clear(); |
| 1825 stale_output_picture_buffers_.clear(); |
| 1826 // We want to continue processing pending input after detecting a config |
| 1827 // change. |
| 1828 pending_input_buffers_.clear(); |
| 1829 pictures_requested_ = false; |
| 1830 if (use_dx11_) { |
| 1831 if (video_format_converter_mft_.get()) { |
| 1832 video_format_converter_mft_->ProcessMessage( |
| 1833 MFT_MESSAGE_NOTIFY_END_STREAMING, 0); |
| 1834 video_format_converter_mft_.Release(); |
| 1835 } |
| 1836 d3d11_device_context_.Release(); |
| 1837 d3d11_device_.Release(); |
| 1838 d3d11_device_manager_.Release(); |
| 1839 d3d11_query_.Release(); |
| 1840 multi_threaded_.Release(); |
| 1841 dx11_video_format_converter_media_type_needs_init_ = true; |
| 1842 } else { |
| 1843 d3d9_.Release(); |
| 1844 d3d9_device_ex_.Release(); |
| 1845 device_manager_.Release(); |
| 1846 query_.Release(); |
| 1825 } | 1847 } |
| 1826 d3d11_device_context_.Release(); | |
| 1827 d3d11_device_.Release(); | |
| 1828 d3d11_device_manager_.Release(); | |
| 1829 d3d11_query_.Release(); | |
| 1830 dx11_video_format_converter_media_type_needs_init_ = true; | |
| 1831 multi_threaded_.Release(); | |
| 1832 } else { | |
| 1833 d3d9_.Release(); | |
| 1834 d3d9_device_ex_.Release(); | |
| 1835 device_manager_.Release(); | |
| 1836 query_.Release(); | |
| 1837 } | 1848 } |
| 1838 | 1849 |
| 1839 SetState(kUninitialized); | 1850 SetState(kUninitialized); |
| 1840 } | 1851 } |
| 1841 | 1852 |
| 1842 void DXVAVideoDecodeAccelerator::NotifyInputBufferRead(int input_buffer_id) { | 1853 void DXVAVideoDecodeAccelerator::NotifyInputBufferRead(int input_buffer_id) { |
| 1843 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); | 1854 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
| 1844 if (client_) | 1855 if (client_) |
| 1845 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); | 1856 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); |
| 1846 } | 1857 } |
| (...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2635 E_FAIL); | 2646 E_FAIL); |
| 2636 } | 2647 } |
| 2637 *config_changed = config_change_detector_->config_changed(); | 2648 *config_changed = config_change_detector_->config_changed(); |
| 2638 return S_OK; | 2649 return S_OK; |
| 2639 } | 2650 } |
| 2640 | 2651 |
| 2641 void DXVAVideoDecodeAccelerator::ConfigChanged(const Config& config) { | 2652 void DXVAVideoDecodeAccelerator::ConfigChanged(const Config& config) { |
| 2642 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); | 2653 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
| 2643 | 2654 |
| 2644 SetState(kConfigChange); | 2655 SetState(kConfigChange); |
| 2645 DismissStaleBuffers(true); | |
| 2646 Invalidate(); | 2656 Invalidate(); |
| 2647 Initialize(config_, client_); | 2657 Initialize(config_, client_); |
| 2648 decoder_thread_task_runner_->PostTask( | 2658 decoder_thread_task_runner_->PostTask( |
| 2649 FROM_HERE, | 2659 FROM_HERE, |
| 2650 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, | 2660 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, |
| 2651 base::Unretained(this))); | 2661 base::Unretained(this))); |
| 2652 } | 2662 } |
| 2653 | 2663 |
| 2654 } // namespace media | 2664 } // namespace media |
| OLD | NEW |