| 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..4ee22907c868916b4afe40164184c52d9ccc5b99 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,43 @@ 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.
|
| + 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 +829,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 +1544,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 +2048,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 +2074,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 +2109,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(
|
|
|