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

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

Powered by Google App Engine
This is Rietveld 408576698