Showing the changes to codec/encoder/core/src/encoder_ext.cpp (1 of 3 files). Show all
Unified · Split
| @@ -321,7 +321,6 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa · 320 unmodified lines | ||
| 321 | 321 | return ENC_RETURN_UNSUPPORTED_PARA; |
| 322 | 322 | } |
| 323 | 323 | |
| 324 | − | |
| 325 | 324 | //about iMultipleThreadIdc, bDeblockingParallelFlag, iLoopFilterDisableIdc, & uiSliceMode |
| 326 | 325 | // (1) Single Thread |
| 327 | 326 | // if (THREAD==1)//single thread |
| @@ -335,9 +334,10 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa · 7 unmodified lines | ||
| 335 | 334 | } |
| 336 | 335 | |
| 337 | 336 | // eSpsPpsIdStrategy checkings |
| 338 | − if (pCodingParam->iSpatialLayerNum > 1 && (SPS_LISTING & pCodingParam->eSpsPpsIdStrategy)) { | |
| 337 | + if (pCodingParam->iSpatialLayerNum > 1 && (!pCodingParam->bSimulcastAVC) | |
| 338 | + && (SPS_LISTING & pCodingParam->eSpsPpsIdStrategy)) { | |
| 339 | 339 | WelsLog (pLogCtx, WELS_LOG_WARNING, |
| 340 | − "ParamValidationExt(), eSpsPpsIdStrategy setting (%d) with multiple SpatialLayers (%d) not supported! eSpsPpsIdStrategy adjusted to CONSTANT_ID", | |
| 340 | + "ParamValidationExt(), eSpsPpsIdStrategy setting (%d) with multiple svc SpatialLayers (%d) not supported! eSpsPpsIdStrategy adjusted to CONSTANT_ID", | |
| 341 | 341 | pCodingParam->eSpsPpsIdStrategy, pCodingParam->iSpatialLayerNum); |
| 342 | 342 | pCodingParam->eSpsPpsIdStrategy = CONSTANT_ID; |
| 343 | 343 | } |
| @@ -540,7 +540,8 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa · 196 unmodified lines | ||
| 540 | 540 | } |
| 541 | 541 | |
| 542 | 542 | if (pCodingParam->uiMaxNalSize < (NAL_HEADER_ADD_0X30BYTES + MAX_MACROBLOCK_SIZE_IN_BYTE)) { |
| 543 | − WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiMaxNalSize (%d) settings! should be larger than (NAL_HEADER_ADD_0X30BYTES + MAX_MACROBLOCK_SIZE_IN_BYTE)(%d)", | |
| 543 | + WelsLog (pLogCtx, WELS_LOG_ERROR, | |
| 544 | + "ParamValidationExt(), invalid uiMaxNalSize (%d) settings! should be larger than (NAL_HEADER_ADD_0X30BYTES + MAX_MACROBLOCK_SIZE_IN_BYTE)(%d)", | |
| 544 | 545 | pCodingParam->uiMaxNalSize, (NAL_HEADER_ADD_0X30BYTES + MAX_MACROBLOCK_SIZE_IN_BYTE)); |
| 545 | 546 | return ENC_RETURN_UNSUPPORTED_PARA; |
| 546 | 547 | } |
| @@ -3140,6 +3141,7 @@ int32_t WelsWriteOneSPS (sWelsEncCtx* pCtx, const int32_t kiSpsIdx, int32_t& iNa · 2593 unmodified lines | ||
| 3140 | 3141 | pCtx->iPosBsBuffer += iNalSize; |
| 3141 | 3142 | return ENC_RETURN_SUCCESS; |
| 3142 | 3143 | } |
| 3144 | + | |
| 3143 | 3145 | int32_t WelsWriteOnePPS (sWelsEncCtx* pCtx, const int32_t kiPpsIdx, int32_t& iNalSize) { |
| 3144 | 3146 | //TODO |
| 3145 | 3147 | int32_t iNal = pCtx->pOut->iNalIndex; |
| @@ -3159,6 +3161,29 @@ int32_t WelsWriteOnePPS (sWelsEncCtx* pCtx, const int32_t kiPpsIdx, int32_t& iNa · 13 unmodified lines | ||
| 3159 | 3161 | return ENC_RETURN_SUCCESS; |
| 3160 | 3162 | } |
| 3161 | 3163 | |
| 3164 | +void UpdatePpsList (sWelsEncCtx* pCtx) { | |
| 3165 | + assert (pCtx->iPpsNum <= MAX_DQ_LAYER_NUM); | |
| 3166 | + | |
| 3167 | + //Generate PPS LIST | |
| 3168 | + int32_t iPpsId = 0, iUsePpsNum = pCtx->iPpsNum; | |
| 3169 | + | |
| 3170 | + for (int32_t iIdrRound = 0; iIdrRound < MAX_PPS_COUNT; iIdrRound++) { | |
| 3171 | + for (iPpsId = 0; iPpsId < pCtx->iPpsNum; iPpsId++) { | |
| 3172 | + pCtx->sPSOVector.iPpsIdList[iPpsId][iIdrRound] = ((iIdrRound * iUsePpsNum + iPpsId) % MAX_PPS_COUNT); | |
| 3173 | + } | |
| 3174 | + } | |
| 3175 | + | |
| 3176 | + for (iPpsId = iUsePpsNum; iPpsId < MAX_PPS_COUNT; iPpsId++) { | |
| 3177 | + memcpy (& (pCtx->pPPSArray[iPpsId]), & (pCtx->pPPSArray[iPpsId % iUsePpsNum]), sizeof (SWelsPPS)); | |
| 3178 | + pCtx->pPPSArray[iPpsId].iPpsId = iPpsId; | |
| 3179 | + pCtx->iPpsNum++; | |
| 3180 | + } | |
| 3181 | + | |
| 3182 | + assert (pCtx->iPpsNum == MAX_PPS_COUNT); | |
| 3183 | + pCtx->sPSOVector.uiInUsePpsNum = pCtx->iPpsNum; | |
| 3184 | + | |
| 3185 | +} | |
| 3186 | + | |
| 3162 | 3187 | /*! |
| 3163 | 3188 | * \brief write all parameter sets introduced in SVC extension |
| 3164 | 3189 | * \return writing results, success or error |
| @@ -3245,29 +3270,11 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 80 unmodified lines | ||
| 3245 | 3270 | } |
| 3246 | 3271 | |
| 3247 | 3272 | /* write all PPS */ |
| 3248 | − iIdx = 0; | |
| 3249 | 3273 | if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) { |
| 3250 | − assert (pCtx->iPpsNum <= MAX_DQ_LAYER_NUM); | |
| 3251 | − | |
| 3252 | − //Generate PPS LIST | |
| 3253 | − int32_t iPpsId = 0, iUsePpsNum = pCtx->iPpsNum; | |
| 3254 | − | |
| 3255 | − for (int32_t iIdrRound = 0; iIdrRound < MAX_PPS_COUNT; iIdrRound++) { | |
| 3256 | − for (iPpsId = 0; iPpsId < pCtx->iPpsNum; iPpsId++) { | |
| 3257 | − pCtx->sPSOVector.iPpsIdList[iPpsId][iIdrRound] = ((iIdrRound * iUsePpsNum + iPpsId) % MAX_PPS_COUNT); | |
| 3258 | − } | |
| 3259 | − } | |
| 3260 | − | |
| 3261 | − for (iPpsId = iUsePpsNum; iPpsId < MAX_PPS_COUNT; iPpsId++) { | |
| 3262 | − memcpy (& (pCtx->pPPSArray[iPpsId]), & (pCtx->pPPSArray[iPpsId % iUsePpsNum]), sizeof (SWelsPPS)); | |
| 3263 | − pCtx->pPPSArray[iPpsId].iPpsId = iPpsId; | |
| 3264 | − pCtx->iPpsNum++; | |
| 3265 | − } | |
| 3266 | − | |
| 3267 | − assert (pCtx->iPpsNum == MAX_PPS_COUNT); | |
| 3268 | − pCtx->sPSOVector.uiInUsePpsNum = pCtx->iPpsNum; | |
| 3274 | + UpdatePpsList (pCtx); | |
| 3269 | 3275 | } |
| 3270 | 3276 | |
| 3277 | + iIdx = 0; | |
| 3271 | 3278 | while (iIdx < pCtx->iPpsNum) { |
| 3272 | 3279 | if ((INCREASING_ID & pCtx->pSvcParam->eSpsPpsIdStrategy)) { |
| 3273 | 3280 | //para_set_type = 2: PPS, use MAX_PPS_COUNT |
| @@ -3479,7 +3486,6 @@ int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t kiSpatialNum, · 205 unmodified lines | ||
| 3479 | 3486 | iCountNal = 1; |
| 3480 | 3487 | //finish writing one NAL |
| 3481 | 3488 | |
| 3482 | − | |
| 3483 | 3489 | pLayerBsInfo->uiSpatialId = iIdx; |
| 3484 | 3490 | pLayerBsInfo->uiTemporalId = 0; |
| 3485 | 3491 | pLayerBsInfo->uiQualityId = 0; |
| @@ -3511,7 +3517,6 @@ int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t kiSpatialNum, · 25 unmodified lines | ||
| 3511 | 3517 | iCountNal = 1; |
| 3512 | 3518 | //finish writing one NAL |
| 3513 | 3519 | |
| 3514 | − | |
| 3515 | 3520 | pLayerBsInfo->uiSpatialId = iIdx; |
| 3516 | 3521 | pLayerBsInfo->uiTemporalId = 0; |
| 3517 | 3522 | pLayerBsInfo->uiQualityId = 0; |
| @@ -3538,6 +3543,87 @@ int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t kiSpatialNum, · 20 unmodified lines | ||
| 3538 | 3543 | return iReturn; |
| 3539 | 3544 | } |
| 3540 | 3545 | |
| 3546 | +int32_t WriteSavcParaset_Listing (sWelsEncCtx* pCtx, const int32_t kiSpatialNum, | |
| 3547 | + SLayerBSInfo*& pLayerBsInfo, int32_t& iLayerNum, int32_t& iFrameSize) { | |
| 3548 | + int32_t iNonVclSize = 0, iCountNal = 0, iReturn; | |
| 3549 | + | |
| 3550 | + // write SPS | |
| 3551 | + iNonVclSize = 0; | |
| 3552 | + | |
| 3553 | + for (int32_t iSpatialId = 0; iSpatialId < kiSpatialNum; iSpatialId++) { | |
| 3554 | + iCountNal = 0; | |
| 3555 | + for (int32_t iIdx = 0; iIdx < pCtx->iSpsNum; iIdx++) { | |
| 3556 | + //writing one NAL | |
| 3557 | + int32_t iNalSize = 0; | |
| 3558 | + iReturn = WelsWriteOneSPS (pCtx, iIdx, iNalSize); | |
| 3559 | + WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS) | |
| 3560 | + | |
| 3561 | + pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize; | |
| 3562 | + iNonVclSize += iNalSize; | |
| 3563 | + iCountNal ++; | |
| 3564 | + //finish writing one NAL | |
| 3565 | + } | |
| 3566 | + | |
| 3567 | + pLayerBsInfo->uiSpatialId = iSpatialId; | |
| 3568 | + pLayerBsInfo->uiTemporalId = 0; | |
| 3569 | + pLayerBsInfo->uiQualityId = 0; | |
| 3570 | + pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER; | |
| 3571 | + pLayerBsInfo->iNalCount = iCountNal; | |
| 3572 | + | |
| 3573 | + //point to next pLayerBsInfo | |
| 3574 | + ++ pLayerBsInfo; | |
| 3575 | + pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer; | |
| 3576 | + pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal; | |
| 3577 | + //update for external countings | |
| 3578 | + iCountNal = 0; | |
| 3579 | + ++ iLayerNum; | |
| 3580 | + } | |
| 3581 | + | |
| 3582 | + // write PPS | |
| 3583 | + if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) { | |
| 3584 | + UpdatePpsList (pCtx); | |
| 3585 | + } | |
| 3586 | + | |
| 3587 | + //TODO: under new strategy, will PPS be correctly updated? | |
| 3588 | + for (int32_t iSpatialId = 0; iSpatialId < kiSpatialNum; iSpatialId++) { | |
| 3589 | + iCountNal = 0; | |
| 3590 | + for (int32_t iIdx = 0; iIdx < pCtx->iPpsNum; iIdx++) { | |
| 3591 | + //writing one NAL | |
| 3592 | + int32_t iNalSize = 0; | |
| 3593 | + iReturn = WelsWriteOnePPS (pCtx, iIdx, iNalSize); | |
| 3594 | + WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS) | |
| 3595 | + | |
| 3596 | + pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize; | |
| 3597 | + iNonVclSize += iNalSize; | |
| 3598 | + iCountNal ++; | |
| 3599 | + //finish writing one NAL | |
| 3600 | + } | |
| 3601 | + | |
| 3602 | + pLayerBsInfo->uiSpatialId = iSpatialId; | |
| 3603 | + pLayerBsInfo->uiTemporalId = 0; | |
| 3604 | + pLayerBsInfo->uiQualityId = 0; | |
| 3605 | + pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER; | |
| 3606 | + pLayerBsInfo->iNalCount = iCountNal; | |
| 3607 | + | |
| 3608 | + //point to next pLayerBsInfo | |
| 3609 | + ++ pLayerBsInfo; | |
| 3610 | + pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer; | |
| 3611 | + pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal; | |
| 3612 | + //update for external countings | |
| 3613 | + iCountNal = 0; | |
| 3614 | + ++ iLayerNum; | |
| 3615 | + } | |
| 3616 | + | |
| 3617 | + // to check number of layers / nals / slices dependencies | |
| 3618 | + if (iLayerNum > MAX_LAYER_NUM_OF_FRAME) { | |
| 3619 | + WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR, "WriteSavcParaset(), iLayerNum(%d) > MAX_LAYER_NUM_OF_FRAME(%d)!", | |
| 3620 | + iLayerNum, MAX_LAYER_NUM_OF_FRAME); | |
| 3621 | + return ENC_RETURN_UNEXPECTED; | |
| 3622 | + } | |
| 3623 | + | |
| 3624 | + iFrameSize += iNonVclSize; | |
| 3625 | + return iReturn; | |
| 3626 | +} | |
| 3541 | 3627 | |
| 3542 | 3628 | /*! |
| 3543 | 3629 | * \brief core svc encoding process |
| @@ -3637,9 +3723,13 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour · 93 unmodified lines | ||
| 3637 | 3723 | ++ pCtx->uiIdrPicId; |
| 3638 | 3724 | // write parameter sets bitstream or SEI/SSEI (if any) here |
| 3639 | 3725 | // TODO: use function pointer instead |
| 3640 | − pCtx->iEncoderError = ((!pSvcParam->bSimulcastAVC) | |
| 3641 | − ? (WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize)) | |
| 3642 | − : (WriteSavcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize))); | |
| 3726 | + if (! (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy)) { | |
| 3727 | + pCtx->iEncoderError = ((!pSvcParam->bSimulcastAVC) | |
| 3728 | + ? (WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize)) | |
| 3729 | + : (WriteSavcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize))); | |
| 3730 | + } else { | |
| 3731 | + pCtx->iEncoderError = WriteSavcParaset_Listing (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize); | |
| 3732 | + } | |
| 3643 | 3733 | WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS) |
| 3644 | 3734 | } |
| 3645 | 3735 | |
| @@ -4217,6 +4307,33 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour · 571 unmodified lines | ||
| 4217 | 4307 | |
| 4218 | 4308 | pFbi->eFrameType = eFrameType; |
| 4219 | 4309 | pFbi->iFrameSizeInBytes = iFrameSize; |
| 4310 | + | |
| 4311 | +#ifdef _DEBUG | |
| 4312 | + if (pFbi->iLayerNum > MAX_LAYER_NUM_OF_FRAME) { | |
| 4313 | + WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR, "WelsEncoderEncodeExt(), iLayerNum(%d) > MAX_LAYER_NUM_OF_FRAME(%d)!", | |
| 4314 | + pFbi->iLayerNum, MAX_LAYER_NUM_OF_FRAME); | |
| 4315 | + return ENC_RETURN_UNEXPECTED; | |
| 4316 | + } | |
| 4317 | + | |
| 4318 | + int32_t iTotalNal = 0; | |
| 4319 | + for (int32_t k = 0; k < pFbi->iLayerNum; k++) { | |
| 4320 | + iTotalNal += pFbi->sLayerInfo[k].iNalCount; | |
| 4321 | + | |
| 4322 | + if ((pCtx->iActiveThreadsNum > 1) && (MAX_NAL_UNITS_IN_LAYER < pFbi->sLayerInfo[k].iNalCount)) { | |
| 4323 | + WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR, | |
| 4324 | + "WelsEncoderEncodeExt(), iCountNumNals(%d) > MAX_NAL_UNITS_IN_LAYER(%d) under multi-thread(%d) NOT supported!", | |
| 4325 | + pFbi->sLayerInfo[k].iNalCount, MAX_NAL_UNITS_IN_LAYER), pCtx->iActiveThreadsNum; | |
| 4326 | + return ENC_RETURN_UNEXPECTED; | |
| 4327 | + } | |
| 4328 | + } | |
| 4329 | + | |
| 4330 | + if (iTotalNal > pCtx->pOut->iCountNals) { | |
| 4331 | + WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR, "WelsEncoderEncodeExt(), iTotalNal(%d) > iCountNals(%d)!", | |
| 4332 | + iTotalNal, pCtx->pOut->iCountNals); | |
| 4333 | + return ENC_RETURN_UNEXPECTED; | |
| 4334 | + } | |
| 4335 | +#endif | |
| 4336 | + | |
| 4220 | 4337 | return ENC_RETURN_SUCCESS; |
| 4221 | 4338 | } |
| 4222 | 4339 | |