зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1389980 - Ensure we only interact with WMF on MTA threads. r=aklotz,mattwoodrow
The IMFTransform interface used by MFTDecoder is documented to require to run on an MTA threads: https://msdn.microsoft.com/en-us/library/windows/desktop/ee892371(v=vs.85).aspx#components We're currently using IMFTransform objects on the main thread, which is STA. So delegate calls to the IMFTransform to the MTA thread when necessary, to ensure it always runs on an MTA thread. The existing uses of IMFTransform objects in the decode thread pool threads will be fine, as those threads are already MTA. We also defer initialization of WMF to the MTA thread, so that we're always interacting with WMF on an MTA thread. MozReview-Commit-ID: Dm8XpdvJLkS --HG-- extra : rebase_source : 0807241c8cdd01c1b99bf946ea4728996ac61f68
This commit is contained in:
Родитель
441293d0f7
Коммит
73738d61f9
|
@ -24,6 +24,7 @@
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "VideoUtils.h"
|
#include "VideoUtils.h"
|
||||||
|
#include "mozilla/mscom/EnsureMTA.h"
|
||||||
|
|
||||||
const CLSID CLSID_VideoProcessorMFT =
|
const CLSID CLSID_VideoProcessorMFT =
|
||||||
{
|
{
|
||||||
|
@ -648,6 +649,7 @@ private:
|
||||||
uint32_t mWidth = 0;
|
uint32_t mWidth = 0;
|
||||||
uint32_t mHeight = 0;
|
uint32_t mHeight = 0;
|
||||||
UINT mDeviceManagerToken = 0;
|
UINT mDeviceManagerToken = 0;
|
||||||
|
bool mConfiuredForSize = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -778,22 +780,35 @@ D3D11DXVA2Manager::InitInternal(layers::KnowsCompositor* aKnowsCompositor,
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mTransform = new MFTDecoder();
|
// The IMFTransform interface used by MFTDecoder is documented to require to
|
||||||
hr = mTransform->Create(CLSID_VideoProcessorMFT);
|
// run on an MTA thread.
|
||||||
if (!SUCCEEDED(hr)) {
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ee892371(v=vs.85).aspx#components
|
||||||
aFailureReason = nsPrintfCString(
|
// The main thread (where this function is called) is STA, not MTA.
|
||||||
"MFTDecoder::Create(CLSID_VideoProcessorMFT) failed with code %X", hr);
|
RefPtr<MFTDecoder> mft;
|
||||||
return hr;
|
mozilla::mscom::EnsureMTA([&]() -> void {
|
||||||
}
|
mft = new MFTDecoder();
|
||||||
|
hr = mft->Create(CLSID_VideoProcessorMFT);
|
||||||
|
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
aFailureReason = nsPrintfCString(
|
||||||
|
"MFTDecoder::Create(CLSID_VideoProcessorMFT) failed with code %X", hr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = mft->SendMFTMessage(MFT_MESSAGE_SET_D3D_MANAGER,
|
||||||
|
ULONG_PTR(mDXGIDeviceManager.get()));
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
aFailureReason = nsPrintfCString("MFTDecoder::SendMFTMessage(MFT_MESSAGE_"
|
||||||
|
"SET_D3D_MANAGER) failed with code %X",
|
||||||
|
hr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
hr = mTransform->SendMFTMessage(MFT_MESSAGE_SET_D3D_MANAGER,
|
|
||||||
ULONG_PTR(mDXGIDeviceManager.get()));
|
|
||||||
if (!SUCCEEDED(hr)) {
|
if (!SUCCEEDED(hr)) {
|
||||||
aFailureReason = nsPrintfCString("MFTDecoder::SendMFTMessage(MFT_MESSAGE_"
|
|
||||||
"SET_D3D_MANAGER) failed with code %X",
|
|
||||||
hr);
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
mTransform = mft;
|
||||||
|
|
||||||
RefPtr<ID3D11VideoDevice> videoDevice;
|
RefPtr<ID3D11VideoDevice> videoDevice;
|
||||||
hr = mDevice->QueryInterface(
|
hr = mDevice->QueryInterface(
|
||||||
|
@ -947,14 +962,18 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
|
||||||
} else {
|
} else {
|
||||||
// Our video sample is in NV12 format but our output texture is in BGRA.
|
// Our video sample is in NV12 format but our output texture is in BGRA.
|
||||||
// Use MFT to do color conversion.
|
// Use MFT to do color conversion.
|
||||||
hr = mTransform->Input(aVideoSample);
|
hr = E_FAIL;
|
||||||
|
mozilla::mscom::EnsureMTA(
|
||||||
|
[&]() -> void { hr = mTransform->Input(aVideoSample); });
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
|
|
||||||
RefPtr<IMFSample> sample;
|
RefPtr<IMFSample> sample;
|
||||||
hr = CreateOutputSample(sample, texture);
|
hr = CreateOutputSample(sample, texture);
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
|
|
||||||
hr = mTransform->Output(&sample);
|
hr = E_FAIL;
|
||||||
|
mozilla::mscom::EnsureMTA(
|
||||||
|
[&]() -> void { hr = mTransform->Output(&sample); });
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1029,14 +1048,19 @@ D3D11DXVA2Manager::CopyToBGRATexture(ID3D11Texture2D *aInTexture,
|
||||||
|
|
||||||
inputSample->AddBuffer(inputBuffer);
|
inputSample->AddBuffer(inputBuffer);
|
||||||
|
|
||||||
hr = mTransform->Input(inputSample);
|
hr = E_FAIL;
|
||||||
|
mozilla::mscom::EnsureMTA(
|
||||||
|
[&]() -> void { hr = mTransform->Input(inputSample); });
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
|
|
||||||
RefPtr<IMFSample> outputSample;
|
RefPtr<IMFSample> outputSample;
|
||||||
hr = CreateOutputSample(outputSample, texture);
|
hr = CreateOutputSample(outputSample, texture);
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
|
|
||||||
hr = mTransform->Output(&outputSample);
|
hr = E_FAIL;
|
||||||
|
mozilla::mscom::EnsureMTA(
|
||||||
|
[&]() -> void { hr = mTransform->Output(&outputSample); });
|
||||||
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
|
|
||||||
texture.forget(aOutTexture);
|
texture.forget(aOutTexture);
|
||||||
|
|
||||||
|
@ -1062,6 +1086,11 @@ HRESULT ConfigureOutput(IMFMediaType* aOutput, void* aData)
|
||||||
HRESULT
|
HRESULT
|
||||||
D3D11DXVA2Manager::ConfigureForSize(uint32_t aWidth, uint32_t aHeight)
|
D3D11DXVA2Manager::ConfigureForSize(uint32_t aWidth, uint32_t aHeight)
|
||||||
{
|
{
|
||||||
|
if (mConfiuredForSize && aWidth == mWidth && aHeight == mHeight) {
|
||||||
|
// If the size hasn't changed, don't reconfigure.
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
mWidth = aWidth;
|
mWidth = aWidth;
|
||||||
mHeight = aHeight;
|
mHeight = aHeight;
|
||||||
|
|
||||||
|
@ -1081,7 +1110,10 @@ D3D11DXVA2Manager::ConfigureForSize(uint32_t aWidth, uint32_t aHeight)
|
||||||
hr = inputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
|
hr = inputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
|
|
||||||
RefPtr<IMFAttributes> attr = mTransform->GetAttributes();
|
RefPtr<IMFAttributes> attr;
|
||||||
|
mozilla::mscom::EnsureMTA(
|
||||||
|
[&]() -> void { attr = mTransform->GetAttributes(); });
|
||||||
|
NS_ENSURE_TRUE(attr != nullptr, E_FAIL);
|
||||||
|
|
||||||
hr = attr->SetUINT32(MF_XVP_PLAYBACK_MODE, TRUE);
|
hr = attr->SetUINT32(MF_XVP_PLAYBACK_MODE, TRUE);
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
|
@ -1103,9 +1135,15 @@ D3D11DXVA2Manager::ConfigureForSize(uint32_t aWidth, uint32_t aHeight)
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
|
|
||||||
gfx::IntSize size(mWidth, mHeight);
|
gfx::IntSize size(mWidth, mHeight);
|
||||||
hr = mTransform->SetMediaTypes(inputType, outputType, ConfigureOutput, &size);
|
hr = E_FAIL;
|
||||||
|
mozilla::mscom::EnsureMTA([&]() -> void {
|
||||||
|
hr =
|
||||||
|
mTransform->SetMediaTypes(inputType, outputType, ConfigureOutput, &size);
|
||||||
|
});
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
|
|
||||||
|
mConfiuredForSize = true;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "WMFUtils.h"
|
#include "WMFUtils.h"
|
||||||
#include "mozilla/Logging.h"
|
#include "mozilla/Logging.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
#include "mozilla/mscom/Utils.h"
|
||||||
|
|
||||||
#define LOG(...) MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
|
#define LOG(...) MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
|
||||||
|
|
||||||
|
@ -26,6 +27,8 @@ MFTDecoder::~MFTDecoder()
|
||||||
HRESULT
|
HRESULT
|
||||||
MFTDecoder::Create(const GUID& aMFTClsID)
|
MFTDecoder::Create(const GUID& aMFTClsID)
|
||||||
{
|
{
|
||||||
|
// Note: IMFTransform is documented to only be safe on MTA threads.
|
||||||
|
MOZ_ASSERT(mscom::IsCurrentThreadMTA());
|
||||||
// Create the IMFTransform to do the decoding.
|
// Create the IMFTransform to do the decoding.
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
hr = CoCreateInstance(aMFTClsID,
|
hr = CoCreateInstance(aMFTClsID,
|
||||||
|
@ -45,6 +48,7 @@ MFTDecoder::SetMediaTypes(IMFMediaType* aInputType,
|
||||||
ConfigureOutputCallback aCallback,
|
ConfigureOutputCallback aCallback,
|
||||||
void* aData)
|
void* aData)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mscom::IsCurrentThreadMTA());
|
||||||
mOutputType = aOutputType;
|
mOutputType = aOutputType;
|
||||||
|
|
||||||
// Set the input type to the one the caller gave us...
|
// Set the input type to the one the caller gave us...
|
||||||
|
@ -69,6 +73,7 @@ MFTDecoder::SetMediaTypes(IMFMediaType* aInputType,
|
||||||
already_AddRefed<IMFAttributes>
|
already_AddRefed<IMFAttributes>
|
||||||
MFTDecoder::GetAttributes()
|
MFTDecoder::GetAttributes()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mscom::IsCurrentThreadMTA());
|
||||||
RefPtr<IMFAttributes> attr;
|
RefPtr<IMFAttributes> attr;
|
||||||
HRESULT hr = mDecoder->GetAttributes(getter_AddRefs(attr));
|
HRESULT hr = mDecoder->GetAttributes(getter_AddRefs(attr));
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
|
||||||
|
@ -80,6 +85,7 @@ MFTDecoder::SetDecoderOutputType(bool aMatchAllAttributes,
|
||||||
ConfigureOutputCallback aCallback,
|
ConfigureOutputCallback aCallback,
|
||||||
void* aData)
|
void* aData)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mscom::IsCurrentThreadMTA());
|
||||||
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
|
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
|
||||||
|
|
||||||
GUID currentSubtype = {0};
|
GUID currentSubtype = {0};
|
||||||
|
@ -127,6 +133,7 @@ MFTDecoder::SetDecoderOutputType(bool aMatchAllAttributes,
|
||||||
HRESULT
|
HRESULT
|
||||||
MFTDecoder::SendMFTMessage(MFT_MESSAGE_TYPE aMsg, ULONG_PTR aData)
|
MFTDecoder::SendMFTMessage(MFT_MESSAGE_TYPE aMsg, ULONG_PTR aData)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mscom::IsCurrentThreadMTA());
|
||||||
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
|
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
|
||||||
HRESULT hr = mDecoder->ProcessMessage(aMsg, aData);
|
HRESULT hr = mDecoder->ProcessMessage(aMsg, aData);
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
|
@ -139,6 +146,7 @@ MFTDecoder::CreateInputSample(const uint8_t* aData,
|
||||||
int64_t aTimestamp,
|
int64_t aTimestamp,
|
||||||
RefPtr<IMFSample>* aOutSample)
|
RefPtr<IMFSample>* aOutSample)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mscom::IsCurrentThreadMTA());
|
||||||
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
|
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -184,6 +192,7 @@ MFTDecoder::CreateInputSample(const uint8_t* aData,
|
||||||
HRESULT
|
HRESULT
|
||||||
MFTDecoder::CreateOutputSample(RefPtr<IMFSample>* aOutSample)
|
MFTDecoder::CreateOutputSample(RefPtr<IMFSample>* aOutSample)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mscom::IsCurrentThreadMTA());
|
||||||
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
|
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -210,6 +219,7 @@ MFTDecoder::CreateOutputSample(RefPtr<IMFSample>* aOutSample)
|
||||||
HRESULT
|
HRESULT
|
||||||
MFTDecoder::Output(RefPtr<IMFSample>* aOutput)
|
MFTDecoder::Output(RefPtr<IMFSample>* aOutput)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mscom::IsCurrentThreadMTA());
|
||||||
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
|
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -275,6 +285,7 @@ MFTDecoder::Input(const uint8_t* aData,
|
||||||
uint32_t aDataSize,
|
uint32_t aDataSize,
|
||||||
int64_t aTimestamp)
|
int64_t aTimestamp)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mscom::IsCurrentThreadMTA());
|
||||||
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
|
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
|
||||||
|
|
||||||
RefPtr<IMFSample> input;
|
RefPtr<IMFSample> input;
|
||||||
|
@ -287,6 +298,7 @@ MFTDecoder::Input(const uint8_t* aData,
|
||||||
HRESULT
|
HRESULT
|
||||||
MFTDecoder::Input(IMFSample* aSample)
|
MFTDecoder::Input(IMFSample* aSample)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mscom::IsCurrentThreadMTA());
|
||||||
HRESULT hr = mDecoder->ProcessInput(0, aSample, 0);
|
HRESULT hr = mDecoder->ProcessInput(0, aSample, 0);
|
||||||
if (hr == MF_E_NOTACCEPTING) {
|
if (hr == MF_E_NOTACCEPTING) {
|
||||||
// MFT *already* has enough data to produce a sample. Retrieve it.
|
// MFT *already* has enough data to produce a sample. Retrieve it.
|
||||||
|
@ -300,6 +312,7 @@ MFTDecoder::Input(IMFSample* aSample)
|
||||||
HRESULT
|
HRESULT
|
||||||
MFTDecoder::Flush()
|
MFTDecoder::Flush()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mscom::IsCurrentThreadMTA());
|
||||||
HRESULT hr = SendMFTMessage(MFT_MESSAGE_COMMAND_FLUSH, 0);
|
HRESULT hr = SendMFTMessage(MFT_MESSAGE_COMMAND_FLUSH, 0);
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
|
|
||||||
|
@ -311,6 +324,7 @@ MFTDecoder::Flush()
|
||||||
HRESULT
|
HRESULT
|
||||||
MFTDecoder::GetOutputMediaType(RefPtr<IMFMediaType>& aMediaType)
|
MFTDecoder::GetOutputMediaType(RefPtr<IMFMediaType>& aMediaType)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mscom::IsCurrentThreadMTA());
|
||||||
NS_ENSURE_TRUE(mDecoder, E_POINTER);
|
NS_ENSURE_TRUE(mDecoder, E_POINTER);
|
||||||
return mDecoder->GetOutputCurrentType(0, getter_AddRefs(aMediaType));
|
return mDecoder->GetOutputCurrentType(0, getter_AddRefs(aMediaType));
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,12 +42,17 @@ namespace mozilla {
|
||||||
namespace wmf {
|
namespace wmf {
|
||||||
|
|
||||||
// If successful, loads all required WMF DLLs and calls the WMF MFStartup()
|
// If successful, loads all required WMF DLLs and calls the WMF MFStartup()
|
||||||
// function.
|
// function. This delegates the WMF MFStartup() call to the MTA thread if
|
||||||
|
// the current thread is not MTA. This is to ensure we always interact with
|
||||||
|
// WMF from threads with the same COM compartment model.
|
||||||
HRESULT MFStartup();
|
HRESULT MFStartup();
|
||||||
|
|
||||||
// Calls the WMF MFShutdown() function. Call this once for every time
|
// Calls the WMF MFShutdown() function. Call this once for every time
|
||||||
// wmf::MFStartup() succeeds. Note: does not unload the WMF DLLs loaded by
|
// wmf::MFStartup() succeeds. Note: does not unload the WMF DLLs loaded by
|
||||||
// MFStartup(); leaves them in memory to save I/O at next MFStartup() call.
|
// MFStartup(); leaves them in memory to save I/O at next MFStartup() call.
|
||||||
|
// This delegates the WMF MFShutdown() call to the MTA thread if the current
|
||||||
|
// thread is not MTA. This is to ensure we always interact with
|
||||||
|
// WMF from threads with the same COM compartment model.
|
||||||
HRESULT MFShutdown();
|
HRESULT MFShutdown();
|
||||||
|
|
||||||
// All functions below are wrappers around the corresponding WMF function,
|
// All functions below are wrappers around the corresponding WMF function,
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "nsWindowsHelpers.h"
|
#include "nsWindowsHelpers.h"
|
||||||
#include "prsystem.h"
|
#include "prsystem.h"
|
||||||
#include "nsIXULRuntime.h"
|
#include "nsIXULRuntime.h"
|
||||||
|
#include "mozilla/mscom/EnsureMTA.h"
|
||||||
|
|
||||||
extern const GUID CLSID_WebmMfVpxDec;
|
extern const GUID CLSID_WebmMfVpxDec;
|
||||||
|
|
||||||
|
@ -135,16 +136,22 @@ WMFDecoderModule::CreateAudioDecoder(const CreateDecoderParams& aParams)
|
||||||
static bool
|
static bool
|
||||||
CanCreateMFTDecoder(const GUID& aGuid)
|
CanCreateMFTDecoder(const GUID& aGuid)
|
||||||
{
|
{
|
||||||
if (FAILED(wmf::MFStartup())) {
|
// The IMFTransform interface used by MFTDecoder is documented to require to
|
||||||
return false;
|
// run on an MTA thread.
|
||||||
}
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ee892371(v=vs.85).aspx#components
|
||||||
bool hasdecoder = false;
|
// Note: our normal SharedThreadPool task queues are initialized to MTA, but
|
||||||
{
|
// the main thread (which calls in here from our CanPlayType implementation)
|
||||||
|
// is not.
|
||||||
|
bool canCreateDecoder = false;
|
||||||
|
mozilla::mscom::EnsureMTA([&]() -> void {
|
||||||
|
if (FAILED(wmf::MFStartup())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
RefPtr<MFTDecoder> decoder(new MFTDecoder());
|
RefPtr<MFTDecoder> decoder(new MFTDecoder());
|
||||||
hasdecoder = SUCCEEDED(decoder->Create(aGuid));
|
canCreateDecoder = SUCCEEDED(decoder->Create(aGuid));
|
||||||
}
|
wmf::MFShutdown();
|
||||||
wmf::MFShutdown();
|
});
|
||||||
return hasdecoder;
|
return canCreateDecoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<const GUID& aGuid>
|
template<const GUID& aGuid>
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "nsWindowsHelpers.h"
|
#include "nsWindowsHelpers.h"
|
||||||
#include <initguid.h>
|
#include <initguid.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "mozilla/mscom/EnsureMTA.h"
|
||||||
|
|
||||||
#ifdef WMF_MUST_DEFINE_AAC_MFT_CLSID
|
#ifdef WMF_MUST_DEFINE_AAC_MFT_CLSID
|
||||||
// Some SDK versions don't define the AAC decoder CLSID.
|
// Some SDK versions don't define the AAC decoder CLSID.
|
||||||
|
@ -220,14 +221,20 @@ MFStartup()
|
||||||
// decltype is unusable for functions having default parameters
|
// decltype is unusable for functions having default parameters
|
||||||
DECL_FUNCTION_PTR(MFStartup, ULONG, DWORD);
|
DECL_FUNCTION_PTR(MFStartup, ULONG, DWORD);
|
||||||
ENSURE_FUNCTION_PTR_(MFStartup, Mfplat.dll)
|
ENSURE_FUNCTION_PTR_(MFStartup, Mfplat.dll)
|
||||||
return MFStartupPtr(MF_WIN7_VERSION, MFSTARTUP_FULL);
|
|
||||||
|
hr = E_FAIL;
|
||||||
|
mozilla::mscom::EnsureMTA(
|
||||||
|
[&]() -> void { hr = MFStartupPtr(MF_WIN7_VERSION, MFSTARTUP_FULL); });
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
MFShutdown()
|
MFShutdown()
|
||||||
{
|
{
|
||||||
ENSURE_FUNCTION_PTR(MFShutdown, Mfplat.dll)
|
ENSURE_FUNCTION_PTR(MFShutdown, Mfplat.dll)
|
||||||
return (MFShutdownPtr)();
|
HRESULT hr = E_FAIL;
|
||||||
|
mozilla::mscom::EnsureMTA([&]() -> void { hr = (MFShutdownPtr)(); });
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
|
|
Загрузка…
Ссылка в новой задаче