Merge pull request #2329 from ruil2/layer4
using independent encoder control logic for SAVC case
This commit is contained in:
commit
67f925674a
@ -82,11 +82,11 @@ int32_t InitFunctionPointers (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* _param,
|
||||
/*!
|
||||
* \brief initialize frame coding
|
||||
*/
|
||||
void InitFrameCoding (sWelsEncCtx* pEncCtx, const EVideoFrameType keFrameType);
|
||||
void LoadBackFrameNum(sWelsEncCtx* pEncCtx);
|
||||
|
||||
EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum);
|
||||
void InitFrameCoding (sWelsEncCtx* pEncCtx, const EVideoFrameType keFrameType,const int32_t kiDidx);
|
||||
void LoadBackFrameNum(sWelsEncCtx* pEncCtx,const int32_t kiDidx);
|
||||
|
||||
EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum,const int32_t kiDidx);
|
||||
void InitBitStream(sWelsEncCtx* pEncCtx);
|
||||
int32_t GetTemporalLevel (SSpatialLayerInternal* fDlp, const int32_t kiFrameNum, const int32_t kiGopSize);
|
||||
/*!
|
||||
* \brief Dump reconstruction for dependency layer
|
||||
|
@ -149,10 +149,7 @@ typedef struct TagWelsEncCtx {
|
||||
SLTRState* pLtr;//[MAX_DEPENDENCY_LAYER];
|
||||
bool bCurFrameMarkedAsSceneLtr;
|
||||
// Derived
|
||||
int32_t iCodingIndex;
|
||||
int32_t iFrameIndex; // count how many frames elapsed during coding context currently
|
||||
int32_t iFrameNum; // current frame number coding
|
||||
int32_t iPOC; // frame iPOC
|
||||
|
||||
EWelsSliceType eSliceType; // currently coding slice type
|
||||
EWelsNalUnitType eNalType; // NAL type
|
||||
EWelsNalRefIdc eNalPriority; // NAL_Reference_Idc currently
|
||||
@ -162,7 +159,6 @@ typedef struct TagWelsEncCtx {
|
||||
uint8_t uiDependencyId; // Idc of dependecy layer to be coded
|
||||
uint8_t uiTemporalId; // Idc of temporal layer to be coded
|
||||
bool bNeedPrefixNalFlag; // whether add prefix nal
|
||||
bool bEncCurFrmAsIdrFlag;
|
||||
|
||||
// Rate control routine
|
||||
SWelsSvcRc* pWelsSvcRc;
|
||||
@ -202,7 +198,6 @@ typedef struct TagWelsEncCtx {
|
||||
|
||||
bool bRefOfCurTidIsLtr[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL];
|
||||
uint16_t uiIdrPicId; // IDR picture id: [0, 65535], this one is used for LTR
|
||||
|
||||
int32_t iMaxSliceCount;// maximal count number of slices for all layers observation
|
||||
int16_t iActiveThreadsNum; // number of threads active so far
|
||||
|
||||
|
@ -86,7 +86,13 @@ typedef struct TagDLayerParam {
|
||||
int8_t iHighestTemporalId;
|
||||
float fInputFrameRate; // input frame rate
|
||||
float fOutputFrameRate; // output frame rate
|
||||
|
||||
// uint16_t uiIdrPicId; // IDR picture id: [0, 65535], this one is used for LTR
|
||||
int32_t iSkipFrameFlag; //_GOM_RC_
|
||||
int32_t iCodingIndex;
|
||||
int32_t iFrameIndex; // count how many frames elapsed during coding context currently
|
||||
bool bEncCurFrmAsIdrFlag;
|
||||
int32_t iFrameNum; // current frame number coding
|
||||
int32_t iPOC; // frame iPOC
|
||||
#ifdef ENABLE_FRAME_DUMP
|
||||
char sRecFileName[MAX_FNAME_LEN]; // file to be constructed
|
||||
#endif//ENABLE_FRAME_DUMP
|
||||
|
@ -140,7 +140,7 @@ class CWelsPreProcess {
|
||||
const uint32_t kuiShortRefCount);
|
||||
void UpdateSrcListLosslessScreenRefSelectionWithLtr (SPicture* pCurPicture, const int32_t kiCurDid,
|
||||
const int32_t kuiMarkLongTermPicIdx, SPicture** pLongRefList);
|
||||
|
||||
bool BuildSpatialLayer(sWelsEncCtx* pCtx, const SSourcePicture* kpSrc,int32_t iSpatialLayer);
|
||||
private:
|
||||
int32_t WelsPreprocessCreate();
|
||||
int32_t WelsPreprocessDestroy();
|
||||
|
@ -211,7 +211,7 @@ int32_t InitFunctionPointers (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* pParam,
|
||||
/*init pixel average function*/
|
||||
/*get one column or row pixel when refinement*/
|
||||
InitMcFunc (&pFuncList->sMcFuncs, uiCpuFlag);
|
||||
InitCoeffFunc (pFuncList,uiCpuFlag,pParam->iEntropyCodingModeFlag);
|
||||
InitCoeffFunc (pFuncList, uiCpuFlag, pParam->iEntropyCodingModeFlag);
|
||||
|
||||
WelsInitEncodingFuncs (pFuncList, uiCpuFlag);
|
||||
WelsInitReconstructionFuncs (pFuncList, uiCpuFlag);
|
||||
@ -226,87 +226,97 @@ int32_t InitFunctionPointers (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* pParam,
|
||||
return iReturn;
|
||||
}
|
||||
|
||||
void UpdateFrameNum(sWelsEncCtx* pEncCtx) {
|
||||
void UpdateFrameNum (sWelsEncCtx* pEncCtx, const int32_t kiDidx) {
|
||||
SSpatialLayerInternal* pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[kiDidx];
|
||||
bool bNeedFrameNumIncreasing = false;
|
||||
for (int32_t i=0; i<MAX_DEPENDENCY_LAYER; i++) {
|
||||
if (NRI_PRI_LOWEST != pEncCtx->eLastNalPriority[i]) {
|
||||
bNeedFrameNumIncreasing = true;
|
||||
}
|
||||
|
||||
if (NRI_PRI_LOWEST != pEncCtx->eLastNalPriority[kiDidx]) {
|
||||
bNeedFrameNumIncreasing = true;
|
||||
}
|
||||
|
||||
if (bNeedFrameNumIncreasing) {
|
||||
if (pEncCtx->iFrameNum < (1 << pEncCtx->pSps->uiLog2MaxFrameNum) - 1)
|
||||
++ pEncCtx->iFrameNum;
|
||||
if (pParamInternal->iFrameNum < (1 << pEncCtx->pSps->uiLog2MaxFrameNum) - 1)
|
||||
++ pParamInternal->iFrameNum;
|
||||
else
|
||||
pEncCtx->iFrameNum = 0; // if iFrameNum overflow
|
||||
}
|
||||
for (int32_t i=0; i<MAX_DEPENDENCY_LAYER; i++) {
|
||||
pEncCtx->eLastNalPriority[i] = NRI_PRI_LOWEST;
|
||||
pParamInternal->iFrameNum = 0; // if iFrameNum overflow
|
||||
}
|
||||
|
||||
pEncCtx->eLastNalPriority[kiDidx] = NRI_PRI_LOWEST;
|
||||
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "UpdateFrameNum,bNeedFrameNumIncreasing = %d,iFrameNum = %d,kiDidx = %d",
|
||||
bNeedFrameNumIncreasing, pParamInternal->iFrameNum, kiDidx);
|
||||
}
|
||||
|
||||
|
||||
void LoadBackFrameNum(sWelsEncCtx* pEncCtx) {
|
||||
bool bNeedFrameNumIncreasing = false;
|
||||
for (int32_t i=0; i<MAX_DEPENDENCY_LAYER; i++) {
|
||||
if (NRI_PRI_LOWEST != pEncCtx->eLastNalPriority[i]) {
|
||||
bNeedFrameNumIncreasing = true;
|
||||
}
|
||||
}
|
||||
if (bNeedFrameNumIncreasing) {
|
||||
if (pEncCtx->iFrameNum != 0) {
|
||||
pEncCtx->iFrameNum --;
|
||||
} else {
|
||||
pEncCtx->iFrameNum = (1 << pEncCtx->pSps->uiLog2MaxFrameNum) - 1;
|
||||
}
|
||||
void LoadBackFrameNum (sWelsEncCtx* pEncCtx, const int32_t kiDidx) {
|
||||
SSpatialLayerInternal* pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[kiDidx];
|
||||
bool bNeedFrameNumIncreasing = false;
|
||||
|
||||
if (NRI_PRI_LOWEST != pEncCtx->eLastNalPriority[kiDidx]) {
|
||||
bNeedFrameNumIncreasing = true;
|
||||
}
|
||||
|
||||
if (bNeedFrameNumIncreasing) {
|
||||
if (pParamInternal->iFrameNum != 0) {
|
||||
pParamInternal->iFrameNum --;
|
||||
} else {
|
||||
pParamInternal->iFrameNum = (1 << pEncCtx->pSps->uiLog2MaxFrameNum) - 1;
|
||||
}
|
||||
}
|
||||
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO,
|
||||
"LoadBackFrameNum,bNeedFrameNumIncreasing = %d,iFrameNum = %d,kiDidx = %d", bNeedFrameNumIncreasing,
|
||||
pParamInternal->iFrameNum, kiDidx);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief initialize frame coding
|
||||
*/
|
||||
void InitFrameCoding (sWelsEncCtx* pEncCtx, const EVideoFrameType keFrameType) {
|
||||
void InitBitStream (sWelsEncCtx* pEncCtx) {
|
||||
// for bitstream writing
|
||||
pEncCtx->iPosBsBuffer = 0; // reset bs pBuffer position
|
||||
pEncCtx->pOut->iNalIndex = 0; // reset NAL index
|
||||
pEncCtx->pOut->iLayerBsIndex = 0; // reset index of Layer Bs
|
||||
|
||||
InitBits (&pEncCtx->pOut->sBsWrite, pEncCtx->pOut->pBsBuffer, pEncCtx->pOut->uiSize);
|
||||
|
||||
}
|
||||
/*!
|
||||
* \brief initialize frame coding
|
||||
*/
|
||||
void InitFrameCoding (sWelsEncCtx* pEncCtx, const EVideoFrameType keFrameType, const int32_t kiDidx) {
|
||||
SSpatialLayerInternal* pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[kiDidx];
|
||||
if (keFrameType == videoFrameTypeP) {
|
||||
++pEncCtx->iFrameIndex;
|
||||
++pParamInternal->iFrameIndex;
|
||||
|
||||
if (pEncCtx->iPOC < (1 << pEncCtx->pSps->iLog2MaxPocLsb) - 2) // if iPOC type is no 0, this need be modification
|
||||
pEncCtx->iPOC += 2; // for POC type 0
|
||||
if (pParamInternal->iPOC < (1 << pEncCtx->pSps->iLog2MaxPocLsb) -
|
||||
2) // if iPOC type is no 0, this need be modification
|
||||
pParamInternal->iPOC += 2; // for POC type 0
|
||||
else
|
||||
pEncCtx->iPOC = 0;
|
||||
pParamInternal->iPOC = 0;
|
||||
|
||||
UpdateFrameNum(pEncCtx);
|
||||
UpdateFrameNum (pEncCtx, kiDidx);
|
||||
|
||||
pEncCtx->eNalType = NAL_UNIT_CODED_SLICE;
|
||||
pEncCtx->eSliceType = P_SLICE;
|
||||
pEncCtx->eNalPriority = NRI_PRI_HIGH;
|
||||
} else if (keFrameType == videoFrameTypeIDR) {
|
||||
pEncCtx->iFrameNum = 0;
|
||||
pEncCtx->iPOC = 0;
|
||||
pEncCtx->bEncCurFrmAsIdrFlag = false;
|
||||
pEncCtx->iFrameIndex = 0;
|
||||
pParamInternal->iFrameNum = 0;
|
||||
pParamInternal->iPOC = 0;
|
||||
pParamInternal->bEncCurFrmAsIdrFlag = false;
|
||||
pParamInternal->iFrameIndex = 0;
|
||||
|
||||
pEncCtx->eNalType = NAL_UNIT_CODED_SLICE_IDR;
|
||||
pEncCtx->eSliceType = I_SLICE;
|
||||
pEncCtx->eNalPriority = NRI_PRI_HIGHEST;
|
||||
|
||||
pEncCtx->iCodingIndex = 0;
|
||||
pParamInternal->iCodingIndex = 0;
|
||||
|
||||
// reset_ref_list
|
||||
|
||||
// rc_init_gop
|
||||
} else if (keFrameType == videoFrameTypeI) {
|
||||
if (pEncCtx->iPOC < (1 << pEncCtx->pSps->iLog2MaxPocLsb) - 2) // if iPOC type is no 0, this need be modification
|
||||
pEncCtx->iPOC += 2; // for POC type 0
|
||||
if (pParamInternal->iPOC < (1 << pEncCtx->pSps->iLog2MaxPocLsb) -
|
||||
2) // if iPOC type is no 0, this need be modification
|
||||
pParamInternal->iPOC += 2; // for POC type 0
|
||||
else
|
||||
pEncCtx->iPOC = 0;
|
||||
pParamInternal->iPOC = 0;
|
||||
|
||||
UpdateFrameNum(pEncCtx);
|
||||
UpdateFrameNum (pEncCtx, kiDidx);
|
||||
|
||||
pEncCtx->eNalType = NAL_UNIT_CODED_SLICE;
|
||||
pEncCtx->eSliceType = I_SLICE;
|
||||
@ -322,11 +332,12 @@ void InitFrameCoding (sWelsEncCtx* pEncCtx, const EVideoFrameType keFrameType) {
|
||||
#endif//FRAME_INFO_OUTPUT
|
||||
}
|
||||
|
||||
EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum) {
|
||||
EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum, const int32_t kiDidx) {
|
||||
SWelsSvcCodingParam* pSvcParam = pEncCtx->pSvcParam;
|
||||
SSpatialLayerInternal* pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[kiDidx];
|
||||
EVideoFrameType iFrameType = videoFrameTypeInvalid;
|
||||
bool bSceneChangeFlag = false;
|
||||
|
||||
int32_t iSkipFrameFlag = pSvcParam->bSimulcastAVC?pParamInternal->iSkipFrameFlag:pEncCtx->iSkipFrameFlag;
|
||||
if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
|
||||
if ((!pSvcParam->bEnableSceneChangeDetect) || pEncCtx->pVaa->bIdrPeriodFlag ||
|
||||
(kiSpatialNum < pSvcParam->iSpatialLayerNum)) {
|
||||
@ -334,7 +345,7 @@ EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum
|
||||
} else {
|
||||
bSceneChangeFlag = pEncCtx->pVaa->bSceneChangeFlag;
|
||||
}
|
||||
if (pEncCtx->pVaa->bIdrPeriodFlag || pEncCtx->bEncCurFrmAsIdrFlag || (!pSvcParam->bEnableLongTermReference
|
||||
if (pEncCtx->pVaa->bIdrPeriodFlag || pParamInternal->bEncCurFrmAsIdrFlag || (!pSvcParam->bEnableLongTermReference
|
||||
&& bSceneChangeFlag)) {
|
||||
iFrameType = videoFrameTypeIDR;
|
||||
} else if (pSvcParam->bEnableLongTermReference && (bSceneChangeFlag
|
||||
@ -356,11 +367,11 @@ EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum
|
||||
} else {
|
||||
iFrameType = videoFrameTypeP;
|
||||
}
|
||||
if (videoFrameTypeP == iFrameType && pEncCtx->iSkipFrameFlag > 0) {
|
||||
-- pEncCtx->iSkipFrameFlag;
|
||||
if (videoFrameTypeP == iFrameType && iSkipFrameFlag > 0) {
|
||||
pParamInternal->iSkipFrameFlag = 0;
|
||||
iFrameType = videoFrameTypeSkip;
|
||||
} else if (videoFrameTypeIDR == iFrameType) {
|
||||
pEncCtx->iCodingIndex = 0;
|
||||
pParamInternal->iCodingIndex = 0;
|
||||
pEncCtx->bCurFrameMarkedAsSceneLtr = true;
|
||||
}
|
||||
|
||||
@ -368,7 +379,7 @@ EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum
|
||||
// perform scene change detection
|
||||
if ((!pSvcParam->bEnableSceneChangeDetect) || pEncCtx->pVaa->bIdrPeriodFlag ||
|
||||
(kiSpatialNum < pSvcParam->iSpatialLayerNum)
|
||||
|| (pEncCtx->iFrameIndex < (VGOP_SIZE << 1))) { // avoid too frequent I frame coding, rc control
|
||||
|| (pParamInternal->iFrameIndex < (VGOP_SIZE << 1))) { // avoid too frequent I frame coding, rc control
|
||||
bSceneChangeFlag = false;
|
||||
} else {
|
||||
bSceneChangeFlag = pEncCtx->pVaa->bSceneChangeFlag;
|
||||
@ -378,13 +389,13 @@ EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum
|
||||
//bIdrPeriodFlag: RC disable || iSpatialNum != pSvcParam->iSpatialLayerNum
|
||||
//pEncCtx->bEncCurFrmAsIdrFlag: 1. first frame should be IDR; 2. idr pause; 3. idr request
|
||||
iFrameType = (pEncCtx->pVaa->bIdrPeriodFlag || bSceneChangeFlag
|
||||
|| pEncCtx->bEncCurFrmAsIdrFlag) ? videoFrameTypeIDR : videoFrameTypeP;
|
||||
|| pParamInternal->bEncCurFrmAsIdrFlag) ? videoFrameTypeIDR : videoFrameTypeP;
|
||||
|
||||
if (videoFrameTypeP == iFrameType && pEncCtx->iSkipFrameFlag > 0) { // for frame skip, 1/5/2010
|
||||
-- pEncCtx->iSkipFrameFlag;
|
||||
if (videoFrameTypeP == iFrameType && iSkipFrameFlag > 0) { // for frame skip, 1/5/2010
|
||||
pParamInternal->iSkipFrameFlag = 0;
|
||||
iFrameType = videoFrameTypeSkip;
|
||||
} else if (videoFrameTypeIDR == iFrameType) {
|
||||
pEncCtx->iCodingIndex = 0;
|
||||
pParamInternal->iCodingIndex = 0;
|
||||
}
|
||||
}
|
||||
return iFrameType;
|
||||
|
@ -1206,6 +1206,7 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p
|
||||
while (iDlayerIndex < iDlayerCount) {
|
||||
SDqLayer* pDqLayer = NULL;
|
||||
SSpatialLayerConfig* pDlayer = &pParam->sSpatialLayers[iDlayerIndex];
|
||||
SSpatialLayerInternal* pParamInternal = &pParam->sDependencyLayers[iDlayerIndex];
|
||||
const int32_t kiMbW = (pDlayer->iVideoWidth + 0x0f) >> 4;
|
||||
const int32_t kiMbH = (pDlayer->iVideoHeight + 0x0f) >> 4;
|
||||
int32_t iMaxSliceNum = 1;
|
||||
@ -1213,6 +1214,12 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p
|
||||
if (iMaxSliceNum < kiSliceNum)
|
||||
iMaxSliceNum = kiSliceNum;
|
||||
|
||||
pParamInternal->iSkipFrameFlag = 0;
|
||||
pParamInternal->iCodingIndex = 0;
|
||||
pParamInternal->iFrameIndex = 0;
|
||||
pParamInternal->iFrameNum = 0;
|
||||
pParamInternal->iPOC = 0;
|
||||
pParamInternal->bEncCurFrmAsIdrFlag = true; // make sure first frame is IDR
|
||||
// pDq layers list
|
||||
pDqLayer = (SDqLayer*)pMa->WelsMallocz (sizeof (SDqLayer), "pDqLayer");
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pDqLayer), FreeMemorySvc (ppCtx))
|
||||
@ -1900,7 +1907,6 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingPa
|
||||
(pMa->WelsMallocz (iCountMaxMbNum * sizeof (int32_t), "pSadCostMb"));
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSadCostMb), FreeMemorySvc (ppCtx))
|
||||
|
||||
(*ppCtx)->bEncCurFrmAsIdrFlag = true; // make sure first frame is IDR
|
||||
(*ppCtx)->iGlobalQp = 26; // global qp in default
|
||||
|
||||
(*ppCtx)->pLtr = (SLTRState*)pMa->WelsMalloc (kiNumDependencyLayers * sizeof (SLTRState), "SLTRState");
|
||||
@ -2802,7 +2808,7 @@ void WelsInitCurrentLayer (sWelsEncCtx* pCtx,
|
||||
SDqIdc* pDqIdc = &pCtx->pDqIdcMap[kiCurDid];
|
||||
int32_t iIdx = 0;
|
||||
int32_t iSliceCount = 0;
|
||||
|
||||
SSpatialLayerInternal* pParamInternal = &pParam->sDependencyLayers[kiCurDid];
|
||||
if (NULL == pCurDq)
|
||||
return;
|
||||
|
||||
@ -2856,8 +2862,9 @@ void WelsInitCurrentLayer (sWelsEncCtx* pCtx,
|
||||
|
||||
pNalHdExt->uiDependencyId = kiCurDid;
|
||||
pNalHdExt->bDiscardableFlag = (pCtx->bNeedPrefixNalFlag) ? (pNalHd->uiNalRefIdc == NRI_PRI_LOWEST) : false;
|
||||
pNalHdExt->bIdrFlag = (pCtx->iFrameNum == 0) && ((pCtx->eNalType == NAL_UNIT_CODED_SLICE_IDR)
|
||||
|| (pCtx->eSliceType == I_SLICE));
|
||||
pNalHdExt->bIdrFlag = (pParamInternal->iFrameNum == 0)
|
||||
&& ((pCtx->eNalType == NAL_UNIT_CODED_SLICE_IDR)
|
||||
|| (pCtx->eSliceType == I_SLICE));
|
||||
pNalHdExt->uiTemporalId = pCtx->uiTemporalId;
|
||||
|
||||
// pEncPic pData
|
||||
@ -3398,9 +3405,16 @@ int32_t WritePadding (sWelsEncCtx* pCtx, int32_t iLen, int32_t& iSize) {
|
||||
int32_t ForceCodingIDR (sWelsEncCtx* pCtx) {
|
||||
if (NULL == pCtx)
|
||||
return 1;
|
||||
for (int32_t iDid = 0; iDid < pCtx->pSvcParam->iSpatialLayerNum; iDid++) {
|
||||
SSpatialLayerInternal* pParamInternal = &pCtx->pSvcParam->sDependencyLayers[iDid];
|
||||
pParamInternal->iCodingIndex = 0;
|
||||
pParamInternal->iSkipFrameFlag = 0;
|
||||
pParamInternal->iFrameIndex = 0;
|
||||
pParamInternal->iFrameNum = 0;
|
||||
pParamInternal->iPOC = 0;
|
||||
pParamInternal->bEncCurFrmAsIdrFlag = true;
|
||||
}
|
||||
|
||||
pCtx->bEncCurFrmAsIdrFlag = true;
|
||||
pCtx->iCodingIndex = 0;
|
||||
pCtx->bCheckWindowStatusRefreshFlag = false;
|
||||
|
||||
WelsLog (&pCtx->sLogCtx, WELS_LOG_INFO, "ForceCodingIDR at InputFrameCount=%d\n",
|
||||
@ -3427,11 +3441,10 @@ int32_t WelsEncoderEncodeParameterSets (sWelsEncCtx* pCtx, void* pDst) {
|
||||
pLayerBsInfo->uiQualityId = 0;
|
||||
pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER;
|
||||
pLayerBsInfo->iNalCount = iCountNal;
|
||||
pLayerBsInfo->eFrameType = videoFrameTypeIDR;
|
||||
pLayerBsInfo->eFrameType = videoFrameTypeInvalid;
|
||||
//pCtx->eLastNalPriority = NRI_PRI_HIGHEST;
|
||||
pFbi->iLayerNum = 1;
|
||||
pFbi->eFrameType = videoFrameTypeInvalid;
|
||||
|
||||
WelsEmms();
|
||||
|
||||
return ENC_RETURN_SUCCESS;
|
||||
@ -3479,75 +3492,69 @@ int32_t WriteSsvcParaset (sWelsEncCtx* pCtx, const int32_t kiSpatialNum,
|
||||
}
|
||||
|
||||
// writing parasets for simulcast avc
|
||||
int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t kiSpatialNum,
|
||||
int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t iIdx,
|
||||
SLayerBSInfo*& pLayerBsInfo, int32_t& iLayerNum, int32_t& iFrameSize) {
|
||||
int32_t iNonVclSize = 0, iCountNal = 0, iReturn = ENC_RETURN_SUCCESS;
|
||||
|
||||
// write SPS
|
||||
iNonVclSize = 0;
|
||||
|
||||
assert ((kiSpatialNum == pCtx->iSpsNum) || (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy));
|
||||
//writing one NAL
|
||||
int32_t iNalSize = 0;
|
||||
iCountNal = 0;
|
||||
|
||||
for (int32_t iIdx = 0; iIdx < pCtx->iSpsNum; iIdx++) {
|
||||
//writing one NAL
|
||||
int32_t iNalSize = 0;
|
||||
iCountNal = 0;
|
||||
iReturn = WelsWriteOneSPS (pCtx, iIdx, iNalSize);
|
||||
WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
|
||||
|
||||
iReturn = WelsWriteOneSPS (pCtx, iIdx, iNalSize);
|
||||
WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
|
||||
pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize;
|
||||
iNonVclSize += iNalSize;
|
||||
iCountNal = 1;
|
||||
|
||||
pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize;
|
||||
iNonVclSize += iNalSize;
|
||||
iCountNal = 1;
|
||||
//finish writing one NAL
|
||||
//finish writing one NAL
|
||||
|
||||
pLayerBsInfo->uiSpatialId = iIdx;
|
||||
pLayerBsInfo->uiTemporalId = 0;
|
||||
pLayerBsInfo->uiQualityId = 0;
|
||||
pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER;
|
||||
pLayerBsInfo->iNalCount = iCountNal;
|
||||
pLayerBsInfo->eFrameType = videoFrameTypeIDR;
|
||||
//point to next pLayerBsInfo
|
||||
++ pLayerBsInfo;
|
||||
++ pCtx->pOut->iLayerBsIndex;
|
||||
pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
|
||||
pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
|
||||
//update for external countings
|
||||
++ iLayerNum;
|
||||
|
||||
}
|
||||
pLayerBsInfo->uiSpatialId = iIdx;
|
||||
pLayerBsInfo->uiTemporalId = 0;
|
||||
pLayerBsInfo->uiQualityId = 0;
|
||||
pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER;
|
||||
pLayerBsInfo->iNalCount = iCountNal;
|
||||
pLayerBsInfo->eFrameType = videoFrameTypeIDR;
|
||||
//point to next pLayerBsInfo
|
||||
++ pLayerBsInfo;
|
||||
++ pCtx->pOut->iLayerBsIndex;
|
||||
pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
|
||||
pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
|
||||
//update for external countings
|
||||
++ iLayerNum;
|
||||
|
||||
// write PPS
|
||||
|
||||
//TODO: under new strategy, will PPS be correctly updated?
|
||||
|
||||
for (int32_t iIdx = 0; iIdx < pCtx->iPpsNum; iIdx++) {
|
||||
//writing one NAL
|
||||
int32_t iNalSize = 0;
|
||||
iCountNal = 0;
|
||||
//writing one NAL
|
||||
iNalSize = 0;
|
||||
iCountNal = 0;
|
||||
|
||||
iReturn = WelsWriteOnePPS (pCtx, iIdx, iNalSize);
|
||||
WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
|
||||
iReturn = WelsWriteOnePPS (pCtx, iIdx, iNalSize);
|
||||
WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
|
||||
|
||||
pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize;
|
||||
iNonVclSize += iNalSize;
|
||||
iCountNal = 1;
|
||||
//finish writing one NAL
|
||||
pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize;
|
||||
iNonVclSize += iNalSize;
|
||||
iCountNal = 1;
|
||||
//finish writing one NAL
|
||||
|
||||
pLayerBsInfo->uiSpatialId = iIdx;
|
||||
pLayerBsInfo->uiTemporalId = 0;
|
||||
pLayerBsInfo->uiQualityId = 0;
|
||||
pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER;
|
||||
pLayerBsInfo->iNalCount = iCountNal;
|
||||
pLayerBsInfo->eFrameType = videoFrameTypeIDR;
|
||||
//point to next pLayerBsInfo
|
||||
++ pLayerBsInfo;
|
||||
++ pCtx->pOut->iLayerBsIndex;
|
||||
pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
|
||||
pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
|
||||
//update for external countings
|
||||
++ iLayerNum;
|
||||
}
|
||||
pLayerBsInfo->uiSpatialId = iIdx;
|
||||
pLayerBsInfo->uiTemporalId = 0;
|
||||
pLayerBsInfo->uiQualityId = 0;
|
||||
pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER;
|
||||
pLayerBsInfo->iNalCount = iCountNal;
|
||||
pLayerBsInfo->eFrameType = videoFrameTypeIDR;
|
||||
//point to next pLayerBsInfo
|
||||
++ pLayerBsInfo;
|
||||
++ pCtx->pOut->iLayerBsIndex;
|
||||
pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
|
||||
pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
|
||||
//update for external countings
|
||||
++ iLayerNum;
|
||||
|
||||
// to check number of layers / nals / slices dependencies
|
||||
if (iLayerNum > MAX_LAYER_NUM_OF_FRAME) {
|
||||
@ -3645,6 +3652,7 @@ int32_t WriteSavcParaset_Listing (sWelsEncCtx* pCtx, const int32_t kiSpatialNum,
|
||||
|
||||
void StackBackEncoderStatus (sWelsEncCtx* pEncCtx,
|
||||
EVideoFrameType keFrameType) {
|
||||
SSpatialLayerInternal* pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
|
||||
// for bitstream writing
|
||||
pEncCtx->iPosBsBuffer = 0; // reset bs pBuffer position
|
||||
pEncCtx->pOut->iNalIndex = 0; // reset NAL index
|
||||
@ -3652,14 +3660,15 @@ void StackBackEncoderStatus (sWelsEncCtx* pEncCtx,
|
||||
|
||||
InitBits (&pEncCtx->pOut->sBsWrite, pEncCtx->pOut->pBsBuffer, pEncCtx->pOut->uiSize);
|
||||
if ((keFrameType == videoFrameTypeP) || (keFrameType == videoFrameTypeI)) {
|
||||
pEncCtx->iFrameIndex --;
|
||||
if (pEncCtx->iPOC != 0) {
|
||||
pEncCtx->iPOC -= 2;
|
||||
pParamInternal->iFrameIndex --;
|
||||
if (pParamInternal->iPOC != 0) {
|
||||
pParamInternal->iPOC -= 2;
|
||||
} else {
|
||||
pEncCtx->iPOC = (1 << pEncCtx->pSps->iLog2MaxPocLsb) - 2;
|
||||
pParamInternal->iPOC = (1 << pEncCtx->pSps->iLog2MaxPocLsb) - 2;
|
||||
}
|
||||
|
||||
LoadBackFrameNum (pEncCtx);
|
||||
LoadBackFrameNum (pEncCtx, pEncCtx->uiDependencyId);
|
||||
|
||||
pEncCtx->eNalType = NAL_UNIT_CODED_SLICE;
|
||||
pEncCtx->eSliceType = P_SLICE;
|
||||
//pEncCtx->eNalPriority = pEncCtx->eLastNalPriority; //not need this since eNalPriority will be updated at the beginning of coding a frame
|
||||
@ -3682,10 +3691,10 @@ void ClearFrameBsInfo (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi) {
|
||||
|
||||
for (int i = 0; i < pFbi->iLayerNum; i++) {
|
||||
pFbi->sLayerInfo[i].iNalCount = 0;
|
||||
pFbi->sLayerInfo[i].eFrameType = videoFrameTypeSkip;
|
||||
}
|
||||
pFbi->iLayerNum = 0;
|
||||
pFbi->iFrameSizeInBytes = 0;
|
||||
pFbi->eFrameType = videoFrameTypeSkip;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3725,6 +3734,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
int8_t iCurTid = 0;
|
||||
bool bAvcBased = false;
|
||||
SLogContext* pLogCtx = & (pCtx->sLogCtx);
|
||||
bool bFinishedWriteHeader = false;
|
||||
#if defined(ENABLE_PSNR_CALC)
|
||||
float fSnrY = .0f, fSnrU = .0f, fSnrV = .0f;
|
||||
#endif//ENABLE_PSNR_CALC
|
||||
@ -3732,7 +3742,6 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
#if defined(_DEBUG)
|
||||
int32_t i = 0, j = 0, k = 0;
|
||||
#endif//_DEBUG
|
||||
|
||||
pCtx->iEncoderError = ENC_RETURN_SUCCESS;
|
||||
pCtx->bCurFrameMarkedAsSceneLtr = false;
|
||||
pFbi->iLayerNum = 0; // for initialization
|
||||
@ -3746,76 +3755,116 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
pCtx->pFuncList->pfRc.pfWelsUpdateMaxBrWindowStatus (pCtx, iSpatialNum, pSrcPic->uiTimeStamp);
|
||||
}
|
||||
|
||||
if (iSpatialNum < 1) { // skip due to temporal layer settings (different frame rate)
|
||||
++ pCtx->iCodingIndex;
|
||||
if (iSpatialNum < 1) {
|
||||
// ++ pCtx->iCodingIndex;
|
||||
pLayerBsInfo->eFrameType = videoFrameTypeSkip;
|
||||
pFbi->eFrameType = videoFrameTypeSkip;
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
|
||||
"[Rc] Frame timestamp = %lld, skip one frame due to preprocessing return (temporal layer settings or else), continual skipped %d frames",
|
||||
pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
eFrameType = DecideFrameType (pCtx, iSpatialNum);
|
||||
if (eFrameType == videoFrameTypeSkip) {
|
||||
if (pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip)
|
||||
pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip (pCtx, iSpatialNum);
|
||||
pFbi->eFrameType = eFrameType;
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
|
||||
"[Rc] Frame timestamp = %lld, skip one frame due to target_br, continual skipped %d frames",
|
||||
pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
//loop each layer to check if have skip frame when RC and frame skip enable
|
||||
if (pCtx->pFuncList->pfRc.pfWelsCheckSkipBasedMaxbr) {
|
||||
bool bSkip = pCtx->pFuncList->pfRc.pfWelsCheckSkipBasedMaxbr (pCtx, iSpatialNum, eFrameType,
|
||||
(uint32_t)pSrcPic->uiTimeStamp);
|
||||
if (bSkip) {
|
||||
pFbi->eFrameType = videoFrameTypeSkip;
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
|
||||
"[Rc] Frame timestamp = %lld, skip one frame due to max_br, continual skipped %d frames",
|
||||
pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
|
||||
return ENC_RETURN_SUCCESS;
|
||||
if (!pSvcParam->bSimulcastAVC) {
|
||||
pCtx->iSkipFrameFlag = false;
|
||||
for (int32_t iDid = 0; iDid < iSpatialNum; iDid++) {
|
||||
if (pCtx->pSvcParam->sDependencyLayers[iDid].iSkipFrameFlag)
|
||||
pCtx->iSkipFrameFlag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
pCtx->iContinualSkipFrames = 0;
|
||||
InitFrameCoding (pCtx, eFrameType);
|
||||
|
||||
iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[pSpatialIndexMap->iDid], pCtx->iCodingIndex,
|
||||
pSvcParam->uiGopSize);
|
||||
pCtx->uiTemporalId = iCurTid;
|
||||
|
||||
InitBitStream (pCtx);
|
||||
pLayerBsInfo->pBsBuf = pCtx->pFrameBs ;
|
||||
pLayerBsInfo->pNalLengthInByte = pCtx->pOut->pNalLen;
|
||||
|
||||
if (eFrameType == videoFrameTypeIDR) {
|
||||
++ pCtx->uiIdrPicId;
|
||||
// write parameter sets bitstream or SEI/SSEI (if any) here
|
||||
// TODO: use function pointer instead
|
||||
if (! (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy)) {
|
||||
pCtx->iEncoderError = ((!pSvcParam->bSimulcastAVC)
|
||||
? (WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize))
|
||||
: (WriteSavcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize)));
|
||||
} else {
|
||||
pCtx->iEncoderError = WriteSavcParaset_Listing (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize);
|
||||
}
|
||||
WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
|
||||
}
|
||||
|
||||
pCtx->pCurDqLayer = pCtx->ppDqLayerList[pSpatialIndexMap->iDid];
|
||||
pCtx->pCurDqLayer->pRefLayer = NULL;
|
||||
|
||||
while (iSpatialIdx < iSpatialNum) {
|
||||
const int32_t iDidIdx = (pSpatialIndexMap + iSpatialIdx)->iDid; // get iDid
|
||||
bool bEncoding = pCtx->pVpp->BuildSpatialLayer (pCtx, pSrcPic, iSpatialIdx);
|
||||
if (!bEncoding) {
|
||||
++iSpatialIdx;
|
||||
continue;
|
||||
}
|
||||
const int32_t iDidIdx = (pSpatialIndexMap + iSpatialIdx)->iDid;
|
||||
SSpatialLayerConfig* pParam = &pSvcParam->sSpatialLayers[iDidIdx];
|
||||
SSpatialLayerInternal* pParamInternal = &pSvcParam->sDependencyLayers[iDidIdx];
|
||||
int32_t iDecompositionStages = pSvcParam->sDependencyLayers[iDidIdx].iDecompositionStages;
|
||||
pCtx->pCurDqLayer = pCtx->ppDqLayerList[iDidIdx];
|
||||
pCtx->uiDependencyId = iCurDid = (int8_t)iDidIdx;
|
||||
|
||||
eFrameType = DecideFrameType (pCtx, iSpatialNum, iDidIdx);
|
||||
if (eFrameType == videoFrameTypeSkip) {
|
||||
eFrameType = videoFrameTypeSkip;
|
||||
pLayerBsInfo->eFrameType = eFrameType;
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
|
||||
"[Rc] Frame timestamp = %lld, skip one frame due to target_br, continual skipped %d frames",
|
||||
pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
|
||||
++ iSpatialIdx;
|
||||
if (pSvcParam->bSimulcastAVC) {
|
||||
if (pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip)
|
||||
pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip (pCtx, iDidIdx);
|
||||
continue;
|
||||
}
|
||||
|
||||
else {
|
||||
if (pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip) {
|
||||
for (int32_t i = 0; i < iSpatialNum; i++) {
|
||||
pCtx->pSvcParam->sDependencyLayers[i].iSkipFrameFlag = false;
|
||||
pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip (pCtx, (pSpatialIndexMap + i)->iDid);
|
||||
}
|
||||
}
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
}
|
||||
//loop each layer to check if have skip frame when RC and frame skip enable
|
||||
if (pCtx->pFuncList->pfRc.pfWelsCheckSkipBasedMaxbr) {
|
||||
bool bSkip = pCtx->pFuncList->pfRc.pfWelsCheckSkipBasedMaxbr (pCtx, iSpatialNum, eFrameType,
|
||||
(uint32_t)pSrcPic->uiTimeStamp);
|
||||
if (bSkip) {
|
||||
eFrameType = videoFrameTypeSkip;
|
||||
pLayerBsInfo->eFrameType = videoFrameTypeSkip;
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
|
||||
"[Rc] Frame timestamp = %lld, skip one frame due to max_br, continual skipped %d frames",
|
||||
pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
|
||||
++ iSpatialIdx;
|
||||
if (pSvcParam->bSimulcastAVC)
|
||||
continue;
|
||||
else
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
}
|
||||
pCtx->iContinualSkipFrames = 0;
|
||||
|
||||
InitFrameCoding (pCtx, eFrameType, iDidIdx);
|
||||
iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[iSpatialIdx], pParamInternal->iCodingIndex,
|
||||
pSvcParam->uiGopSize);
|
||||
pCtx->uiTemporalId = iCurTid;
|
||||
|
||||
if (eFrameType == videoFrameTypeIDR) {
|
||||
// write parameter sets bitstream or SEI/SSEI (if any) here
|
||||
// TODO: use function pointer instead
|
||||
if (! (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy)) {
|
||||
if (pSvcParam->bSimulcastAVC) {
|
||||
pCtx->iEncoderError = WriteSavcParaset (pCtx, iCurDid, pLayerBsInfo, iLayerNum, iFrameSize);
|
||||
++ pCtx->uiIdrPicId;
|
||||
} else if (!bFinishedWriteHeader) {
|
||||
pCtx->iEncoderError = WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize);
|
||||
++ pCtx->uiIdrPicId;
|
||||
bFinishedWriteHeader = true;
|
||||
}
|
||||
} else if (!bFinishedWriteHeader) {
|
||||
pCtx->iEncoderError = WriteSavcParaset_Listing (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize);
|
||||
bFinishedWriteHeader = true;
|
||||
++ pCtx->uiIdrPicId;
|
||||
}
|
||||
WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
|
||||
}
|
||||
|
||||
pCtx->pVpp->AnalyzeSpatialPic (pCtx, iDidIdx);
|
||||
|
||||
pCtx->pEncPic = pEncPic = (pSpatialIndexMap + iSpatialIdx)->pSrc;
|
||||
pCtx->pEncPic->iPictureType = pCtx->eSliceType;
|
||||
pCtx->pEncPic->iFramePoc = pCtx->iPOC;
|
||||
pCtx->pEncPic->iFramePoc = pParamInternal->iPOC;
|
||||
|
||||
iCurWidth = pParam->iVideoWidth;
|
||||
iCurHeight = pParam->iVideoHeight;
|
||||
@ -3880,12 +3929,12 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
fsnr = pCtx->pDecPic;
|
||||
#endif//#if defined(ENABLE_FRAME_DUMP) || defined(ENABLE_PSNR_CALC)
|
||||
pCtx->pDecPic->iPictureType = pCtx->eSliceType;
|
||||
pCtx->pDecPic->iFramePoc = pCtx->iPOC;
|
||||
pCtx->pDecPic->iFramePoc = pParamInternal->iPOC;
|
||||
|
||||
WelsInitCurrentLayer (pCtx, iCurWidth, iCurHeight);
|
||||
|
||||
pCtx->pFuncList->pMarkPic (pCtx);
|
||||
if (!pCtx->pFuncList->pBuildRefList (pCtx, pCtx->iPOC, 0)) {
|
||||
if (!pCtx->pFuncList->pBuildRefList (pCtx, pParamInternal->iPOC, 0)) {
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING,
|
||||
"WelsEncoderEncodeExt(), WelsBuildRefList failed for P frames, pCtx->iNumRef0= %d. ForceCodingIDR!",
|
||||
pCtx->iNumRef0);
|
||||
@ -3904,7 +3953,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
pCtx->pVpp->AnalyzePictureComplexity (pCtx, pCtx->pEncPic, ((pCtx->eSliceType == P_SLICE)
|
||||
&& (pCtx->iNumRef0 > 0)) ? pCtx->pRefList0[0] : NULL,
|
||||
iCurDid, (pCtx->eSliceType == P_SLICE) && pSvcParam->bEnableBackgroundDetection);
|
||||
WelsUpdateRefSyntax (pCtx, pCtx->iPOC,
|
||||
WelsUpdateRefSyntax (pCtx, pParamInternal->iPOC,
|
||||
eFrameType); //get reordering syntax used for writing slice header and transmit to encoder.
|
||||
PrefetchReferencePicture (pCtx, eFrameType); // update reference picture for current pDq layer
|
||||
|
||||
@ -4033,6 +4082,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
pLbi->uiQualityId = 0;
|
||||
pLbi->iNalCount = 0;
|
||||
pLbi->eFrameType = eFrameType;
|
||||
|
||||
int32_t iIdx = 0;
|
||||
while (iIdx < kiPartitionCnt) {
|
||||
pCtx->pSliceThreading->pThreadPEncCtx[iIdx].pFrameBsInfo = pFbi;
|
||||
@ -4252,7 +4302,8 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
++ iLayerNum;
|
||||
++ pLayerBsInfo;
|
||||
++ pCtx->pOut->iLayerBsIndex;
|
||||
|
||||
WelsLog (pLogCtx, WELS_LOG_DEBUG,
|
||||
"WelsEncoderEncodeExt() test iLayerNum = %d,iCountNal = %d,iLayerSize = %d", iLayerNum, iCountNal, iLayerSize);
|
||||
pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
|
||||
pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
|
||||
|
||||
@ -4321,6 +4372,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
&& (pCtx->pLtr[pCtx->uiDependencyId].iLTRMarkMode == LTR_DIRECT_MARK)) || eFrameType == videoFrameTypeIDR)) {
|
||||
pCtx->bRefOfCurTidIsLtr[iDidIdx][iCurTid] = true;
|
||||
}
|
||||
++ pParamInternal->iCodingIndex;
|
||||
}//end of (iSpatialIdx/iSpatialNum)
|
||||
|
||||
if (ENC_RETURN_CORRECTED == pCtx->iEncoderError) {
|
||||
@ -4361,7 +4413,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
return 1;
|
||||
}
|
||||
|
||||
++ pCtx->iCodingIndex;
|
||||
|
||||
pFbi->iLayerNum = iLayerNum;
|
||||
pFbi->iSubSeqId = GetSubSequenceId (pCtx, eFrameType);
|
||||
|
||||
@ -4370,13 +4422,19 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
pFbi->iSubSeqId, iFrameSize);
|
||||
for (int32_t i = 0; i < iLayerNum; i++)
|
||||
WelsLog (pLogCtx, WELS_LOG_DEBUG,
|
||||
"WelsEncoderEncodeExt() OutputInfo iLayerId = %d,iNalType = %d,iNalCount = %d, first Nal Length=%d", i,
|
||||
pFbi->sLayerInfo[i].uiLayerType, pFbi->sLayerInfo[i].iNalCount, pFbi->sLayerInfo[i].pNalLengthInByte[0]);
|
||||
"WelsEncoderEncodeExt() OutputInfo iLayerId = %d,iNalType = %d,iNalCount = %d, first Nal Length=%d,uiSpatialId = %d", i,
|
||||
pFbi->sLayerInfo[i].uiLayerType, pFbi->sLayerInfo[i].iNalCount, pFbi->sLayerInfo[i].pNalLengthInByte[0],
|
||||
pFbi->sLayerInfo[i].uiSpatialId);
|
||||
WelsEmms();
|
||||
|
||||
pFbi->eFrameType = eFrameType;
|
||||
pLayerBsInfo->eFrameType = eFrameType;
|
||||
pFbi->iFrameSizeInBytes = iFrameSize;
|
||||
|
||||
pFbi->eFrameType = eFrameType;
|
||||
for (int32_t k = 0; k < pFbi->iLayerNum; k++) {
|
||||
if (pFbi->eFrameType != pFbi->sLayerInfo[k].eFrameType) {
|
||||
pFbi->eFrameType = videoFrameTypeIPMixed;
|
||||
}
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
if (pFbi->iLayerNum > MAX_LAYER_NUM_OF_FRAME) {
|
||||
WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR, "WelsEncoderEncodeExt(), iLayerNum(%d) > MAX_LAYER_NUM_OF_FRAME(%d)!",
|
||||
@ -4402,7 +4460,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
return ENC_RETURN_UNEXPECTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
WelsLog (& pCtx->sLogCtx, WELS_LOG_INFO, "return ENC_RETURN_SUCCESS");
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
@ -4565,9 +4623,8 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
||||
// reset the scaled spatial picture size
|
||||
(*ppCtx)->pVpp->WelsPreprocessReset (*ppCtx);
|
||||
//if WelsInitEncoderExt succeed
|
||||
|
||||
//for LTR
|
||||
(*ppCtx)->uiIdrPicId = uiTmpIdrPicId;
|
||||
(*ppCtx)->uiIdrPicId = uiTmpIdrPicId ;//this is for LTR!; //this is for LTR!
|
||||
|
||||
//for sEncoderStatistics
|
||||
memcpy ((*ppCtx)->sEncoderStatistics, sTempEncoderStatistics, sizeof (sTempEncoderStatistics));
|
||||
@ -4601,7 +4658,8 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
||||
pOldParam->uiGopSize = pNewParam->uiGopSize;
|
||||
if (pOldParam->iTemporalLayerNum != pNewParam->iTemporalLayerNum) {
|
||||
pOldParam->iTemporalLayerNum = pNewParam->iTemporalLayerNum;
|
||||
(*ppCtx)->iCodingIndex = 0;
|
||||
for (int32_t iIndexD = 0; iIndexD < MAX_DEPENDENCY_LAYER; iIndexD++)
|
||||
pOldParam->sDependencyLayers[iIndexD].iCodingIndex = 0;
|
||||
}
|
||||
pOldParam->iDecompStages = pNewParam->iDecompStages;
|
||||
/* denoise control */
|
||||
@ -4663,7 +4721,6 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
||||
|
||||
memcpy (pOldDlpInternal->uiCodingIdx2TemporalId, pNewDlpInternal->uiCodingIdx2TemporalId,
|
||||
sizeof (pOldDlpInternal->uiCodingIdx2TemporalId)); // confirmed_safe_unsafe_usage
|
||||
|
||||
++ iIndexD;
|
||||
} while (iIndexD < pOldParam->iSpatialLayerNum);
|
||||
}
|
||||
|
@ -685,6 +685,7 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
|
||||
SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc;
|
||||
const int32_t kiOutputBits = pWelsSvcRc->iBitsPerFrame;
|
||||
const int32_t kiOutputMaxBits = pWelsSvcRc->iMaxBitsPerFrame;
|
||||
SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
|
||||
//condition 1: whole pBuffer fullness
|
||||
pWelsSvcRc->iBufferFullnessSkip += (pWelsSvcRc->iFrameDqBits - kiOutputBits);
|
||||
pWelsSvcRc->iBufferMaxBRFullness[EVEN_TIME_WINDOW] += (pWelsSvcRc->iFrameDqBits - kiOutputMaxBits);
|
||||
@ -704,7 +705,7 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
|
||||
if ((pWelsSvcRc->iBufferFullnessSkip > pWelsSvcRc->iBufferSizeSkip
|
||||
&& pWelsSvcRc->iAverageFrameQp > pWelsSvcRc->iSkipQpValue)
|
||||
|| (dIncPercent > pWelsSvcRc->iRcVaryPercentage)) {
|
||||
pEncCtx->iSkipFrameFlag = 1;
|
||||
pDLayerParamInternal->iSkipFrameFlag = 1;
|
||||
}
|
||||
}
|
||||
void WelsRcFrameDelayJudge (sWelsEncCtx* pEncCtx, EVideoFrameType eFrameType, long long uiTimeStamp) {
|
||||
@ -772,35 +773,38 @@ void WelsRcFrameDelayJudge (sWelsEncCtx* pEncCtx, EVideoFrameType eFrameType, lo
|
||||
//loop each layer to check if have skip frame when RC and frame skip enable (maxbr>0)
|
||||
bool CheckFrameSkipBasedMaxbr (sWelsEncCtx* pEncCtx, int32_t iSpatialNum, EVideoFrameType eFrameType,
|
||||
const uint32_t uiTimeStamp) {
|
||||
SSpatialPicIndex* pSpatialIndexMap = &pEncCtx->sSpatialIndexMap[0];
|
||||
bool bSkipMustFlag = false;
|
||||
if (!pEncCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge)
|
||||
return false;
|
||||
for (int32_t i = 0; i < iSpatialNum; i++) {
|
||||
if (UNSPECIFIED_BIT_RATE == pEncCtx->pSvcParam->sSpatialLayers[i].iMaxSpatialBitrate) {
|
||||
break;
|
||||
}
|
||||
pEncCtx->uiDependencyId = (uint8_t) (pSpatialIndexMap + i)->iDid;
|
||||
if( pEncCtx->pSvcParam->bSimulcastAVC){
|
||||
int32_t iDidIdx = pEncCtx->uiDependencyId;
|
||||
if (UNSPECIFIED_BIT_RATE == pEncCtx->pSvcParam->sSpatialLayers[iDidIdx].iMaxSpatialBitrate)
|
||||
return false;
|
||||
|
||||
pEncCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge (pEncCtx, eFrameType, uiTimeStamp);
|
||||
if (true == pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId].bSkipFlag) {
|
||||
bSkipMustFlag = true;
|
||||
pEncCtx->iContinualSkipFrames++;
|
||||
break;
|
||||
if (true == pEncCtx->pWelsSvcRc[iDidIdx].bSkipFlag) {
|
||||
bSkipMustFlag = true;
|
||||
pEncCtx->pWelsSvcRc[iDidIdx].uiLastTimeStamp = uiTimeStamp;
|
||||
pEncCtx->iContinualSkipFrames++;
|
||||
}
|
||||
}else{
|
||||
for(int32_t i = 0;i<iSpatialNum;i++){
|
||||
if (UNSPECIFIED_BIT_RATE == pEncCtx->pSvcParam->sSpatialLayers[i].iMaxSpatialBitrate)
|
||||
break;
|
||||
|
||||
pEncCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge (pEncCtx, eFrameType, uiTimeStamp);
|
||||
if (true == pEncCtx->pWelsSvcRc[i].bSkipFlag) {
|
||||
bSkipMustFlag = true;
|
||||
pEncCtx->pWelsSvcRc[i].uiLastTimeStamp = uiTimeStamp;
|
||||
pEncCtx->iContinualSkipFrames++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bSkipMustFlag) {
|
||||
for (int32_t i = 0; i < iSpatialNum; i++)
|
||||
pEncCtx->pWelsSvcRc[i].uiLastTimeStamp = uiTimeStamp;
|
||||
}
|
||||
return bSkipMustFlag;
|
||||
}
|
||||
|
||||
void UpdateBufferWhenFrameSkipped (sWelsEncCtx* pEncCtx, int32_t iSpatialNum) {
|
||||
SSpatialPicIndex* pSpatialIndexMap = &pEncCtx->sSpatialIndexMap[0];
|
||||
|
||||
for (int32_t i = 0; i < iSpatialNum; i++) {
|
||||
int32_t iCurDid = (pSpatialIndexMap + i)->iDid;
|
||||
void UpdateBufferWhenFrameSkipped (sWelsEncCtx* pEncCtx, int32_t iCurDid) {
|
||||
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[iCurDid];
|
||||
const int32_t kiOutputBits = pWelsSvcRc->iBitsPerFrame;
|
||||
const int32_t kiOutputMaxBits = pWelsSvcRc->iMaxBitsPerFrame;
|
||||
@ -817,7 +821,6 @@ void UpdateBufferWhenFrameSkipped (sWelsEncCtx* pEncCtx, int32_t iSpatialNum) {
|
||||
pWelsSvcRc->iSkipFrameNum++;
|
||||
pWelsSvcRc->iSkipFrameInVGop++;
|
||||
|
||||
}
|
||||
pEncCtx->iContinualSkipFrames++;
|
||||
if ((pEncCtx->iContinualSkipFrames % 3) == 0) {
|
||||
//output a warning when iContinualSkipFrames is large enough, which may indicate subjective quality problem
|
||||
@ -906,7 +909,7 @@ void RcVBufferCalculationPadding (sWelsEncCtx* pEncCtx) {
|
||||
|
||||
void RcTraceFrameBits (sWelsEncCtx* pEncCtx, long long uiTimeStamp) {
|
||||
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
|
||||
|
||||
SSpatialLayerInternal *pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
|
||||
if (pWelsSvcRc->iPredFrameBit != 0)
|
||||
pWelsSvcRc->iPredFrameBit = (int32_t) (LAST_FRAME_PREDICT_WEIGHT * pWelsSvcRc->iFrameDqBits +
|
||||
(1 - LAST_FRAME_PREDICT_WEIGHT) * pWelsSvcRc->iPredFrameBit);
|
||||
@ -919,7 +922,7 @@ void RcTraceFrameBits (sWelsEncCtx* pEncCtx, long long uiTimeStamp) {
|
||||
pEncCtx->uiDependencyId, uiTimeStamp, pEncCtx->eSliceType, pEncCtx->iGlobalQp, pWelsSvcRc->iAverageFrameQp,
|
||||
pWelsSvcRc->iMaxFrameQp,
|
||||
pWelsSvcRc->iMinFrameQp,
|
||||
pEncCtx->iFrameIndex, pEncCtx->uiTemporalId, pWelsSvcRc->iFrameDqBits, pWelsSvcRc->iBitsPerFrame,
|
||||
pParamInternal->iFrameIndex, pEncCtx->uiTemporalId, pWelsSvcRc->iFrameDqBits, pWelsSvcRc->iBitsPerFrame,
|
||||
pWelsSvcRc->iTargetBits, pWelsSvcRc->iRemainingBits, pWelsSvcRc->iBufferSizeSkip);
|
||||
|
||||
}
|
||||
|
@ -155,6 +155,7 @@ static inline void DeleteInvalidLTR (sWelsEncCtx* pCtx) {
|
||||
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
|
||||
int32_t iMaxFrameNumPlus1 = (1 << pCtx->pSps->uiLog2MaxFrameNum);
|
||||
int32_t i;
|
||||
SSpatialLayerInternal *pParamInternal = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
|
||||
SLogContext* pLogCtx = & (pCtx->sLogCtx);
|
||||
|
||||
for (i = 0; i < LONG_TERM_REF_NUM; i++) {
|
||||
@ -168,7 +169,7 @@ static inline void DeleteInvalidLTR (sWelsEncCtx* pCtx) {
|
||||
DeleteLTRFromLongList (pCtx, i);
|
||||
pLtr->bLTRMarkEnable = true;
|
||||
if (pRefList->uiLongRefCount == 0) {
|
||||
pCtx->bEncCurFrmAsIdrFlag = true;
|
||||
pParamInternal->bEncCurFrmAsIdrFlag = true;
|
||||
}
|
||||
} else if (CompareFrameNum (pLongRefList[i]->iMarkFrameNum , pLtr->iLastCorFrameNumDec ,
|
||||
iMaxFrameNumPlus1) == FRAME_NUM_BIGGER
|
||||
@ -181,7 +182,7 @@ static inline void DeleteInvalidLTR (sWelsEncCtx* pCtx) {
|
||||
DeleteLTRFromLongList (pCtx, i);
|
||||
pLtr->bLTRMarkEnable = true;
|
||||
if (pRefList->uiLongRefCount == 0) {
|
||||
pCtx->bEncCurFrmAsIdrFlag = true;
|
||||
pParamInternal->bEncCurFrmAsIdrFlag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -195,12 +196,13 @@ static inline void HandleLTRMarkFeedback (sWelsEncCtx* pCtx) {
|
||||
SRefList* pRefList = pCtx->ppRefPicListExt[pCtx->uiDependencyId];
|
||||
SPicture** pLongRefList = pRefList->pLongRefList;
|
||||
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
|
||||
SSpatialLayerInternal *pParamInternal = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
|
||||
int32_t i, j;
|
||||
|
||||
if (pLtr->uiLtrMarkState == LTR_MARKING_SUCCESS) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
|
||||
"pLtr->uiLtrMarkState = %d, pLtr.iCurLtrIdx = %d , pLtr->iLtrMarkFbFrameNum = %d ,pCtx->iFrameNum = %d ",
|
||||
pLtr->uiLtrMarkState, pLtr->iCurLtrIdx, pLtr->iLtrMarkFbFrameNum, pCtx->iFrameNum);
|
||||
pLtr->uiLtrMarkState, pLtr->iCurLtrIdx, pLtr->iLtrMarkFbFrameNum, pParamInternal->iFrameNum);
|
||||
for (i = 0; i < pRefList->uiLongRefCount; i++) {
|
||||
if (pLongRefList[i]->iFrameNum == pLtr->iLtrMarkFbFrameNum && pLongRefList[i]->uiRecieveConfirmed != RECIEVE_SUCCESS) {
|
||||
|
||||
@ -239,7 +241,7 @@ static inline void HandleLTRMarkFeedback (sWelsEncCtx* pCtx) {
|
||||
pLtr->bLTRMarkEnable = true;
|
||||
|
||||
if (pLtr->iLTRMarkSuccessNum == 0) {
|
||||
pCtx->bEncCurFrmAsIdrFlag = true; // no LTR , means IDR recieve failed, force next frame IDR
|
||||
pParamInternal->bEncCurFrmAsIdrFlag = true; // no LTR , means IDR recieve failed, force next frame IDR
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -256,6 +258,7 @@ static inline void LTRMarkProcess (sWelsEncCtx* pCtx) {
|
||||
int32_t i = 0;
|
||||
int32_t j = 0;
|
||||
bool bMoveLtrFromShortToLong = false;
|
||||
SSpatialLayerInternal *pParamInternal = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
|
||||
|
||||
if (pCtx->eSliceType == I_SLICE) {
|
||||
i = 0;
|
||||
@ -265,7 +268,7 @@ static inline void LTRMarkProcess (sWelsEncCtx* pCtx) {
|
||||
|
||||
if (pLtr->iLTRMarkMode == LTR_DELAY_MARK) {
|
||||
for (i = 0; i < pRefList->uiShortRefCount; i++) {
|
||||
if (CompareFrameNum (pCtx->iFrameNum, pShortRefList[i]->iFrameNum + iGoPFrameNumInterval,
|
||||
if (CompareFrameNum (pParamInternal->iFrameNum, pShortRefList[i]->iFrameNum + iGoPFrameNumInterval,
|
||||
iMaxFrameNumPlus1) == FRAME_NUM_EQUAL) {
|
||||
break;
|
||||
}
|
||||
@ -276,7 +279,7 @@ static inline void LTRMarkProcess (sWelsEncCtx* pCtx) {
|
||||
if (pCtx->eSliceType == I_SLICE || pLtr->bLTRMarkingFlag) {
|
||||
pShortRefList[i]->bIsLongRef = true;
|
||||
pShortRefList[i]->iLongTermPicNum = pLtr->iCurLtrIdx;
|
||||
pShortRefList[i]->iMarkFrameNum = pCtx->iFrameNum;
|
||||
pShortRefList[i]->iMarkFrameNum = pParamInternal->iFrameNum;
|
||||
}
|
||||
|
||||
// delay one gop to move LTR from int16_t list to int32_t list
|
||||
@ -376,8 +379,8 @@ bool WelsUpdateRefList (sWelsEncCtx* pCtx) {
|
||||
// move picture in list
|
||||
pCtx->pDecPic->uiTemporalId = kuiTid;
|
||||
pCtx->pDecPic->uiSpatialId = kuiDid;
|
||||
pCtx->pDecPic->iFrameNum = pCtx->iFrameNum;
|
||||
pCtx->pDecPic->iFramePoc = pCtx->iPOC;
|
||||
pCtx->pDecPic->iFrameNum = pParamD->iFrameNum;
|
||||
pCtx->pDecPic->iFramePoc = pParamD->iPOC;
|
||||
pCtx->pDecPic->uiRecieveConfirmed = RECIEVE_UNKOWN;
|
||||
pCtx->pDecPic->bUsedAsRef = true;
|
||||
|
||||
@ -405,7 +408,7 @@ bool WelsUpdateRefList (sWelsEncCtx* pCtx) {
|
||||
DeleteSTRFromShortList (pCtx, i);
|
||||
}
|
||||
if (pRefList->uiShortRefCount > 0 && (pRefList->pShortRefList[0]->uiTemporalId > 0
|
||||
|| pRefList->pShortRefList[0]->iFrameNum != pCtx->iFrameNum)) {
|
||||
|| pRefList->pShortRefList[0]->iFrameNum != pParamD->iFrameNum)) {
|
||||
pRefList->pShortRefList[0]->SetUnref();
|
||||
DeleteSTRFromShortList (pCtx, 0);
|
||||
}
|
||||
@ -433,11 +436,12 @@ bool CheckCurMarkFrameNumUsed (sWelsEncCtx* pCtx) {
|
||||
SPicture** pLongRefList = pRefList->pLongRefList;
|
||||
int32_t iGoPFrameNumInterval = ((pCtx->pSvcParam->uiGopSize >> 1) > 1) ? (pCtx->pSvcParam->uiGopSize >> 1) : (1);
|
||||
int32_t iMaxFrameNumPlus1 = (1 << pCtx->pSps->uiLog2MaxFrameNum);
|
||||
SSpatialLayerInternal *pParamInternal = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < pRefList->uiLongRefCount; i++) {
|
||||
if ((pCtx->iFrameNum == pLongRefList[i]->iFrameNum && pLtr->iLTRMarkMode == LTR_DIRECT_MARK) ||
|
||||
(CompareFrameNum (pCtx->iFrameNum + iGoPFrameNumInterval, pLongRefList[i]->iFrameNum,
|
||||
if ((pParamInternal->iFrameNum == pLongRefList[i]->iFrameNum && pLtr->iLTRMarkMode == LTR_DIRECT_MARK) ||
|
||||
(CompareFrameNum (pParamInternal->iFrameNum + iGoPFrameNumInterval, pLongRefList[i]->iFrameNum,
|
||||
iMaxFrameNumPlus1) == FRAME_NUM_EQUAL && pLtr->iLTRMarkMode == LTR_DELAY_MARK)) {
|
||||
return false;
|
||||
}
|
||||
@ -513,10 +517,11 @@ int32_t FilterLTRRecoveryRequest (sWelsEncCtx* pCtx, SLTRRecoverRequest* pLTRRec
|
||||
SLTRRecoverRequest* pRequest = pLTRRecoverRequest;
|
||||
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
|
||||
int32_t iMaxFrameNumPlus1 = (1 << pCtx->pSps->uiLog2MaxFrameNum);
|
||||
SSpatialLayerInternal* pParamInternal = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
|
||||
if (pCtx->pSvcParam->bEnableLongTermReference) {
|
||||
if (pRequest->uiFeedbackType == LTR_RECOVERY_REQUEST && pRequest->uiIDRPicId == pCtx->uiIdrPicId) {
|
||||
if (pRequest->iLastCorrectFrameNum == -1) {
|
||||
pCtx->bEncCurFrmAsIdrFlag = true;
|
||||
pParamInternal->bEncCurFrmAsIdrFlag = true;
|
||||
return true;
|
||||
} else if (pRequest->iCurrentFrameNum == -1) {
|
||||
pLtr->bReceivedT0LostFlag = true;
|
||||
@ -541,7 +546,7 @@ int32_t FilterLTRRecoveryRequest (sWelsEncCtx* pCtx, SLTRRecoverRequest* pLTRRec
|
||||
, pRequest->uiFeedbackType, pRequest->uiIDRPicId, pRequest->iCurrentFrameNum, pRequest->iLastCorrectFrameNum);
|
||||
}
|
||||
} else if (!pCtx->pSvcParam->bEnableLongTermReference) {
|
||||
pCtx->bEncCurFrmAsIdrFlag = true;
|
||||
pParamInternal->bEncCurFrmAsIdrFlag = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -577,7 +582,7 @@ bool WelsBuildRefList (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBestLtrRe
|
||||
const int32_t kiNumRef = pCtx->pSvcParam->iNumRefFrame;
|
||||
const uint8_t kuiTid = pCtx->uiTemporalId;
|
||||
uint32_t i = 0;
|
||||
|
||||
SSpatialLayerInternal* pParamD = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
|
||||
// to support any type of cur_dq->mgs_control
|
||||
// [ 0: using current layer to do ME/MC;
|
||||
// -1: using store base layer to do ME/MC;
|
||||
@ -586,13 +591,12 @@ bool WelsBuildRefList (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBestLtrRe
|
||||
// build reference list 0/1 if applicable
|
||||
|
||||
pCtx->iNumRef0 = 0;
|
||||
|
||||
if (pCtx->eSliceType != I_SLICE) {
|
||||
if (pCtx->pSvcParam->bEnableLongTermReference && pLtr->bReceivedT0LostFlag && pCtx->uiTemporalId == 0) {
|
||||
for (i = 0; i < pRefList->uiLongRefCount; i++) {
|
||||
if (pRefList->pLongRefList[i]->uiRecieveConfirmed == RECIEVE_SUCCESS) {
|
||||
pCtx->pRefList0[pCtx->iNumRef0++] = pRefList->pLongRefList[i];
|
||||
pLtr->iLastRecoverFrameNum = pCtx->iFrameNum;
|
||||
pLtr->iLastRecoverFrameNum = pParamD->iFrameNum;
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
|
||||
"pRef is int32_t !iLastRecoverFrameNum = %d, pRef iFrameNum = %d,LTR number = %d,",
|
||||
pLtr->iLastRecoverFrameNum, pCtx->pRefList0[0]->iFrameNum, pRefList->uiLongRefCount);
|
||||
@ -690,18 +694,18 @@ void WelsUpdateRefSyntax (sWelsEncCtx* pCtx, const int32_t iPOC, const int32_t u
|
||||
|
||||
int32_t iAbsDiffPicNumMinus1 = -1;
|
||||
SSlice* pSliceList = NULL;
|
||||
|
||||
SSpatialLayerInternal* pParamD = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
|
||||
/*syntax for ref_pic_list_reordering()*/
|
||||
if (pCtx->iNumRef0 > 0) {
|
||||
iAbsDiffPicNumMinus1 = pCtx->iFrameNum - (pCtx->pRefList0[0]->iFrameNum) - 1;
|
||||
if (pCtx->iNumRef0 > 0){
|
||||
iAbsDiffPicNumMinus1 = pParamD->iFrameNum - (pCtx->pRefList0[0]->iFrameNum) - 1;
|
||||
|
||||
if (iAbsDiffPicNumMinus1 < 0) {
|
||||
WelsLog(&(pCtx->sLogCtx), WELS_LOG_INFO, "WelsUpdateRefSyntax():::uiAbsDiffPicNumMinus1:%d", iAbsDiffPicNumMinus1);
|
||||
iAbsDiffPicNumMinus1 += (1 << (pCtx->pSps->uiLog2MaxFrameNum));
|
||||
WelsLog(&(pCtx->sLogCtx), WELS_LOG_INFO, "WelsUpdateRefSyntax():::uiAbsDiffPicNumMinus1< 0, update as:%d",
|
||||
WelsLog(&(pCtx->sLogCtx), WELS_LOG_INFO, "WelsUpdateRefSyntax():::uiAbsDiffPicNumMinus1:%d", iAbsDiffPicNumMinus1);
|
||||
iAbsDiffPicNumMinus1 += (1 << (pCtx->pSps->uiLog2MaxFrameNum));
|
||||
WelsLog(&(pCtx->sLogCtx), WELS_LOG_INFO, "WelsUpdateRefSyntax():::uiAbsDiffPicNumMinus1< 0, update as:%d",
|
||||
iAbsDiffPicNumMinus1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pCtx->iActiveThreadsNum >0) {
|
||||
// to do: will replace with thread based buffer later
|
||||
@ -772,8 +776,8 @@ bool WelsUpdateRefListScreen (sWelsEncCtx* pCtx) {
|
||||
// move picture in list
|
||||
pCtx->pDecPic->uiTemporalId = pCtx->uiTemporalId;
|
||||
pCtx->pDecPic->uiSpatialId = pCtx->uiDependencyId;
|
||||
pCtx->pDecPic->iFrameNum = pCtx->iFrameNum;
|
||||
pCtx->pDecPic->iFramePoc = pCtx->iPOC;
|
||||
pCtx->pDecPic->iFrameNum = pParamD->iFrameNum;
|
||||
pCtx->pDecPic->iFramePoc = pParamD->iPOC;
|
||||
pCtx->pDecPic->bUsedAsRef = true;
|
||||
pCtx->pDecPic->bIsLongRef = true;
|
||||
pCtx->pDecPic->bIsSceneLTR = pLtr->bLTRMarkingFlag || (pCtx->pSvcParam->bEnableLongTermReference
|
||||
@ -801,6 +805,7 @@ bool WelsBuildRefListScreen (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBes
|
||||
SWelsSvcCodingParam* pParam = pCtx->pSvcParam;
|
||||
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pCtx->pVaa);
|
||||
const int32_t iNumRef = pParam->iNumRefFrame;
|
||||
SSpatialLayerInternal* pParamD = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
|
||||
pCtx->iNumRef0 = 0;
|
||||
|
||||
if (pCtx->eSliceType != I_SLICE) {
|
||||
@ -816,7 +821,7 @@ bool WelsBuildRefListScreen (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBes
|
||||
pCtx->pRefList0[pCtx->iNumRef0++] = pRefPic;
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
|
||||
"WelsBuildRefListScreen(), current iFrameNum = %d, current Tid = %d, ref iFrameNum = %d, ref uiTemporalId = %d, ref is Scene LTR = %d, LTR count = %d,iNumRef = %d",
|
||||
pCtx->iFrameNum, pCtx->uiTemporalId,
|
||||
pParamD->iFrameNum, pCtx->uiTemporalId,
|
||||
pRefPic->iFrameNum, pRefPic->uiTemporalId, pRefPic->bIsSceneLTR,
|
||||
pRefList->uiLongRefCount, iNumRef);
|
||||
}
|
||||
@ -831,7 +836,7 @@ bool WelsBuildRefListScreen (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBes
|
||||
pCtx->pRefList0[pCtx->iNumRef0++] = pRefList->pLongRefList[i];
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
|
||||
"WelsBuildRefListScreen(), ref !current iFrameNum = %d, ref iFrameNum = %d,LTR number = %d",
|
||||
pCtx->iFrameNum, pCtx->pRefList0[pCtx->iNumRef0 - 1]->iFrameNum, pRefList->uiLongRefCount);
|
||||
pParamD->iFrameNum, pCtx->pRefList0[pCtx->iNumRef0 - 1]->iFrameNum, pRefList->uiLongRefCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -902,7 +907,7 @@ void WelsMarkPicScreen (sWelsEncCtx* pCtx) {
|
||||
int32_t iMaxTid = WELS_LOG2 (pCtx->pSvcParam->uiGopSize);
|
||||
int32_t iMaxActualLtrIdx = -1;
|
||||
SSlice* pSliceList = NULL;
|
||||
|
||||
SSpatialLayerInternal* pParamD = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
|
||||
if (pCtx->pSvcParam->bEnableLongTermReference)
|
||||
iMaxActualLtrIdx = pCtx->pSvcParam->iNumRefFrame - STR_ROOM - 1 - WELS_MAX (iMaxTid , 1);
|
||||
|
||||
@ -953,9 +958,9 @@ void WelsMarkPicScreen (sWelsEncCtx* pCtx) {
|
||||
if (ppLongRefList[i]->bUsedAsRef && ppLongRefList[i]->bIsLongRef && (!ppLongRefList[i]->bIsSceneLTR)
|
||||
&& iMaxMultiRefTid == ppLongRefList[i]->uiTemporalId) {
|
||||
assert (IsValidFrameNum (ppLongRefList[i]->iFrameNum)); // pLtr->iCurLtrIdx must have a value
|
||||
int32_t iDeltaFrameNum = (pCtx->iFrameNum >= ppLongRefList[i]->iFrameNum)
|
||||
? (pCtx->iFrameNum - ppLongRefList[i]->iFrameNum)
|
||||
: (pCtx->iFrameNum + iMaxFrameNum - ppLongRefList[i]->iFrameNum);
|
||||
int32_t iDeltaFrameNum = (pParamD->iFrameNum >= ppLongRefList[i]->iFrameNum)
|
||||
? (pParamD->iFrameNum - ppLongRefList[i]->iFrameNum)
|
||||
: (pParamD->iFrameNum + iMaxFrameNum - ppLongRefList[i]->iFrameNum);
|
||||
|
||||
if (iDeltaFrameNum > iLongestDeltaFrameNum) {
|
||||
pLtr->iCurLtrIdx = ppLongRefList[i]->iLongTermPicNum;
|
||||
|
@ -679,7 +679,7 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) {
|
||||
const int32_t kiFirstMbInPartition = pPrivateData->iStartMbIndex; // inclusive
|
||||
const int32_t kiEndMbInPartition = pPrivateData->iEndMbIndex; // exclusive
|
||||
int32_t iAnyMbLeftInPartition = kiEndMbInPartition - kiFirstMbInPartition;
|
||||
|
||||
SSpatialLayerInternal *pParamInternal = &pCodingParam->sDependencyLayers[kiCurDid];
|
||||
iSliceIdx = pPrivateData->iSliceIndex;
|
||||
SSliceHeaderExt* pStartSliceHeaderExt = &pCurDq->sLayerInfo.pSliceInLayer[iSliceIdx].sSliceHeaderExt;
|
||||
pStartSliceHeaderExt->sSliceHeader.iFirstMbInSlice = kiFirstMbInPartition;
|
||||
@ -695,7 +695,7 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) {
|
||||
uiThrdRet = 1;
|
||||
WelsLog (&pEncPEncCtx->sLogCtx, WELS_LOG_WARNING,
|
||||
"[MT] CodingSliceThreadProc Too many slices: coding_idx %d, iSliceIdx %d, pSliceCtx->iMaxSliceNumConstraint %d",
|
||||
pEncPEncCtx->iCodingIndex,
|
||||
pParamInternal->iCodingIndex,
|
||||
iSliceIdx, pSliceCtx->iMaxSliceNumConstraint);
|
||||
WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
|
||||
pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent,
|
||||
@ -740,7 +740,7 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) {
|
||||
uiThrdRet = iReturn;
|
||||
WelsLog (&pEncPEncCtx->sLogCtx, WELS_LOG_WARNING,
|
||||
"[MT] CodingSliceThreadProc, WriteSliceBs not successful: coding_idx %d, iSliceIdx %d, BufferSize %d, m_iSliceSize %d, iPayloadSize %d",
|
||||
pEncPEncCtx->iCodingIndex,
|
||||
pParamInternal->iCodingIndex,
|
||||
iSliceIdx, pSliceBs->uiSize, iSliceSize, pSliceBs->sNalList[0].iPayloadSize);
|
||||
|
||||
WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
|
||||
|
@ -89,14 +89,14 @@ void WelsSliceHeaderScalExtInit (SDqLayer* pCurLayer, SSlice* pSlice) {
|
||||
void WelsSliceHeaderExtInit (sWelsEncCtx* pEncCtx, SDqLayer* pCurLayer, SSlice* pSlice) {
|
||||
SSliceHeaderExt* pCurSliceExt = &pSlice->sSliceHeaderExt;
|
||||
SSliceHeader* pCurSliceHeader = &pCurSliceExt->sSliceHeader;
|
||||
|
||||
SSpatialLayerInternal *pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
|
||||
pCurSliceHeader->eSliceType = pEncCtx->eSliceType;
|
||||
|
||||
pCurSliceExt->bStoreRefBasePicFlag = false;
|
||||
|
||||
pCurSliceHeader->iFirstMbInSlice = WelsGetFirstMbOfSlice (pCurLayer->sLayerInfo.pSliceInLayer, pSlice->uiSliceIdx);
|
||||
|
||||
pCurSliceHeader->iFrameNum = pEncCtx->iFrameNum;
|
||||
pCurSliceHeader->iFrameNum = pParamInternal->iFrameNum;
|
||||
pCurSliceHeader->uiIdrPicId = pEncCtx->uiIdrPicId;
|
||||
|
||||
pCurSliceHeader->iPicOrderCntLsb = pEncCtx->pEncPic->iFramePoc; // 0
|
||||
|
@ -185,8 +185,9 @@ int32_t CWelsPreProcess::BuildSpatialPicList (sWelsEncCtx* pCtx, const SSourcePi
|
||||
pSvcParam->SUsedPicRect.iTop = 0;
|
||||
pSvcParam->SUsedPicRect.iWidth = ((kpSrcPic->iPicWidth >> 1) << 1);
|
||||
pSvcParam->SUsedPicRect.iHeight = ((kpSrcPic->iPicHeight >> 1) << 1);
|
||||
if((pSvcParam->SUsedPicRect.iWidth<16)||((pSvcParam->SUsedPicRect.iHeight<16))){
|
||||
WelsLog ( & (pCtx->sLogCtx), WELS_LOG_ERROR, "Don't support width(%d) or height(%d) which is less than 16 ",pSvcParam->SUsedPicRect.iWidth,pSvcParam->SUsedPicRect.iHeight);
|
||||
if ((pSvcParam->SUsedPicRect.iWidth < 16) || ((pSvcParam->SUsedPicRect.iHeight < 16))) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "Don't support width(%d) or height(%d) which is less than 16 ",
|
||||
pSvcParam->SUsedPicRect.iWidth, pSvcParam->SUsedPicRect.iHeight);
|
||||
return -1;
|
||||
}
|
||||
if (WelsPreprocessReset (pCtx) != 0)
|
||||
@ -201,8 +202,6 @@ int32_t CWelsPreProcess::BuildSpatialPicList (sWelsEncCtx* pCtx, const SSourcePi
|
||||
return -1;
|
||||
|
||||
pCtx->pVaa->bSceneChangeFlag = pCtx->pVaa->bIdrPeriodFlag = false;
|
||||
if (pSvcParam->uiIntraPeriod)
|
||||
pCtx->pVaa->bIdrPeriodFlag = (1 + pCtx->iFrameIndex >= (int32_t)pSvcParam->uiIntraPeriod) ? true : false;
|
||||
|
||||
iSpatialNum = SingleLayerPreprocess (pCtx, kpSrcPic, &m_sScaledPicture);
|
||||
|
||||
@ -213,10 +212,10 @@ int32_t CWelsPreProcess::AnalyzeSpatialPic (sWelsEncCtx* pCtx, const int32_t kiD
|
||||
SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam;
|
||||
bool bNeededMbAq = (pSvcParam->bEnableAdaptiveQuant && (pCtx->eSliceType == P_SLICE));
|
||||
bool bCalculateBGD = (pCtx->eSliceType == P_SLICE && pSvcParam->bEnableBackgroundDetection);
|
||||
|
||||
SSpatialLayerInternal* pParamInternal = &pSvcParam->sDependencyLayers[kiDidx];
|
||||
int32_t iCurTemporalIdx = m_uiSpatialLayersInTemporal[kiDidx] - 1;
|
||||
|
||||
int32_t iRefTemporalIdx = (int32_t)g_kuiRefTemporalIdx[pSvcParam->iDecompStages][pCtx->iCodingIndex &
|
||||
int32_t iRefTemporalIdx = (int32_t)g_kuiRefTemporalIdx[pSvcParam->iDecompStages][pParamInternal->iCodingIndex &
|
||||
(pSvcParam->uiGopSize - 1)];
|
||||
if (pCtx->uiTemporalId == 0 && pCtx->pLtr[pCtx->uiDependencyId].bReceivedT0LostFlag)
|
||||
iRefTemporalIdx = m_uiSpatialLayersInTemporal[kiDidx] + pCtx->pVaa->uiValidLongTermPicIdx;
|
||||
@ -253,6 +252,9 @@ int32_t CWelsPreProcess::AnalyzeSpatialPic (sWelsEncCtx* pCtx, const int32_t kiD
|
||||
if (bNeededMbAq) {
|
||||
SPicture* pCurPic = m_pLastSpatialPicture[kiDidx][1];
|
||||
SPicture* pRefPic = m_pLastSpatialPicture[kiDidx][0];
|
||||
//printf("pCurPicDid = %d,pCurPicTid = %d,pRefPicDid = %d,pRefPicTid = %d,kiDidx = %d,pCurPic = %x,pRefPic = %x,bbCurPic = %x\n",
|
||||
// pCurPic->uiSpatialId,pCurPic->uiTemporalId,pCurPic->uiSpatialId,pCurPic->uiTemporalId,kiDidx,pCurPic,pRefPic,m_pSpatialPic[kiDidx][iCurTemporalIdx]);
|
||||
|
||||
|
||||
AdaptiveQuantCalculation (pCtx->pVaa, pCurPic, pRefPic);
|
||||
}
|
||||
@ -285,6 +287,8 @@ int32_t CWelsPreProcess::UpdateSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodin
|
||||
}
|
||||
WelsExchangeSpatialPictures (&m_pSpatialPic[kiDidx][kiCurPos],
|
||||
&m_pSpatialPic[kiDidx][iCurTid]);
|
||||
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -294,6 +298,43 @@ int32_t CWelsPreProcess::UpdateSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodin
|
||||
* SingleLayerPreprocess: down sampling if applicable
|
||||
* @return: exact number of spatial layers need to encoder indeed
|
||||
*/
|
||||
bool CWelsPreProcess::BuildSpatialLayer (sWelsEncCtx* pCtx, const SSourcePicture* kpSrc, int32_t iDependencyId) {
|
||||
SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam;
|
||||
int32_t iMaxDid = pSvcParam->iSpatialLayerNum - 1;
|
||||
SSpatialPicIndex* pSpatialIndexMap = &pCtx->sSpatialIndexMap[0];
|
||||
SSpatialLayerConfig* pDlayerParam = &pSvcParam->sSpatialLayers[iDependencyId];
|
||||
SSpatialLayerInternal* pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId];
|
||||
int32_t iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pDlayerParamInternal->iCodingIndex &
|
||||
(pSvcParam->uiGopSize - 1)];
|
||||
|
||||
|
||||
if (iTemporalId != INVALID_TEMPORAL_ID) {
|
||||
if (iDependencyId == iMaxDid) {
|
||||
return true;
|
||||
} else {
|
||||
int32_t iPicturePos = m_uiSpatialLayersInTemporal[iDependencyId] - 1;
|
||||
Scaled_Picture* pScaledPicture = &m_sScaledPicture;
|
||||
|
||||
int32_t iSrcWidth = pSvcParam->SUsedPicRect.iWidth;
|
||||
int32_t iSrcHeight = pSvcParam->SUsedPicRect.iHeight;
|
||||
int32_t iTargetWidth = pDlayerParam->iVideoWidth;
|
||||
int32_t iTargetHeight = pDlayerParam->iVideoHeight;
|
||||
|
||||
SPicture* pSrcPic = (pSpatialIndexMap + iMaxDid)->pSrc;; // large
|
||||
SPicture* pDstPic = m_pSpatialPic[iDependencyId][iPicturePos]; // small
|
||||
|
||||
int32_t iShrinkWidth = pScaledPicture->iScaledWidth[iDependencyId];
|
||||
int32_t iShrinkHeight = pScaledPicture->iScaledHeight[iDependencyId];
|
||||
DownsamplePadding (pSrcPic, pDstPic, iSrcWidth, iSrcHeight, iShrinkWidth, iShrinkHeight, iTargetWidth, iTargetHeight,
|
||||
true);
|
||||
WelsUpdateSpatialIdxMap (pCtx, iDependencyId, pDstPic, iDependencyId);
|
||||
m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSourcePicture* kpSrc,
|
||||
Scaled_Picture* pScaledPicture) {
|
||||
SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam;
|
||||
@ -310,19 +351,22 @@ int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSource
|
||||
int32_t iTargetWidth = 0;
|
||||
int32_t iTargetHeight = 0;
|
||||
int32_t iTemporalId = 0;
|
||||
int32_t iActualSpatialLayerNum = 0;
|
||||
|
||||
pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId];
|
||||
pDlayerParam = &pSvcParam->sSpatialLayers[iDependencyId];
|
||||
iTargetWidth = pDlayerParam->iVideoWidth;
|
||||
iTargetHeight = pDlayerParam->iVideoHeight;
|
||||
iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pCtx->iCodingIndex & (pSvcParam->uiGopSize - 1)];
|
||||
iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pDlayerParamInternal->iCodingIndex &
|
||||
(pSvcParam->uiGopSize - 1)];
|
||||
iSrcWidth = pSvcParam->SUsedPicRect.iWidth;
|
||||
iSrcHeight = pSvcParam->SUsedPicRect.iHeight;
|
||||
|
||||
if (pSvcParam->uiIntraPeriod)
|
||||
pCtx->pVaa->bIdrPeriodFlag = (1 + pDlayerParamInternal->iFrameIndex >= (int32_t)pSvcParam->uiIntraPeriod) ? true :
|
||||
false;
|
||||
|
||||
pSrcPic = pScaledPicture->pScaledInputPicture ? pScaledPicture->pScaledInputPicture :
|
||||
m_pSpatialPic[iDependencyId][iPicturePos];
|
||||
|
||||
WelsMoveMemoryWrapper (pSvcParam, pSrcPic, kpSrc, iSrcWidth, iSrcHeight);
|
||||
|
||||
if (pSvcParam->bEnableDenoise)
|
||||
@ -343,11 +387,13 @@ int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSource
|
||||
|
||||
if (pSvcParam->bEnableSceneChangeDetect && !pCtx->pVaa->bIdrPeriodFlag) {
|
||||
if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
|
||||
pCtx->pVaa->eSceneChangeIdc = (pCtx->bEncCurFrmAsIdrFlag ? LARGE_CHANGED_SCENE : DetectSceneChangeScreen (pCtx,
|
||||
pDstPic));
|
||||
pCtx->pVaa->eSceneChangeIdc = (pDlayerParamInternal->bEncCurFrmAsIdrFlag ? LARGE_CHANGED_SCENE :
|
||||
DetectSceneChangeScreen (pCtx,
|
||||
pDstPic));
|
||||
pCtx->pVaa->bSceneChangeFlag = (LARGE_CHANGED_SCENE == pCtx->pVaa->eSceneChangeIdc);
|
||||
} else {
|
||||
if ((!pCtx->bEncCurFrmAsIdrFlag) && ! (pCtx->iCodingIndex & (pSvcParam->uiGopSize - 1))) {
|
||||
if ((!pDlayerParamInternal->bEncCurFrmAsIdrFlag)
|
||||
&& ! (pDlayerParamInternal->iCodingIndex & (pSvcParam->uiGopSize - 1))) {
|
||||
SPicture* pRefPic = pCtx->pLtr[iDependencyId].bReceivedT0LostFlag ?
|
||||
m_pSpatialPic[iDependencyId][m_uiSpatialLayersInTemporal[iDependencyId] +
|
||||
pCtx->pVaa->uiValidLongTermPicIdx] : m_pLastSpatialPicture[iDependencyId][0];
|
||||
@ -357,61 +403,28 @@ int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSource
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pSvcParam->iSpatialLayerNum; i++) {
|
||||
if (pSvcParam->sDependencyLayers[i].uiCodingIdx2TemporalId[pCtx->iCodingIndex & (pSvcParam->uiGopSize - 1)]
|
||||
!= INVALID_TEMPORAL_ID) {
|
||||
++ iActualSpatialLayerNum;
|
||||
}
|
||||
}
|
||||
WelsUpdateSpatialIdxMap (pCtx, iDependencyId, pDstPic, iDependencyId);
|
||||
m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos];
|
||||
|
||||
if (iTemporalId != INVALID_TEMPORAL_ID) {
|
||||
WelsUpdateSpatialIdxMap (pCtx, iActualSpatialLayerNum - 1, pDstPic, iDependencyId);
|
||||
++ iSpatialNum;
|
||||
-- iActualSpatialLayerNum;
|
||||
}
|
||||
|
||||
m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos];
|
||||
-- iDependencyId;
|
||||
|
||||
// generate other spacial layer
|
||||
// pSrc is
|
||||
// -- padded input pic, if downsample should be applied to generate highest layer, [if] block above
|
||||
// -- highest layer, if no downsampling, [else] block above
|
||||
if (pSvcParam->iSpatialLayerNum > 1) {
|
||||
while (iDependencyId >= 0) {
|
||||
pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId];
|
||||
pDlayerParam = &pSvcParam->sSpatialLayers[iDependencyId];
|
||||
iTargetWidth = pDlayerParam->iVideoWidth;
|
||||
iTargetHeight = pDlayerParam->iVideoHeight;
|
||||
iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pCtx->iCodingIndex & (pSvcParam->uiGopSize - 1)];
|
||||
iPicturePos = m_uiSpatialLayersInTemporal[iDependencyId] - 1;
|
||||
iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pDlayerParamInternal->iCodingIndex &
|
||||
(pSvcParam->uiGopSize - 1)];
|
||||
|
||||
// NOT work for CGS, FIXME
|
||||
// spatial layer is able to encode indeed
|
||||
if ((iTemporalId != INVALID_TEMPORAL_ID)) {
|
||||
// down sampling performed
|
||||
|
||||
pDstPic = m_pSpatialPic[iDependencyId][iPicturePos]; // small
|
||||
iShrinkWidth = pScaledPicture->iScaledWidth[iDependencyId];
|
||||
iShrinkHeight = pScaledPicture->iScaledHeight[iDependencyId];
|
||||
DownsamplePadding (pSrcPic, pDstPic, iSrcWidth, iSrcHeight, iShrinkWidth, iShrinkHeight, iTargetWidth, iTargetHeight,
|
||||
true);
|
||||
|
||||
WelsUpdateSpatialIdxMap (pCtx, iActualSpatialLayerNum - 1, pDstPic, iDependencyId);
|
||||
|
||||
-- iActualSpatialLayerNum;
|
||||
++ iSpatialNum;
|
||||
|
||||
m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos];
|
||||
}
|
||||
-- iDependencyId;
|
||||
}
|
||||
}
|
||||
|
||||
return iSpatialNum;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Whether input picture need be scaled?
|
||||
*/
|
||||
@ -999,6 +1012,7 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
|
||||
#define STATIC_SCENE_MOTION_RATIO 0.01f
|
||||
SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam;
|
||||
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pCtx->pVaa);
|
||||
SSpatialLayerInternal* pParamInternal = &pSvcParam->sDependencyLayers[0];
|
||||
if (NULL == pCtx || NULL == pVaaExt || NULL == pCurPicture) {
|
||||
return LARGE_CHANGED_SCENE;
|
||||
}
|
||||
@ -1040,7 +1054,7 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
|
||||
const int32_t iNegligibleMotionBlocks = (static_cast<int32_t> ((pCurPicture->iWidthInPixel >> 3) *
|
||||
(pCurPicture->iHeightInPixel >> 3) * STATIC_SCENE_MOTION_RATIO));
|
||||
const uint8_t iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[m_pEncCtx->sSpatialIndexMap[0].iDid],
|
||||
m_pEncCtx->iCodingIndex, pSvcParam->uiGopSize);
|
||||
pParamInternal->iCodingIndex, pSvcParam->uiGopSize);
|
||||
if (iCurTid == INVALID_TEMPORAL_ID) {
|
||||
return LARGE_CHANGED_SCENE;
|
||||
}
|
||||
@ -1135,7 +1149,7 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
|
||||
}
|
||||
|
||||
WelsLog (pLogCtx, WELS_LOG_DEBUG, "iVaaFrameSceneChangeIdc = %d,codingIdx = %d", iVaaFrameSceneChangeIdc,
|
||||
pCtx->iCodingIndex);
|
||||
pParamInternal->iCodingIndex);
|
||||
|
||||
SaveBestRefToVaa (sLtrSaved, & (pVaaExt->sVaaStrBestRefCandidate[0]));
|
||||
pVaaExt->iVaaBestRefFrameNum = sLtrSaved.pRefPicture->iFrameNum;
|
||||
|
@ -145,7 +145,7 @@ WelsErrorType CWelsSliceEncodingTask::ExecuteTask() {
|
||||
#if MT_DEBUG_BS_WR
|
||||
m_pSliceBs->bSliceCodedFlag = false;
|
||||
#endif//MT_DEBUG_BS_WR
|
||||
|
||||
SSpatialLayerInternal *pParamInternal = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId];
|
||||
if (m_bNeedPrefix) {
|
||||
if (m_eNalRefIdc != NRI_PRI_LOWEST) {
|
||||
WelsLoadNalForSlice (m_pSliceBs, NAL_UNIT_PREFIX, m_eNalRefIdc);
|
||||
@ -171,7 +171,7 @@ WelsErrorType CWelsSliceEncodingTask::ExecuteTask() {
|
||||
if (ENC_RETURN_SUCCESS != iReturn) {
|
||||
WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING,
|
||||
"[MT] CWelsSliceEncodingTask ExecuteTask(), WriteSliceBs not successful: coding_idx %d, um_iSliceIdx %d",
|
||||
m_pCtx->iCodingIndex,
|
||||
pParamInternal->iCodingIndex,
|
||||
m_iSliceIdx);
|
||||
return iReturn;
|
||||
}
|
||||
@ -209,11 +209,11 @@ WelsErrorType CWelsLoadBalancingSlicingEncodingTask::InitTask() {
|
||||
|
||||
void CWelsLoadBalancingSlicingEncodingTask::FinishTask() {
|
||||
CWelsSliceEncodingTask::FinishTask();
|
||||
|
||||
SSpatialLayerInternal *pParamInternal = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId];
|
||||
m_pSlice->uiSliceConsumeTime = (uint32_t) (WelsTime() - m_iSliceStart);
|
||||
WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DEBUG,
|
||||
"[MT] CWelsLoadBalancingSlicingEncodingTask()FinishTask, coding_idx %d, um_iSliceIdx %d, uiSliceConsumeTime %d, m_iSliceSize %d, iFirstMbInSlice %d, count_num_mb_in_slice %d at time=%" PRId64,
|
||||
m_pCtx->iCodingIndex,
|
||||
pParamInternal->iCodingIndex,
|
||||
m_iSliceIdx,
|
||||
m_pSlice->uiSliceConsumeTime,
|
||||
m_iSliceSize,
|
||||
@ -230,7 +230,7 @@ WelsErrorType CWelsConstrainedSizeSlicingEncodingTask::ExecuteTask() {
|
||||
SSliceCtx* pSliceCtx = &pCurDq->sSliceEncCtx;
|
||||
const int32_t kiSliceIdxStep = m_pCtx->iActiveThreadsNum;
|
||||
|
||||
|
||||
SSpatialLayerInternal *pParamInternal = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId];
|
||||
SSliceHeaderExt* pStartSliceHeaderExt = &pCurDq->sLayerInfo.pSliceInLayer[m_iSliceIdx].sSliceHeaderExt;
|
||||
|
||||
//deal with partition: TODO: here SSliceThreadPrivateData is just for parition info and actually has little relationship with threadbuffer, and iThreadIndex is not used in threadpool model, need renaming after removing old logic to avoid confusion
|
||||
@ -252,7 +252,7 @@ WelsErrorType CWelsConstrainedSizeSlicingEncodingTask::ExecuteTask() {
|
||||
if (iLocalSliceIdx >= pSliceCtx->iMaxSliceNumConstraint) {
|
||||
WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING,
|
||||
"[MT] CWelsConstrainedSizeSlicingEncodingTask ExecuteTask() coding_idx %d, uiLocalSliceIdx %d, pSliceCtx->iMaxSliceNumConstraint %d",
|
||||
m_pCtx->iCodingIndex,
|
||||
pParamInternal->iCodingIndex,
|
||||
iLocalSliceIdx, pSliceCtx->iMaxSliceNumConstraint);
|
||||
return ENC_RETURN_KNOWN_ISSUE;
|
||||
}
|
||||
@ -288,7 +288,7 @@ WelsErrorType CWelsConstrainedSizeSlicingEncodingTask::ExecuteTask() {
|
||||
if (ENC_RETURN_SUCCESS != iReturn) {
|
||||
WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING,
|
||||
"[MT] CWelsConstrainedSizeSlicingEncodingTask ExecuteTask(), WriteSliceBs not successful: coding_idx %d, uiLocalSliceIdx %d, BufferSize %d, m_iSliceSize %d, iPayloadSize %d",
|
||||
m_pCtx->iCodingIndex,
|
||||
pParamInternal->iCodingIndex,
|
||||
iLocalSliceIdx, m_pSliceBs->uiSize, m_iSliceSize, m_pSliceBs->sNalList[0].iPayloadSize);
|
||||
return iReturn;
|
||||
}
|
||||
@ -305,7 +305,7 @@ WelsErrorType CWelsConstrainedSizeSlicingEncodingTask::ExecuteTask() {
|
||||
|
||||
WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DEBUG,
|
||||
"[MT] CWelsConstrainedSizeSlicingEncodingTask(), coding_idx %d, iPartitionId %d, m_iThreadIdx %d, iLocalSliceIdx %d, m_iSliceSize %d, ParamValidationExt(), invalid uiMaxNalSizeiEndMbInPartition %d, pCurDq->pLastCodedMbIdxOfPartition[%d] %d\n",
|
||||
m_pCtx->iCodingIndex, kiPartitionId, m_iThreadIdx, iLocalSliceIdx, m_iSliceSize,
|
||||
pParamInternal->iCodingIndex, kiPartitionId, m_iThreadIdx, iLocalSliceIdx, m_iSliceSize,
|
||||
kiEndMbInPartition, kiPartitionId, pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId]);
|
||||
|
||||
iAnyMbLeftInPartition = kiEndMbInPartition - (1 + pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId]);
|
||||
|
@ -1391,6 +1391,7 @@ TEST_F (EncodeDecodeTestAPI, DiffSlicingInDlayer) {
|
||||
sParam.sSpatialLayers[2].sSliceArgument.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
|
||||
sParam.sSpatialLayers[2].sSliceArgument.uiSliceNum = (rand() % 30) + 1;
|
||||
|
||||
|
||||
int rv = encoder_->InitializeExt (&sParam);
|
||||
ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user