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

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

Powered by Google App Engine
This is Rietveld 408576698