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. |
11 #endif // !defined(OS_WIN) | 11 #endif // !defined(OS_WIN) |
12 | 12 |
13 #include <codecapi.h> | 13 #include <codecapi.h> |
14 #include <dxgi1_2.h> | 14 #include <dxgi1_2.h> |
15 #include <ks.h> | 15 #include <ks.h> |
16 #include <mfapi.h> | 16 #include <mfapi.h> |
17 #include <mferror.h> | 17 #include <mferror.h> |
18 #include <ntverp.h> | 18 #include <ntverp.h> |
19 #include <stddef.h> | 19 #include <stddef.h> |
20 #include <string.h> | 20 #include <string.h> |
21 #include <wmcodecdsp.h> | 21 #include <wmcodecdsp.h> |
22 | 22 |
23 #include "base/atomicops.h" | 23 #include "base/atomicops.h" |
24 #include "base/base_paths_win.h" | 24 #include "base/base_paths_win.h" |
25 #include "base/bind.h" | 25 #include "base/bind.h" |
26 #include "base/callback.h" | 26 #include "base/callback.h" |
27 #include "base/debug/alias.h" | 27 #include "base/debug/alias.h" |
| 28 #include "base/debug/dump_without_crashing.h" |
28 #include "base/file_version_info.h" | 29 #include "base/file_version_info.h" |
29 #include "base/files/file_path.h" | 30 #include "base/files/file_path.h" |
30 #include "base/location.h" | 31 #include "base/location.h" |
31 #include "base/logging.h" | 32 #include "base/logging.h" |
32 #include "base/macros.h" | 33 #include "base/macros.h" |
33 #include "base/memory/shared_memory.h" | 34 #include "base/memory/shared_memory.h" |
34 #include "base/path_service.h" | 35 #include "base/path_service.h" |
35 #include "base/single_thread_task_runner.h" | 36 #include "base/single_thread_task_runner.h" |
36 #include "base/stl_util.h" | 37 #include "base/stl_util.h" |
37 #include "base/threading/thread_local_storage.h" | 38 #include "base/threading/thread_local_storage.h" |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 }; | 182 }; |
182 | 183 |
183 constexpr const wchar_t* const kMediaFoundationVideoDecoderDLLs[] = { | 184 constexpr const wchar_t* const kMediaFoundationVideoDecoderDLLs[] = { |
184 L"mf.dll", L"mfplat.dll", L"msmpeg2vdec.dll", | 185 L"mf.dll", L"mfplat.dll", L"msmpeg2vdec.dll", |
185 }; | 186 }; |
186 | 187 |
187 // Vectored exception handlers are global to the entire process, so use TLS to | 188 // Vectored exception handlers are global to the entire process, so use TLS to |
188 // ensure only the thread with the ScopedExceptionCatcher dumps anything. | 189 // ensure only the thread with the ScopedExceptionCatcher dumps anything. |
189 base::ThreadLocalStorage::StaticSlot g_catcher_tls_slot = TLS_INITIALIZER; | 190 base::ThreadLocalStorage::StaticSlot g_catcher_tls_slot = TLS_INITIALIZER; |
190 | 191 |
| 192 base::subtle::Atomic32 g_dump_count; |
| 193 |
191 uint64_t GetCurrentQPC() { | 194 uint64_t GetCurrentQPC() { |
192 LARGE_INTEGER perf_counter_now = {}; | 195 LARGE_INTEGER perf_counter_now = {}; |
193 // Use raw QueryPerformanceCounter to avoid grabbing locks or allocating | 196 // Use raw QueryPerformanceCounter to avoid grabbing locks or allocating |
194 // memory in an exception handler; | 197 // memory in an exception handler; |
195 ::QueryPerformanceCounter(&perf_counter_now); | 198 ::QueryPerformanceCounter(&perf_counter_now); |
196 return perf_counter_now.QuadPart; | 199 return perf_counter_now.QuadPart; |
197 } | 200 } |
198 | 201 |
199 // This is information about the last exception. Writing into it may be racy, | 202 // This is information about the last exception. Writing into it may be racy, |
200 // but that should be ok because the information is only used for debugging. | 203 // but that should be ok because the information is only used for debugging. |
201 DWORD g_last_exception_code; | 204 DWORD g_last_exception_code; |
202 uint64_t g_last_exception_time; | 205 uint64_t g_last_exception_time; |
203 uint64_t g_last_process_output_time; | 206 uint64_t g_last_process_output_time; |
204 HRESULT g_last_unhandled_error; | 207 HRESULT g_last_unhandled_error; |
205 | 208 |
206 LONG CALLBACK VectoredCrashHandler(EXCEPTION_POINTERS* exception_pointers) { | 209 LONG CALLBACK VectoredCrashHandler(EXCEPTION_POINTERS* exception_pointers) { |
207 if (g_catcher_tls_slot.Get()) { | 210 if (g_catcher_tls_slot.Get()) { |
208 g_last_exception_code = exception_pointers->ExceptionRecord->ExceptionCode; | 211 g_last_exception_code = exception_pointers->ExceptionRecord->ExceptionCode; |
209 g_last_exception_time = GetCurrentQPC(); | 212 g_last_exception_time = GetCurrentQPC(); |
| 213 if (exception_pointers->ExceptionRecord->ExceptionCode == |
| 214 EXCEPTION_DEBUG_EVENT) { |
| 215 base::debug::Alias(&exception_pointers); |
| 216 // Only dump first time to ensure we don't spend a lot of time doing this |
| 217 // if the driver continually causes exceptions. |
| 218 if (base::subtle::Barrier_AtomicIncrement(&g_dump_count, 1) == 1) |
| 219 base::debug::DumpWithoutCrashing(); |
| 220 } |
210 } | 221 } |
211 return EXCEPTION_CONTINUE_SEARCH; | 222 return EXCEPTION_CONTINUE_SEARCH; |
212 } | 223 } |
213 | 224 |
214 // The MS VP9 MFT swallows driver exceptions and later hangs because it gets | 225 // The MS VP9 MFT swallows driver exceptions and later hangs because it gets |
215 // into a weird state. Add a vectored exception handler so information about | 226 // into a weird state. Add a vectored exception handler so information about |
216 // the exception can be retrieved. See http://crbug.com/636158 | 227 // the exception can be retrieved. See http://crbug.com/636158 |
217 class ScopedExceptionCatcher { | 228 class ScopedExceptionCatcher { |
218 public: | 229 public: |
219 explicit ScopedExceptionCatcher(bool handle_exception) { | 230 explicit ScopedExceptionCatcher(bool handle_exception) { |
(...skipping 2756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2976 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, | 2987 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, |
2977 base::Unretained(this))); | 2988 base::Unretained(this))); |
2978 } | 2989 } |
2979 | 2990 |
2980 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const { | 2991 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const { |
2981 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; | 2992 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; |
2982 return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; | 2993 return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; |
2983 } | 2994 } |
2984 | 2995 |
2985 } // namespace media | 2996 } // namespace media |
OLD | NEW |