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 |