Chromium Code Reviews| Index: content/common/gpu/media/dxva_video_decode_accelerator_win.cc |
| diff --git a/content/common/gpu/media/dxva_video_decode_accelerator_win.cc b/content/common/gpu/media/dxva_video_decode_accelerator_win.cc |
| index 236d7840e87e54e37892a19489d5a2cb000f68b0..b9c0aa7517f9dfda44896423f3f0ea92a7271da2 100644 |
| --- a/content/common/gpu/media/dxva_video_decode_accelerator_win.cc |
| +++ b/content/common/gpu/media/dxva_video_decode_accelerator_win.cc |
| @@ -109,24 +109,6 @@ DEFINE_GUID(CLSID_VideoProcessorMFT, |
| DEFINE_GUID(MF_XVP_PLAYBACK_MODE, 0x3c5d293f, 0xad67, 0x4e29, 0xaf, 0x12, |
| 0xcf, 0x3e, 0x23, 0x8a, 0xcc, 0xe9); |
| -// Helper class to automatically lock unlock the DX11 device in a scope. |
| -class AutoDX11DeviceLock { |
| - public: |
| - explicit AutoDX11DeviceLock(ID3D10Multithread* multi_threaded) |
| - : multi_threaded_(multi_threaded) { |
| - multi_threaded_->Enter(); |
| - } |
| - |
| - ~AutoDX11DeviceLock() { |
| - multi_threaded_->Leave(); |
| - } |
| - |
| - private: |
| - base::win::ScopedComPtr<ID3D10Multithread> multi_threaded_; |
| - |
| - DISALLOW_COPY_AND_ASSIGN(AutoDX11DeviceLock); |
| -}; |
| - |
| } // namespace |
| namespace content { |
| @@ -803,21 +785,44 @@ bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() { |
| d3d11_device_manager_.Receive()); |
| RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false); |
| - base::win::ScopedComPtr<ID3D11Device> angle_device = |
| - QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE); |
| - RETURN_ON_FAILURE( |
| - angle_device.get(), |
| - "Failed to query DX11 device object from ANGLE", |
| - false); |
| + // This array defines the set of DirectX hardware feature levels we support. |
| + // The ordering MUST be preserved. All applications are assumed to support |
| + // 9.1 unless otherwise stated by the application, which is not our case. |
|
sandersd (OOO until July 31)
2015/12/09 23:02:49
I'm not clear what the last sentence means.
ananta
2015/12/09 23:15:03
Fixed comment
|
| + |
| + D3D_FEATURE_LEVEL feature_levels[] = { |
| + D3D_FEATURE_LEVEL_11_1, |
| + D3D_FEATURE_LEVEL_11_0, |
| + D3D_FEATURE_LEVEL_10_1, |
| + D3D_FEATURE_LEVEL_10_0, |
| + D3D_FEATURE_LEVEL_9_3, |
| + D3D_FEATURE_LEVEL_9_2, |
| + D3D_FEATURE_LEVEL_9_1 |
| + }; |
| - using_angle_device_ = true; |
| - d3d11_device_ = angle_device; |
| + UINT flags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; |
| + |
| +#if defined _DEBUG |
| + flags |= D3D11_CREATE_DEVICE_DEBUG; |
| +#endif |
| + |
| + D3D_FEATURE_LEVEL feature_level_out = D3D_FEATURE_LEVEL_11_0; |
| + hr = D3D11CreateDevice(NULL, |
| + D3D_DRIVER_TYPE_HARDWARE, |
| + NULL, |
| + flags, |
| + feature_levels, |
| + arraysize(feature_levels), |
| + D3D11_SDK_VERSION, |
| + d3d11_device_.Receive(), |
| + &feature_level_out, |
| + d3d11_device_context_.Receive()); |
| + RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device", false); |
| // Enable multithreaded mode on the device. This ensures that accesses to |
| // context are synchronized across threads. We have multiple threads |
| // accessing the context, the media foundation decoder threads and the |
| // decoder thread via the video format conversion transform. |
| - hr = multi_threaded_.QueryFrom(angle_device.get()); |
| + hr = multi_threaded_.QueryFrom(d3d11_device_.get()); |
| RETURN_ON_HR_FAILURE(hr, "Failed to query ID3D10Multithread", false); |
| multi_threaded_->SetMultithreadProtected(TRUE); |
| @@ -825,6 +830,14 @@ bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() { |
| dx11_dev_manager_reset_token_); |
| RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); |
| + D3D11_QUERY_DESC query_desc; |
| + query_desc.Query = D3D11_QUERY_EVENT; |
| + query_desc.MiscFlags = 0; |
| + hr = d3d11_device_->CreateQuery( |
| + &query_desc, |
| + d3d11_query_.Receive()); |
| + RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false); |
| + |
| HMODULE video_processor_dll = ::GetModuleHandle(L"msvproc.dll"); |
| RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor", |
| false); |
| @@ -1532,8 +1545,10 @@ void DXVAVideoDecodeAccelerator::Invalidate() { |
| MFT_MESSAGE_NOTIFY_END_STREAMING, 0); |
| video_format_converter_mft_.Release(); |
| } |
| + d3d11_device_context_.Release(); |
| d3d11_device_.Release(); |
| d3d11_device_manager_.Release(); |
| + d3d11_query_.Release(); |
| dx11_video_format_converter_media_type_needs_init_ = true; |
| } else { |
| d3d9_.Release(); |
| @@ -2034,10 +2049,6 @@ void DXVAVideoDecodeAccelerator::CopyTexture(ID3D11Texture2D* src_texture, |
| output_sample->AddBuffer(output_buffer.get()); |
| - // Lock the device here as we are accessing the DX11 video context and the |
| - // texture which need to be synchronized with the main thread. |
| - AutoDX11DeviceLock device_lock(multi_threaded_.get()); |
| - |
| hr = video_format_converter_mft_->ProcessInput(0, video_frame, 0); |
| if (FAILED(hr)) { |
| DCHECK(false); |
| @@ -2064,14 +2075,18 @@ void DXVAVideoDecodeAccelerator::CopyTexture(ID3D11Texture2D* src_texture, |
| "Failed to convert output sample format.", PLATFORM_FAILURE,); |
| } |
| - main_thread_task_runner_->PostTask( |
| + d3d11_device_context_->Flush(); |
| + d3d11_device_context_->End(d3d11_query_.get()); |
| + |
| + decoder_thread_task_runner_->PostDelayedTask( |
| FROM_HERE, |
| - base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, |
| - weak_this_factory_.GetWeakPtr(), |
| - nullptr, |
| - nullptr, |
| - picture_buffer_id, |
| - input_buffer_id)); |
| + base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder, |
| + base::Unretained(this), 0, |
| + reinterpret_cast<IDirect3DSurface9*>(NULL), |
| + reinterpret_cast<IDirect3DSurface9*>(NULL), |
| + picture_buffer_id, input_buffer_id), |
| + base::TimeDelta::FromMilliseconds( |
| + kFlushDecoderSurfaceTimeoutMs)); |
| } |
| void DXVAVideoDecodeAccelerator::FlushDecoder( |
| @@ -2095,11 +2110,22 @@ void DXVAVideoDecodeAccelerator::FlushDecoder( |
| // infinite loop. |
| // Workaround is to have an upper limit of 4 on the number of iterations to |
| // wait for the Flush to finish. |
| - DCHECK(!use_dx11_); |
| HRESULT hr = E_FAIL; |
| - |
| - hr = query_->GetData(NULL, 0, D3DGETDATA_FLUSH); |
| + if (use_dx11_) { |
| + BOOL query_data = 0; |
| + hr = d3d11_device_context_->GetData(d3d11_query_.get(), &query_data, |
| + sizeof(BOOL), 0); |
| + if (FAILED(hr)) { |
| + base::debug::Alias(&hr); |
| + // TODO(ananta) |
| + // Remove this CHECK when the change to use DX11 for H/W decoding |
| + // stablizes. |
| + CHECK(false); |
| + } |
| + } else { |
| + hr = query_->GetData(NULL, 0, D3DGETDATA_FLUSH); |
| + } |
| if ((hr == S_FALSE) && (++iterations < kMaxIterationsForD3DFlush)) { |
| decoder_thread_task_runner_->PostDelayedTask( |