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

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

Issue 1859043005: Attempt to fix a crash in the GPU process while determining the max H.264 resolution which can be s… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix comment 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
« no previous file with comments | « content/common/gpu/media/dxva_video_decode_accelerator_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
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_, &current_length_); 173 HRESULT hr = media_buffer_->Lock(&buffer_, &max_length_, &current_length_);
(...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « content/common/gpu/media/dxva_video_decode_accelerator_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698