Chromium Code Reviews| Index: content/common/gpu/media/dxva_video_decode_accelerator.cc |
| diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.cc b/content/common/gpu/media/dxva_video_decode_accelerator.cc |
| index 29d90065efdb6b9d81dec1bd73d0cb2da761f0bb..242a1c45ae46408a9a6818d8ac67ec6c09a84f35 100644 |
| --- a/content/common/gpu/media/dxva_video_decode_accelerator.cc |
| +++ b/content/common/gpu/media/dxva_video_decode_accelerator.cc |
| @@ -621,7 +621,8 @@ DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( |
| use_dx11_(false), |
| dx11_video_format_converter_media_type_needs_init_(true), |
| gl_context_(gl_context), |
| - weak_this_factory_(this) { |
| + weak_this_factory_(this), |
|
DaleCurtis
2015/11/02 19:58:30
Weak factory should always be last.
ananta
2015/11/02 22:17:56
Done.
|
| + dx11_device_locked_(false) { |
| weak_ptr_ = weak_this_factory_.GetWeakPtr(); |
| memset(&input_stream_info_, 0, sizeof(input_stream_info_)); |
| memset(&output_stream_info_, 0, sizeof(output_stream_info_)); |
| @@ -804,10 +805,9 @@ bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() { |
| // 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. |
| - base::win::ScopedComPtr<ID3D10Multithread> multi_threaded; |
| - hr = multi_threaded.QueryFrom(d3d11_device_context_.get()); |
| + hr = multi_threaded_.QueryFrom(d3d11_device_context_.get()); |
| RETURN_ON_HR_FAILURE(hr, "Failed to query ID3D10Multithread", false); |
| - multi_threaded->SetMultithreadProtected(TRUE); |
| + multi_threaded_->SetMultithreadProtected(TRUE); |
| hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(), |
| dx11_dev_manager_reset_token_); |
| @@ -968,7 +968,7 @@ void DXVAVideoDecodeAccelerator::Reset() { |
| RETURN_AND_NOTIFY_ON_FAILURE((state == kNormal || state == kStopped), |
| "Reset: invalid state: " << state, ILLEGAL_STATE,); |
| - decoder_thread_.Stop(); |
| + StopDecoderThread(); |
| SetState(kResetting); |
| @@ -1498,7 +1498,7 @@ void DXVAVideoDecodeAccelerator::StopOnError( |
| void DXVAVideoDecodeAccelerator::Invalidate() { |
| if (GetState() == kUninitialized) |
| return; |
| - decoder_thread_.Stop(); |
| + StopDecoderThread(); |
| weak_this_factory_.InvalidateWeakPtrs(); |
| output_picture_buffers_.clear(); |
| stale_output_picture_buffers_.clear(); |
| @@ -2011,6 +2011,12 @@ void DXVAVideoDecodeAccelerator::CopyTexture(ID3D11Texture2D* src_texture, |
| output_sample->AddBuffer(output_buffer.get()); |
| + // Lock the device here as we are accessing the destination texture created |
| + // on the main thread. |
| + CHECK(!dx11_device_locked_); |
| + dx11_device_locked_ = true; |
| + multi_threaded_->Enter(); |
| + |
| DWORD status = 0; |
| MFT_OUTPUT_DATA_BUFFER format_converter_output = {}; |
| format_converter_output.pSample = output_sample.get(); |
| @@ -2091,6 +2097,9 @@ void DXVAVideoDecodeAccelerator::FlushDecoder( |
| return; |
| } |
| + dx11_device_locked_ = false; |
| + multi_threaded_->Leave(); |
| + |
| main_thread_task_runner_->PostTask( |
| FROM_HERE, |
| base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, |
| @@ -2271,4 +2280,22 @@ bool DXVAVideoDecodeAccelerator::GetVideoFrameDimensions( |
| return true; |
| } |
| +void DXVAVideoDecodeAccelerator::StopDecoderThread() { |
| + if (main_thread_task_runner_->BelongsToCurrentThread()) { |
| + if (decoder_thread_.IsRunning()) { |
| + decoder_thread_task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&DXVAVideoDecodeAccelerator::StopDecoderThread, |
| + base::Unretained(this))); |
| + } |
| + decoder_thread_.Stop(); |
| + return; |
| + } |
| + |
| + if (dx11_device_locked_) { |
| + dx11_device_locked_ = false; |
| + multi_threaded_->Leave(); |
| + } |
| +} |
| + |
| } // namespace content |