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)
|
||||
|
||||
const float baseCRF = 22.0f;
|
||||
const mfxVersion version = {4, 1}; //Highest supported version on Sandy Bridge
|
||||
const mfxIMPL validImpl[] = {MFX_IMPL_HARDWARE_ANY, MFX_IMPL_HARDWARE};
|
||||
const struct {
|
||||
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[] = {
|
||||
TO_STR(MFX_IMPL_AUTO),
|
||||
TO_STR(MFX_IMPL_SOFTWARE),
|
||||
@ -65,6 +73,19 @@ namespace
|
||||
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)
|
||||
{
|
||||
mfxU32 fr;
|
||||
@ -109,11 +130,10 @@ namespace
|
||||
bool CheckQSVHardwareSupport(bool log=true)
|
||||
{
|
||||
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 = version;
|
||||
auto result = test.Init(impl, &ver);
|
||||
mfxVersion ver = impl->version;
|
||||
auto result = test.Init(impl->type | impl->intf, &ver);
|
||||
if(result != MFX_ERR_NONE)
|
||||
continue;
|
||||
if(log)
|
||||
@ -268,25 +288,21 @@ public:
|
||||
: enc(nullptr), bFirstFrameProcessed(false), bFirstFrameQueued(false)
|
||||
{
|
||||
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 = version;
|
||||
mfxStatus result = MFX_ERR_UNKNOWN;
|
||||
for(ver.Minor = 6; ver.Minor >= 4; ver.Minor -= 2)
|
||||
{
|
||||
result = session.Init(impl, &ver);
|
||||
ver = impl->version;
|
||||
auto result = session.Init(impl->type | impl->intf, &ver);
|
||||
if(result == MFX_ERR_NONE)
|
||||
{
|
||||
mfxIMPL 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;
|
||||
}
|
||||
}
|
||||
if(result == MFX_ERR_NONE)
|
||||
break;
|
||||
}
|
||||
|
||||
session.SetPriority(MFX_PRIORITY_HIGH);
|
||||
|
||||
@ -302,7 +318,7 @@ public:
|
||||
params.mfx.TargetKbps = maxBitrate;
|
||||
params.mfx.MaxKbps = maxBitrate;
|
||||
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.GopRefDist = 8;
|
||||
params.mfx.IdrInterval = 0;
|
||||
|
@ -58,7 +58,7 @@ public:
|
||||
|
||||
// Initialize device using DXGI 1.1 interface
|
||||
virtual
|
||||
bool Init(const mfxU32 adapterNum) = 0;
|
||||
bool Init(const bool countDisplays, const mfxU32 adapterNum) = 0;
|
||||
|
||||
// Obtain graphic card's parameter
|
||||
mfxU32 GetVendorID(void) const;
|
||||
@ -113,7 +113,7 @@ public:
|
||||
|
||||
// Initialize device
|
||||
virtual
|
||||
bool Init(const mfxU32 adapterNum);
|
||||
bool Init(const bool countDisplays, const mfxU32 adapterNum);
|
||||
|
||||
// Close the object
|
||||
virtual
|
||||
@ -137,7 +137,7 @@ public:
|
||||
~DXVA2Device(void);
|
||||
|
||||
// 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
|
||||
mfxU32 GetVendorID(void) const;
|
||||
|
@ -58,7 +58,7 @@ public:
|
||||
~MFXLibraryIterator(void);
|
||||
|
||||
// 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
|
||||
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
|
||||
mfxRes = libIterator.Init(implTypes[curImplIdx].implType,
|
||||
implInterface != MFX_IMPL_VIA_D3D11,
|
||||
implTypes[curImplIdx].adapterID,
|
||||
currentStorage);
|
||||
|
||||
|
@ -164,7 +164,7 @@ 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
|
||||
Close();
|
||||
@ -181,7 +181,6 @@ bool DXGI1Device::Init(const mfxU32 adapterNum)
|
||||
IDXGIFactory1 *pFactory;
|
||||
IDXGIAdapter1 *pAdapter;
|
||||
DXGI_ADAPTER_DESC1 desc;
|
||||
mfxU32 curAdapter, maxAdapters;
|
||||
HRESULT hRes;
|
||||
|
||||
// load address of procedure to create DXGI 1.1 factory
|
||||
@ -203,54 +202,46 @@ bool DXGI1Device::Init(const mfxU32 adapterNum)
|
||||
}
|
||||
m_pDXGIFactory1 = pFactory;
|
||||
|
||||
// get the number of adapters
|
||||
curAdapter = 0;
|
||||
maxAdapters = 0;
|
||||
mfxU32 outputs = 0;
|
||||
do
|
||||
if(countDisplays)
|
||||
{
|
||||
// get the required adapted
|
||||
hRes = pFactory->EnumAdapters1(curAdapter, &pAdapter);
|
||||
if (FAILED(hRes))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
mfxU32 curOutput = 0;
|
||||
HRESULT h;
|
||||
do
|
||||
UINT display = 0;
|
||||
for(UINT adapter = 0; pFactory->EnumAdapters1(adapter, &pAdapter) != DXGI_ERROR_NOT_FOUND; adapter++)
|
||||
{
|
||||
IDXGIOutput *out;
|
||||
h = pAdapter->EnumOutputs(curOutput, &out);
|
||||
|
||||
if(FAILED(h))
|
||||
break;
|
||||
|
||||
// if it is the required adapter, save the interface
|
||||
if (outputs == adapterNum)
|
||||
m_pDXGIAdapter1 = pAdapter;
|
||||
|
||||
for(UINT start_display = display; pAdapter->EnumOutputs(display-start_display, &out) != DXGI_ERROR_NOT_FOUND; display++)
|
||||
{
|
||||
out->Release();
|
||||
|
||||
outputs += 1;
|
||||
curOutput += 1;
|
||||
} while(!m_pDXGIAdapter1 && SUCCEEDED(h));
|
||||
if (display != adapterNum)
|
||||
continue;
|
||||
|
||||
m_pDXGIAdapter1 = pAdapter;
|
||||
break;
|
||||
}
|
||||
|
||||
if(m_pDXGIAdapter1)
|
||||
break;
|
||||
|
||||
if(!m_pDXGIAdapter1)
|
||||
pAdapter->Release();
|
||||
|
||||
curAdapter += 1;
|
||||
|
||||
} while (!m_pDXGIAdapter1 && SUCCEEDED(hRes));
|
||||
maxAdapters = curAdapter;
|
||||
}
|
||||
|
||||
// there is no required adapter
|
||||
if (adapterNum >= outputs)
|
||||
{
|
||||
if (adapterNum > display)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
hRes = pFactory->EnumAdapters1(adapterNum, &pAdapter);
|
||||
if(FAILED(hRes))
|
||||
return false;
|
||||
|
||||
m_pDXGIAdapter1 = pAdapter;
|
||||
}
|
||||
pAdapter = (IDXGIAdapter1 *) m_pDXGIAdapter1;
|
||||
|
||||
if(!pAdapter)
|
||||
return false;
|
||||
|
||||
// get the adapter's parameters
|
||||
hRes = pAdapter->GetDesc1(&desc);
|
||||
if (FAILED(hRes))
|
||||
@ -292,7 +283,7 @@ 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;
|
||||
bool bRes;
|
||||
@ -301,7 +292,7 @@ bool DXVA2Device::InitDXGI1(const mfxU32 adapterNum)
|
||||
Close();
|
||||
|
||||
// create modern DXGI device
|
||||
bRes = dxgi1Device.Init(adapterNum);
|
||||
bRes = dxgi1Device.Init(countDisplays, adapterNum);
|
||||
if (false == bRes)
|
||||
{
|
||||
return false;
|
||||
|
@ -90,7 +90,7 @@ 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;
|
||||
HKEY rootHKey;
|
||||
@ -121,7 +121,7 @@ mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, const mfxU32 adapterNu
|
||||
m_implType = implType;
|
||||
|
||||
// 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 ));
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
|
Loading…
x
Reference in New Issue
Block a user