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 |