Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(621)

Side by Side Diff: content/common/gpu/media/dxva_video_decode_accelerator.cc

Issue 1493913003: Ensure that the code in the DXVA DX11 decoder which can potentially access the DX11 device context … (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove commented out code Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/common/gpu/media/dxva_video_decode_accelerator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "content/common/gpu/media/dxva_video_decode_accelerator.h" 5 #include "content/common/gpu/media/dxva_video_decode_accelerator.h"
6 6
7 #if !defined(OS_WIN) 7 #if !defined(OS_WIN)
8 #error This file should only be built on Windows. 8 #error This file should only be built on Windows.
9 #endif // !defined(OS_WIN) 9 #endif // !defined(OS_WIN)
10 10
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 #endif 102 #endif
103 103
104 // MF_XVP_PLAYBACK_MODE 104 // MF_XVP_PLAYBACK_MODE
105 // Data type: UINT32 (treat as BOOL) 105 // Data type: UINT32 (treat as BOOL)
106 // If this attribute is TRUE, the video processor will run in playback mode 106 // If this attribute is TRUE, the video processor will run in playback mode
107 // where it allows callers to allocate output samples and allows last frame 107 // where it allows callers to allocate output samples and allows last frame
108 // regeneration (repaint). 108 // regeneration (repaint).
109 DEFINE_GUID(MF_XVP_PLAYBACK_MODE, 0x3c5d293f, 0xad67, 0x4e29, 0xaf, 0x12, 109 DEFINE_GUID(MF_XVP_PLAYBACK_MODE, 0x3c5d293f, 0xad67, 0x4e29, 0xaf, 0x12,
110 0xcf, 0x3e, 0x23, 0x8a, 0xcc, 0xe9); 110 0xcf, 0x3e, 0x23, 0x8a, 0xcc, 0xe9);
111 111
112 // Helper class to automatically lock unlock the DX11 device in a scope.
113 class AutoDX11DeviceLock {
114 public:
115 explicit AutoDX11DeviceLock(ID3D10Multithread* multi_threaded)
116 : multi_threaded_(multi_threaded) {
117 multi_threaded_->Enter();
118 }
119
120 ~AutoDX11DeviceLock() {
121 multi_threaded_->Leave();
122 }
123
124 private:
125 base::win::ScopedComPtr<ID3D10Multithread> multi_threaded_;
126
127 DISALLOW_COPY_AND_ASSIGN(AutoDX11DeviceLock);
128 };
129
112 } // namespace 130 } // namespace
113 131
114 namespace content { 132 namespace content {
115 133
116 static const media::VideoCodecProfile kSupportedProfiles[] = { 134 static const media::VideoCodecProfile kSupportedProfiles[] = {
117 media::H264PROFILE_BASELINE, 135 media::H264PROFILE_BASELINE,
118 media::H264PROFILE_MAIN, 136 media::H264PROFILE_MAIN,
119 media::H264PROFILE_HIGH, 137 media::H264PROFILE_HIGH,
120 media::VP8PROFILE_ANY, 138 media::VP8PROFILE_ANY,
121 media::VP9PROFILE_ANY 139 media::VP9PROFILE_ANY
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 800
783 base::win::ScopedComPtr<ID3D11Device> angle_device = 801 base::win::ScopedComPtr<ID3D11Device> angle_device =
784 QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE); 802 QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE);
785 RETURN_ON_FAILURE( 803 RETURN_ON_FAILURE(
786 angle_device.get(), 804 angle_device.get(),
787 "Failed to query DX11 device object from ANGLE", 805 "Failed to query DX11 device object from ANGLE",
788 false); 806 false);
789 807
790 using_angle_device_ = true; 808 using_angle_device_ = true;
791 d3d11_device_ = angle_device; 809 d3d11_device_ = angle_device;
792 d3d11_device_->GetImmediateContext(d3d11_device_context_.Receive());
793 RETURN_ON_FAILURE(
794 d3d11_device_context_.get(),
795 "Failed to query DX11 device context from ANGLE device",
796 false);
797 810
798 // Enable multithreaded mode on the device. This ensures that accesses to 811 // Enable multithreaded mode on the device. This ensures that accesses to
799 // context are synchronized across threads. We have multiple threads 812 // context are synchronized across threads. We have multiple threads
800 // accessing the context, the media foundation decoder threads and the 813 // accessing the context, the media foundation decoder threads and the
801 // decoder thread via the video format conversion transform. 814 // decoder thread via the video format conversion transform.
802 hr = multi_threaded_.QueryFrom(angle_device.get()); 815 hr = multi_threaded_.QueryFrom(angle_device.get());
803 RETURN_ON_HR_FAILURE(hr, "Failed to query ID3D10Multithread", false); 816 RETURN_ON_HR_FAILURE(hr, "Failed to query ID3D10Multithread", false);
804 multi_threaded_->SetMultithreadProtected(TRUE); 817 multi_threaded_->SetMultithreadProtected(TRUE);
805 818
806 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(), 819 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(),
807 dx11_dev_manager_reset_token_); 820 dx11_dev_manager_reset_token_);
808 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); 821 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false);
809 822
810 D3D11_QUERY_DESC query_desc;
811 query_desc.Query = D3D11_QUERY_EVENT;
812 query_desc.MiscFlags = 0;
813 hr = d3d11_device_->CreateQuery(
814 &query_desc,
815 d3d11_query_.Receive());
816 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false);
817
818 HMODULE video_processor_dll = ::GetModuleHandle(L"msvproc.dll"); 823 HMODULE video_processor_dll = ::GetModuleHandle(L"msvproc.dll");
819 RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor", 824 RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor",
820 false); 825 false);
821 826
822 hr = CreateCOMObjectFromDll( 827 hr = CreateCOMObjectFromDll(
823 video_processor_dll, 828 video_processor_dll,
824 CLSID_VideoProcessorMFT, 829 CLSID_VideoProcessorMFT,
825 __uuidof(IMFTransform), 830 __uuidof(IMFTransform),
826 video_format_converter_mft_.ReceiveVoid()); 831 video_format_converter_mft_.ReceiveVoid());
827 if (FAILED(hr)) { 832 if (FAILED(hr)) {
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
1515 pending_output_samples_.clear(); 1520 pending_output_samples_.clear();
1516 pending_input_buffers_.clear(); 1521 pending_input_buffers_.clear();
1517 decoder_.Release(); 1522 decoder_.Release();
1518 1523
1519 if (use_dx11_) { 1524 if (use_dx11_) {
1520 if (video_format_converter_mft_.get()) { 1525 if (video_format_converter_mft_.get()) {
1521 video_format_converter_mft_->ProcessMessage( 1526 video_format_converter_mft_->ProcessMessage(
1522 MFT_MESSAGE_NOTIFY_END_STREAMING, 0); 1527 MFT_MESSAGE_NOTIFY_END_STREAMING, 0);
1523 video_format_converter_mft_.Release(); 1528 video_format_converter_mft_.Release();
1524 } 1529 }
1525 d3d11_device_context_.Release();
1526 d3d11_device_.Release(); 1530 d3d11_device_.Release();
1527 d3d11_device_manager_.Release(); 1531 d3d11_device_manager_.Release();
1528 d3d11_query_.Release();
1529 dx11_video_format_converter_media_type_needs_init_ = true; 1532 dx11_video_format_converter_media_type_needs_init_ = true;
1530 } else { 1533 } else {
1531 d3d9_.Release(); 1534 d3d9_.Release();
1532 d3d9_device_ex_.Release(); 1535 d3d9_device_ex_.Release();
1533 device_manager_.Release(); 1536 device_manager_.Release();
1534 query_.Release(); 1537 query_.Release();
1535 } 1538 }
1536 1539
1537 SetState(kUninitialized); 1540 SetState(kUninitialized);
1538 } 1541 }
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1991 return; 1994 return;
1992 } 1995 }
1993 1996
1994 DCHECK(video_frame); 1997 DCHECK(video_frame);
1995 1998
1996 base::win::ScopedComPtr<IMFSample> input_sample; 1999 base::win::ScopedComPtr<IMFSample> input_sample;
1997 input_sample.Attach(video_frame); 2000 input_sample.Attach(video_frame);
1998 2001
1999 DCHECK(video_format_converter_mft_.get()); 2002 DCHECK(video_format_converter_mft_.get());
2000 2003
2001 // d3d11_device_context_->Begin(d3d11_query_.get());
2002
2003 hr = video_format_converter_mft_->ProcessInput(0, video_frame, 0);
2004 if (FAILED(hr)) {
2005 DCHECK(false);
2006 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2007 "Failed to convert output sample format.", PLATFORM_FAILURE,);
2008 }
2009
2010 // The video processor MFT requires output samples to be allocated by the 2004 // The video processor MFT requires output samples to be allocated by the
2011 // caller. We create a sample with a buffer backed with the ID3D11Texture2D 2005 // caller. We create a sample with a buffer backed with the ID3D11Texture2D
2012 // interface exposed by ANGLE. This works nicely as this ensures that the 2006 // interface exposed by ANGLE. This works nicely as this ensures that the
2013 // video processor coverts the color space of the output frame and copies 2007 // video processor coverts the color space of the output frame and copies
2014 // the result into the ANGLE texture. 2008 // the result into the ANGLE texture.
2015 base::win::ScopedComPtr<IMFSample> output_sample; 2009 base::win::ScopedComPtr<IMFSample> output_sample;
2016 hr = MFCreateSample(output_sample.Receive()); 2010 hr = MFCreateSample(output_sample.Receive());
2017 if (FAILED(hr)) { 2011 if (FAILED(hr)) {
2018 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2012 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2019 "Failed to create output sample.", PLATFORM_FAILURE,); 2013 "Failed to create output sample.", PLATFORM_FAILURE,);
2020 } 2014 }
2021 2015
2022 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; 2016 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
2023 hr = MFCreateDXGISurfaceBuffer( 2017 hr = MFCreateDXGISurfaceBuffer(
2024 __uuidof(ID3D11Texture2D), dest_texture, 0, FALSE, 2018 __uuidof(ID3D11Texture2D), dest_texture, 0, FALSE,
2025 output_buffer.Receive()); 2019 output_buffer.Receive());
2026 if (FAILED(hr)) { 2020 if (FAILED(hr)) {
2027 base::debug::Alias(&hr); 2021 base::debug::Alias(&hr);
2028 // TODO(ananta) 2022 // TODO(ananta)
2029 // Remove this CHECK when the change to use DX11 for H/W decoding 2023 // Remove this CHECK when the change to use DX11 for H/W decoding
2030 // stablizes. 2024 // stablizes.
2031 CHECK(false); 2025 CHECK(false);
2032 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2026 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2033 "Failed to create output sample.", PLATFORM_FAILURE,); 2027 "Failed to create output sample.", PLATFORM_FAILURE,);
2034 } 2028 }
2035 2029
2036 output_sample->AddBuffer(output_buffer.get()); 2030 output_sample->AddBuffer(output_buffer.get());
2037 2031
2038 // Lock the device here as we are accessing the destination texture created 2032 // Lock the device here as we are accessing the DX11 video context and the
2039 // on the main thread. 2033 // texture which need to be synchronized with the main thread.
2040 multi_threaded_->Enter(); 2034 AutoDX11DeviceLock device_lock(multi_threaded_.get());
DaleCurtis 2015/12/03 22:09:24 This will hold the lock for all the calls below to
ananta 2015/12/03 22:11:02 ProcessInput and ProcessOutput.
2035
2036 hr = video_format_converter_mft_->ProcessInput(0, video_frame, 0);
2037 if (FAILED(hr)) {
2038 DCHECK(false);
2039 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2040 "Failed to convert output sample format.", PLATFORM_FAILURE,);
2041 }
2041 2042
2042 DWORD status = 0; 2043 DWORD status = 0;
2043 MFT_OUTPUT_DATA_BUFFER format_converter_output = {}; 2044 MFT_OUTPUT_DATA_BUFFER format_converter_output = {};
2044 format_converter_output.pSample = output_sample.get(); 2045 format_converter_output.pSample = output_sample.get();
2045 hr = video_format_converter_mft_->ProcessOutput( 2046 hr = video_format_converter_mft_->ProcessOutput(
2046 0, // No flags 2047 0, // No flags
2047 1, // # of out streams to pull from 2048 1, // # of out streams to pull from
2048 &format_converter_output, 2049 &format_converter_output,
2049 &status); 2050 &status);
2050 2051
2051 d3d11_device_context_->Flush();
2052 d3d11_device_context_->End(d3d11_query_.get());
2053
2054 multi_threaded_->Leave();
2055
2056 if (FAILED(hr)) { 2052 if (FAILED(hr)) {
2057 base::debug::Alias(&hr); 2053 base::debug::Alias(&hr);
2058 // TODO(ananta) 2054 // TODO(ananta)
2059 // Remove this CHECK when the change to use DX11 for H/W decoding 2055 // Remove this CHECK when the change to use DX11 for H/W decoding
2060 // stablizes. 2056 // stablizes.
2061 CHECK(false); 2057 CHECK(false);
2062 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2058 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2063 "Failed to convert output sample format.", PLATFORM_FAILURE,); 2059 "Failed to convert output sample format.", PLATFORM_FAILURE,);
2064 } 2060 }
2065 2061
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2227 if (FAILED(hr)) { 2223 if (FAILED(hr)) {
2228 base::debug::Alias(&hr); 2224 base::debug::Alias(&hr);
2229 // TODO(ananta) 2225 // TODO(ananta)
2230 // Remove this CHECK when the change to use DX11 for H/W decoding 2226 // Remove this CHECK when the change to use DX11 for H/W decoding
2231 // stablizes. 2227 // stablizes.
2232 CHECK(false); 2228 CHECK(false);
2233 } 2229 }
2234 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2230 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2235 "Failed to set converter output type", PLATFORM_FAILURE, false); 2231 "Failed to set converter output type", PLATFORM_FAILURE, false);
2236 2232
2237 hr = video_format_converter_mft_->ProcessMessage(
2238 MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
2239 if (FAILED(hr)) {
2240 // TODO(ananta)
2241 // Remove this CHECK when the change to use DX11 for H/W decoding
2242 // stablizes.
2243 RETURN_AND_NOTIFY_ON_FAILURE(
2244 false, "Failed to initialize video converter.", PLATFORM_FAILURE,
2245 false);
2246 }
2247 dx11_video_format_converter_media_type_needs_init_ = false; 2233 dx11_video_format_converter_media_type_needs_init_ = false;
2248 return true; 2234 return true;
2249 } 2235 }
2250 out_media_type.Release(); 2236 out_media_type.Release();
2251 } 2237 }
2252 return false; 2238 return false;
2253 } 2239 }
2254 2240
2255 bool DXVAVideoDecodeAccelerator::GetVideoFrameDimensions( 2241 bool DXVAVideoDecodeAccelerator::GetVideoFrameDimensions(
2256 IMFSample* sample, 2242 IMFSample* sample,
(...skipping 27 matching lines...) Expand all
2284 D3DSURFACE_DESC surface_desc; 2270 D3DSURFACE_DESC surface_desc;
2285 hr = surface->GetDesc(&surface_desc); 2271 hr = surface->GetDesc(&surface_desc);
2286 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false); 2272 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false);
2287 *width = surface_desc.Width; 2273 *width = surface_desc.Width;
2288 *height = surface_desc.Height; 2274 *height = surface_desc.Height;
2289 } 2275 }
2290 return true; 2276 return true;
2291 } 2277 }
2292 2278
2293 } // namespace content 2279 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/dxva_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698