| 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 "media/gpu/dxva_video_decode_accelerator_win.h" | 5 #include "media/gpu/dxva_video_decode_accelerator_win.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #if !defined(OS_WIN) | 9 #if !defined(OS_WIN) |
| 10 #error This file should only be built on Windows. | 10 #error This file should only be built on Windows. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 #include "gpu/command_buffer/service/gpu_preferences.h" | 44 #include "gpu/command_buffer/service/gpu_preferences.h" |
| 45 #include "gpu/config/gpu_driver_bug_workarounds.h" | 45 #include "gpu/config/gpu_driver_bug_workarounds.h" |
| 46 #include "media/base/media_switches.h" | 46 #include "media/base/media_switches.h" |
| 47 #include "media/base/win/mf_helpers.h" | 47 #include "media/base/win/mf_helpers.h" |
| 48 #include "media/base/win/mf_initializer.h" | 48 #include "media/base/win/mf_initializer.h" |
| 49 #include "media/gpu/dxva_picture_buffer_win.h" | 49 #include "media/gpu/dxva_picture_buffer_win.h" |
| 50 #include "media/video/video_decode_accelerator.h" | 50 #include "media/video/video_decode_accelerator.h" |
| 51 #include "third_party/angle/include/EGL/egl.h" | 51 #include "third_party/angle/include/EGL/egl.h" |
| 52 #include "third_party/angle/include/EGL/eglext.h" | 52 #include "third_party/angle/include/EGL/eglext.h" |
| 53 #include "ui/gfx/color_space_win.h" | 53 #include "ui/gfx/color_space_win.h" |
| 54 #include "ui/gl/gl_angle_util_win.h" |
| 54 #include "ui/gl/gl_bindings.h" | 55 #include "ui/gl/gl_bindings.h" |
| 55 #include "ui/gl/gl_context.h" | 56 #include "ui/gl/gl_context.h" |
| 56 #include "ui/gl/gl_fence.h" | 57 #include "ui/gl/gl_fence.h" |
| 57 #include "ui/gl/gl_surface_egl.h" | 58 #include "ui/gl/gl_surface_egl.h" |
| 58 | 59 |
| 59 namespace { | 60 namespace { |
| 60 | 61 |
| 61 // AMD | 62 // AMD |
| 62 // Path is appended on to the PROGRAM_FILES base path. | 63 // Path is appended on to the PROGRAM_FILES base path. |
| 63 const wchar_t kAMDVPXDecoderDLLPath[] = | 64 const wchar_t kAMDVPXDecoderDLLPath[] = |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 | 319 |
| 319 base::win::ScopedComPtr<IClassFactory> factory; | 320 base::win::ScopedComPtr<IClassFactory> factory; |
| 320 HRESULT hr = | 321 HRESULT hr = |
| 321 get_class_object(clsid, __uuidof(IClassFactory), factory.ReceiveVoid()); | 322 get_class_object(clsid, __uuidof(IClassFactory), factory.ReceiveVoid()); |
| 322 RETURN_ON_HR_FAILURE(hr, "DllGetClassObject failed", hr); | 323 RETURN_ON_HR_FAILURE(hr, "DllGetClassObject failed", hr); |
| 323 | 324 |
| 324 hr = factory->CreateInstance(NULL, iid, object); | 325 hr = factory->CreateInstance(NULL, iid, object); |
| 325 return hr; | 326 return hr; |
| 326 } | 327 } |
| 327 | 328 |
| 328 // Helper function to query the ANGLE device object. The template argument T | |
| 329 // identifies the device interface being queried. IDirect3DDevice9Ex for d3d9 | |
| 330 // and ID3D11Device for dx11. | |
| 331 template <class T> | |
| 332 base::win::ScopedComPtr<T> QueryDeviceObjectFromANGLE(int object_type) { | |
| 333 base::win::ScopedComPtr<T> device_object; | |
| 334 | |
| 335 EGLDisplay egl_display = nullptr; | |
| 336 intptr_t egl_device = 0; | |
| 337 intptr_t device = 0; | |
| 338 | |
| 339 { | |
| 340 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. GetHardwareDisplay"); | |
| 341 egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); | |
| 342 } | |
| 343 | |
| 344 RETURN_ON_FAILURE(gl::GLSurfaceEGL::HasEGLExtension("EGL_EXT_device_query"), | |
| 345 "EGL_EXT_device_query missing", device_object); | |
| 346 | |
| 347 PFNEGLQUERYDISPLAYATTRIBEXTPROC QueryDisplayAttribEXT = nullptr; | |
| 348 | |
| 349 { | |
| 350 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. eglGetProcAddress"); | |
| 351 | |
| 352 QueryDisplayAttribEXT = reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>( | |
| 353 eglGetProcAddress("eglQueryDisplayAttribEXT")); | |
| 354 | |
| 355 RETURN_ON_FAILURE( | |
| 356 QueryDisplayAttribEXT, | |
| 357 "Failed to get the eglQueryDisplayAttribEXT function from ANGLE", | |
| 358 device_object); | |
| 359 } | |
| 360 | |
| 361 PFNEGLQUERYDEVICEATTRIBEXTPROC QueryDeviceAttribEXT = nullptr; | |
| 362 | |
| 363 { | |
| 364 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. eglGetProcAddress"); | |
| 365 | |
| 366 QueryDeviceAttribEXT = reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>( | |
| 367 eglGetProcAddress("eglQueryDeviceAttribEXT")); | |
| 368 | |
| 369 RETURN_ON_FAILURE( | |
| 370 QueryDeviceAttribEXT, | |
| 371 "Failed to get the eglQueryDeviceAttribEXT function from ANGLE", | |
| 372 device_object); | |
| 373 } | |
| 374 | |
| 375 { | |
| 376 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. QueryDisplayAttribEXT"); | |
| 377 | |
| 378 RETURN_ON_FAILURE( | |
| 379 QueryDisplayAttribEXT(egl_display, EGL_DEVICE_EXT, &egl_device), | |
| 380 "The eglQueryDisplayAttribEXT function failed to get the EGL device", | |
| 381 device_object); | |
| 382 } | |
| 383 | |
| 384 RETURN_ON_FAILURE(egl_device, "Failed to get the EGL device", device_object); | |
| 385 | |
| 386 { | |
| 387 TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. QueryDisplayAttribEXT"); | |
| 388 | |
| 389 RETURN_ON_FAILURE( | |
| 390 QueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(egl_device), | |
| 391 object_type, &device), | |
| 392 "The eglQueryDeviceAttribEXT function failed to get the device", | |
| 393 device_object); | |
| 394 | |
| 395 RETURN_ON_FAILURE(device, "Failed to get the ANGLE device", device_object); | |
| 396 } | |
| 397 | |
| 398 device_object = reinterpret_cast<T*>(device); | |
| 399 return device_object; | |
| 400 } | |
| 401 | |
| 402 H264ConfigChangeDetector::H264ConfigChangeDetector() | 329 H264ConfigChangeDetector::H264ConfigChangeDetector() |
| 403 : last_sps_id_(0), | 330 : last_sps_id_(0), |
| 404 last_pps_id_(0), | 331 last_pps_id_(0), |
| 405 config_changed_(false), | 332 config_changed_(false), |
| 406 pending_config_changed_(false) {} | 333 pending_config_changed_(false) {} |
| 407 | 334 |
| 408 H264ConfigChangeDetector::~H264ConfigChangeDetector() {} | 335 H264ConfigChangeDetector::~H264ConfigChangeDetector() {} |
| 409 | 336 |
| 410 bool H264ConfigChangeDetector::DetectConfig(const uint8_t* stream, | 337 bool H264ConfigChangeDetector::DetectConfig(const uint8_t* stream, |
| 411 unsigned int size) { | 338 unsigned int size) { |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 hr = Direct3DCreate9Ex(D3D_SDK_VERSION, d3d9_.Receive()); | 627 hr = Direct3DCreate9Ex(D3D_SDK_VERSION, d3d9_.Receive()); |
| 701 RETURN_ON_HR_FAILURE(hr, "Direct3DCreate9Ex failed", false); | 628 RETURN_ON_HR_FAILURE(hr, "Direct3DCreate9Ex failed", false); |
| 702 | 629 |
| 703 hr = d3d9_->CheckDeviceFormatConversion( | 630 hr = d3d9_->CheckDeviceFormatConversion( |
| 704 D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, | 631 D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, |
| 705 static_cast<D3DFORMAT>(MAKEFOURCC('N', 'V', '1', '2')), D3DFMT_X8R8G8B8); | 632 static_cast<D3DFORMAT>(MAKEFOURCC('N', 'V', '1', '2')), D3DFMT_X8R8G8B8); |
| 706 RETURN_ON_HR_FAILURE(hr, "D3D9 driver does not support H/W format conversion", | 633 RETURN_ON_HR_FAILURE(hr, "D3D9 driver does not support H/W format conversion", |
| 707 false); | 634 false); |
| 708 | 635 |
| 709 base::win::ScopedComPtr<IDirect3DDevice9> angle_device = | 636 base::win::ScopedComPtr<IDirect3DDevice9> angle_device = |
| 710 QueryDeviceObjectFromANGLE<IDirect3DDevice9>(EGL_D3D9_DEVICE_ANGLE); | 637 gl::QueryD3D9DeviceObjectFromANGLE(); |
| 711 if (angle_device.get()) | 638 if (angle_device.get()) |
| 712 using_angle_device_ = true; | 639 using_angle_device_ = true; |
| 713 | 640 |
| 714 if (using_angle_device_) { | 641 if (using_angle_device_) { |
| 715 hr = d3d9_device_ex_.QueryFrom(angle_device.get()); | 642 hr = d3d9_device_ex_.QueryFrom(angle_device.get()); |
| 716 RETURN_ON_HR_FAILURE( | 643 RETURN_ON_HR_FAILURE( |
| 717 hr, "QueryInterface for IDirect3DDevice9Ex from angle device failed", | 644 hr, "QueryInterface for IDirect3DDevice9Ex from angle device failed", |
| 718 false); | 645 false); |
| 719 } else { | 646 } else { |
| 720 D3DPRESENT_PARAMETERS present_params = {0}; | 647 D3DPRESENT_PARAMETERS present_params = {0}; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 } | 767 } |
| 841 | 768 |
| 842 bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() { | 769 bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() { |
| 843 // The device may exist if the last state was a config change. | 770 // The device may exist if the last state was a config change. |
| 844 if (d3d11_device_.get()) | 771 if (d3d11_device_.get()) |
| 845 return true; | 772 return true; |
| 846 HRESULT hr = create_dxgi_device_manager_(&dx11_dev_manager_reset_token_, | 773 HRESULT hr = create_dxgi_device_manager_(&dx11_dev_manager_reset_token_, |
| 847 d3d11_device_manager_.Receive()); | 774 d3d11_device_manager_.Receive()); |
| 848 RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false); | 775 RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false); |
| 849 | 776 |
| 850 angle_device_ = | 777 angle_device_ = gl::QueryD3D11DeviceObjectFromANGLE(); |
| 851 QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE); | |
| 852 if (!angle_device_) | 778 if (!angle_device_) |
| 853 copy_nv12_textures_ = false; | 779 copy_nv12_textures_ = false; |
| 854 if (share_nv12_textures_) { | 780 if (share_nv12_textures_) { |
| 855 RETURN_ON_FAILURE(angle_device_.get(), "Failed to get d3d11 device", false); | 781 RETURN_ON_FAILURE(angle_device_.get(), "Failed to get d3d11 device", false); |
| 856 | 782 |
| 857 using_angle_device_ = true; | 783 using_angle_device_ = true; |
| 858 d3d11_device_ = angle_device_; | 784 d3d11_device_ = angle_device_; |
| 859 } else { | 785 } else { |
| 860 // This array defines the set of DirectX hardware feature levels we support. | 786 // This array defines the set of DirectX hardware feature levels we support. |
| 861 // The ordering MUST be preserved. All applications are assumed to support | 787 // The ordering MUST be preserved. All applications are assumed to support |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1343 // To detect if a driver supports the desired resolutions, we try and create | 1269 // To detect if a driver supports the desired resolutions, we try and create |
| 1344 // a DXVA decoder instance for that resolution and profile. If that succeeds | 1270 // a DXVA decoder instance for that resolution and profile. If that succeeds |
| 1345 // we assume that the driver supports H/W H.264 decoding for that resolution. | 1271 // we assume that the driver supports H/W H.264 decoding for that resolution. |
| 1346 HRESULT hr = E_FAIL; | 1272 HRESULT hr = E_FAIL; |
| 1347 base::win::ScopedComPtr<ID3D11Device> device; | 1273 base::win::ScopedComPtr<ID3D11Device> device; |
| 1348 | 1274 |
| 1349 { | 1275 { |
| 1350 TRACE_EVENT0("gpu,startup", | 1276 TRACE_EVENT0("gpu,startup", |
| 1351 "GetMaxH264Resolution. QueryDeviceObjectFromANGLE"); | 1277 "GetMaxH264Resolution. QueryDeviceObjectFromANGLE"); |
| 1352 | 1278 |
| 1353 device = QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE); | 1279 device = gl::QueryD3D11DeviceObjectFromANGLE(); |
| 1354 if (!device.get()) | 1280 if (!device.get()) |
| 1355 return max_resolution; | 1281 return max_resolution; |
| 1356 } | 1282 } |
| 1357 | 1283 |
| 1358 base::win::ScopedComPtr<ID3D11VideoDevice> video_device; | 1284 base::win::ScopedComPtr<ID3D11VideoDevice> video_device; |
| 1359 hr = device.QueryInterface(__uuidof(ID3D11VideoDevice), | 1285 hr = device.QueryInterface(__uuidof(ID3D11VideoDevice), |
| 1360 video_device.ReceiveVoid()); | 1286 video_device.ReceiveVoid()); |
| 1361 if (FAILED(hr)) | 1287 if (FAILED(hr)) |
| 1362 return max_resolution; | 1288 return max_resolution; |
| 1363 | 1289 |
| (...skipping 1583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2947 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, | 2873 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, |
| 2948 base::Unretained(this))); | 2874 base::Unretained(this))); |
| 2949 } | 2875 } |
| 2950 | 2876 |
| 2951 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const { | 2877 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const { |
| 2952 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; | 2878 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; |
| 2953 return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; | 2879 return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; |
| 2954 } | 2880 } |
| 2955 | 2881 |
| 2956 } // namespace media | 2882 } // namespace media |
| OLD | NEW |