| 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 1760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1771 // This function is also called from FlushInternal in a loop which could | 1771 // This function is also called from FlushInternal in a loop which could |
| 1772 // result in the state transitioning to kStopped due to no decoded output. | 1772 // result in the state transitioning to kStopped due to no decoded output. |
| 1773 State state = GetState(); | 1773 State state = GetState(); |
| 1774 RETURN_AND_NOTIFY_ON_FAILURE( | 1774 RETURN_AND_NOTIFY_ON_FAILURE( |
| 1775 (state == kNormal || state == kFlushing || state == kStopped), | 1775 (state == kNormal || state == kFlushing || state == kStopped), |
| 1776 "DoDecode: not in normal/flushing/stopped state", ILLEGAL_STATE, ); | 1776 "DoDecode: not in normal/flushing/stopped state", ILLEGAL_STATE, ); |
| 1777 | 1777 |
| 1778 if (D3D11Device()) | 1778 if (D3D11Device()) |
| 1779 g_last_device_removed_reason = D3D11Device()->GetDeviceRemovedReason(); | 1779 g_last_device_removed_reason = D3D11Device()->GetDeviceRemovedReason(); |
| 1780 | 1780 |
| 1781 MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0}; | |
| 1782 DWORD status = 0; | |
| 1783 HRESULT hr; | |
| 1784 { | |
| 1785 ScopedExceptionCatcher catcher(using_ms_vp9_mft_); | |
| 1786 g_last_process_output_time = GetCurrentQPC(); | |
| 1787 hr = decoder_->ProcessOutput(0, // No flags | |
| 1788 1, // # of out streams to pull from | |
| 1789 &output_data_buffer, &status); | |
| 1790 } | |
| 1791 IMFCollection* events = output_data_buffer.pEvents; | |
| 1792 if (events != NULL) { | |
| 1793 DVLOG(1) << "Got events from ProcessOuput, but discarding"; | |
| 1794 events->Release(); | |
| 1795 } | |
| 1796 base::win::ScopedComPtr<IMFSample> output_sample; | 1781 base::win::ScopedComPtr<IMFSample> output_sample; |
| 1797 output_sample.Attach(output_data_buffer.pSample); | 1782 int retries = 10; |
| 1798 if (FAILED(hr)) { | 1783 while (true) { |
| 1799 // A stream change needs further ProcessInput calls to get back decoder | 1784 output_sample.Reset(); |
| 1800 // output which is why we need to set the state to stopped. | 1785 MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0}; |
| 1801 if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { | 1786 DWORD status = 0; |
| 1802 if (!SetDecoderOutputMediaType(MFVideoFormat_NV12) && | 1787 HRESULT hr; |
| 1803 !SetDecoderOutputMediaType(MFVideoFormat_P010) && | 1788 { |
| 1804 !SetDecoderOutputMediaType(MFVideoFormat_P016)) { | 1789 ScopedExceptionCatcher catcher(using_ms_vp9_mft_); |
| 1805 // Decoder didn't let us set NV12 output format. Not sure as to why | 1790 g_last_process_output_time = GetCurrentQPC(); |
| 1806 // this can happen. Give up in disgust. | 1791 hr = decoder_->ProcessOutput(0, // No flags |
| 1807 NOTREACHED() << "Failed to set decoder output media type to NV12"; | 1792 1, // # of out streams to pull from |
| 1793 &output_data_buffer, &status); |
| 1794 } |
| 1795 IMFCollection* events = output_data_buffer.pEvents; |
| 1796 if (events != NULL) { |
| 1797 DVLOG(1) << "Got events from ProcessOuput, but discarding"; |
| 1798 events->Release(); |
| 1799 } |
| 1800 output_sample.Attach(output_data_buffer.pSample); |
| 1801 if (FAILED(hr)) { |
| 1802 // A stream change needs further ProcessInput calls to get back decoder |
| 1803 // output which is why we need to set the state to stopped. |
| 1804 if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { |
| 1805 if (!SetDecoderOutputMediaType(MFVideoFormat_NV12) && |
| 1806 !SetDecoderOutputMediaType(MFVideoFormat_P010) && |
| 1807 !SetDecoderOutputMediaType(MFVideoFormat_P016)) { |
| 1808 // Decoder didn't let us set NV12 output format. Not sure as to why |
| 1809 // this can happen. Give up in disgust. |
| 1810 NOTREACHED() << "Failed to set decoder output media type to NV12"; |
| 1811 SetState(kStopped); |
| 1812 } else { |
| 1813 if (retries-- > 0) { |
| 1814 DVLOG(1) << "Received format change from the decoder, retrying."; |
| 1815 continue; // Retry |
| 1816 } else { |
| 1817 RETURN_AND_NOTIFY_ON_FAILURE( |
| 1818 false, "Received too many format changes from decoder.", |
| 1819 PLATFORM_FAILURE, ); |
| 1820 } |
| 1821 } |
| 1822 return; |
| 1823 } else if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { |
| 1824 // No more output from the decoder. Stop playback. |
| 1808 SetState(kStopped); | 1825 SetState(kStopped); |
| 1826 return; |
| 1809 } else { | 1827 } else { |
| 1810 DVLOG(1) << "Received output format change from the decoder." | 1828 NOTREACHED() << "Unhandled error in DoDecode()"; |
| 1811 " Recursively invoking DoDecode"; | 1829 g_last_unhandled_error = hr; |
| 1812 DoDecode(color_space); | 1830 return; |
| 1813 } | 1831 } |
| 1814 return; | |
| 1815 } else if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { | |
| 1816 // No more output from the decoder. Stop playback. | |
| 1817 SetState(kStopped); | |
| 1818 return; | |
| 1819 } else { | |
| 1820 NOTREACHED() << "Unhandled error in DoDecode()"; | |
| 1821 g_last_unhandled_error = hr; | |
| 1822 return; | |
| 1823 } | 1832 } |
| 1833 |
| 1834 break; // No more retries needed. |
| 1824 } | 1835 } |
| 1825 TRACE_EVENT_ASYNC_END0("gpu", "DXVAVideoDecodeAccelerator.Decoding", this); | 1836 TRACE_EVENT_ASYNC_END0("gpu", "DXVAVideoDecodeAccelerator.Decoding", this); |
| 1826 | 1837 |
| 1827 TRACE_COUNTER1("DXVA Decoding", "TotalPacketsBeforeDecode", | 1838 TRACE_COUNTER1("DXVA Decoding", "TotalPacketsBeforeDecode", |
| 1828 inputs_before_decode_); | 1839 inputs_before_decode_); |
| 1829 | 1840 |
| 1830 inputs_before_decode_ = 0; | 1841 inputs_before_decode_ = 0; |
| 1831 | 1842 |
| 1832 RETURN_AND_NOTIFY_ON_FAILURE(ProcessOutputSample(output_sample, color_space), | 1843 RETURN_AND_NOTIFY_ON_FAILURE(ProcessOutputSample(output_sample, color_space), |
| 1833 "Failed to process output sample.", | 1844 "Failed to process output sample.", |
| (...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3006 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const { | 3017 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const { |
| 3007 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; | 3018 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; |
| 3008 return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; | 3019 return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; |
| 3009 } | 3020 } |
| 3010 | 3021 |
| 3011 ID3D11Device* DXVAVideoDecodeAccelerator::D3D11Device() const { | 3022 ID3D11Device* DXVAVideoDecodeAccelerator::D3D11Device() const { |
| 3012 return share_nv12_textures_ ? angle_device_.Get() : d3d11_device_.Get(); | 3023 return share_nv12_textures_ ? angle_device_.Get() : d3d11_device_.Get(); |
| 3013 } | 3024 } |
| 3014 | 3025 |
| 3015 } // namespace media | 3026 } // namespace media |
| OLD | NEW |