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

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

Issue 1745903002: Introduce GpuVideoDecodeAcceleratorFactory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Instantiate GVDAFactoryImpl instead of GVDAFactory from content/common Created 4 years, 9 months 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
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_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 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo( 665 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo(
666 int32_t buffer_id, 666 int32_t buffer_id,
667 IMFSample* sample) 667 IMFSample* sample)
668 : input_buffer_id(buffer_id), picture_buffer_id(-1) { 668 : input_buffer_id(buffer_id), picture_buffer_id(-1) {
669 output_sample.Attach(sample); 669 output_sample.Attach(sample);
670 } 670 }
671 671
672 DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {} 672 DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {}
673 673
674 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( 674 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator(
675 const base::Callback<bool(void)>& make_context_current, 675 const GetGLContextCallback& get_gl_context_cb,
676 gfx::GLContext* gl_context, 676 const MakeGLContextCurrentCallback& make_context_current_cb,
677 bool enable_accelerated_vpx_decode) 677 bool enable_accelerated_vpx_decode)
678 : client_(NULL), 678 : client_(NULL),
679 dev_manager_reset_token_(0), 679 dev_manager_reset_token_(0),
680 dx11_dev_manager_reset_token_(0), 680 dx11_dev_manager_reset_token_(0),
681 egl_config_(NULL), 681 egl_config_(NULL),
682 state_(kUninitialized), 682 state_(kUninitialized),
683 pictures_requested_(false), 683 pictures_requested_(false),
684 inputs_before_decode_(0), 684 inputs_before_decode_(0),
685 sent_drain_message_(false), 685 sent_drain_message_(false),
686 make_context_current_(make_context_current), 686 get_gl_context_cb_(get_gl_context_cb),
687 make_context_current_cb_(make_context_current_cb),
687 codec_(media::kUnknownVideoCodec), 688 codec_(media::kUnknownVideoCodec),
688 decoder_thread_("DXVAVideoDecoderThread"), 689 decoder_thread_("DXVAVideoDecoderThread"),
689 pending_flush_(false), 690 pending_flush_(false),
690 use_dx11_(false), 691 use_dx11_(false),
691 use_keyed_mutex_(false), 692 use_keyed_mutex_(false),
692 dx11_video_format_converter_media_type_needs_init_(true), 693 dx11_video_format_converter_media_type_needs_init_(true),
693 gl_context_(gl_context),
694 using_angle_device_(false), 694 using_angle_device_(false),
695 enable_accelerated_vpx_decode_(enable_accelerated_vpx_decode), 695 enable_accelerated_vpx_decode_(enable_accelerated_vpx_decode),
696 weak_this_factory_(this) { 696 weak_this_factory_(this) {
697 weak_ptr_ = weak_this_factory_.GetWeakPtr(); 697 weak_ptr_ = weak_this_factory_.GetWeakPtr();
698 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); 698 memset(&input_stream_info_, 0, sizeof(input_stream_info_));
699 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); 699 memset(&output_stream_info_, 0, sizeof(output_stream_info_));
700 } 700 }
701 701
702 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { 702 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() {
703 client_ = NULL; 703 client_ = NULL;
704 } 704 }
705 705
706 bool DXVAVideoDecodeAccelerator::Initialize(const Config& config, 706 bool DXVAVideoDecodeAccelerator::Initialize(const Config& config,
707 Client* client) { 707 Client* client) {
708 if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) {
709 NOTREACHED() << "GL callbacks are required for this VDA";
710 return false;
711 }
712
708 if (config.is_encrypted) { 713 if (config.is_encrypted) {
709 NOTREACHED() << "Encrypted streams are not supported for this VDA"; 714 NOTREACHED() << "Encrypted streams are not supported for this VDA";
710 return false; 715 return false;
711 } 716 }
712 717
713 client_ = client; 718 client_ = client;
714 719
715 main_thread_task_runner_ = base::MessageLoop::current()->task_runner(); 720 main_thread_task_runner_ = base::MessageLoop::current()->task_runner();
716 721
717 bool profile_supported = false; 722 bool profile_supported = false;
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 "Failed to reuse picture buffer", 1063 "Failed to reuse picture buffer",
1059 PLATFORM_FAILURE, ); 1064 PLATFORM_FAILURE, );
1060 1065
1061 ProcessPendingSamples(); 1066 ProcessPendingSamples();
1062 if (pending_flush_) { 1067 if (pending_flush_) {
1063 decoder_thread_task_runner_->PostTask( 1068 decoder_thread_task_runner_->PostTask(
1064 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, 1069 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal,
1065 base::Unretained(this))); 1070 base::Unretained(this)));
1066 } 1071 }
1067 } else { 1072 } else {
1068 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), 1073 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
1069 "Failed to make context current", 1074 "Failed to make context current",
1070 PLATFORM_FAILURE, ); 1075 PLATFORM_FAILURE, );
1071 it->second->ResetReuseFence(); 1076 it->second->ResetReuseFence();
1072 1077
1073 WaitForOutputBuffer(picture_buffer_id, 0); 1078 WaitForOutputBuffer(picture_buffer_id, 0);
1074 } 1079 }
1075 } 1080 }
1076 1081
1077 void DXVAVideoDecodeAccelerator::WaitForOutputBuffer(int32_t picture_buffer_id, 1082 void DXVAVideoDecodeAccelerator::WaitForOutputBuffer(int32_t picture_buffer_id,
1078 int count) { 1083 int count) {
1079 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 1084 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
1080 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id); 1085 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id);
1081 if (it == output_picture_buffers_.end()) 1086 if (it == output_picture_buffers_.end())
1082 return; 1087 return;
1083 1088
1084 DXVAPictureBuffer* picture_buffer = it->second.get(); 1089 DXVAPictureBuffer* picture_buffer = it->second.get();
1085 1090
1086 DCHECK(!picture_buffer->available()); 1091 DCHECK(!picture_buffer->available());
1087 DCHECK(picture_buffer->waiting_to_reuse()); 1092 DCHECK(picture_buffer->waiting_to_reuse());
1088 1093
1089 gfx::GLFence* fence = picture_buffer->reuse_fence(); 1094 gfx::GLFence* fence = picture_buffer->reuse_fence();
1090 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), 1095 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
1091 "Failed to make context current", 1096 "Failed to make context current",
1092 PLATFORM_FAILURE, ); 1097 PLATFORM_FAILURE, );
1093 if (count <= kMaxIterationsForANGLEReuseFlush && !fence->HasCompleted()) { 1098 if (count <= kMaxIterationsForANGLEReuseFlush && !fence->HasCompleted()) {
1094 main_thread_task_runner_->PostDelayedTask( 1099 main_thread_task_runner_->PostDelayedTask(
1095 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::WaitForOutputBuffer, 1100 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::WaitForOutputBuffer,
1096 weak_this_factory_.GetWeakPtr(), 1101 weak_this_factory_.GetWeakPtr(),
1097 picture_buffer_id, count + 1), 1102 picture_buffer_id, count + 1),
1098 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs)); 1103 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs));
1099 return; 1104 return;
1100 } 1105 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 StartDecoderThread(); 1179 StartDecoderThread();
1175 SetState(kNormal); 1180 SetState(kNormal);
1176 } 1181 }
1177 1182
1178 void DXVAVideoDecodeAccelerator::Destroy() { 1183 void DXVAVideoDecodeAccelerator::Destroy() {
1179 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 1184 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
1180 Invalidate(); 1185 Invalidate();
1181 delete this; 1186 delete this;
1182 } 1187 }
1183 1188
1184 bool DXVAVideoDecodeAccelerator::CanDecodeOnIOThread() { 1189 bool DXVAVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
1190 const base::WeakPtr<Client>& decode_client,
1191 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
1185 return false; 1192 return false;
1186 } 1193 }
1187 1194
1188 GLenum DXVAVideoDecodeAccelerator::GetSurfaceInternalFormat() const { 1195 GLenum DXVAVideoDecodeAccelerator::GetSurfaceInternalFormat() const {
1189 return GL_BGRA_EXT; 1196 return GL_BGRA_EXT;
1190 } 1197 }
1191 1198
1192 // static 1199 // static
1193 media::VideoDecodeAccelerator::SupportedProfiles 1200 media::VideoDecodeAccelerator::SupportedProfiles
1194 DXVAVideoDecodeAccelerator::GetSupportedProfiles() { 1201 DXVAVideoDecodeAccelerator::GetSupportedProfiles() {
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1358 RETURN_ON_HR_FAILURE(hr, "Failed to enable DXVA H/W decoding", false); 1365 RETURN_ON_HR_FAILURE(hr, "Failed to enable DXVA H/W decoding", false);
1359 } 1366 }
1360 1367
1361 hr = attributes->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE); 1368 hr = attributes->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE);
1362 if (SUCCEEDED(hr)) { 1369 if (SUCCEEDED(hr)) {
1363 DVLOG(1) << "Successfully set Low latency mode on decoder."; 1370 DVLOG(1) << "Successfully set Low latency mode on decoder.";
1364 } else { 1371 } else {
1365 DVLOG(1) << "Failed to set Low latency mode on decoder. Error: " << hr; 1372 DVLOG(1) << "Failed to set Low latency mode on decoder. Error: " << hr;
1366 } 1373 }
1367 1374
1375 auto gl_context = get_gl_context_cb_.Run();
1376 RETURN_ON_FAILURE(gl_context, "Couldn't get GL context", false);
1377
1368 // The decoder should use DX11 iff 1378 // The decoder should use DX11 iff
1369 // 1. The underlying H/W decoder supports it. 1379 // 1. The underlying H/W decoder supports it.
1370 // 2. We have a pointer to the MFCreateDXGIDeviceManager function needed for 1380 // 2. We have a pointer to the MFCreateDXGIDeviceManager function needed for
1371 // this. This should always be true for Windows 8+. 1381 // this. This should always be true for Windows 8+.
1372 // 3. ANGLE is using DX11. 1382 // 3. ANGLE is using DX11.
1373 DCHECK(gl_context_);
1374 if (create_dxgi_device_manager_ && 1383 if (create_dxgi_device_manager_ &&
1375 (gl_context_->GetGLRenderer().find("Direct3D11") != 1384 (gl_context->GetGLRenderer().find("Direct3D11") != std::string::npos)) {
1376 std::string::npos)) {
1377 UINT32 dx11_aware = 0; 1385 UINT32 dx11_aware = 0;
1378 attributes->GetUINT32(MF_SA_D3D11_AWARE, &dx11_aware); 1386 attributes->GetUINT32(MF_SA_D3D11_AWARE, &dx11_aware);
1379 use_dx11_ = !!dx11_aware; 1387 use_dx11_ = !!dx11_aware;
1380 } 1388 }
1381 1389
1382 use_keyed_mutex_ = 1390 use_keyed_mutex_ =
1383 use_dx11_ && gfx::GLSurfaceEGL::HasEGLExtension("EGL_ANGLE_keyed_mutex"); 1391 use_dx11_ && gfx::GLSurfaceEGL::HasEGLExtension("EGL_ANGLE_keyed_mutex");
1384 1392
1385 return true; 1393 return true;
1386 } 1394 }
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1568 pictures_requested_ = true; 1576 pictures_requested_ = true;
1569 return true; 1577 return true;
1570 } 1578 }
1571 1579
1572 void DXVAVideoDecodeAccelerator::ProcessPendingSamples() { 1580 void DXVAVideoDecodeAccelerator::ProcessPendingSamples() {
1573 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 1581 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
1574 1582
1575 if (!output_picture_buffers_.size()) 1583 if (!output_picture_buffers_.size())
1576 return; 1584 return;
1577 1585
1578 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), 1586 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
1579 "Failed to make context current", PLATFORM_FAILURE,); 1587 "Failed to make context current",
1588 PLATFORM_FAILURE, );
1580 1589
1581 OutputBuffers::iterator index; 1590 OutputBuffers::iterator index;
1582 1591
1583 for (index = output_picture_buffers_.begin(); 1592 for (index = output_picture_buffers_.begin();
1584 index != output_picture_buffers_.end() && 1593 index != output_picture_buffers_.end() &&
1585 OutputSamplesPresent(); 1594 OutputSamplesPresent();
1586 ++index) { 1595 ++index) {
1587 if (index->second->available()) { 1596 if (index->second->available()) {
1588 PendingSampleInfo* pending_sample = NULL; 1597 PendingSampleInfo* pending_sample = NULL;
1589 { 1598 {
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
2067 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id); 2076 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id);
2068 if (it == output_picture_buffers_.end()) 2077 if (it == output_picture_buffers_.end())
2069 return; 2078 return;
2070 2079
2071 // If the picture buffer is marked as available it probably means that there 2080 // If the picture buffer is marked as available it probably means that there
2072 // was a Reset operation which dropped the output frame. 2081 // was a Reset operation which dropped the output frame.
2073 DXVAPictureBuffer* picture_buffer = it->second.get(); 2082 DXVAPictureBuffer* picture_buffer = it->second.get();
2074 if (picture_buffer->available()) 2083 if (picture_buffer->available())
2075 return; 2084 return;
2076 2085
2077 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), 2086 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
2078 "Failed to make context current", PLATFORM_FAILURE,); 2087 "Failed to make context current",
2088 PLATFORM_FAILURE, );
2079 2089
2080 DCHECK(!output_picture_buffers_.empty()); 2090 DCHECK(!output_picture_buffers_.empty());
2081 2091
2082 bool result = picture_buffer->CopySurfaceComplete(src_surface, dest_surface); 2092 bool result = picture_buffer->CopySurfaceComplete(src_surface, dest_surface);
2083 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface", 2093 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface",
2084 PLATFORM_FAILURE, ); 2094 PLATFORM_FAILURE, );
2085 2095
2086 NotifyPictureReady(picture_buffer->id(), input_buffer_id); 2096 NotifyPictureReady(picture_buffer->id(), input_buffer_id);
2087 2097
2088 { 2098 {
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
2448 hr = transform->SetOutputType(0, media_type.get(), 0); // No flags 2458 hr = transform->SetOutputType(0, media_type.get(), 0); // No flags
2449 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false); 2459 RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false);
2450 return true; 2460 return true;
2451 } 2461 }
2452 media_type.Release(); 2462 media_type.Release();
2453 } 2463 }
2454 return false; 2464 return false;
2455 } 2465 }
2456 2466
2457 } // namespace content 2467 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698