Added headless Direct3D11 mode for QSV on Ivy Bridge or better
This commit is contained in:
parent
ae170aefbe
commit
fcc8b34c57
@ -42,8 +42,16 @@ namespace
|
|||||||
#define TO_STR(a) TEXT(#a)
|
#define TO_STR(a) TEXT(#a)
|
||||||
|
|
||||||
const float baseCRF = 22.0f;
|
const float baseCRF = 22.0f;
|
||||||
const mfxVersion version = {4, 1}; //Highest supported version on Sandy Bridge
|
const struct {
|
||||||
const mfxIMPL validImpl[] = {MFX_IMPL_HARDWARE_ANY, MFX_IMPL_HARDWARE};
|
mfxU32 type,
|
||||||
|
intf;
|
||||||
|
mfxVersion version;
|
||||||
|
} validImpl[] = {
|
||||||
|
{ MFX_IMPL_HARDWARE_ANY, MFX_IMPL_VIA_D3D11, {6, 1} },
|
||||||
|
{ MFX_IMPL_HARDWARE, MFX_IMPL_VIA_D3D11, {6, 1} },
|
||||||
|
{ MFX_IMPL_HARDWARE_ANY, MFX_IMPL_VIA_ANY, {4, 1} }, //Sandy Bridge
|
||||||
|
{ MFX_IMPL_HARDWARE, MFX_IMPL_VIA_ANY, {4, 1} },
|
||||||
|
};
|
||||||
const TCHAR* implStr[] = {
|
const TCHAR* implStr[] = {
|
||||||
TO_STR(MFX_IMPL_AUTO),
|
TO_STR(MFX_IMPL_AUTO),
|
||||||
TO_STR(MFX_IMPL_SOFTWARE),
|
TO_STR(MFX_IMPL_SOFTWARE),
|
||||||
@ -65,6 +73,19 @@ namespace
|
|||||||
TO_STR(MFX_TARGETUSAGE_BEST_SPEED)
|
TO_STR(MFX_TARGETUSAGE_BEST_SPEED)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TCHAR* qsv_intf_str(const mfxU32 impl)
|
||||||
|
{
|
||||||
|
switch(impl & (-MFX_IMPL_VIA_ANY))
|
||||||
|
{
|
||||||
|
#define VIA_STR(x) case MFX_IMPL_VIA_##x: return TEXT(" | ") TO_STR(MFX_IMPL_VIA_##x)
|
||||||
|
VIA_STR(ANY);
|
||||||
|
VIA_STR(D3D9);
|
||||||
|
VIA_STR(D3D11);
|
||||||
|
#undef VIA_STR
|
||||||
|
default: return nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void ConvertFrameRate(mfxF64 dFrameRate, mfxU32& pnFrameRateExtN, mfxU32& pnFrameRateExtD)
|
void ConvertFrameRate(mfxF64 dFrameRate, mfxU32& pnFrameRateExtN, mfxU32& pnFrameRateExtD)
|
||||||
{
|
{
|
||||||
mfxU32 fr;
|
mfxU32 fr;
|
||||||
@ -109,11 +130,10 @@ namespace
|
|||||||
bool CheckQSVHardwareSupport(bool log=true)
|
bool CheckQSVHardwareSupport(bool log=true)
|
||||||
{
|
{
|
||||||
MFXVideoSession test;
|
MFXVideoSession test;
|
||||||
for(int i = 0; i < sizeof(validImpl)/sizeof(validImpl[0]); i++)
|
for(auto impl = std::begin(validImpl); impl != std::end(validImpl); impl++)
|
||||||
{
|
{
|
||||||
mfxIMPL impl = validImpl[i];
|
mfxVersion ver = impl->version;
|
||||||
mfxVersion ver = version;
|
auto result = test.Init(impl->type | impl->intf, &ver);
|
||||||
auto result = test.Init(impl, &ver);
|
|
||||||
if(result != MFX_ERR_NONE)
|
if(result != MFX_ERR_NONE)
|
||||||
continue;
|
continue;
|
||||||
if(log)
|
if(log)
|
||||||
@ -268,25 +288,21 @@ public:
|
|||||||
: enc(nullptr), bFirstFrameProcessed(false), bFirstFrameQueued(false)
|
: enc(nullptr), bFirstFrameProcessed(false), bFirstFrameQueued(false)
|
||||||
{
|
{
|
||||||
Log(TEXT("------------------------------------------"));
|
Log(TEXT("------------------------------------------"));
|
||||||
for(int i = 0; i < sizeof(validImpl)/sizeof(validImpl[0]); i++)
|
|
||||||
|
for(auto impl = std::begin(validImpl); impl != std::end(validImpl); impl++)
|
||||||
{
|
{
|
||||||
mfxIMPL impl = validImpl[i];
|
ver = impl->version;
|
||||||
ver = version;
|
auto result = session.Init(impl->type | impl->intf, &ver);
|
||||||
mfxStatus result = MFX_ERR_UNKNOWN;
|
|
||||||
for(ver.Minor = 6; ver.Minor >= 4; ver.Minor -= 2)
|
|
||||||
{
|
|
||||||
result = session.Init(impl, &ver);
|
|
||||||
if(result == MFX_ERR_NONE)
|
if(result == MFX_ERR_NONE)
|
||||||
{
|
{
|
||||||
mfxIMPL actual;
|
mfxIMPL actual;
|
||||||
session.QueryIMPL(&actual);
|
session.QueryIMPL(&actual);
|
||||||
Log(TEXT("QSV version %u.%u using %s (actual: %s)"), ver.Major, ver.Minor, implStr[impl], implStr[actual]);
|
auto intf_str = qsv_intf_str(actual);
|
||||||
|
Log(TEXT("QSV version %u.%u using %s (actual: %s%s)"), ver.Major, ver.Minor,
|
||||||
|
implStr[impl->type], implStr[actual & (MFX_IMPL_VIA_ANY - 1)], intf_str ? intf_str : TEXT(""));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(result == MFX_ERR_NONE)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
session.SetPriority(MFX_PRIORITY_HIGH);
|
session.SetPriority(MFX_PRIORITY_HIGH);
|
||||||
|
|
||||||
@ -302,7 +318,7 @@ public:
|
|||||||
params.mfx.TargetKbps = maxBitrate;
|
params.mfx.TargetKbps = maxBitrate;
|
||||||
params.mfx.MaxKbps = maxBitrate;
|
params.mfx.MaxKbps = maxBitrate;
|
||||||
params.mfx.BufferSizeInKB = bufferSize/8;
|
params.mfx.BufferSizeInKB = bufferSize/8;
|
||||||
params.mfx.GopOptFlag = MFX_GOP_CLOSED | MFX_GOP_STRICT;
|
params.mfx.GopOptFlag = MFX_GOP_CLOSED;
|
||||||
params.mfx.GopPicSize = 250;
|
params.mfx.GopPicSize = 250;
|
||||||
params.mfx.GopRefDist = 8;
|
params.mfx.GopRefDist = 8;
|
||||||
params.mfx.IdrInterval = 0;
|
params.mfx.IdrInterval = 0;
|
||||||
|
@ -58,7 +58,7 @@ public:
|
|||||||
|
|
||||||
// Initialize device using DXGI 1.1 interface
|
// Initialize device using DXGI 1.1 interface
|
||||||
virtual
|
virtual
|
||||||
bool Init(const mfxU32 adapterNum) = 0;
|
bool Init(const bool countDisplays, const mfxU32 adapterNum) = 0;
|
||||||
|
|
||||||
// Obtain graphic card's parameter
|
// Obtain graphic card's parameter
|
||||||
mfxU32 GetVendorID(void) const;
|
mfxU32 GetVendorID(void) const;
|
||||||
@ -113,7 +113,7 @@ public:
|
|||||||
|
|
||||||
// Initialize device
|
// Initialize device
|
||||||
virtual
|
virtual
|
||||||
bool Init(const mfxU32 adapterNum);
|
bool Init(const bool countDisplays, const mfxU32 adapterNum);
|
||||||
|
|
||||||
// Close the object
|
// Close the object
|
||||||
virtual
|
virtual
|
||||||
@ -137,7 +137,7 @@ public:
|
|||||||
~DXVA2Device(void);
|
~DXVA2Device(void);
|
||||||
|
|
||||||
// Initialize device using DXGI 1.1 interface
|
// Initialize device using DXGI 1.1 interface
|
||||||
bool InitDXGI1(const mfxU32 adapterNum);
|
bool InitDXGI1(const bool countDisplays, const mfxU32 adapterNum);
|
||||||
|
|
||||||
// Obtain graphic card's parameter
|
// Obtain graphic card's parameter
|
||||||
mfxU32 GetVendorID(void) const;
|
mfxU32 GetVendorID(void) const;
|
||||||
|
@ -58,7 +58,7 @@ public:
|
|||||||
~MFXLibraryIterator(void);
|
~MFXLibraryIterator(void);
|
||||||
|
|
||||||
// Initialize the iterator
|
// Initialize the iterator
|
||||||
mfxStatus Init(eMfxImplType implType, const mfxU32 adapterNum, int storageID);
|
mfxStatus Init(eMfxImplType implType, const bool countDisplays, const mfxU32 adapterNum, int storageID);
|
||||||
|
|
||||||
// Get the next library path
|
// Get the next library path
|
||||||
mfxStatus SelectDLLVersion(wchar_t *pPath, size_t pathSize, eMfxImplType *pImplType, mfxVersion minVersion);
|
mfxStatus SelectDLLVersion(wchar_t *pPath, size_t pathSize, eMfxImplType *pImplType, mfxVersion minVersion);
|
||||||
|
@ -172,6 +172,7 @@ mfxStatus DISPATCHER_EXPOSED_PREFIX(MFXInit)(mfxIMPL impl, mfxVersion *pVer, mfx
|
|||||||
{
|
{
|
||||||
// initialize the library iterator
|
// initialize the library iterator
|
||||||
mfxRes = libIterator.Init(implTypes[curImplIdx].implType,
|
mfxRes = libIterator.Init(implTypes[curImplIdx].implType,
|
||||||
|
implInterface != MFX_IMPL_VIA_D3D11,
|
||||||
implTypes[curImplIdx].adapterID,
|
implTypes[curImplIdx].adapterID,
|
||||||
currentStorage);
|
currentStorage);
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ void DXGI1Device::Close(void)
|
|||||||
|
|
||||||
} // void DXGI1Device::Close(void)
|
} // void DXGI1Device::Close(void)
|
||||||
|
|
||||||
bool DXGI1Device::Init(const mfxU32 adapterNum)
|
bool DXGI1Device::Init(const bool countDisplays, const mfxU32 adapterNum)
|
||||||
{
|
{
|
||||||
// release the object before initialization
|
// release the object before initialization
|
||||||
Close();
|
Close();
|
||||||
@ -181,7 +181,6 @@ bool DXGI1Device::Init(const mfxU32 adapterNum)
|
|||||||
IDXGIFactory1 *pFactory;
|
IDXGIFactory1 *pFactory;
|
||||||
IDXGIAdapter1 *pAdapter;
|
IDXGIAdapter1 *pAdapter;
|
||||||
DXGI_ADAPTER_DESC1 desc;
|
DXGI_ADAPTER_DESC1 desc;
|
||||||
mfxU32 curAdapter, maxAdapters;
|
|
||||||
HRESULT hRes;
|
HRESULT hRes;
|
||||||
|
|
||||||
// load address of procedure to create DXGI 1.1 factory
|
// load address of procedure to create DXGI 1.1 factory
|
||||||
@ -203,54 +202,46 @@ bool DXGI1Device::Init(const mfxU32 adapterNum)
|
|||||||
}
|
}
|
||||||
m_pDXGIFactory1 = pFactory;
|
m_pDXGIFactory1 = pFactory;
|
||||||
|
|
||||||
// get the number of adapters
|
if(countDisplays)
|
||||||
curAdapter = 0;
|
|
||||||
maxAdapters = 0;
|
|
||||||
mfxU32 outputs = 0;
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
// get the required adapted
|
UINT display = 0;
|
||||||
hRes = pFactory->EnumAdapters1(curAdapter, &pAdapter);
|
for(UINT adapter = 0; pFactory->EnumAdapters1(adapter, &pAdapter) != DXGI_ERROR_NOT_FOUND; adapter++)
|
||||||
if (FAILED(hRes))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
mfxU32 curOutput = 0;
|
|
||||||
HRESULT h;
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
IDXGIOutput *out;
|
IDXGIOutput *out;
|
||||||
h = pAdapter->EnumOutputs(curOutput, &out);
|
for(UINT start_display = display; pAdapter->EnumOutputs(display-start_display, &out) != DXGI_ERROR_NOT_FOUND; display++)
|
||||||
|
{
|
||||||
if(FAILED(h))
|
|
||||||
break;
|
|
||||||
|
|
||||||
// if it is the required adapter, save the interface
|
|
||||||
if (outputs == adapterNum)
|
|
||||||
m_pDXGIAdapter1 = pAdapter;
|
|
||||||
|
|
||||||
out->Release();
|
out->Release();
|
||||||
|
|
||||||
outputs += 1;
|
if (display != adapterNum)
|
||||||
curOutput += 1;
|
continue;
|
||||||
} while(!m_pDXGIAdapter1 && SUCCEEDED(h));
|
|
||||||
|
m_pDXGIAdapter1 = pAdapter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_pDXGIAdapter1)
|
||||||
|
break;
|
||||||
|
|
||||||
if(!m_pDXGIAdapter1)
|
|
||||||
pAdapter->Release();
|
pAdapter->Release();
|
||||||
|
}
|
||||||
curAdapter += 1;
|
|
||||||
|
|
||||||
} while (!m_pDXGIAdapter1 && SUCCEEDED(hRes));
|
|
||||||
maxAdapters = curAdapter;
|
|
||||||
|
|
||||||
// there is no required adapter
|
// there is no required adapter
|
||||||
if (adapterNum >= outputs)
|
if (adapterNum > display)
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hRes = pFactory->EnumAdapters1(adapterNum, &pAdapter);
|
||||||
|
if(FAILED(hRes))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_pDXGIAdapter1 = pAdapter;
|
||||||
|
}
|
||||||
pAdapter = (IDXGIAdapter1 *) m_pDXGIAdapter1;
|
pAdapter = (IDXGIAdapter1 *) m_pDXGIAdapter1;
|
||||||
|
|
||||||
|
if(!pAdapter)
|
||||||
|
return false;
|
||||||
|
|
||||||
// get the adapter's parameters
|
// get the adapter's parameters
|
||||||
hRes = pAdapter->GetDesc1(&desc);
|
hRes = pAdapter->GetDesc1(&desc);
|
||||||
if (FAILED(hRes))
|
if (FAILED(hRes))
|
||||||
@ -292,7 +283,7 @@ void DXVA2Device::Close(void)
|
|||||||
|
|
||||||
} // void DXVA2Device::Close(void)
|
} // void DXVA2Device::Close(void)
|
||||||
|
|
||||||
bool DXVA2Device::InitDXGI1(const mfxU32 adapterNum)
|
bool DXVA2Device::InitDXGI1(const bool countDisplays, const mfxU32 adapterNum)
|
||||||
{
|
{
|
||||||
DXGI1Device dxgi1Device;
|
DXGI1Device dxgi1Device;
|
||||||
bool bRes;
|
bool bRes;
|
||||||
@ -301,7 +292,7 @@ bool DXVA2Device::InitDXGI1(const mfxU32 adapterNum)
|
|||||||
Close();
|
Close();
|
||||||
|
|
||||||
// create modern DXGI device
|
// create modern DXGI device
|
||||||
bRes = dxgi1Device.Init(adapterNum);
|
bRes = dxgi1Device.Init(countDisplays, adapterNum);
|
||||||
if (false == bRes)
|
if (false == bRes)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -90,7 +90,7 @@ void MFXLibraryIterator::Release(void)
|
|||||||
|
|
||||||
} // void MFXLibraryIterator::Release(void)
|
} // void MFXLibraryIterator::Release(void)
|
||||||
|
|
||||||
mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, const mfxU32 adapterNum, int storageID)
|
mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, const bool countDisplays, const mfxU32 adapterNum, int storageID)
|
||||||
{
|
{
|
||||||
DXVA2Device dxvaDevice;
|
DXVA2Device dxvaDevice;
|
||||||
HKEY rootHKey;
|
HKEY rootHKey;
|
||||||
@ -121,7 +121,7 @@ mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, const mfxU32 adapterNu
|
|||||||
m_implType = implType;
|
m_implType = implType;
|
||||||
|
|
||||||
// try to open DXGI 1.1 device to get hardware ID
|
// try to open DXGI 1.1 device to get hardware ID
|
||||||
if (!dxvaDevice.InitDXGI1(adapterNum))
|
if (!dxvaDevice.InitDXGI1(countDisplays, adapterNum))
|
||||||
{
|
{
|
||||||
DISPATCHER_LOG_INFO((("dxvaDevice.InitDXGI1(%d) Failed "), adapterNum ));
|
DISPATCHER_LOG_INFO((("dxvaDevice.InitDXGI1(%d) Failed "), adapterNum ));
|
||||||
return MFX_ERR_UNSUPPORTED;
|
return MFX_ERR_UNSUPPORTED;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user