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