| OLD | NEW |
| 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_win.h" | 5 #include "content/common/gpu/media/dxva_video_decode_accelerator_win.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 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo( | 644 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo( |
| 645 int32_t buffer_id, | 645 int32_t buffer_id, |
| 646 IMFSample* sample) | 646 IMFSample* sample) |
| 647 : input_buffer_id(buffer_id), picture_buffer_id(-1) { | 647 : input_buffer_id(buffer_id), picture_buffer_id(-1) { |
| 648 output_sample.Attach(sample); | 648 output_sample.Attach(sample); |
| 649 } | 649 } |
| 650 | 650 |
| 651 DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {} | 651 DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {} |
| 652 | 652 |
| 653 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( | 653 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( |
| 654 const base::Callback<bool(void)>& make_context_current, | 654 const gpu_vda_helpers::GetGLContextCb& get_gl_context_cb, |
| 655 gfx::GLContext* gl_context) | 655 const gpu_vda_helpers::MakeGLContextCurrentCb& make_context_current_cb) |
| 656 : client_(NULL), | 656 : client_(NULL), |
| 657 dev_manager_reset_token_(0), | 657 dev_manager_reset_token_(0), |
| 658 dx11_dev_manager_reset_token_(0), | 658 dx11_dev_manager_reset_token_(0), |
| 659 egl_config_(NULL), | 659 egl_config_(NULL), |
| 660 state_(kUninitialized), | 660 state_(kUninitialized), |
| 661 pictures_requested_(false), | 661 pictures_requested_(false), |
| 662 inputs_before_decode_(0), | 662 inputs_before_decode_(0), |
| 663 sent_drain_message_(false), | 663 sent_drain_message_(false), |
| 664 make_context_current_(make_context_current), | 664 get_gl_context_cb_(get_gl_context_cb), |
| 665 make_context_current_cb_(make_context_current_cb), |
| 665 codec_(media::kUnknownVideoCodec), | 666 codec_(media::kUnknownVideoCodec), |
| 666 decoder_thread_("DXVAVideoDecoderThread"), | 667 decoder_thread_("DXVAVideoDecoderThread"), |
| 667 pending_flush_(false), | 668 pending_flush_(false), |
| 668 use_dx11_(false), | 669 use_dx11_(false), |
| 669 use_keyed_mutex_(false), | 670 use_keyed_mutex_(false), |
| 670 dx11_video_format_converter_media_type_needs_init_(true), | 671 dx11_video_format_converter_media_type_needs_init_(true), |
| 671 gl_context_(gl_context), | |
| 672 using_angle_device_(false), | 672 using_angle_device_(false), |
| 673 weak_this_factory_(this) { | 673 weak_this_factory_(this) { |
| 674 DCHECK(!get_gl_context_cb_.is_null()); |
| 674 weak_ptr_ = weak_this_factory_.GetWeakPtr(); | 675 weak_ptr_ = weak_this_factory_.GetWeakPtr(); |
| 675 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); | 676 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); |
| 676 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); | 677 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); |
| 677 } | 678 } |
| 678 | 679 |
| 679 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { | 680 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { |
| 680 client_ = NULL; | 681 client_ = NULL; |
| 681 } | 682 } |
| 682 | 683 |
| 683 bool DXVAVideoDecodeAccelerator::Initialize(const Config& config, | 684 bool DXVAVideoDecodeAccelerator::Initialize(const Config& config, |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1099 StartDecoderThread(); | 1100 StartDecoderThread(); |
| 1100 SetState(kNormal); | 1101 SetState(kNormal); |
| 1101 } | 1102 } |
| 1102 | 1103 |
| 1103 void DXVAVideoDecodeAccelerator::Destroy() { | 1104 void DXVAVideoDecodeAccelerator::Destroy() { |
| 1104 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); | 1105 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
| 1105 Invalidate(); | 1106 Invalidate(); |
| 1106 delete this; | 1107 delete this; |
| 1107 } | 1108 } |
| 1108 | 1109 |
| 1109 bool DXVAVideoDecodeAccelerator::CanDecodeOnIOThread() { | 1110 bool DXVAVideoDecodeAccelerator::TryInitializeDecodeOnSeparateThread( |
| 1111 const base::WeakPtr<Client>& decode_client, |
| 1112 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { |
| 1110 return false; | 1113 return false; |
| 1111 } | 1114 } |
| 1112 | 1115 |
| 1113 GLenum DXVAVideoDecodeAccelerator::GetSurfaceInternalFormat() const { | 1116 GLenum DXVAVideoDecodeAccelerator::GetSurfaceInternalFormat() const { |
| 1114 return GL_BGRA_EXT; | 1117 return GL_BGRA_EXT; |
| 1115 } | 1118 } |
| 1116 | 1119 |
| 1117 // static | 1120 // static |
| 1118 media::VideoDecodeAccelerator::SupportedProfiles | 1121 media::VideoDecodeAccelerator::SupportedProfiles |
| 1119 DXVAVideoDecodeAccelerator::GetSupportedProfiles() { | 1122 DXVAVideoDecodeAccelerator::GetSupportedProfiles() { |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1284 RETURN_ON_HR_FAILURE(hr, "Failed to enable DXVA H/W decoding", false); | 1287 RETURN_ON_HR_FAILURE(hr, "Failed to enable DXVA H/W decoding", false); |
| 1285 } | 1288 } |
| 1286 | 1289 |
| 1287 hr = attributes->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE); | 1290 hr = attributes->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE); |
| 1288 if (SUCCEEDED(hr)) { | 1291 if (SUCCEEDED(hr)) { |
| 1289 DVLOG(1) << "Successfully set Low latency mode on decoder."; | 1292 DVLOG(1) << "Successfully set Low latency mode on decoder."; |
| 1290 } else { | 1293 } else { |
| 1291 DVLOG(1) << "Failed to set Low latency mode on decoder. Error: " << hr; | 1294 DVLOG(1) << "Failed to set Low latency mode on decoder. Error: " << hr; |
| 1292 } | 1295 } |
| 1293 | 1296 |
| 1297 auto gl_context = get_gl_context_cb_.Run(); |
| 1298 RETURN_ON_FAILURE(gl_context, "Couldn't get GL context", false); |
| 1299 |
| 1294 // The decoder should use DX11 iff | 1300 // The decoder should use DX11 iff |
| 1295 // 1. The underlying H/W decoder supports it. | 1301 // 1. The underlying H/W decoder supports it. |
| 1296 // 2. We have a pointer to the MFCreateDXGIDeviceManager function needed for | 1302 // 2. We have a pointer to the MFCreateDXGIDeviceManager function needed for |
| 1297 // this. This should always be true for Windows 8+. | 1303 // this. This should always be true for Windows 8+. |
| 1298 // 3. ANGLE is using DX11. | 1304 // 3. ANGLE is using DX11. |
| 1299 DCHECK(gl_context_); | |
| 1300 if (create_dxgi_device_manager_ && | 1305 if (create_dxgi_device_manager_ && |
| 1301 (gl_context_->GetGLRenderer().find("Direct3D11") != | 1306 (gl_context->GetGLRenderer().find("Direct3D11") != std::string::npos)) { |
| 1302 std::string::npos)) { | |
| 1303 UINT32 dx11_aware = 0; | 1307 UINT32 dx11_aware = 0; |
| 1304 attributes->GetUINT32(MF_SA_D3D11_AWARE, &dx11_aware); | 1308 attributes->GetUINT32(MF_SA_D3D11_AWARE, &dx11_aware); |
| 1305 use_dx11_ = !!dx11_aware; | 1309 use_dx11_ = !!dx11_aware; |
| 1306 } | 1310 } |
| 1307 | 1311 |
| 1308 use_keyed_mutex_ = | 1312 use_keyed_mutex_ = |
| 1309 use_dx11_ && gfx::GLSurfaceEGL::HasEGLExtension("EGL_ANGLE_keyed_mutex"); | 1313 use_dx11_ && gfx::GLSurfaceEGL::HasEGLExtension("EGL_ANGLE_keyed_mutex"); |
| 1310 | 1314 |
| 1311 return true; | 1315 return true; |
| 1312 } | 1316 } |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1494 pictures_requested_ = true; | 1498 pictures_requested_ = true; |
| 1495 return true; | 1499 return true; |
| 1496 } | 1500 } |
| 1497 | 1501 |
| 1498 void DXVAVideoDecodeAccelerator::ProcessPendingSamples() { | 1502 void DXVAVideoDecodeAccelerator::ProcessPendingSamples() { |
| 1499 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); | 1503 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
| 1500 | 1504 |
| 1501 if (!output_picture_buffers_.size()) | 1505 if (!output_picture_buffers_.size()) |
| 1502 return; | 1506 return; |
| 1503 | 1507 |
| 1504 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), | 1508 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), |
| 1505 "Failed to make context current", PLATFORM_FAILURE,); | 1509 "Failed to make context current", |
| 1510 PLATFORM_FAILURE, ); |
| 1506 | 1511 |
| 1507 OutputBuffers::iterator index; | 1512 OutputBuffers::iterator index; |
| 1508 | 1513 |
| 1509 for (index = output_picture_buffers_.begin(); | 1514 for (index = output_picture_buffers_.begin(); |
| 1510 index != output_picture_buffers_.end() && | 1515 index != output_picture_buffers_.end() && |
| 1511 OutputSamplesPresent(); | 1516 OutputSamplesPresent(); |
| 1512 ++index) { | 1517 ++index) { |
| 1513 if (index->second->available()) { | 1518 if (index->second->available()) { |
| 1514 PendingSampleInfo* pending_sample = NULL; | 1519 PendingSampleInfo* pending_sample = NULL; |
| 1515 { | 1520 { |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1993 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id); | 1998 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id); |
| 1994 if (it == output_picture_buffers_.end()) | 1999 if (it == output_picture_buffers_.end()) |
| 1995 return; | 2000 return; |
| 1996 | 2001 |
| 1997 // If the picture buffer is marked as available it probably means that there | 2002 // If the picture buffer is marked as available it probably means that there |
| 1998 // was a Reset operation which dropped the output frame. | 2003 // was a Reset operation which dropped the output frame. |
| 1999 DXVAPictureBuffer* picture_buffer = it->second.get(); | 2004 DXVAPictureBuffer* picture_buffer = it->second.get(); |
| 2000 if (picture_buffer->available()) | 2005 if (picture_buffer->available()) |
| 2001 return; | 2006 return; |
| 2002 | 2007 |
| 2003 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), | 2008 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), |
| 2004 "Failed to make context current", PLATFORM_FAILURE,); | 2009 "Failed to make context current", |
| 2010 PLATFORM_FAILURE, ); |
| 2005 | 2011 |
| 2006 DCHECK(!output_picture_buffers_.empty()); | 2012 DCHECK(!output_picture_buffers_.empty()); |
| 2007 | 2013 |
| 2008 bool result = picture_buffer->CopySurfaceComplete(src_surface, dest_surface); | 2014 bool result = picture_buffer->CopySurfaceComplete(src_surface, dest_surface); |
| 2009 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface", | 2015 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface", |
| 2010 PLATFORM_FAILURE, ); | 2016 PLATFORM_FAILURE, ); |
| 2011 | 2017 |
| 2012 NotifyPictureReady(picture_buffer->id(), input_buffer_id); | 2018 NotifyPictureReady(picture_buffer->id(), input_buffer_id); |
| 2013 | 2019 |
| 2014 { | 2020 { |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2380 } | 2386 } |
| 2381 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false); | 2387 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false); |
| 2382 return true; | 2388 return true; |
| 2383 } | 2389 } |
| 2384 media_type.Release(); | 2390 media_type.Release(); |
| 2385 } | 2391 } |
| 2386 return false; | 2392 return false; |
| 2387 } | 2393 } |
| 2388 | 2394 |
| 2389 } // namespace content | 2395 } // namespace content |
| OLD | NEW |