ref: b1ce6997f98da6fabb82c55cf7cb549c49953d48
parent: e1b8cd20196ae5fe83db4ba1939dc9aa1bc39089
author: xiaotianshi2 <xiaotianshimail2@gmail.com>
date: Sun Jun 28 13:19:55 EDT 2020
Add thread decoding support for multi-slice frame. Note: In each call to DecodeFrameNoDelay, iSrcLen must be the byte-size of one coded video frame.
--- a/codec/decoder/core/src/decoder.cpp
+++ b/codec/decoder/core/src/decoder.cpp
@@ -813,7 +813,7 @@
}
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
if (pCtx->bAuReadyFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) {
- if (pCtx->pThreadCtx == NULL) {
+ if (GetThreadCount (pCtx) <= 1) {
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
} else {
pCtx->pAccessUnitList->uiAvailUnitsNum = 1;
@@ -873,11 +873,11 @@
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3);
}
- if (pCtx->pThreadCtx == NULL) {
+ if (GetThreadCount (pCtx) <= 1) {
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
}
if (pCtx->bAuReadyFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) {
- if (pCtx->pThreadCtx == NULL) {
+ if (GetThreadCount (pCtx) <= 1) {
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
} else {
pCtx->pAccessUnitList->uiAvailUnitsNum = 1;
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -2338,7 +2338,7 @@
*/
int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
int32_t iErr = ERR_NONE;
- if (pCtx->pThreadCtx == NULL) {
+ if (GetThreadCount (pCtx) <= 1) {
iErr = InitConstructAccessUnit (pCtx, pDstInfo);
if (ERR_NONE != iErr) {
return iErr;
@@ -2550,7 +2550,7 @@
isNewFrame = pCtx->pDec == NULL;
}
if (pCtx->pDec == NULL) {
- if (pLastThreadCtx != NULL) {
+ if (pLastThreadCtx != NULL && iIdx == 0) {
pLastThreadCtx->pDec->bUsedAsRef = pLastThreadCtx->pCtx->uiNalRefIdc > 0;
if (pLastThreadCtx->pDec->bUsedAsRef) {
for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
@@ -2686,7 +2686,19 @@
if (pCtx->bNewSeqBegin) {
iPrevFrameNum = 0;
} else if (pLastThreadCtx->pDec != NULL) {
- iPrevFrameNum = pLastThreadCtx->pDec->iFrameNum;
+ if (pLastThreadCtx->pDec->uiTimeStamp == pCtx->uiTimeStamp - 1) {
+ iPrevFrameNum = pLastThreadCtx->pDec->iFrameNum;
+ if (iPrevFrameNum == -1) iPrevFrameNum = pLastThreadCtx->pCtx->iFrameNum;
+ } else {
+ int32_t id = pThreadCtx->sThreadInfo.uiThrNum;
+ for (int32_t i = 0; i < iThreadCount; ++i) {
+ if (pThreadCtx[i - id].pCtx->uiTimeStamp == pCtx->uiTimeStamp - 1) {
+ if (pThreadCtx[i - id].pDec != NULL) iPrevFrameNum = pThreadCtx[i - id].pDec->iFrameNum;
+ if (iPrevFrameNum == -1) iPrevFrameNum = pThreadCtx[i - id].pCtx->iFrameNum;
+ break;
+ }
+ }
+ }
} else {
iPrevFrameNum = pCtx->bNewSeqBegin ? 0 : pLastThreadCtx->pCtx->iFrameNum;
}
@@ -2734,8 +2746,10 @@
ComputeColocatedTemporalScaling (pCtx);
if (iThreadCount > 1) {
- memset (&pCtx->lastReadyHeightOffset[0][0], -1, LIST_A * MAX_REF_PIC_COUNT * sizeof (int16_t));
- SET_EVENT (&pThreadCtx->sSliceDecodeStart);
+ if (iIdx == 0) {
+ memset (&pCtx->lastReadyHeightOffset[0][0], -1, LIST_A * MAX_REF_PIC_COUNT * sizeof (int16_t));
+ SET_EVENT (&pThreadCtx->sSliceDecodeStart);
+ }
iRet = WelsDecodeAndConstructSlice (pCtx);
} else {
iRet = WelsDecodeSlice (pCtx, bFreshSliceAvailable, pNalCur);
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -1374,6 +1374,13 @@
sThreadCtx.pCtx->iImgHeightInPixel = m_pLastDecThrCtx->pCtx->iImgHeightInPixel;
}
}
+
+ //if threadCount > 1, then each thread must contain exact one complete frame.
+ if (GetThreadCount (sThreadCtx.pCtx) > 1) {
+ sThreadCtx.pCtx->pAccessUnitList->uiAvailUnitsNum = 0;
+ sThreadCtx.pCtx->pAccessUnitList->uiActualUnitsNum = 0;
+ }
+
int32_t iRet = DecodeFrame2WithCtx (sThreadCtx.pCtx, sThreadCtx.kpSrc, sThreadCtx.kiSrcLen, sThreadCtx.ppDst,
&sThreadCtx.sDstInfo);