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

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

Issue 1839193003: Reland: Introduce GpuVideoDecodeAcceleratorFactory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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 797 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo( 808 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo(
809 int32_t buffer_id, 809 int32_t buffer_id,
810 IMFSample* sample) 810 IMFSample* sample)
811 : input_buffer_id(buffer_id), picture_buffer_id(-1) { 811 : input_buffer_id(buffer_id), picture_buffer_id(-1) {
812 output_sample.Attach(sample); 812 output_sample.Attach(sample);
813 } 813 }
814 814
815 DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {} 815 DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {}
816 816
817 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( 817 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator(
818 const base::Callback<bool(void)>& make_context_current, 818 const GetGLContextCallback& get_gl_context_cb,
819 gfx::GLContext* gl_context, 819 const MakeGLContextCurrentCallback& make_context_current_cb,
820 bool enable_accelerated_vpx_decode) 820 bool enable_accelerated_vpx_decode)
821 : client_(NULL), 821 : client_(NULL),
822 dev_manager_reset_token_(0), 822 dev_manager_reset_token_(0),
823 dx11_dev_manager_reset_token_(0), 823 dx11_dev_manager_reset_token_(0),
824 egl_config_(NULL), 824 egl_config_(NULL),
825 state_(kUninitialized), 825 state_(kUninitialized),
826 pictures_requested_(false), 826 pictures_requested_(false),
827 inputs_before_decode_(0), 827 inputs_before_decode_(0),
828 sent_drain_message_(false), 828 sent_drain_message_(false),
829 make_context_current_(make_context_current), 829 get_gl_context_cb_(get_gl_context_cb),
830 make_context_current_cb_(make_context_current_cb),
830 codec_(media::kUnknownVideoCodec), 831 codec_(media::kUnknownVideoCodec),
831 decoder_thread_("DXVAVideoDecoderThread"), 832 decoder_thread_("DXVAVideoDecoderThread"),
832 pending_flush_(false), 833 pending_flush_(false),
833 use_dx11_(false), 834 use_dx11_(false),
834 use_keyed_mutex_(false), 835 use_keyed_mutex_(false),
835 dx11_video_format_converter_media_type_needs_init_(true), 836 dx11_video_format_converter_media_type_needs_init_(true),
836 gl_context_(gl_context),
837 using_angle_device_(false), 837 using_angle_device_(false),
838 enable_accelerated_vpx_decode_(enable_accelerated_vpx_decode), 838 enable_accelerated_vpx_decode_(enable_accelerated_vpx_decode),
839 weak_this_factory_(this) { 839 weak_this_factory_(this) {
840 weak_ptr_ = weak_this_factory_.GetWeakPtr(); 840 weak_ptr_ = weak_this_factory_.GetWeakPtr();
841 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); 841 memset(&input_stream_info_, 0, sizeof(input_stream_info_));
842 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); 842 memset(&output_stream_info_, 0, sizeof(output_stream_info_));
843 } 843 }
844 844
845 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { 845 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() {
846 client_ = NULL; 846 client_ = NULL;
847 } 847 }
848 848
849 bool DXVAVideoDecodeAccelerator::Initialize(const Config& config, 849 bool DXVAVideoDecodeAccelerator::Initialize(const Config& config,
850 Client* client) { 850 Client* client) {
851 if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) {
852 NOTREACHED() << "GL callbacks are required for this VDA";
853 return false;
854 }
855
851 if (config.is_encrypted) { 856 if (config.is_encrypted) {
852 NOTREACHED() << "Encrypted streams are not supported for this VDA"; 857 NOTREACHED() << "Encrypted streams are not supported for this VDA";
853 return false; 858 return false;
854 } 859 }
855 860
856 client_ = client; 861 client_ = client;
857 862
858 main_thread_task_runner_ = base::MessageLoop::current()->task_runner(); 863 main_thread_task_runner_ = base::MessageLoop::current()->task_runner();
859 864
860 bool profile_supported = false; 865 bool profile_supported = false;
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 "Failed to reuse picture buffer", 1212 "Failed to reuse picture buffer",
1208 PLATFORM_FAILURE, ); 1213 PLATFORM_FAILURE, );
1209 1214
1210 ProcessPendingSamples(); 1215 ProcessPendingSamples();
1211 if (pending_flush_) { 1216 if (pending_flush_) {
1212 decoder_thread_task_runner_->PostTask( 1217 decoder_thread_task_runner_->PostTask(
1213 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, 1218 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal,
1214 base::Unretained(this))); 1219 base::Unretained(this)));
1215 } 1220 }
1216 } else { 1221 } else {
1217 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), 1222 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
1218 "Failed to make context current", 1223 "Failed to make context current",
1219 PLATFORM_FAILURE, ); 1224 PLATFORM_FAILURE, );
1220 it->second->ResetReuseFence(); 1225 it->second->ResetReuseFence();
1221 1226
1222 WaitForOutputBuffer(picture_buffer_id, 0); 1227 WaitForOutputBuffer(picture_buffer_id, 0);
1223 } 1228 }
1224 } 1229 }
1225 1230
1226 void DXVAVideoDecodeAccelerator::WaitForOutputBuffer(int32_t picture_buffer_id, 1231 void DXVAVideoDecodeAccelerator::WaitForOutputBuffer(int32_t picture_buffer_id,
1227 int count) { 1232 int count) {
1228 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 1233 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
1229 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id); 1234 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id);
1230 if (it == output_picture_buffers_.end()) 1235 if (it == output_picture_buffers_.end())
1231 return; 1236 return;
1232 1237
1233 DXVAPictureBuffer* picture_buffer = it->second.get(); 1238 DXVAPictureBuffer* picture_buffer = it->second.get();
1234 1239
1235 DCHECK(!picture_buffer->available()); 1240 DCHECK(!picture_buffer->available());
1236 DCHECK(picture_buffer->waiting_to_reuse()); 1241 DCHECK(picture_buffer->waiting_to_reuse());
1237 1242
1238 gfx::GLFence* fence = picture_buffer->reuse_fence(); 1243 gfx::GLFence* fence = picture_buffer->reuse_fence();
1239 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), 1244 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
1240 "Failed to make context current", 1245 "Failed to make context current",
1241 PLATFORM_FAILURE, ); 1246 PLATFORM_FAILURE, );
1242 if (count <= kMaxIterationsForANGLEReuseFlush && !fence->HasCompleted()) { 1247 if (count <= kMaxIterationsForANGLEReuseFlush && !fence->HasCompleted()) {
1243 main_thread_task_runner_->PostDelayedTask( 1248 main_thread_task_runner_->PostDelayedTask(
1244 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::WaitForOutputBuffer, 1249 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::WaitForOutputBuffer,
1245 weak_this_factory_.GetWeakPtr(), 1250 weak_this_factory_.GetWeakPtr(),
1246 picture_buffer_id, count + 1), 1251 picture_buffer_id, count + 1),
1247 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs)); 1252 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs));
1248 return; 1253 return;
1249 } 1254 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 StartDecoderThread(); 1328 StartDecoderThread();
1324 SetState(kNormal); 1329 SetState(kNormal);
1325 } 1330 }
1326 1331
1327 void DXVAVideoDecodeAccelerator::Destroy() { 1332 void DXVAVideoDecodeAccelerator::Destroy() {
1328 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 1333 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
1329 Invalidate(); 1334 Invalidate();
1330 delete this; 1335 delete this;
1331 } 1336 }
1332 1337
1333 bool DXVAVideoDecodeAccelerator::CanDecodeOnIOThread() { 1338 bool DXVAVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
1339 const base::WeakPtr<Client>& decode_client,
1340 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
1334 return false; 1341 return false;
1335 } 1342 }
1336 1343
1337 GLenum DXVAVideoDecodeAccelerator::GetSurfaceInternalFormat() const { 1344 GLenum DXVAVideoDecodeAccelerator::GetSurfaceInternalFormat() const {
1338 return GL_BGRA_EXT; 1345 return GL_BGRA_EXT;
1339 } 1346 }
1340 1347
1341 // static 1348 // static
1342 media::VideoDecodeAccelerator::SupportedProfiles 1349 media::VideoDecodeAccelerator::SupportedProfiles
1343 DXVAVideoDecodeAccelerator::GetSupportedProfiles() { 1350 DXVAVideoDecodeAccelerator::GetSupportedProfiles() {
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1507 RETURN_ON_HR_FAILURE(hr, "Failed to enable DXVA H/W decoding", false); 1514 RETURN_ON_HR_FAILURE(hr, "Failed to enable DXVA H/W decoding", false);
1508 } 1515 }
1509 1516
1510 hr = attributes->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE); 1517 hr = attributes->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE);
1511 if (SUCCEEDED(hr)) { 1518 if (SUCCEEDED(hr)) {
1512 DVLOG(1) << "Successfully set Low latency mode on decoder."; 1519 DVLOG(1) << "Successfully set Low latency mode on decoder.";
1513 } else { 1520 } else {
1514 DVLOG(1) << "Failed to set Low latency mode on decoder. Error: " << hr; 1521 DVLOG(1) << "Failed to set Low latency mode on decoder. Error: " << hr;
1515 } 1522 }
1516 1523
1524 auto gl_context = get_gl_context_cb_.Run();
1525 RETURN_ON_FAILURE(gl_context, "Couldn't get GL context", false);
1526
1517 // The decoder should use DX11 iff 1527 // The decoder should use DX11 iff
1518 // 1. The underlying H/W decoder supports it. 1528 // 1. The underlying H/W decoder supports it.
1519 // 2. We have a pointer to the MFCreateDXGIDeviceManager function needed for 1529 // 2. We have a pointer to the MFCreateDXGIDeviceManager function needed for
1520 // this. This should always be true for Windows 8+. 1530 // this. This should always be true for Windows 8+.
1521 // 3. ANGLE is using DX11. 1531 // 3. ANGLE is using DX11.
1522 DCHECK(gl_context_);
1523 if (create_dxgi_device_manager_ && 1532 if (create_dxgi_device_manager_ &&
1524 (gl_context_->GetGLRenderer().find("Direct3D11") != 1533 (gl_context->GetGLRenderer().find("Direct3D11") != std::string::npos)) {
1525 std::string::npos)) {
1526 UINT32 dx11_aware = 0; 1534 UINT32 dx11_aware = 0;
1527 attributes->GetUINT32(MF_SA_D3D11_AWARE, &dx11_aware); 1535 attributes->GetUINT32(MF_SA_D3D11_AWARE, &dx11_aware);
1528 use_dx11_ = !!dx11_aware; 1536 use_dx11_ = !!dx11_aware;
1529 } 1537 }
1530 1538
1531 use_keyed_mutex_ = 1539 use_keyed_mutex_ =
1532 use_dx11_ && gfx::GLSurfaceEGL::HasEGLExtension("EGL_ANGLE_keyed_mutex"); 1540 use_dx11_ && gfx::GLSurfaceEGL::HasEGLExtension("EGL_ANGLE_keyed_mutex");
1533 1541
1534 return true; 1542 return true;
1535 } 1543 }
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1717 pictures_requested_ = true; 1725 pictures_requested_ = true;
1718 return true; 1726 return true;
1719 } 1727 }
1720 1728
1721 void DXVAVideoDecodeAccelerator::ProcessPendingSamples() { 1729 void DXVAVideoDecodeAccelerator::ProcessPendingSamples() {
1722 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 1730 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
1723 1731
1724 if (!output_picture_buffers_.size()) 1732 if (!output_picture_buffers_.size())
1725 return; 1733 return;
1726 1734
1727 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), 1735 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
1728 "Failed to make context current", PLATFORM_FAILURE,); 1736 "Failed to make context current",
1737 PLATFORM_FAILURE, );
1729 1738
1730 OutputBuffers::iterator index; 1739 OutputBuffers::iterator index;
1731 1740
1732 for (index = output_picture_buffers_.begin(); 1741 for (index = output_picture_buffers_.begin();
1733 index != output_picture_buffers_.end() && 1742 index != output_picture_buffers_.end() &&
1734 OutputSamplesPresent(); 1743 OutputSamplesPresent();
1735 ++index) { 1744 ++index) {
1736 if (index->second->available()) { 1745 if (index->second->available()) {
1737 PendingSampleInfo* pending_sample = NULL; 1746 PendingSampleInfo* pending_sample = NULL;
1738 { 1747 {
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
2241 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id); 2250 OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id);
2242 if (it == output_picture_buffers_.end()) 2251 if (it == output_picture_buffers_.end())
2243 return; 2252 return;
2244 2253
2245 // If the picture buffer is marked as available it probably means that there 2254 // If the picture buffer is marked as available it probably means that there
2246 // was a Reset operation which dropped the output frame. 2255 // was a Reset operation which dropped the output frame.
2247 DXVAPictureBuffer* picture_buffer = it->second.get(); 2256 DXVAPictureBuffer* picture_buffer = it->second.get();
2248 if (picture_buffer->available()) 2257 if (picture_buffer->available())
2249 return; 2258 return;
2250 2259
2251 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), 2260 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
2252 "Failed to make context current", PLATFORM_FAILURE,); 2261 "Failed to make context current",
2262 PLATFORM_FAILURE, );
2253 2263
2254 DCHECK(!output_picture_buffers_.empty()); 2264 DCHECK(!output_picture_buffers_.empty());
2255 2265
2256 bool result = picture_buffer->CopySurfaceComplete(src_surface, dest_surface); 2266 bool result = picture_buffer->CopySurfaceComplete(src_surface, dest_surface);
2257 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface", 2267 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface",
2258 PLATFORM_FAILURE, ); 2268 PLATFORM_FAILURE, );
2259 2269
2260 NotifyPictureReady(picture_buffer->id(), input_buffer_id); 2270 NotifyPictureReady(picture_buffer->id(), input_buffer_id);
2261 2271
2262 { 2272 {
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
2656 DismissStaleBuffers(true); 2666 DismissStaleBuffers(true);
2657 Invalidate(); 2667 Invalidate();
2658 Initialize(config_, client_); 2668 Initialize(config_, client_);
2659 decoder_thread_task_runner_->PostTask( 2669 decoder_thread_task_runner_->PostTask(
2660 FROM_HERE, 2670 FROM_HERE,
2661 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, 2671 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers,
2662 base::Unretained(this))); 2672 base::Unretained(this)));
2663 } 2673 }
2664 2674
2665 } // namespace content 2675 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698