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:
@@ -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;
|
||||
|
Reference in New Issue
Block a user