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

Unified Diff: content/common/gpu/media/dxva_video_decode_accelerator.cc

Issue 1235373003: Fix a crasher in the GPU process caused by the DXVA code attempting to create an instance of the Vi… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix indent Created 5 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/gpu/media/dxva_video_decode_accelerator.cc
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.cc b/content/common/gpu/media/dxva_video_decode_accelerator.cc
index 568b128e1d1bdea5e0d98bed04fda5db6b54b733..4b9530791071df99911215f489677cef6488166d 100644
--- a/content/common/gpu/media/dxva_video_decode_accelerator.cc
+++ b/content/common/gpu/media/dxva_video_decode_accelerator.cc
@@ -100,7 +100,8 @@ DEFINE_GUID(CLSID_VideoProcessorMFT,
// regeneration (repaint).
DEFINE_GUID(MF_XVP_PLAYBACK_MODE, 0x3c5d293f, 0xad67, 0x4e29, 0xaf, 0x12,
0xcf, 0x3e, 0x23, 0x8a, 0xcc, 0xe9);
-}
+
+} // namespace
namespace content {
@@ -241,6 +242,34 @@ static IMFSample* CreateSampleFromInputBuffer(
alignment);
}
+// Helper function to create a COM object instance from a DLL. The alternative
+// is to use the CoCreateInstance API which requires the COM apartment to be
+// initialized which is not the case on the GPU main thread. We want to avoid
+// initializing COM as it may have sideeffects.
+HRESULT CreateCOMObjectFromDll(HMODULE dll, const CLSID& clsid, const IID& iid,
+ void** object) {
+ if (!dll || !object)
+ return E_INVALIDARG;
+
+ using GetClassObject = HRESULT (WINAPI*)(
+ const CLSID& clsid, const IID& iid, void** object);
+
+ GetClassObject get_class_object = reinterpret_cast<GetClassObject>(
+ GetProcAddress(dll, "DllGetClassObject"));
+ RETURN_ON_FAILURE(
+ get_class_object, "Failed to get DllGetClassObject pointer", false);
+
+ base::win::ScopedComPtr<IClassFactory> factory;
+ HRESULT hr = get_class_object(
+ clsid,
+ __uuidof(IClassFactory),
+ factory.ReceiveVoid());
+ RETURN_ON_HR_FAILURE(hr, "DllGetClassObject failed", false);
+
+ hr = factory->CreateInstance(NULL, iid, object);
+ return hr;
+}
+
// Maintains information about a DXVA picture buffer, i.e. whether it is
// available for rendering, the texture information, etc.
struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer {
@@ -727,13 +756,15 @@ bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() {
d3d11_query_.Receive());
RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false);
- hr = ::CoCreateInstance(
- CLSID_VideoProcessorMFT,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_IMFTransform,
- reinterpret_cast<void**>(video_format_converter_mft_.Receive()));
+ HMODULE video_processor_dll = ::LoadLibrary(L"msvproc.dll");
+ RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor",
+ false);
+ hr = CreateCOMObjectFromDll(
+ video_processor_dll,
+ CLSID_VideoProcessorMFT,
+ __uuidof(IMFTransform),
+ video_format_converter_mft_.ReceiveVoid());
if (FAILED(hr)) {
base::debug::Alias(&hr);
// TODO(ananta)
@@ -741,6 +772,7 @@ bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() {
// stablizes.
CHECK(false);
}
+
RETURN_ON_HR_FAILURE(hr, "Failed to create video format converter", false);
return true;
}
@@ -943,6 +975,8 @@ DXVAVideoDecodeAccelerator::GetSupportedProfiles() {
bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) {
HMODULE decoder_dll = NULL;
+ CLSID clsid = {};
+
// Profile must fall within the valid range for one of the supported codecs.
if (profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX) {
// We mimic the steps CoCreateInstance uses to instantiate the object. This
@@ -967,6 +1001,7 @@ bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) {
"blacklisted version of msmpeg2vdec.dll 6.7.7140",
false);
codec_ = media::kCodecH264;
+ clsid = __uuidof(CMSH264DecoderMFT);
} else if (profile == media::VP8PROFILE_ANY ||
profile == media::VP9PROFILE_ANY) {
int program_files_key = base::DIR_PROGRAM_FILES;
@@ -983,9 +1018,11 @@ bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) {
if (profile == media::VP8PROFILE_ANY) {
codec_ = media::kCodecVP8;
dll_path = dll_path.Append(kVP8DecoderDLLName);
+ clsid = CLSID_WebmMfVp8Dec;
} else {
codec_ = media::kCodecVP9;
dll_path = dll_path.Append(kVP9DecoderDLLName);
+ clsid = CLSID_WebmMfVp9Dec;
}
decoder_dll = ::LoadLibraryEx(dll_path.value().data(), NULL,
LOAD_WITH_ALTERED_SEARCH_PATH);
@@ -994,36 +1031,10 @@ bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) {
RETURN_ON_FAILURE(false, "Unsupported codec.", false);
}
- typedef HRESULT(WINAPI * GetClassObject)(
- const CLSID & clsid, const IID & iid, void * *object);
-
- GetClassObject get_class_object = reinterpret_cast<GetClassObject>(
- GetProcAddress(decoder_dll, "DllGetClassObject"));
- RETURN_ON_FAILURE(
- get_class_object, "Failed to get DllGetClassObject pointer", false);
-
- base::win::ScopedComPtr<IClassFactory> factory;
- HRESULT hr;
- if (codec_ == media::kCodecH264) {
- hr = get_class_object(__uuidof(CMSH264DecoderMFT),
- __uuidof(IClassFactory),
- reinterpret_cast<void**>(factory.Receive()));
- } else if (codec_ == media::kCodecVP8) {
- hr = get_class_object(CLSID_WebmMfVp8Dec,
- __uuidof(IClassFactory),
- reinterpret_cast<void**>(factory.Receive()));
- } else if (codec_ == media::kCodecVP9) {
- hr = get_class_object(CLSID_WebmMfVp9Dec,
- __uuidof(IClassFactory),
- reinterpret_cast<void**>(factory.Receive()));
- } else {
- RETURN_ON_FAILURE(false, "Unsupported codec.", false);
- }
- RETURN_ON_HR_FAILURE(hr, "DllGetClassObject for decoder failed", false);
-
- hr = factory->CreateInstance(NULL,
- __uuidof(IMFTransform),
- reinterpret_cast<void**>(decoder_.Receive()));
+ HRESULT hr = CreateCOMObjectFromDll(decoder_dll,
+ clsid,
+ __uuidof(IMFTransform),
+ decoder_.ReceiveVoid());
RETURN_ON_HR_FAILURE(hr, "Failed to create decoder instance", false);
RETURN_ON_FAILURE(CheckDecoderDxvaSupport(),
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698