diff --git a/Source/Encoder_QSV.cpp b/Source/Encoder_QSV.cpp index e75ed439..3cd3189c 100644 --- a/Source/Encoder_QSV.cpp +++ b/Source/Encoder_QSV.cpp @@ -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,24 +288,20 @@ 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); - 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]); - break; - } - } + ver = impl->version; + auto result = session.Init(impl->type | impl->intf, &ver); if(result == MFX_ERR_NONE) + { + mfxIMPL actual; + session.QueryIMPL(&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; + } } 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; diff --git a/libmfx/include/mfx_dxva2_device.h b/libmfx/include/mfx_dxva2_device.h index b9227632..ab3e888c 100644 --- a/libmfx/include/mfx_dxva2_device.h +++ b/libmfx/include/mfx_dxva2_device.h @@ -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; diff --git a/libmfx/include/mfx_library_iterator.h b/libmfx/include/mfx_library_iterator.h index 79b02b0b..7d4e51f0 100644 --- a/libmfx/include/mfx_library_iterator.h +++ b/libmfx/include/mfx_library_iterator.h @@ -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); diff --git a/libmfx/src/main.cpp b/libmfx/src/main.cpp index 6d3b4eda..6c6a386e 100644 --- a/libmfx/src/main.cpp +++ b/libmfx/src/main.cpp @@ -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); diff --git a/libmfx/src/mfx_dxva2_device.cpp b/libmfx/src/mfx_dxva2_device.cpp index 1ed7130a..0daf05c9 100644 --- a/libmfx/src/mfx_dxva2_device.cpp +++ b/libmfx/src/mfx_dxva2_device.cpp @@ -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)) + for(UINT start_display = display; pAdapter->EnumOutputs(display-start_display, &out) != DXGI_ERROR_NOT_FOUND; display++) + { + out->Release(); + + if (display != adapterNum) + continue; + + m_pDXGIAdapter1 = pAdapter; + break; + } + + if(m_pDXGIAdapter1) break; - // if it is the required adapter, save the interface - if (outputs == adapterNum) - m_pDXGIAdapter1 = pAdapter; - - out->Release(); - - outputs += 1; - curOutput += 1; - } while(!m_pDXGIAdapter1 && SUCCEEDED(h)); - - if(!m_pDXGIAdapter1) pAdapter->Release(); + } - curAdapter += 1; - - } while (!m_pDXGIAdapter1 && SUCCEEDED(hRes)); - maxAdapters = curAdapter; - - // there is no required adapter - if (adapterNum >= outputs) + // there is no required adapter + if (adapterNum > display) + return false; + } + else { - return false; + 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; diff --git a/libmfx/src/mfx_library_iterator.cpp b/libmfx/src/mfx_library_iterator.cpp index 7b150584..d169ee95 100644 --- a/libmfx/src/mfx_library_iterator.cpp +++ b/libmfx/src/mfx_library_iterator.cpp @@ -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;