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 "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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 // where it allows callers to allocate output samples and allows last frame | 109 // where it allows callers to allocate output samples and allows last frame |
110 // regeneration (repaint). | 110 // regeneration (repaint). |
111 DEFINE_GUID(MF_XVP_PLAYBACK_MODE, 0x3c5d293f, 0xad67, 0x4e29, 0xaf, 0x12, | 111 DEFINE_GUID(MF_XVP_PLAYBACK_MODE, 0x3c5d293f, 0xad67, 0x4e29, 0xaf, 0x12, |
112 0xcf, 0x3e, 0x23, 0x8a, 0xcc, 0xe9); | 112 0xcf, 0x3e, 0x23, 0x8a, 0xcc, 0xe9); |
113 | 113 |
114 // Defines the GUID for the Intel H264 DXVA device. | 114 // Defines the GUID for the Intel H264 DXVA device. |
115 static const GUID DXVA2_Intel_ModeH264_E = { | 115 static const GUID DXVA2_Intel_ModeH264_E = { |
116 0x604F8E68, 0x4951, 0x4c54,{ 0x88, 0xFE, 0xAB, 0xD2, 0x5C, 0x15, 0xB3, 0xD6} | 116 0x604F8E68, 0x4951, 0x4c54,{ 0x88, 0xFE, 0xAB, 0xD2, 0x5C, 0x15, 0xB3, 0xD6} |
117 }; | 117 }; |
118 | 118 |
| 119 // R600, R700, Evergreen and Cayman AMD cards. These support DXVA via UVD3 |
| 120 // or earlier, and don't handle resolutions higher than 1920 x 1088 well. |
| 121 static const DWORD g_AMDUVD3GPUList[] = { |
| 122 0x9400, 0x9401, 0x9402, 0x9403, 0x9405, 0x940a, 0x940b, 0x940f, 0x94c0, |
| 123 0x94c1, 0x94c3, 0x94c4, 0x94c5, 0x94c6, 0x94c7, 0x94c8, 0x94c9, 0x94cb, |
| 124 0x94cc, 0x94cd, 0x9580, 0x9581, 0x9583, 0x9586, 0x9587, 0x9588, 0x9589, |
| 125 0x958a, 0x958b, 0x958c, 0x958d, 0x958e, 0x958f, 0x9500, 0x9501, 0x9504, |
| 126 0x9505, 0x9506, 0x9507, 0x9508, 0x9509, 0x950f, 0x9511, 0x9515, 0x9517, |
| 127 0x9519, 0x95c0, 0x95c2, 0x95c4, 0x95c5, 0x95c6, 0x95c7, 0x95c9, 0x95cc, |
| 128 0x95cd, 0x95ce, 0x95cf, 0x9590, 0x9591, 0x9593, 0x9595, 0x9596, 0x9597, |
| 129 0x9598, 0x9599, 0x959b, 0x9610, 0x9611, 0x9612, 0x9613, 0x9614, 0x9615, |
| 130 0x9616, 0x9710, 0x9711, 0x9712, 0x9713, 0x9714, 0x9715, 0x9440, 0x9441, |
| 131 0x9442, 0x9443, 0x9444, 0x9446, 0x944a, 0x944b, 0x944c, 0x944e, 0x9450, |
| 132 0x9452, 0x9456, 0x945a, 0x945b, 0x945e, 0x9460, 0x9462, 0x946a, 0x946b, |
| 133 0x947a, 0x947b, 0x9480, 0x9487, 0x9488, 0x9489, 0x948a, 0x948f, 0x9490, |
| 134 0x9491, 0x9495, 0x9498, 0x949c, 0x949e, 0x949f, 0x9540, 0x9541, 0x9542, |
| 135 0x954e, 0x954f, 0x9552, 0x9553, 0x9555, 0x9557, 0x955f, 0x94a0, 0x94a1, |
| 136 0x94a3, 0x94b1, 0x94b3, 0x94b4, 0x94b5, 0x94b9, 0x68e0, 0x68e1, 0x68e4, |
| 137 0x68e5, 0x68e8, 0x68e9, 0x68f1, 0x68f2, 0x68f8, 0x68f9, 0x68fa, 0x68fe, |
| 138 0x68c0, 0x68c1, 0x68c7, 0x68c8, 0x68c9, 0x68d8, 0x68d9, 0x68da, 0x68de, |
| 139 0x68a0, 0x68a1, 0x68a8, 0x68a9, 0x68b0, 0x68b8, 0x68b9, 0x68ba, 0x68be, |
| 140 0x68bf, 0x6880, 0x6888, 0x6889, 0x688a, 0x688c, 0x688d, 0x6898, 0x6899, |
| 141 0x689b, 0x689e, 0x689c, 0x689d, 0x9802, 0x9803, 0x9804, 0x9805, 0x9806, |
| 142 0x9807, 0x9808, 0x9809, 0x980a, 0x9640, 0x9641, 0x9647, 0x9648, 0x964a, |
| 143 0x964b, 0x964c, 0x964e, 0x964f, 0x9642, 0x9643, 0x9644, 0x9645, 0x9649, |
| 144 0x6720, 0x6721, 0x6722, 0x6723, 0x6724, 0x6725, 0x6726, 0x6727, 0x6728, |
| 145 0x6729, 0x6738, 0x6739, 0x673e, 0x6740, 0x6741, 0x6742, 0x6743, 0x6744, |
| 146 0x6745, 0x6746, 0x6747, 0x6748, 0x6749, 0x674a, 0x6750, 0x6751, 0x6758, |
| 147 0x6759, 0x675b, 0x675d, 0x675f, 0x6840, 0x6841, 0x6842, 0x6843, 0x6849, |
| 148 0x6850, 0x6858, 0x6859, 0x6760, 0x6761, 0x6762, 0x6763, 0x6764, 0x6765, |
| 149 0x6766, 0x6767, 0x6768, 0x6770, 0x6771, 0x6772, 0x6778, 0x6779, 0x677b, |
| 150 0x6700, 0x6701, 0x6702, 0x6703, 0x6704, 0x6705, 0x6706, 0x6707, 0x6708, |
| 151 0x6709, 0x6718, 0x6719, 0x671c, 0x671d, 0x671f, 0x683D, 0x9900, 0x9901, |
| 152 0x9903, 0x9904, 0x9905, 0x9906, 0x9907, 0x9908, 0x9909, 0x990a, 0x990b, |
| 153 0x990c, 0x990d, 0x990e, 0x990f, 0x9910, 0x9913, 0x9917, 0x9918, 0x9919, |
| 154 0x9990, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998, |
| 155 0x9999, 0x999a, 0x999b, 0x999c, 0x999d, 0x99a0, 0x99a2, 0x99a4, |
| 156 }; |
| 157 |
| 158 // Legacy Intel GPUs (Second generation) which have trouble with resolutions |
| 159 // higher than 1920 x 1088 |
| 160 static const DWORD g_IntelLegacyGPUList[] = { |
| 161 0x102, 0x106, 0x116, 0x126, |
| 162 }; |
| 163 |
119 // Provides scoped access to the underlying buffer in an IMFMediaBuffer | 164 // Provides scoped access to the underlying buffer in an IMFMediaBuffer |
120 // instance. | 165 // instance. |
121 class MediaBufferScopedPointer { | 166 class MediaBufferScopedPointer { |
122 public: | 167 public: |
123 MediaBufferScopedPointer(IMFMediaBuffer* media_buffer) | 168 MediaBufferScopedPointer(IMFMediaBuffer* media_buffer) |
124 : media_buffer_(media_buffer), | 169 : media_buffer_(media_buffer), |
125 buffer_(nullptr), | 170 buffer_(nullptr), |
126 max_length_(0), | 171 max_length_(0), |
127 current_length_(0) { | 172 current_length_(0) { |
128 HRESULT hr = media_buffer_->Lock(&buffer_, &max_length_, ¤t_length_); | 173 HRESULT hr = media_buffer_->Lock(&buffer_, &max_length_, ¤t_length_); |
(...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1501 profile_id == DXVA2_Intel_ModeH264_E)) { | 1546 profile_id == DXVA2_Intel_ModeH264_E)) { |
1502 decoder_guid = profile_id; | 1547 decoder_guid = profile_id; |
1503 found = true; | 1548 found = true; |
1504 break; | 1549 break; |
1505 } | 1550 } |
1506 } | 1551 } |
1507 if (!found) | 1552 if (!found) |
1508 return max_resolution; | 1553 return max_resolution; |
1509 } | 1554 } |
1510 | 1555 |
| 1556 // Legacy AMD drivers with UVD3 or earlier and some Intel GPU's crash while |
| 1557 // creating surfaces larger than 1920 x 1088. |
| 1558 if (IsLegacyGPU(device.get())) |
| 1559 return max_resolution; |
| 1560 |
1511 // We look for the following resolutions in the driver. | 1561 // We look for the following resolutions in the driver. |
1512 // TODO(ananta) | 1562 // TODO(ananta) |
1513 // Look into whether this list needs to be expanded. | 1563 // Look into whether this list needs to be expanded. |
1514 static std::pair<int, int> resolution_array[] = { | 1564 static std::pair<int, int> resolution_array[] = { |
1515 // Use 1088 to account for 16x16 macroblocks. | 1565 // Use 1088 to account for 16x16 macroblocks. |
1516 std::make_pair(1920, 1088), | 1566 std::make_pair(1920, 1088), |
1517 std::make_pair(2560, 1440), | 1567 std::make_pair(2560, 1440), |
1518 std::make_pair(3840, 2160), | 1568 std::make_pair(3840, 2160), |
1519 std::make_pair(4096, 2160), | 1569 std::make_pair(4096, 2160), |
1520 std::make_pair(4096, 2304), | 1570 std::make_pair(4096, 2304), |
(...skipping 25 matching lines...) Expand all Loading... |
1546 video_decoder.Receive()); | 1596 video_decoder.Receive()); |
1547 if (!video_decoder.get()) | 1597 if (!video_decoder.get()) |
1548 return max_resolution; | 1598 return max_resolution; |
1549 | 1599 |
1550 max_resolution = resolution_array[res_idx]; | 1600 max_resolution = resolution_array[res_idx]; |
1551 } | 1601 } |
1552 } | 1602 } |
1553 return max_resolution; | 1603 return max_resolution; |
1554 } | 1604 } |
1555 | 1605 |
| 1606 // static |
| 1607 bool DXVAVideoDecodeAccelerator::IsLegacyGPU(ID3D11Device* device) { |
| 1608 static const int kAMDGPUId1 = 0x1002; |
| 1609 static const int kAMDGPUId2 = 0x1022; |
| 1610 static const int kIntelGPU = 0x8086; |
| 1611 |
| 1612 static bool legacy_gpu = true; |
| 1613 // This flag ensures that we determine the GPU type once. |
| 1614 static bool legacy_gpu_determined = false; |
| 1615 |
| 1616 if (legacy_gpu_determined) |
| 1617 return legacy_gpu; |
| 1618 |
| 1619 legacy_gpu_determined = true; |
| 1620 |
| 1621 base::win::ScopedComPtr<IDXGIDevice> dxgi_device; |
| 1622 HRESULT hr = dxgi_device.QueryFrom(device); |
| 1623 if (FAILED(hr)) |
| 1624 return legacy_gpu; |
| 1625 |
| 1626 base::win::ScopedComPtr<IDXGIAdapter> adapter; |
| 1627 hr = dxgi_device->GetAdapter(adapter.Receive()); |
| 1628 if (FAILED(hr)) |
| 1629 return legacy_gpu; |
| 1630 |
| 1631 DXGI_ADAPTER_DESC adapter_desc = {}; |
| 1632 hr = adapter->GetDesc(&adapter_desc); |
| 1633 if (FAILED(hr)) |
| 1634 return legacy_gpu; |
| 1635 |
| 1636 // We check if the device is an Intel or an AMD device and whether it is in |
| 1637 // the global list defined by the g_AMDUVD3GPUList and g_IntelLegacyGPUList |
| 1638 // arrays above. If yes then the device is treated as a legacy device. |
| 1639 if ((adapter_desc.VendorId == kAMDGPUId1) || |
| 1640 adapter_desc.VendorId == kAMDGPUId2) { |
| 1641 { |
| 1642 TRACE_EVENT0("gpu,startup", |
| 1643 "DXVAVideoDecodeAccelerator::IsLegacyGPU. AMD check"); |
| 1644 for (size_t i = 0; i < arraysize(g_AMDUVD3GPUList); i++) { |
| 1645 if (adapter_desc.DeviceId == g_AMDUVD3GPUList[i]) |
| 1646 return legacy_gpu; |
| 1647 } |
| 1648 } |
| 1649 } else if (adapter_desc.VendorId == kIntelGPU) { |
| 1650 { |
| 1651 TRACE_EVENT0("gpu,startup", |
| 1652 "DXVAVideoDecodeAccelerator::IsLegacyGPU. Intel check"); |
| 1653 for (size_t i = 0; i < arraysize(g_IntelLegacyGPUList); i++) { |
| 1654 if (adapter_desc.DeviceId == g_IntelLegacyGPUList[i]) |
| 1655 return legacy_gpu; |
| 1656 } |
| 1657 } |
| 1658 } |
| 1659 legacy_gpu = false; |
| 1660 return legacy_gpu; |
| 1661 } |
| 1662 |
1556 bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) { | 1663 bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) { |
1557 HMODULE decoder_dll = NULL; | 1664 HMODULE decoder_dll = NULL; |
1558 | 1665 |
1559 CLSID clsid = {}; | 1666 CLSID clsid = {}; |
1560 | 1667 |
1561 // Profile must fall within the valid range for one of the supported codecs. | 1668 // Profile must fall within the valid range for one of the supported codecs. |
1562 if (profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX) { | 1669 if (profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX) { |
1563 // We mimic the steps CoCreateInstance uses to instantiate the object. This | 1670 // We mimic the steps CoCreateInstance uses to instantiate the object. This |
1564 // was previously done because it failed inside the sandbox, and now is done | 1671 // was previously done because it failed inside the sandbox, and now is done |
1565 // as a more minimal approach to avoid other side-effects CCI might have (as | 1672 // as a more minimal approach to avoid other side-effects CCI might have (as |
(...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2846 DismissStaleBuffers(true); | 2953 DismissStaleBuffers(true); |
2847 Invalidate(); | 2954 Invalidate(); |
2848 Initialize(config_, client_); | 2955 Initialize(config_, client_); |
2849 decoder_thread_task_runner_->PostTask( | 2956 decoder_thread_task_runner_->PostTask( |
2850 FROM_HERE, | 2957 FROM_HERE, |
2851 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, | 2958 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, |
2852 base::Unretained(this))); | 2959 base::Unretained(this))); |
2853 } | 2960 } |
2854 | 2961 |
2855 } // namespace content | 2962 } // namespace content |
OLD | NEW |