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

Side by Side Diff: content/common/gpu/media/dxva_video_decode_accelerator.cc

Issue 1427213002: Lock the decoder device (Angle) device from the decoder thread before copying the decoded frame to … (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix locking Created 5 years, 1 month 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.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.h" 5 #include "content/common/gpu/media/dxva_video_decode_accelerator.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 603 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 pictures_requested_(false), 614 pictures_requested_(false),
615 inputs_before_decode_(0), 615 inputs_before_decode_(0),
616 sent_drain_message_(false), 616 sent_drain_message_(false),
617 make_context_current_(make_context_current), 617 make_context_current_(make_context_current),
618 codec_(media::kUnknownVideoCodec), 618 codec_(media::kUnknownVideoCodec),
619 decoder_thread_("DXVAVideoDecoderThread"), 619 decoder_thread_("DXVAVideoDecoderThread"),
620 pending_flush_(false), 620 pending_flush_(false),
621 use_dx11_(false), 621 use_dx11_(false),
622 dx11_video_format_converter_media_type_needs_init_(true), 622 dx11_video_format_converter_media_type_needs_init_(true),
623 gl_context_(gl_context), 623 gl_context_(gl_context),
624 weak_this_factory_(this) { 624 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.
625 dx11_device_locked_(false) {
625 weak_ptr_ = weak_this_factory_.GetWeakPtr(); 626 weak_ptr_ = weak_this_factory_.GetWeakPtr();
626 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); 627 memset(&input_stream_info_, 0, sizeof(input_stream_info_));
627 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); 628 memset(&output_stream_info_, 0, sizeof(output_stream_info_));
628 } 629 }
629 630
630 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { 631 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() {
631 client_ = NULL; 632 client_ = NULL;
632 } 633 }
633 634
634 bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, 635 bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 d3d11_device_->GetImmediateContext(d3d11_device_context_.Receive()); 798 d3d11_device_->GetImmediateContext(d3d11_device_context_.Receive());
798 RETURN_ON_FAILURE( 799 RETURN_ON_FAILURE(
799 d3d11_device_context_.get(), 800 d3d11_device_context_.get(),
800 "Failed to query DX11 device context from ANGLE device", 801 "Failed to query DX11 device context from ANGLE device",
801 false); 802 false);
802 803
803 // Enable multithreaded mode on the context. This ensures that accesses to 804 // Enable multithreaded mode on the context. This ensures that accesses to
804 // context are synchronized across threads. We have multiple threads 805 // context are synchronized across threads. We have multiple threads
805 // accessing the context, the media foundation decoder threads and the 806 // accessing the context, the media foundation decoder threads and the
806 // decoder thread via the video format conversion transform. 807 // decoder thread via the video format conversion transform.
807 base::win::ScopedComPtr<ID3D10Multithread> multi_threaded; 808 hr = multi_threaded_.QueryFrom(d3d11_device_context_.get());
808 hr = multi_threaded.QueryFrom(d3d11_device_context_.get());
809 RETURN_ON_HR_FAILURE(hr, "Failed to query ID3D10Multithread", false); 809 RETURN_ON_HR_FAILURE(hr, "Failed to query ID3D10Multithread", false);
810 multi_threaded->SetMultithreadProtected(TRUE); 810 multi_threaded_->SetMultithreadProtected(TRUE);
811 811
812 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(), 812 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(),
813 dx11_dev_manager_reset_token_); 813 dx11_dev_manager_reset_token_);
814 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); 814 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false);
815 815
816 D3D11_QUERY_DESC query_desc; 816 D3D11_QUERY_DESC query_desc;
817 query_desc.Query = D3D11_QUERY_EVENT; 817 query_desc.Query = D3D11_QUERY_EVENT;
818 query_desc.MiscFlags = 0; 818 query_desc.MiscFlags = 0;
819 hr = d3d11_device_->CreateQuery( 819 hr = d3d11_device_->CreateQuery(
820 &query_desc, 820 &query_desc,
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 961
962 void DXVAVideoDecodeAccelerator::Reset() { 962 void DXVAVideoDecodeAccelerator::Reset() {
963 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 963 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
964 964
965 DVLOG(1) << "DXVAVideoDecodeAccelerator::Reset"; 965 DVLOG(1) << "DXVAVideoDecodeAccelerator::Reset";
966 966
967 State state = GetState(); 967 State state = GetState();
968 RETURN_AND_NOTIFY_ON_FAILURE((state == kNormal || state == kStopped), 968 RETURN_AND_NOTIFY_ON_FAILURE((state == kNormal || state == kStopped),
969 "Reset: invalid state: " << state, ILLEGAL_STATE,); 969 "Reset: invalid state: " << state, ILLEGAL_STATE,);
970 970
971 decoder_thread_.Stop(); 971 StopDecoderThread();
972 972
973 SetState(kResetting); 973 SetState(kResetting);
974 974
975 // If we have pending output frames waiting for display then we drop those 975 // If we have pending output frames waiting for display then we drop those
976 // frames and set the corresponding picture buffer as available. 976 // frames and set the corresponding picture buffer as available.
977 PendingOutputSamples::iterator index; 977 PendingOutputSamples::iterator index;
978 for (index = pending_output_samples_.begin(); 978 for (index = pending_output_samples_.begin();
979 index != pending_output_samples_.end(); 979 index != pending_output_samples_.end();
980 ++index) { 980 ++index) {
981 if (index->picture_buffer_id != -1) { 981 if (index->picture_buffer_id != -1) {
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
1491 client_ = NULL; 1491 client_ = NULL;
1492 1492
1493 if (GetState() != kUninitialized) { 1493 if (GetState() != kUninitialized) {
1494 Invalidate(); 1494 Invalidate();
1495 } 1495 }
1496 } 1496 }
1497 1497
1498 void DXVAVideoDecodeAccelerator::Invalidate() { 1498 void DXVAVideoDecodeAccelerator::Invalidate() {
1499 if (GetState() == kUninitialized) 1499 if (GetState() == kUninitialized)
1500 return; 1500 return;
1501 decoder_thread_.Stop(); 1501 StopDecoderThread();
1502 weak_this_factory_.InvalidateWeakPtrs(); 1502 weak_this_factory_.InvalidateWeakPtrs();
1503 output_picture_buffers_.clear(); 1503 output_picture_buffers_.clear();
1504 stale_output_picture_buffers_.clear(); 1504 stale_output_picture_buffers_.clear();
1505 pending_output_samples_.clear(); 1505 pending_output_samples_.clear();
1506 pending_input_buffers_.clear(); 1506 pending_input_buffers_.clear();
1507 decoder_.Release(); 1507 decoder_.Release();
1508 1508
1509 if (use_dx11_) { 1509 if (use_dx11_) {
1510 if (video_format_converter_mft_.get()) { 1510 if (video_format_converter_mft_.get()) {
1511 video_format_converter_mft_->ProcessMessage( 1511 video_format_converter_mft_->ProcessMessage(
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
2004 // TODO(ananta) 2004 // TODO(ananta)
2005 // Remove this CHECK when the change to use DX11 for H/W decoding 2005 // Remove this CHECK when the change to use DX11 for H/W decoding
2006 // stablizes. 2006 // stablizes.
2007 CHECK(false); 2007 CHECK(false);
2008 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2008 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2009 "Failed to create output sample.", PLATFORM_FAILURE,); 2009 "Failed to create output sample.", PLATFORM_FAILURE,);
2010 } 2010 }
2011 2011
2012 output_sample->AddBuffer(output_buffer.get()); 2012 output_sample->AddBuffer(output_buffer.get());
2013 2013
2014 // Lock the device here as we are accessing the destination texture created
2015 // on the main thread.
2016 CHECK(!dx11_device_locked_);
2017 dx11_device_locked_ = true;
2018 multi_threaded_->Enter();
2019
2014 DWORD status = 0; 2020 DWORD status = 0;
2015 MFT_OUTPUT_DATA_BUFFER format_converter_output = {}; 2021 MFT_OUTPUT_DATA_BUFFER format_converter_output = {};
2016 format_converter_output.pSample = output_sample.get(); 2022 format_converter_output.pSample = output_sample.get();
2017 hr = video_format_converter_mft_->ProcessOutput( 2023 hr = video_format_converter_mft_->ProcessOutput(
2018 0, // No flags 2024 0, // No flags
2019 1, // # of out streams to pull from 2025 1, // # of out streams to pull from
2020 &format_converter_output, 2026 &format_converter_output,
2021 &status); 2027 &status);
2022 2028
2023 d3d11_device_context_->Flush(); 2029 d3d11_device_context_->Flush();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2084 if ((hr == S_FALSE) && (++iterations < kMaxIterationsForD3DFlush)) { 2090 if ((hr == S_FALSE) && (++iterations < kMaxIterationsForD3DFlush)) {
2085 decoder_thread_task_runner_->PostDelayedTask( 2091 decoder_thread_task_runner_->PostDelayedTask(
2086 FROM_HERE, 2092 FROM_HERE,
2087 base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder, 2093 base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder,
2088 base::Unretained(this), iterations, src_surface, 2094 base::Unretained(this), iterations, src_surface,
2089 dest_surface, picture_buffer_id, input_buffer_id), 2095 dest_surface, picture_buffer_id, input_buffer_id),
2090 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs)); 2096 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs));
2091 return; 2097 return;
2092 } 2098 }
2093 2099
2100 dx11_device_locked_ = false;
2101 multi_threaded_->Leave();
2102
2094 main_thread_task_runner_->PostTask( 2103 main_thread_task_runner_->PostTask(
2095 FROM_HERE, 2104 FROM_HERE,
2096 base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, 2105 base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete,
2097 weak_this_factory_.GetWeakPtr(), 2106 weak_this_factory_.GetWeakPtr(),
2098 src_surface, 2107 src_surface,
2099 dest_surface, 2108 dest_surface,
2100 picture_buffer_id, 2109 picture_buffer_id,
2101 input_buffer_id)); 2110 input_buffer_id));
2102 } 2111 }
2103 2112
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 false); 2273 false);
2265 D3DSURFACE_DESC surface_desc; 2274 D3DSURFACE_DESC surface_desc;
2266 hr = surface->GetDesc(&surface_desc); 2275 hr = surface->GetDesc(&surface_desc);
2267 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false); 2276 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false);
2268 *width = surface_desc.Width; 2277 *width = surface_desc.Width;
2269 *height = surface_desc.Height; 2278 *height = surface_desc.Height;
2270 } 2279 }
2271 return true; 2280 return true;
2272 } 2281 }
2273 2282
2283 void DXVAVideoDecodeAccelerator::StopDecoderThread() {
2284 if (main_thread_task_runner_->BelongsToCurrentThread()) {
2285 if (decoder_thread_.IsRunning()) {
2286 decoder_thread_task_runner_->PostTask(
2287 FROM_HERE,
2288 base::Bind(&DXVAVideoDecodeAccelerator::StopDecoderThread,
2289 base::Unretained(this)));
2290 }
2291 decoder_thread_.Stop();
2292 return;
2293 }
2294
2295 if (dx11_device_locked_) {
2296 dx11_device_locked_ = false;
2297 multi_threaded_->Leave();
2298 }
2299 }
2300
2274 } // namespace content 2301 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/dxva_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698