| 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 |