ref: 2f262a0cb10077bd3e3ae77057344bfa102cb289
parent: 033c6a0448227d6290b402435c7faec9d3063dd0
parent: ffba96449165b59546f19d0c5e8fd5c35c44c32e
author: huili2 <huili2@cisco.com>
date: Mon Nov 18 03:57:05 EST 2019
Merge pull request #3207 from xiaotianshi2/thread_commit_additional2 fix a few UT test cases in thread decoding mode.
--- a/codec/console/dec/src/h264dec.cpp
+++ b/codec/console/dec/src/h264dec.cpp
@@ -283,7 +283,7 @@
goto label_exit;
iSliceSize = static_cast<int32_t> (pInfo[2]);
} else {
- if (iThreadCount > 1) {
+ if (iThreadCount >= 1) {
uint8_t* uSpsPtr = NULL;
int32_t iSpsByteCount = 0;
iSliceSize = readPicture (pBuf, iFileSize, iBufPos, uSpsPtr, iSpsByteCount);
@@ -577,7 +577,7 @@
pDecoder->SetOption (DECODER_OPTION_TRACE_LEVEL, &iLevelSetting);
}
- int32_t iThreadCount = 1;
+ int32_t iThreadCount = 0;
pDecoder->SetOption (DECODER_OPTION_NUM_OF_THREADS, &iThreadCount);
if (pDecoder->Initialize (&sDecParam)) {
--- a/codec/decoder/core/inc/decoder_context.h
+++ b/codec/decoder/core/inc/decoder_context.h
@@ -550,6 +550,14 @@
}
}
}
+static inline int32_t GetThreadCount (PWelsDecoderContext pCtx) {
+ int32_t iThreadCount = 0;
+ if (pCtx->pThreadCtx != NULL) {
+ PWelsDecoderThreadCTX pThreadCtx = (PWelsDecoderThreadCTX)pCtx->pThreadCtx;
+ iThreadCount = pThreadCtx->sThreadInfo.uiThrMaxNum;
+ }
+ return iThreadCount;
+}
//#ifdef __cplusplus
//}
//#endif//__cplusplus
--- a/codec/decoder/core/inc/picture.h
+++ b/codec/decoder/core/inc/picture.h
@@ -69,8 +69,7 @@
/*******************************sef_definition for misc use****************************/
bool bUsedAsRef; //for ref pic management
bool bIsLongRef; // long term reference frame flag //for ref pic management
- uint8_t uiRefCount;
- bool bAvailableFlag; // indicate whether it is available in this picture memory block.
+ int8_t iRefCount;
bool bIsComplete; // indicate whether current picture is complete, not from EC
/*******************************for future use****************************/
--- a/codec/decoder/core/src/decode_slice.cpp
+++ b/codec/decoder/core/src/decode_slice.cpp
@@ -236,7 +236,7 @@
}
WelsMbInterSampleConstruction (pCtx, pCurDqLayer, pDstY, pDstCb, pDstCr, iLumaStride, iChromaStride);
- if (pCtx->pThreadCtx == NULL) {
+ if (GetThreadCount (pCtx) <= 1) {
pCtx->sBlockFunc.pWelsSetNonZeroCountFunc (
pCurDqLayer->pNzc[pCurDqLayer->iMbXyIndex]); // set all none-zero nzc to 1; dbk can be opti!
}
@@ -1365,7 +1365,7 @@
pCurDqLayer->pInterPredictionDoneFlag[iMbXy] = 0;
memset (pCurDqLayer->pDec->pRefIndex[0][iMbXy], 0, sizeof (int8_t) * 16);
- bool bIsPending = pCtx->pThreadCtx != NULL;
+ bool bIsPending = GetThreadCount (pCtx) > 1;
pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[0] && (ppRefPic[0]->bIsComplete
|| bIsPending));
//predict mv
@@ -1421,7 +1421,7 @@
memset (pCurDqLayer->pDirect[iMbXy], 0, sizeof (int8_t) * 16);
- bool bIsPending = pCtx->pThreadCtx != NULL;
+ bool bIsPending = GetThreadCount (pCtx) > 1;
if (uiCode) {
int16_t pMv[LIST_A][2] = { {0, 0}, { 0, 0 } };
@@ -1696,7 +1696,7 @@
SDeblockingFilter pFilter;
int32_t iFilterIdc = 1;
- if (pCtx->pThreadCtx && pSliceHeader->uiDisableDeblockingFilterIdc != 1) {
+ if (pSliceHeader->uiDisableDeblockingFilterIdc != 1) {
WelsDeblockingInitFilter (pCtx, pFilter, iFilterIdc);
}
@@ -1764,11 +1764,15 @@
pCurDqLayer->iMbX = iMbX;
pCurDqLayer->iMbY = iMbY;
pCurDqLayer->iMbXyIndex = iNextMbXyIndex;
- if ((iMbY > iLastMby) && (iLastMbx == pCurDqLayer->iMbWidth - 1)) {
- SET_EVENT (&pCtx->pDec->pReadyEvent[iLastMby]);
+ if (GetThreadCount (pCtx) > 1) {
+ if ((iMbY > iLastMby) && (iLastMbx == pCurDqLayer->iMbWidth - 1)) {
+ SET_EVENT (&pCtx->pDec->pReadyEvent[iLastMby]);
+ }
}
} while (1);
- SET_EVENT (&pCtx->pDec->pReadyEvent[pCurDqLayer->iMbY]);
+ if (GetThreadCount (pCtx) > 1) {
+ SET_EVENT (&pCtx->pDec->pReadyEvent[pCurDqLayer->iMbY]);
+ }
return ERR_NONE;
}
@@ -2467,7 +2471,7 @@
pCurDqLayer->pInterPredictionDoneFlag[iMbXy] = 0;
memset (pCurDqLayer->pDec->pRefIndex[0][iMbXy], 0, sizeof (int8_t) * 16);
- bool bIsPending = pCtx->pThreadCtx != NULL;
+ bool bIsPending = GetThreadCount (pCtx) > 1;
pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[0] && (ppRefPic[0]->bIsComplete
|| bIsPending));
//predict iMv
@@ -2564,7 +2568,7 @@
pCurDqLayer->pInterPredictionDoneFlag[iMbXy] = 0;
memset (pCurDqLayer->pDec->pRefIndex[LIST_0][iMbXy], 0, sizeof (int8_t) * 16);
memset (pCurDqLayer->pDec->pRefIndex[LIST_1][iMbXy], 0, sizeof (int8_t) * 16);
- bool bIsPending = pCtx->pThreadCtx != NULL;
+ bool bIsPending = GetThreadCount (pCtx) > 1;
pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPicL0[0] && (ppRefPicL0[0]->bIsComplete
|| bIsPending)) || ! (ppRefPicL1[0] && (ppRefPicL1[0]->bIsComplete || bIsPending));
--- a/codec/decoder/core/src/decoder.cpp
+++ b/codec/decoder/core/src/decoder.cpp
@@ -151,8 +151,7 @@
for (int32_t i = 0; i < pPicNewBuf->iCapacity; i++) {
pPicNewBuf->ppPic[i]->bUsedAsRef = false;
pPicNewBuf->ppPic[i]->bIsLongRef = false;
- pPicNewBuf->ppPic[i]->uiRefCount = 0;
- pPicNewBuf->ppPic[i]->bAvailableFlag = true;
+ pPicNewBuf->ppPic[i]->iRefCount = 0;
pPicNewBuf->ppPic[i]->bIsComplete = false;
}
// remove old PicBuf
@@ -240,8 +239,7 @@
for (int32_t i = 0; i < pPicNewBuf->iCapacity; i++) {
pPicNewBuf->ppPic[i]->bUsedAsRef = false;
pPicNewBuf->ppPic[i]->bIsLongRef = false;
- pPicNewBuf->ppPic[i]->uiRefCount = 0;
- pPicNewBuf->ppPic[i]->bAvailableFlag = true;
+ pPicNewBuf->ppPic[i]->iRefCount = 0;
pPicNewBuf->ppPic[i]->bIsComplete = false;
}
// remove old PicBuf
@@ -440,7 +438,7 @@
iNumRefFrames = MAX_REF_PIC_COUNT + 2;
} else {
iNumRefFrames = pCtx->pSps->iNumRefFrames + 2;
- if (pCtx->pThreadCtx != NULL) {
+ if (GetThreadCount (pCtx) > 1) {
iNumRefFrames = MAX_REF_PIC_COUNT + 1;
}
}
@@ -484,7 +482,7 @@
&& kiPicHeight == pCtx->iImgHeightInPixel) && (!bNeedChangePicQueue)) // have same scaled buffer
// sync update pRefList
- if (pCtx->pThreadCtx == NULL) {
+ if (GetThreadCount (pCtx) <= 1) {
WelsResetRefPic (pCtx); // added to sync update ref list due to pictures are free
}
@@ -562,7 +560,7 @@
if (NULL != pPicBuff && NULL != *pPicBuff) {
DestroyPicBuff (pCtx, pPicBuff, pMa);
}
- if (pCtx->pThreadCtx != NULL) {
+ if (GetThreadCount (pCtx) > 1) {
//prevent from double destruction of PPicBuff
PWelsDecoderThreadCTX pThreadCtx = (PWelsDecoderThreadCTX) (pCtx->pThreadCtx);
int32_t threadCount = pThreadCtx->sThreadInfo.uiThrMaxNum;
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -221,10 +221,10 @@
ppDst[1] = ppDst[1] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
pDstInfo->iBufferStatus = 1;
- if (pCtx->pThreadCtx != NULL && pPic->bIsComplete == false) {
+ if (GetThreadCount (pCtx) > 1 && pPic->bIsComplete == false) {
pPic->bIsComplete = true;
}
- if (pCtx->pThreadCtx != NULL) {
+ if (GetThreadCount (pCtx) > 1) {
uint32_t uiMbHeight = (pCtx->pDec->iHeightInPixel + 15) >> 4;
for (uint32_t i = 0; i < uiMbHeight; ++i) {
SET_EVENT (&pCtx->pDec->pReadyEvent[i]);
@@ -231,7 +231,7 @@
}
}
bool bOutResChange = false;
- if (pCtx->pThreadCtx == NULL || pCtx->pLastThreadCtx == NULL) {
+ if (GetThreadCount (pCtx) <= 1 || pCtx->pLastThreadCtx == NULL) {
bOutResChange = (pCtx->iLastImgWidthInPixel != pDstInfo->UsrData.sSystemBuffer.iWidth)
|| (pCtx->iLastImgHeightInPixel != pDstInfo->UsrData.sSystemBuffer.iHeight);
} else {
@@ -2282,7 +2282,7 @@
*/
int32_t AllocPicBuffOnNewSeqBegin (PWelsDecoderContext pCtx) {
//try to allocate or relocate DPB memory only when new sequence is coming.
- if (pCtx->pThreadCtx == NULL) {
+ if (GetThreadCount (pCtx) <= 1) {
WelsResetRefPic (pCtx); //clear ref pPic when IDR NAL
}
int32_t iErr = SyncPictureResolutionExt (pCtx, pCtx->pSps->iMbWidth, pCtx->pSps->iMbHeight);
@@ -2418,7 +2418,7 @@
int32_t InitRefPicList (PWelsDecoderContext pCtx, const uint8_t kuiNRi, int32_t iPoc) {
int32_t iRet = ERR_NONE;
- if (pCtx->pThreadCtx != NULL && pCtx->bNewSeqBegin) {
+ if (GetThreadCount (pCtx) > 1 && pCtx->bNewSeqBegin) {
WelsResetRefPic (pCtx);
}
if (pCtx->eSliceType == B_SLICE) {
@@ -2495,6 +2495,7 @@
pLastThreadCtx->iPicBuffIdx);
}
}
+ int32_t iThreadCount = GetThreadCount (pCtx);
int32_t iPpsId = 0;
int32_t iRet = ERR_NONE;
@@ -2542,7 +2543,7 @@
}
}
bool isNewFrame = true;
- if (pThreadCtx != NULL) {
+ if (iThreadCount > 1) {
isNewFrame = pCtx->pDec == NULL;
}
if (pCtx->pDec == NULL) {
@@ -2553,7 +2554,6 @@
uint32_t i = 0;
while (i < MAX_DPB_COUNT && pLastThreadCtx->pCtx->sRefPic.pRefList[listIdx][i]) {
pLastThreadCtx->pDec->pRefPic[listIdx][i] = pLastThreadCtx->pCtx->sRefPic.pRefList[listIdx][i];
- pLastThreadCtx->pDec->pRefPic[listIdx][i]->bAvailableFlag = false;
++i;
}
}
@@ -2563,30 +2563,8 @@
} else {
pCtx->sRefPic = pLastThreadCtx->pCtx->sRefPic;
}
- //printf ("last uiDecodingTimeStamp = %d\n", pLastThreadCtx->pCtx->uiDecodingTimeStamp);
- for (int32_t i = 0; i < pCtx->sRefPic.uiRefCount[LIST_0]; ++i) {
- if (pCtx->sRefPic.pRefList[LIST_0][i] != NULL) {
- pCtx->sRefPic.pRefList[LIST_0][i]->bAvailableFlag = false;
- }
- }
- for (int32_t i = 0; i < pCtx->sRefPic.uiRefCount[LIST_1]; ++i) {
- if (pCtx->sRefPic.pRefList[LIST_1][i] != NULL) {
- pCtx->sRefPic.pRefList[LIST_1][i]->bAvailableFlag = false;
- }
- }
}
pCtx->pDec = PrefetchPic (pCtx->pPicBuff);
- if (pThreadCtx != NULL) {
- if (pCtx->pDec != NULL) {
- pCtx->pDec->bAvailableFlag = false;
- pCtx->pDec->bIsUngroupedMultiSlice = false;
- pThreadCtx->pDec = pCtx->pDec;
- uint32_t uiMbHeight = (pCtx->pDec->iHeightInPixel + 15) >> 4;
- for (uint32_t i = 0; i < uiMbHeight; ++i) {
- RESET_EVENT (&pCtx->pDec->pReadyEvent[i]);
- }
- }
- }
if (pCtx->iTotalNumMbRec != 0)
pCtx->iTotalNumMbRec = 0;
@@ -2598,6 +2576,15 @@
pCtx->iErrorCode |= dsOutOfMemory;
return ERR_INFO_REF_COUNT_OVERFLOW;
}
+ if (pThreadCtx != NULL) {
+ pCtx->pDec->bIsUngroupedMultiSlice = false;
+ pThreadCtx->pDec = pCtx->pDec;
+ if (iThreadCount > 1) ++pCtx->pDec->iRefCount;
+ uint32_t uiMbHeight = (pCtx->pDec->iHeightInPixel + 15) >> 4;
+ for (uint32_t i = 0; i < uiMbHeight; ++i) {
+ RESET_EVENT (&pCtx->pDec->pReadyEvent[i]);
+ }
+ }
pCtx->pDec->bNewSeqBegin = pCtx->bNewSeqBegin; //set flag for start decoding
} else if (pCtx->iTotalNumMbRec == 0) { //pDec != NULL, already start
pCtx->pDec->bNewSeqBegin = pCtx->bNewSeqBegin; //set flag for start decoding
@@ -2743,7 +2730,7 @@
if (pSh->eSliceType == B_SLICE && !pSh->iDirectSpatialMvPredFlag)
ComputeColocatedTemporalScaling (pCtx);
- if (pThreadCtx != NULL) {
+ if (iThreadCount > 1) {
memset (&pCtx->lastReadyHeightOffset[0][0], -1, LIST_A * MAX_REF_PIC_COUNT * sizeof (int16_t));
SET_EVENT (&pThreadCtx->sSliceDecodeStart);
iRet = WelsDecodeAndConstructSlice (pCtx);
@@ -2765,7 +2752,7 @@
}
}
- if (pThreadCtx == NULL && bReconstructSlice) {
+ if (iThreadCount <= 1 && bReconstructSlice) {
if ((iRet = WelsDecodeConstructSlice (pCtx, pNalCur)) != ERR_NONE) {
pCtx->pDec->bIsComplete = false; // reconstruction error, directly set the flag false
return iRet;
@@ -2772,7 +2759,7 @@
}
}
if (bAllRefComplete && pCtx->eSliceType != I_SLICE) {
- if (pCtx->pThreadCtx == NULL) {
+ if (iThreadCount <= 1) {
if (pCtx->sRefPic.uiRefCount[LIST_0] > 0) {
bAllRefComplete &= CheckRefPicturesComplete (pCtx);
} else {
@@ -2829,17 +2816,22 @@
}
}
- if (pThreadCtx != NULL && pCtx->uiDecodingTimeStamp > 1 && pCtx->pLastDecPicInfo->uiDecodingTimeStamp > 0) {
- while (pCtx->uiDecodingTimeStamp > pCtx->pLastDecPicInfo->uiDecodingTimeStamp + 1) {
- WelsSleep (1);
+ if (iThreadCount >= 1) {
+ int32_t id = pThreadCtx->sThreadInfo.uiThrNum;
+ for (int32_t i = 0; i < iThreadCount; ++i) {
+ if (i != id) {
+ if (pThreadCtx[i - id].sSliceDecodeStart.isSignaled) {
+ while (pThreadCtx[i - id].pCtx->uiDecodingTimeStamp < pCtx->uiDecodingTimeStamp) {
+ WelsSleep (1);
+ }
+ }
+ }
}
- }
- if (pThreadCtx != NULL) {
pCtx->pLastDecPicInfo->uiDecodingTimeStamp = pCtx->uiDecodingTimeStamp;
}
iRet = DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
if (iRet) {
- if (pThreadCtx != NULL) {
+ if (iThreadCount > 1) {
SET_EVENT (&pThreadCtx->sSliceDecodeFinsh);
}
return iRet;
@@ -2847,7 +2839,7 @@
pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb = pCtx->pDec; //store latest decoded picture for EC
pCtx->bUsedAsRef = pCtx->uiNalRefIdc > 0;
- if (pCtx->pThreadCtx == NULL) {
+ if (iThreadCount <= 1) {
if (pCtx->bUsedAsRef) {
for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
uint32_t i = 0;
@@ -2870,7 +2862,7 @@
pCtx->pDec->iLinesize,
pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture);
}
- } else {
+ } else if (iThreadCount > 1) {
SET_EVENT (&pThreadCtx->sImageReady);
}
pCtx->pDec = NULL; //after frame decoding, always set to NULL
@@ -2881,10 +2873,9 @@
pCtx->pLastDecPicInfo->iPrevFrameNum = pSh->iFrameNum;
if (pCtx->pLastDecPicInfo->bLastHasMmco5)
pCtx->pLastDecPicInfo->iPrevFrameNum = 0;
- if (pThreadCtx != NULL) {
- int32_t threadCount = pThreadCtx->sThreadInfo.uiThrMaxNum;
+ if (iThreadCount > 1) {
int32_t id = pThreadCtx->sThreadInfo.uiThrNum;
- for (int32_t i = 0; i < threadCount; ++i) {
+ for (int32_t i = 0; i < iThreadCount; ++i) {
if (pThreadCtx[i - id].pCtx != NULL) {
unsigned long long uiTimeStamp = pThreadCtx[i - id].pCtx->uiTimeStamp;
if (uiTimeStamp > 0 && pThreadCtx[i - id].pCtx->sSpsPpsCtx.iSeqId > pCtx->sSpsPpsCtx.iSeqId) {
@@ -2899,7 +2890,7 @@
}
}
}
- if (pThreadCtx != NULL) {
+ if (iThreadCount > 1) {
SET_EVENT (&pThreadCtx->sSliceDecodeFinsh);
}
return ERR_NONE;
--- a/codec/decoder/core/src/manage_dec_ref.cpp
+++ b/codec/decoder/core/src/manage_dec_ref.cpp
@@ -80,6 +80,7 @@
pRef->uiSpatialId = -1;
pRef->iSpsId = -1;
pRef->bIsComplete = false;
+ pRef->iRefCount = 0;
if (pRef->eSliceType == I_SLICE) {
return;
@@ -88,7 +89,7 @@
for (int32_t i = 0; i < MAX_DPB_COUNT; ++i) {
for (int32_t list = 0; list < lists; ++list) {
if (pRef->pRefPic[list][i] != NULL) {
- pRef->pRefPic[list][i]->bAvailableFlag = true;
+ pRef->pRefPic[list][i]->iRefCount = 0;
pRef->pRefPic[list][i] = NULL;
}
}
@@ -781,8 +782,8 @@
for (i = 0; i < pRefPic->uiShortRefCount[LIST_0]; i++) {
if (pRefPic->pShortRefList[LIST_0][i]->iFrameNum == iFrameNum) {
iMoveSize = pRefPic->uiShortRefCount[LIST_0] - i - 1;
- pRefPic->pShortRefList[LIST_0][i]->bUsedAsRef = false;
pPic = pRefPic->pShortRefList[LIST_0][i];
+ pPic->bUsedAsRef = false;
pRefPic->pShortRefList[LIST_0][i] = NULL;
if (iMoveSize > 0) {
memmove (&pRefPic->pShortRefList[LIST_0][i], &pRefPic->pShortRefList[LIST_0][i + 1],
--- a/codec/decoder/core/src/mv_pred.cpp
+++ b/codec/decoder/core/src/mv_pred.cpp
@@ -315,7 +315,7 @@
mbType = GetMbType (pCurDqLayer)[iMbXy];
PPicture colocPic = pCtx->sRefPic.pRefList[LIST_1][0];
- if (pCtx->pThreadCtx != NULL) {
+ if (GetThreadCount (pCtx) > 1) {
if (16 * pCurDqLayer->iMbY > pCtx->lastReadyHeightOffset[1][0]) {
if (colocPic->pReadyEvent[pCurDqLayer->iMbY].isSignaled != 1) {
WAIT_EVENT (&colocPic->pReadyEvent[pCurDqLayer->iMbY], WELS_DEC_THREAD_WAIT_INFINITE);
--- a/codec/decoder/core/src/parse_mb_syn_cabac.cpp
+++ b/codec/decoder/core/src/parse_mb_syn_cabac.cpp
@@ -535,7 +535,7 @@
pRefCount[0] = pSliceHeader->uiRefCount[0];
pRefCount[1] = pSliceHeader->uiRefCount[1];
- bool bIsPending = pCtx->pThreadCtx != NULL;
+ bool bIsPending = GetThreadCount (pCtx) > 1;
switch (pCurDqLayer->pDec->pMbType[iMbXy]) {
case MB_TYPE_16x16: {
@@ -741,7 +741,7 @@
MbType mbType = pCurDqLayer->pDec->pMbType[iMbXy];
- bool bIsPending = pCtx->pThreadCtx != NULL;
+ bool bIsPending = GetThreadCount (pCtx) > 1;
if (IS_DIRECT (mbType)) {
--- a/codec/decoder/core/src/parse_mb_syn_cavlc.cpp
+++ b/codec/decoder/core/src/parse_mb_syn_cavlc.cpp
@@ -1083,7 +1083,7 @@
iRefCount[0] = pSliceHeader->uiRefCount[0];
iRefCount[1] = pSliceHeader->uiRefCount[1];
- bool bIsPending = pCtx->pThreadCtx != NULL;
+ bool bIsPending = GetThreadCount (pCtx) > 1;
switch (pCurDqLayer->pDec->pMbType[iMbXy]) {
case MB_TYPE_16x16: {
@@ -1348,7 +1348,7 @@
iRefCount[0] = pSliceHeader->uiRefCount[0];
iRefCount[1] = pSliceHeader->uiRefCount[1];
- bool bIsPending = pCtx->pThreadCtx != NULL;
+ bool bIsPending = GetThreadCount (pCtx) > 1;
MbType mbType = pCurDqLayer->pDec->pMbType[iMbXy];
if (IS_DIRECT (mbType)) {
--- a/codec/decoder/core/src/pic_queue.cpp
+++ b/codec/decoder/core/src/pic_queue.cpp
@@ -106,12 +106,14 @@
pPic->iWidthInPixel = kiPicWidth;
pPic->iHeightInPixel = kiPicHeight;
pPic->iFrameNum = -1;
- pPic->bAvailableFlag = true;
+ pPic->iRefCount = 0;
uint32_t uiMbWidth = (kiPicWidth + 15) >> 4;
uint32_t uiMbHeight = (kiPicHeight + 15) >> 4;
uint32_t uiMbCount = uiMbWidth * uiMbHeight;
+
pPic->pMbCorrectlyDecodedFlag = (bool*)pMa->WelsMallocz (uiMbCount * sizeof (bool), "pPic->pMbCorrectlyDecodedFlag");
+
pPic->pMbType = (uint32_t*)pMa->WelsMallocz (uiMbCount * sizeof (uint32_t), "pPic->pMbType");
pPic->pMv[LIST_0] = (int16_t (*)[16][2])pMa->WelsMallocz (uiMbCount * sizeof (
int16_t) * MV_A * MB_BLOCK4x4_NUM, "pPic->pMv[]");
@@ -182,8 +184,8 @@
}
for (iPicIdx = pPicBuf->iCurrentIdx + 1; iPicIdx < pPicBuf->iCapacity ; ++iPicIdx) {
- if (pPicBuf->ppPic[iPicIdx] != NULL && pPicBuf->ppPic[iPicIdx]->bAvailableFlag
- && !pPicBuf->ppPic[iPicIdx]->bUsedAsRef) {
+ if (pPicBuf->ppPic[iPicIdx] != NULL && !pPicBuf->ppPic[iPicIdx]->bUsedAsRef
+ && pPicBuf->ppPic[iPicIdx]->iRefCount <= 0) {
pPic = pPicBuf->ppPic[iPicIdx];
break;
}
@@ -194,8 +196,8 @@
return pPic;
}
for (iPicIdx = 0 ; iPicIdx <= pPicBuf->iCurrentIdx ; ++iPicIdx) {
- if (pPicBuf->ppPic[iPicIdx] != NULL && pPicBuf->ppPic[iPicIdx]->bAvailableFlag
- && !pPicBuf->ppPic[iPicIdx]->bUsedAsRef) {
+ if (pPicBuf->ppPic[iPicIdx] != NULL && !pPicBuf->ppPic[iPicIdx]->bUsedAsRef
+ && pPicBuf->ppPic[iPicIdx]->iRefCount <= 0) {
pPic = pPicBuf->ppPic[iPicIdx];
break;
}
--- a/codec/decoder/core/src/rec_mb.cpp
+++ b/codec/decoder/core/src/rec_mb.cpp
@@ -252,7 +252,7 @@
iFullMVy = WELS_CLIP3 (iFullMVy, ((-PADDING_LENGTH + 2) * (1 << 2)),
((pMCRefMem->iPicHeight + PADDING_LENGTH - 19) * (1 << 2)));
- if (pCtx->pThreadCtx != NULL && iRefIdx >= 0) {
+ if (GetThreadCount (pCtx) > 1 && iRefIdx >= 0) {
// wait for the lines of reference macroblock (3 + 16).
PPicture pRefPic = pCtx->sRefPic.pRefList[listIdx][iRefIdx];
if (pCtx->bNewSeqBegin && (pCtx->iErrorCode & dsRefLost)) {
--- a/codec/decoder/plus/inc/welsDecoderExt.h
+++ b/codec/decoder/plus/inc/welsDecoderExt.h
@@ -120,6 +120,7 @@
bool m_bIsBaseline;
int32_t m_iCpuCount;
int32_t m_iThreadCount;
+ int32_t m_iCtxCount;
PPicBuff m_pPicBuff;
bool m_bParamSetsLostFlag;
bool m_bFreezeOutput;
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -105,7 +105,9 @@
RESET_EVENT (&pLastThreadCtx->sSliceDecodeStart);
}
pThrCtx->pDec = NULL;
- RESET_EVENT (&pThrCtx->sSliceDecodeFinsh);
+ if (GetThreadCount (pThrCtx->pCtx) > 1) {
+ RESET_EVENT (&pThrCtx->sSliceDecodeFinsh);
+ }
iRet |= pWelsDecoder->DecodeFrame2WithCtx (pThrCtx->pCtx, NULL, 0, pThrCtx->ppDst, &pThrCtx->sDstInfo);
//WelsMutexUnlock (&pWelsDecoder->m_csDecoder);
@@ -133,7 +135,8 @@
m_uiDecodeTimeStamp (0),
m_bIsBaseline (false),
m_iCpuCount (1),
- m_iThreadCount (1),
+ m_iThreadCount (0),
+ m_iCtxCount (1),
m_pPicBuff (NULL),
m_bParamSetsLostFlag (false),
m_bFreezeOutput (false),
@@ -167,8 +170,9 @@
if (m_iCpuCount > WELS_DEC_MAX_NUM_CPU) {
m_iCpuCount = WELS_DEC_MAX_NUM_CPU;
}
- m_pDecThrCtx = new SWelsDecoderThreadCTX[m_iThreadCount];
- memset (m_pDecThrCtx, 0, sizeof (SWelsDecoderThreadCTX)*m_iThreadCount);
+
+ m_pDecThrCtx = new SWelsDecoderThreadCTX[m_iCtxCount];
+ memset (m_pDecThrCtx, 0, sizeof (SWelsDecoderThreadCTX)*m_iCtxCount);
for (int32_t i = 0; i < WELS_DEC_MAX_NUM_CPU; ++i) {
m_pDecThrCtxActive[i] = NULL;
}
@@ -277,7 +281,7 @@
}
void CWelsDecoder::UninitDecoder (void) {
- for (int32_t i = 0; i < m_iThreadCount; ++i) {
+ for (int32_t i = 0; i < m_iCtxCount; ++i) {
if (m_pDecThrCtx[i].pCtx != NULL) {
if (i > 0) {
WelsResetRefPicWithoutUnRef (m_pDecThrCtx[i].pCtx);
@@ -288,7 +292,7 @@
}
void CWelsDecoder::OpenDecoderThreads() {
- if (m_iThreadCount > 1) {
+ if (m_iThreadCount >= 1) {
m_uiDecodeTimeStamp = 0;
CREATE_SEMAPHORE (&m_sIsBusy, m_iThreadCount, m_iThreadCount, NULL);
WelsMutexInit (&m_csDecoder);
@@ -318,7 +322,7 @@
}
}
void CWelsDecoder::CloseDecoderThreads() {
- if (m_iThreadCount > 1) {
+ if (m_iThreadCount >= 1) {
for (int32_t i = 0; i < m_iThreadCount; i++) { //waiting the completion begun slices
WAIT_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsIdle, WELS_DEC_THREAD_WAIT_INFINITE);
m_pDecThrCtx[i].sThreadInfo.uiCommand = WELS_DEC_THREAD_COMMAND_ABORT;
@@ -367,8 +371,8 @@
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
"CWelsDecoder::init_decoder(), openh264 codec version = %s, ParseOnly = %d",
VERSION_NUMBER, (int32_t)pParam->bParseOnly);
- if (m_iThreadCount > 1 && pParam->bParseOnly) {
- m_iThreadCount = 1;
+ if (m_iThreadCount >= 1 && pParam->bParseOnly) {
+ m_iThreadCount = 0;
}
OpenDecoderThreads();
//reset decoder context
@@ -377,9 +381,9 @@
memset (&m_sVlcTable, 0, sizeof (SVlcTable));
UninitDecoder();
WelsDecoderLastDecPicInfoDefaults (m_sLastDecPicInfo);
- for (int32_t i = 0; i < m_iThreadCount; ++i) {
+ for (int32_t i = 0; i < m_iCtxCount; ++i) {
InitDecoderCtx (m_pDecThrCtx[i].pCtx, pParam);
- if (m_iThreadCount > 1) {
+ if (m_iThreadCount >= 1) {
m_pDecThrCtx[i].pCtx->pThreadCtx = &m_pDecThrCtx[i];
}
}
@@ -429,7 +433,7 @@
int32_t CWelsDecoder::ResetDecoder (PWelsDecoderContext& pCtx) {
// TBC: need to be modified when context and trace point are null
- if (m_iThreadCount > 1) {
+ if (m_iThreadCount >= 1) {
ThreadResetDecoder (pCtx);
} else {
if (pCtx != NULL && m_pWelsTrace != NULL) {
@@ -472,9 +476,8 @@
if (eOptID == DECODER_OPTION_NUM_OF_THREADS) {
if (pOption != NULL) {
int32_t threadCount = * ((int32_t*)pOption);
- if (threadCount <= 0) {
- threadCount = 1;
- } else if (threadCount > m_iCpuCount) {
+ if (threadCount < 0) threadCount = 0;
+ if (threadCount > m_iCpuCount) {
threadCount = m_iCpuCount;
}
if (threadCount > 3) {
@@ -484,14 +487,15 @@
m_iThreadCount = threadCount;
if (m_pDecThrCtx != NULL) {
delete [] m_pDecThrCtx;
- m_pDecThrCtx = new SWelsDecoderThreadCTX[m_iThreadCount];
- memset (m_pDecThrCtx, 0, sizeof (SWelsDecoderThreadCTX)*m_iThreadCount);
+ m_iCtxCount = m_iThreadCount == 0 ? 1 : m_iThreadCount;
+ m_pDecThrCtx = new SWelsDecoderThreadCTX[m_iCtxCount];
+ memset (m_pDecThrCtx, 0, sizeof (SWelsDecoderThreadCTX)*m_iCtxCount);
}
}
}
return cmResultSuccess;
}
- for (int32_t i = 0; i < m_iThreadCount; ++i) {
+ for (int32_t i = 0; i < m_iCtxCount; ++i) {
PWelsDecoderContext pDecContext = m_pDecThrCtx[i].pCtx;
if (pDecContext == NULL && eOptID != DECODER_OPTION_TRACE_LEVEL &&
eOptID != DECODER_OPTION_TRACE_CALLBACK && eOptID != DECODER_OPTION_TRACE_CALLBACK_CONTEXT)
@@ -502,6 +506,8 @@
iVal = * ((int*)pOption); // boolean value for whether enabled End Of Stream flag
+ if (pDecContext == NULL) return dsInitialOptExpected;
+
pDecContext->bEndOfStreamFlag = iVal ? true : false;
return cmResultSuccess;
@@ -509,6 +515,8 @@
if (pOption == NULL)
return cmInitParaError;
+ if (pDecContext == NULL) return dsInitialOptExpected;
+
iVal = * ((int*)pOption); // int value for error concealment idc
iVal = WELS_CLIP3 (iVal, (int32_t)ERROR_CON_DISABLE, (int32_t)ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE);
if ((pDecContext->pParam->bParseOnly) && (iVal != (int32_t)ERROR_CON_DISABLE)) {
@@ -550,6 +558,7 @@
return cmInitParaError;
} else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {
if (pOption) {
+ if (pDecContext == NULL) return dsInitialOptExpected;
pDecContext->pDecoderStatistics->iStatisticsLogInterval = (* ((unsigned int*)pOption));
return cmResultSuccess;
}
@@ -681,7 +690,7 @@
unsigned char** ppDst,
SBufferInfo* pDstInfo) {
int iRet = dsErrorFree;
- if (m_iThreadCount > 1) {
+ if (m_iThreadCount >= 1) {
iRet = ThreadDecodeFrameInternal (kpSrc, kiSrcLen, ppDst, pDstInfo);
if (m_sReoderingStatus.iNumOfPicts) {
WAIT_EVENT (&m_sBufferingEvent, WELS_DEC_THREAD_WAIT_INFINITE);
@@ -742,6 +751,9 @@
}
#endif//OUTPUT_BIT_STREAM
pDecContext->bEndOfStreamFlag = false;
+ if (GetThreadCount (pDecContext) <= 0) {
+ pDecContext->uiDecodingTimeStamp = ++m_uiDecodeTimeStamp;
+ }
} else {
//For application MODE, the error detection should be added for safe.
//But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
@@ -752,13 +764,13 @@
int64_t iStart, iEnd;
iStart = WelsTime();
- if (pDecContext->pThreadCtx == NULL) {
+ if (GetThreadCount (pDecContext) <= 1) {
ppDst[0] = ppDst[1] = ppDst[2] = NULL;
}
pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize
unsigned long long uiInBsTimeStamp = pDstInfo->uiInBsTimeStamp;
- if (pDecContext->pThreadCtx == NULL) {
+ if (GetThreadCount (pDecContext) <= 1) {
memset (pDstInfo, 0, sizeof (SBufferInfo));
}
pDstInfo->uiInBsTimeStamp = uiInBsTimeStamp;
@@ -856,7 +868,7 @@
OutputStatisticsLog (*pDecContext->pDecoderStatistics);
- if (pDecContext->pThreadCtx != NULL) {
+ if (GetThreadCount (pDecContext) >= 1) {
WAIT_EVENT (&m_sReleaseBufferEvent, WELS_DEC_THREAD_WAIT_INFINITE);
RESET_EVENT (&m_sBufferingEvent);
BufferingReadyPicture (pDecContext, ppDst, pDstInfo);
@@ -882,7 +894,7 @@
iEnd = WelsTime();
pDecContext->dDecTime += (iEnd - iStart) / 1e3;
- if (pDecContext->pThreadCtx != NULL) {
+ if (GetThreadCount (pDecContext) >= 1) {
WAIT_EVENT (&m_sReleaseBufferEvent, WELS_DEC_THREAD_WAIT_INFINITE);
RESET_EVENT (&m_sBufferingEvent);
BufferingReadyPicture (pDecContext, ppDst, pDstInfo);
@@ -904,9 +916,11 @@
DECODING_STATE CWelsDecoder::FlushFrame (unsigned char** ppDst,
SBufferInfo* pDstInfo) {
bool bEndOfStreamFlag = true;
- for (int32_t j = 0; j < m_iThreadCount; ++j) {
- if (!m_pDecThrCtx[j].pCtx->bEndOfStreamFlag) {
- bEndOfStreamFlag = false;
+ if (m_iThreadCount <= 1) {
+ for (int32_t j = 0; j < m_iCtxCount; ++j) {
+ if (!m_pDecThrCtx[j].pCtx->bEndOfStreamFlag) {
+ bEndOfStreamFlag = false;
+ }
}
}
if (bEndOfStreamFlag && m_sReoderingStatus.iNumOfPicts > 0) {
@@ -934,9 +948,10 @@
ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
- PPicBuff pPicBuff = m_iThreadCount == 1 ? m_pDecThrCtx[0].pCtx->pPicBuff : m_pPicBuff;
+ PPicBuff pPicBuff = m_iThreadCount <= 1 ? m_pDecThrCtx[0].pCtx->pPicBuff : m_pPicBuff;
if (m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx < pPicBuff->iCapacity) {
- pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
+ PPicture pPic = pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx];
+ --pPic->iRefCount;
}
m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;
m_sReoderingStatus.iMinPOC = IMinInt32;
@@ -1001,6 +1016,7 @@
if (m_sReoderingStatus.iNumOfPicts && pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb
&& pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb->bNewSeqBegin) {
m_sReoderingStatus.iLastGOPRemainPicts = m_sReoderingStatus.iNumOfPicts;
+
for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
if (m_sPictInfoList[i].iPOC > IMinInt32) {
m_sPictInfoList[i].bLastGOP = true;
@@ -1036,7 +1052,7 @@
m_sPictInfoList[i].iPOC = pCtx->pSliceHeader->iPicOrderCntLsb;
m_sPictInfoList[i].uiDecodingTimeStamp = pCtx->uiDecodingTimeStamp;
m_sPictInfoList[i].iPicBuffIdx = pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb->iPicBuffIdx;
- pCtx->pPicBuff->ppPic[m_sPictInfoList[i].iPicBuffIdx]->bAvailableFlag = false;
+ if (GetThreadCount (pCtx) <= 1) ++pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb->iRefCount;
m_sPictInfoList[i].bLastGOP = false;
pDstInfo->iBufferStatus = 0;
++m_sReoderingStatus.iNumOfPicts;
@@ -1051,6 +1067,9 @@
void CWelsDecoder::ReleaseBufferedReadyPicture (PWelsDecoderContext pCtx, unsigned char** ppDst,
SBufferInfo* pDstInfo) {
PPicBuff pPicBuff = pCtx ? pCtx->pPicBuff : m_pPicBuff;
+ if (pCtx == NULL && m_iThreadCount <= 1) {
+ pCtx = m_pDecThrCtx[0].pCtx;
+ }
if (!m_bIsBaseline && m_sReoderingStatus.iLastGOPRemainPicts > 0) {
m_sReoderingStatus.iMinPOC = IMinInt32;
for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
@@ -1075,7 +1094,8 @@
ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
- pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
+ PPicture pPic = pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx];
+ --pPic->iRefCount;
m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;
m_sReoderingStatus.iMinPOC = IMinInt32;
--m_sReoderingStatus.iNumOfPicts;
@@ -1107,7 +1127,8 @@
ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
- pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
+ PPicture pPic = pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx];
+ --pPic->iRefCount;
--m_sReoderingStatus.iNumOfPicts;
}
return;
@@ -1147,7 +1168,8 @@
ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
- pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
+ PPicture pPic = pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx];
+ --pPic->iRefCount;
m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;
m_sReoderingStatus.iMinPOC = IMinInt32;
--m_sReoderingStatus.iNumOfPicts;
@@ -1159,7 +1181,6 @@
SBufferInfo* pDstInfo) {
DECODING_STATE iRet = dsErrorFree;
if (pDstInfo->iBufferStatus == 1) {
- ++pDecContext->uiDecodingTimeStamp;
m_bIsBaseline = pDecContext->pSps->uiProfileIdc == 66 || pDecContext->pSps->uiProfileIdc == 83;
if (!m_bIsBaseline) {
BufferingReadyPicture (pDecContext, ppDst, pDstInfo);
@@ -1364,7 +1385,9 @@
memcpy (&m_pDecThrCtx[signal].sDstInfo, pDstInfo, sizeof (SBufferInfo));
ParseAccessUnit (m_pDecThrCtx[signal]);
- m_pLastDecThrCtx = &m_pDecThrCtx[signal];
+ if (m_iThreadCount > 1) {
+ m_pLastDecThrCtx = &m_pDecThrCtx[signal];
+ }
m_pDecThrCtx[signal].sThreadInfo.uiCommand = WELS_DEC_THREAD_COMMAND_RUN;
RELEASE_SEMAPHORE (&m_pDecThrCtx[signal].sThreadInfo.sIsActivated);