| 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(),
 | 
| 
 |