obs-qsv11: Enable QSV texture-based encoding

Enables a pipeline for texture-based encoding with QSV. Utilizes OBS
NV12 output for encode to avoid offloading them from GPU, which will
increase performance. The option to select old QSV pipeline still
remains and will fallback if new pipeline fails.
This commit is contained in:
brittneysclark
2019-03-27 18:21:44 -07:00
committed by jp9000
parent 355cd6ccc0
commit cc896b6c03
9 changed files with 283 additions and 4 deletions

View File

@@ -569,6 +569,70 @@ mfxStatus QSV_Encoder_Internal::Encode(uint64_t ts, uint8_t *pDataY,
return sts;
}
mfxStatus QSV_Encoder_Internal::Encode_tex(uint64_t ts, uint32_t tex_handle,
uint64_t lock_key,
uint64_t *next_key,
mfxBitstream **pBS)
{
mfxStatus sts = MFX_ERR_NONE;
*pBS = NULL;
int nTaskIdx = GetFreeTaskIndex(m_pTaskPool, m_nTaskPool);
int nSurfIdx = GetFreeSurfaceIndex(m_pmfxSurfaces, m_nSurfNum);
while (MFX_ERR_NOT_FOUND == nTaskIdx || MFX_ERR_NOT_FOUND == nSurfIdx) {
// No more free tasks or surfaces, need to sync
sts = m_session.SyncOperation(
m_pTaskPool[m_nFirstSyncTask].syncp, 60000);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
mfxU8 *pTemp = m_outBitstream.Data;
memcpy(&m_outBitstream, &m_pTaskPool[m_nFirstSyncTask].mfxBS,
sizeof(mfxBitstream));
m_pTaskPool[m_nFirstSyncTask].mfxBS.Data = pTemp;
m_pTaskPool[m_nFirstSyncTask].mfxBS.DataLength = 0;
m_pTaskPool[m_nFirstSyncTask].mfxBS.DataOffset = 0;
m_pTaskPool[m_nFirstSyncTask].syncp = NULL;
nTaskIdx = m_nFirstSyncTask;
m_nFirstSyncTask = (m_nFirstSyncTask + 1) % m_nTaskPool;
*pBS = &m_outBitstream;
nSurfIdx = GetFreeSurfaceIndex(m_pmfxSurfaces, m_nSurfNum);
}
mfxFrameSurface1 *pSurface = m_pmfxSurfaces[nSurfIdx];
//copy to default surface directly
pSurface->Data.TimeStamp = ts;
if (m_bUseD3D11 || m_bD3D9HACK) {
sts = simple_copytex(m_mfxAllocator.pthis, pSurface->Data.MemId,
tex_handle, lock_key, next_key);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
}
for (;;) {
// Encode a frame asynchronously (returns immediately)
sts = m_pmfxENC->EncodeFrameAsync(NULL, pSurface,
&m_pTaskPool[nTaskIdx].mfxBS,
&m_pTaskPool[nTaskIdx].syncp);
if (MFX_ERR_NONE < sts && !m_pTaskPool[nTaskIdx].syncp) {
// Repeat the call if warning and no output
if (MFX_WRN_DEVICE_BUSY == sts)
MSDK_SLEEP(
1); // Wait if device is busy, then repeat the same call
} else if (MFX_ERR_NONE < sts && m_pTaskPool[nTaskIdx].syncp) {
sts = MFX_ERR_NONE; // Ignore warnings if output is available
break;
} else if (MFX_ERR_NOT_ENOUGH_BUFFER == sts) {
// Allocate more bitstream buffer memory here if needed...
break;
} else
break;
}
return sts;
}
mfxStatus QSV_Encoder_Internal::Drain()
{
mfxStatus sts = MFX_ERR_NONE;