Chromium Code Reviews| 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..09a7603556aa4fa904d5b3d529a2fcf3ae7e1419 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; |
| + |
| + typedef HRESULT(WINAPI * GetClassObject)( |
|
DaleCurtis
2015/07/15 23:11:56
No space before & and * on all lines? If you want,
ananta
2015/07/15 23:15:01
eek. i dunno how i uploaded with this :(
Will uplo
ananta
2015/07/15 23:23:25
Done.
|
| + 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), |
| + reinterpret_cast<void**>(factory.Receive())); |
|
DaleCurtis
2015/07/15 23:11:56
ReceiveVoid to avoid cast?
ananta
2015/07/15 23:23:25
Done.
|
| + 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( |
| + 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, |
| - NULL, |
| - CLSCTX_INPROC_SERVER, |
| - IID_IMFTransform, |
| + __uuidof(IMFTransform), |
| reinterpret_cast<void**>(video_format_converter_mft_.Receive())); |
| - |
| 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; |
| } |
| @@ -994,36 +1026,22 @@ 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; |
| + CLSID clsid = {}; |
|
DaleCurtis
2015/07/15 23:11:56
Seems you could just roll this into the conditiona
ananta
2015/07/15 23:23:25
Yes. Done.
|
| if (codec_ == media::kCodecH264) { |
| - hr = get_class_object(__uuidof(CMSH264DecoderMFT), |
| - __uuidof(IClassFactory), |
| - reinterpret_cast<void**>(factory.Receive())); |
| + clsid = __uuidof(CMSH264DecoderMFT); |
| } else if (codec_ == media::kCodecVP8) { |
| - hr = get_class_object(CLSID_WebmMfVp8Dec, |
| - __uuidof(IClassFactory), |
| - reinterpret_cast<void**>(factory.Receive())); |
| + clsid = CLSID_WebmMfVp8Dec; |
| } else if (codec_ == media::kCodecVP9) { |
| - hr = get_class_object(CLSID_WebmMfVp9Dec, |
| - __uuidof(IClassFactory), |
| - reinterpret_cast<void**>(factory.Receive())); |
| + clsid = CLSID_WebmMfVp9Dec; |
| } else { |
| - RETURN_ON_FAILURE(false, "Unsupported codec.", false); |
| + NOTREACHED() << "Unsupported codec: " << codec_; |
| } |
| - 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), |
| + reinterpret_cast<void**>( |
| + decoder_.Receive())); |
|
DaleCurtis
2015/07/15 23:11:56
ReceiveVoid
|
| RETURN_ON_HR_FAILURE(hr, "Failed to create decoder instance", false); |
| RETURN_ON_FAILURE(CheckDecoderDxvaSupport(), |