| 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( | 
|  |