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

Side by Side Diff: content/common/gpu/media/dxva_video_decode_accelerator_win.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: Rebased to tip 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_win.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_win.h" 5 #include "content/common/gpu/media/dxva_video_decode_accelerator_win.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 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 805
788 base::win::ScopedComPtr<ID3D11Device> angle_device = 806 base::win::ScopedComPtr<ID3D11Device> angle_device =
789 QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE); 807 QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE);
790 RETURN_ON_FAILURE( 808 RETURN_ON_FAILURE(
791 angle_device.get(), 809 angle_device.get(),
792 "Failed to query DX11 device object from ANGLE", 810 "Failed to query DX11 device object from ANGLE",
793 false); 811 false);
794 812
795 using_angle_device_ = true; 813 using_angle_device_ = true;
796 d3d11_device_ = angle_device; 814 d3d11_device_ = angle_device;
797 d3d11_device_->GetImmediateContext(d3d11_device_context_.Receive());
798 RETURN_ON_FAILURE(
799 d3d11_device_context_.get(),
800 "Failed to query DX11 device context from ANGLE device",
801 false);
802 815
803 // Enable multithreaded mode on the device. This ensures that accesses to 816 // Enable multithreaded mode on the device. This ensures that accesses to
804 // context are synchronized across threads. We have multiple threads 817 // context are synchronized across threads. We have multiple threads
805 // accessing the context, the media foundation decoder threads and the 818 // accessing the context, the media foundation decoder threads and the
806 // decoder thread via the video format conversion transform. 819 // decoder thread via the video format conversion transform.
807 hr = multi_threaded_.QueryFrom(angle_device.get()); 820 hr = multi_threaded_.QueryFrom(angle_device.get());
808 RETURN_ON_HR_FAILURE(hr, "Failed to query ID3D10Multithread", false); 821 RETURN_ON_HR_FAILURE(hr, "Failed to query ID3D10Multithread", false);
809 multi_threaded_->SetMultithreadProtected(TRUE); 822 multi_threaded_->SetMultithreadProtected(TRUE);
810 823
811 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(), 824 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(),
812 dx11_dev_manager_reset_token_); 825 dx11_dev_manager_reset_token_);
813 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); 826 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false);
814 827
815 D3D11_QUERY_DESC query_desc;
816 query_desc.Query = D3D11_QUERY_EVENT;
817 query_desc.MiscFlags = 0;
818 hr = d3d11_device_->CreateQuery(
819 &query_desc,
820 d3d11_query_.Receive());
821 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false);
822
823 HMODULE video_processor_dll = ::GetModuleHandle(L"msvproc.dll"); 828 HMODULE video_processor_dll = ::GetModuleHandle(L"msvproc.dll");
824 RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor", 829 RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor",
825 false); 830 false);
826 831
827 hr = CreateCOMObjectFromDll( 832 hr = CreateCOMObjectFromDll(
828 video_processor_dll, 833 video_processor_dll,
829 CLSID_VideoProcessorMFT, 834 CLSID_VideoProcessorMFT,
830 __uuidof(IMFTransform), 835 __uuidof(IMFTransform),
831 video_format_converter_mft_.ReceiveVoid()); 836 video_format_converter_mft_.ReceiveVoid());
832 if (FAILED(hr)) { 837 if (FAILED(hr)) {
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
1520 pending_output_samples_.clear(); 1525 pending_output_samples_.clear();
1521 pending_input_buffers_.clear(); 1526 pending_input_buffers_.clear();
1522 decoder_.Release(); 1527 decoder_.Release();
1523 1528
1524 if (use_dx11_) { 1529 if (use_dx11_) {
1525 if (video_format_converter_mft_.get()) { 1530 if (video_format_converter_mft_.get()) {
1526 video_format_converter_mft_->ProcessMessage( 1531 video_format_converter_mft_->ProcessMessage(
1527 MFT_MESSAGE_NOTIFY_END_STREAMING, 0); 1532 MFT_MESSAGE_NOTIFY_END_STREAMING, 0);
1528 video_format_converter_mft_.Release(); 1533 video_format_converter_mft_.Release();
1529 } 1534 }
1530 d3d11_device_context_.Release();
1531 d3d11_device_.Release(); 1535 d3d11_device_.Release();
1532 d3d11_device_manager_.Release(); 1536 d3d11_device_manager_.Release();
1533 d3d11_query_.Release();
1534 dx11_video_format_converter_media_type_needs_init_ = true; 1537 dx11_video_format_converter_media_type_needs_init_ = true;
1535 } else { 1538 } else {
1536 d3d9_.Release(); 1539 d3d9_.Release();
1537 d3d9_device_ex_.Release(); 1540 d3d9_device_ex_.Release();
1538 device_manager_.Release(); 1541 device_manager_.Release();
1539 query_.Release(); 1542 query_.Release();
1540 } 1543 }
1541 1544
1542 SetState(kUninitialized); 1545 SetState(kUninitialized);
1543 } 1546 }
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1996 return; 1999 return;
1997 } 2000 }
1998 2001
1999 DCHECK(video_frame); 2002 DCHECK(video_frame);
2000 2003
2001 base::win::ScopedComPtr<IMFSample> input_sample; 2004 base::win::ScopedComPtr<IMFSample> input_sample;
2002 input_sample.Attach(video_frame); 2005 input_sample.Attach(video_frame);
2003 2006
2004 DCHECK(video_format_converter_mft_.get()); 2007 DCHECK(video_format_converter_mft_.get());
2005 2008
2006 // d3d11_device_context_->Begin(d3d11_query_.get());
2007
2008 hr = video_format_converter_mft_->ProcessInput(0, video_frame, 0);
2009 if (FAILED(hr)) {
2010 DCHECK(false);
2011 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2012 "Failed to convert output sample format.", PLATFORM_FAILURE,);
2013 }
2014
2015 // The video processor MFT requires output samples to be allocated by the 2009 // The video processor MFT requires output samples to be allocated by the
2016 // caller. We create a sample with a buffer backed with the ID3D11Texture2D 2010 // caller. We create a sample with a buffer backed with the ID3D11Texture2D
2017 // interface exposed by ANGLE. This works nicely as this ensures that the 2011 // interface exposed by ANGLE. This works nicely as this ensures that the
2018 // video processor coverts the color space of the output frame and copies 2012 // video processor coverts the color space of the output frame and copies
2019 // the result into the ANGLE texture. 2013 // the result into the ANGLE texture.
2020 base::win::ScopedComPtr<IMFSample> output_sample; 2014 base::win::ScopedComPtr<IMFSample> output_sample;
2021 hr = MFCreateSample(output_sample.Receive()); 2015 hr = MFCreateSample(output_sample.Receive());
2022 if (FAILED(hr)) { 2016 if (FAILED(hr)) {
2023 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2017 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2024 "Failed to create output sample.", PLATFORM_FAILURE,); 2018 "Failed to create output sample.", PLATFORM_FAILURE,);
2025 } 2019 }
2026 2020
2027 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; 2021 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
2028 hr = MFCreateDXGISurfaceBuffer( 2022 hr = MFCreateDXGISurfaceBuffer(
2029 __uuidof(ID3D11Texture2D), dest_texture, 0, FALSE, 2023 __uuidof(ID3D11Texture2D), dest_texture, 0, FALSE,
2030 output_buffer.Receive()); 2024 output_buffer.Receive());
2031 if (FAILED(hr)) { 2025 if (FAILED(hr)) {
2032 base::debug::Alias(&hr); 2026 base::debug::Alias(&hr);
2033 // TODO(ananta) 2027 // TODO(ananta)
2034 // Remove this CHECK when the change to use DX11 for H/W decoding 2028 // Remove this CHECK when the change to use DX11 for H/W decoding
2035 // stablizes. 2029 // stablizes.
2036 CHECK(false); 2030 CHECK(false);
2037 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2031 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2038 "Failed to create output sample.", PLATFORM_FAILURE,); 2032 "Failed to create output sample.", PLATFORM_FAILURE,);
2039 } 2033 }
2040 2034
2041 output_sample->AddBuffer(output_buffer.get()); 2035 output_sample->AddBuffer(output_buffer.get());
2042 2036
2043 // Lock the device here as we are accessing the destination texture created 2037 // Lock the device here as we are accessing the DX11 video context and the
2044 // on the main thread. 2038 // texture which need to be synchronized with the main thread.
2045 multi_threaded_->Enter(); 2039 AutoDX11DeviceLock device_lock(multi_threaded_.get());
2040
2041 hr = video_format_converter_mft_->ProcessInput(0, video_frame, 0);
2042 if (FAILED(hr)) {
2043 DCHECK(false);
2044 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2045 "Failed to convert output sample format.", PLATFORM_FAILURE,);
2046 }
2046 2047
2047 DWORD status = 0; 2048 DWORD status = 0;
2048 MFT_OUTPUT_DATA_BUFFER format_converter_output = {}; 2049 MFT_OUTPUT_DATA_BUFFER format_converter_output = {};
2049 format_converter_output.pSample = output_sample.get(); 2050 format_converter_output.pSample = output_sample.get();
2050 hr = video_format_converter_mft_->ProcessOutput( 2051 hr = video_format_converter_mft_->ProcessOutput(
2051 0, // No flags 2052 0, // No flags
2052 1, // # of out streams to pull from 2053 1, // # of out streams to pull from
2053 &format_converter_output, 2054 &format_converter_output,
2054 &status); 2055 &status);
2055 2056
2056 d3d11_device_context_->Flush();
2057 d3d11_device_context_->End(d3d11_query_.get());
2058
2059 multi_threaded_->Leave();
2060
2061 if (FAILED(hr)) { 2057 if (FAILED(hr)) {
2062 base::debug::Alias(&hr); 2058 base::debug::Alias(&hr);
2063 // TODO(ananta) 2059 // TODO(ananta)
2064 // Remove this CHECK when the change to use DX11 for H/W decoding 2060 // Remove this CHECK when the change to use DX11 for H/W decoding
2065 // stablizes. 2061 // stablizes.
2066 CHECK(false); 2062 CHECK(false);
2067 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2063 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2068 "Failed to convert output sample format.", PLATFORM_FAILURE,); 2064 "Failed to convert output sample format.", PLATFORM_FAILURE,);
2069 } 2065 }
2070 2066
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2232 if (FAILED(hr)) { 2228 if (FAILED(hr)) {
2233 base::debug::Alias(&hr); 2229 base::debug::Alias(&hr);
2234 // TODO(ananta) 2230 // TODO(ananta)
2235 // Remove this CHECK when the change to use DX11 for H/W decoding 2231 // Remove this CHECK when the change to use DX11 for H/W decoding
2236 // stablizes. 2232 // stablizes.
2237 CHECK(false); 2233 CHECK(false);
2238 } 2234 }
2239 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2235 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2240 "Failed to set converter output type", PLATFORM_FAILURE, false); 2236 "Failed to set converter output type", PLATFORM_FAILURE, false);
2241 2237
2242 hr = video_format_converter_mft_->ProcessMessage(
2243 MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
2244 if (FAILED(hr)) {
2245 // TODO(ananta)
2246 // Remove this CHECK when the change to use DX11 for H/W decoding
2247 // stablizes.
2248 RETURN_AND_NOTIFY_ON_FAILURE(
2249 false, "Failed to initialize video converter.", PLATFORM_FAILURE,
2250 false);
2251 }
2252 dx11_video_format_converter_media_type_needs_init_ = false; 2238 dx11_video_format_converter_media_type_needs_init_ = false;
2253 return true; 2239 return true;
2254 } 2240 }
2255 out_media_type.Release(); 2241 out_media_type.Release();
2256 } 2242 }
2257 return false; 2243 return false;
2258 } 2244 }
2259 2245
2260 bool DXVAVideoDecodeAccelerator::GetVideoFrameDimensions( 2246 bool DXVAVideoDecodeAccelerator::GetVideoFrameDimensions(
2261 IMFSample* sample, 2247 IMFSample* sample,
(...skipping 27 matching lines...) Expand all
2289 D3DSURFACE_DESC surface_desc; 2275 D3DSURFACE_DESC surface_desc;
2290 hr = surface->GetDesc(&surface_desc); 2276 hr = surface->GetDesc(&surface_desc);
2291 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false); 2277 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false);
2292 *width = surface_desc.Width; 2278 *width = surface_desc.Width;
2293 *height = surface_desc.Height; 2279 *height = surface_desc.Height;
2294 } 2280 }
2295 return true; 2281 return true;
2296 } 2282 }
2297 2283
2298 } // namespace content 2284 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/dxva_video_decode_accelerator_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698