Chromium Code Reviews| Index: media/gpu/dxva_video_decode_accelerator_win.cc |
| diff --git a/media/gpu/dxva_video_decode_accelerator_win.cc b/media/gpu/dxva_video_decode_accelerator_win.cc |
| index 935cd72dff6cde80ed2545b77f526283a4a89ea6..13838e0bfc6978efab2a1ab8f9b14684f7b317ee 100644 |
| --- a/media/gpu/dxva_video_decode_accelerator_win.cc |
| +++ b/media/gpu/dxva_video_decode_accelerator_win.cc |
| @@ -24,6 +24,7 @@ |
| #include "base/bind.h" |
| #include "base/callback.h" |
| #include "base/debug/alias.h" |
| +#include "base/debug/dump_without_crashing.h" |
|
scottmg
2016/12/08 17:18:32
Instead of this, #include "third_party/crashpad/cr
|
| #include "base/file_version_info.h" |
| #include "base/files/file_path.h" |
| #include "base/location.h" |
| @@ -31,6 +32,7 @@ |
| #include "base/macros.h" |
| #include "base/memory/shared_memory.h" |
| #include "base/path_service.h" |
| +#include "base/process/process.h" |
| #include "base/single_thread_task_runner.h" |
| #include "base/stl_util.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| @@ -182,6 +184,32 @@ constexpr const wchar_t* const kMediaFoundationVideoDecoderDLLs[] = { |
| L"mf.dll", L"mfplat.dll", L"msmpeg2vdec.dll", |
| }; |
| +LONG CALLBACK VectoredCrashHandler(EXCEPTION_POINTERS* exception_pointers) { |
| + // Try to get crashpad to handle this. |
|
scottmg
2016/12/08 17:18:32
Then, replace 188-190 with
CrashpadClient::Dump
|
| + UnhandledExceptionFilter(exception_pointers); |
| + base::Process::Current().Terminate(1, true); |
| + return EXCEPTION_CONTINUE_SEARCH; |
| +} |
| + |
| +// The MS VP9 MFT swallows driver exceptions and later hangs because it gets |
| +// into a weird state. Add a vectored exception handler so the process will |
| +// crash instead. See http://crbug.com/636158 |
| +class ScopedExceptionCrasher { |
| + public: |
| + ScopedExceptionCrasher(bool handle_exception) { |
|
scottmg
2016/12/08 17:18:32
explicit
|
| + if (handle_exception) |
| + handler_ = AddVectoredExceptionHandler(TRUE, &VectoredCrashHandler); |
| + } |
| + |
| + ~ScopedExceptionCrasher() { |
| + if (handler_) |
| + RemoveVectoredExceptionHandler(handler_); |
| + } |
| + |
| + private: |
| + void* handler_ = nullptr; |
|
scottmg
2016/12/08 17:18:32
DISALLOW...
|
| +}; |
| + |
| } // namespace |
| namespace media { |
| @@ -1744,9 +1772,13 @@ void DXVAVideoDecodeAccelerator::DoDecode(const gfx::ColorSpace& color_space) { |
| MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0}; |
| DWORD status = 0; |
| - HRESULT hr = decoder_->ProcessOutput(0, // No flags |
| - 1, // # of out streams to pull from |
| - &output_data_buffer, &status); |
| + HRESULT hr; |
| + { |
| + ScopedExceptionCrasher crasher(using_ms_vp9_mft_); |
| + hr = decoder_->ProcessOutput(0, // No flags |
| + 1, // # of out streams to pull from |
| + &output_data_buffer, &status); |
| + } |
| IMFCollection* events = output_data_buffer.pEvents; |
| if (events != NULL) { |
| DVLOG(1) << "Got events from ProcessOuput, but discarding"; |
| @@ -2174,8 +2206,10 @@ void DXVAVideoDecodeAccelerator::DecodeInternal( |
| this); |
| } |
| inputs_before_decode_++; |
| - |
| - hr = decoder_->ProcessInput(0, sample.get(), 0); |
| + { |
| + ScopedExceptionCrasher crasher(using_ms_vp9_mft_); |
| + hr = decoder_->ProcessInput(0, sample.get(), 0); |
| + } |
| // As per msdn if the decoder returns MF_E_NOTACCEPTING then it means that it |
| // has enough data to produce one or more output samples. In this case the |
| // recommended options are to |