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 | return ENC_RETURN_UNSUPPORTED_PARA; | 321 | return ENC_RETURN_UNSUPPORTED_PARA; |
| 322 | } | 322 | } |
| 323 | 323 | ||
| 324 | |||
| 325 | //about iMultipleThreadIdc, bDeblockingParallelFlag, iLoopFilterDisableIdc, & uiSliceMode | 324 | //about iMultipleThreadIdc, bDeblockingParallelFlag, iLoopFilterDisableIdc, & uiSliceMode |
| 326 | // (1) Single Thread | 325 | // (1) Single Thread |
| 327 | // if (THREAD==1)//single thread | 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 | // eSpsPpsIdStrategy checkings | 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 | WelsLog (pLogCtx, WELS_LOG_WARNING, | 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 | pCodingParam->eSpsPpsIdStrategy, pCodingParam->iSpatialLayerNum); | 341 | pCodingParam->eSpsPpsIdStrategy, pCodingParam->iSpatialLayerNum); |
| 342 | pCodingParam->eSpsPpsIdStrategy = CONSTANT_ID; | 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 | if (pCodingParam->uiMaxNalSize < (NAL_HEADER_ADD_0X30BYTES + MAX_MACROBLOCK_SIZE_IN_BYTE)) { | 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 | pCodingParam->uiMaxNalSize, (NAL_HEADER_ADD_0X30BYTES + MAX_MACROBLOCK_SIZE_IN_BYTE)); | 545 | pCodingParam->uiMaxNalSize, (NAL_HEADER_ADD_0X30BYTES + MAX_MACROBLOCK_SIZE_IN_BYTE)); |
| 545 | return ENC_RETURN_UNSUPPORTED_PARA; | 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 | pCtx->iPosBsBuffer += iNalSize; | 3141 | pCtx->iPosBsBuffer += iNalSize; |
| 3141 | return ENC_RETURN_SUCCESS; | 3142 | return ENC_RETURN_SUCCESS; |
| 3142 | } | 3143 | } |
| 3144 | |||
| 3143 | int32_t WelsWriteOnePPS (sWelsEncCtx* pCtx, const int32_t kiPpsIdx, int32_t& iNalSize) { | 3145 | int32_t WelsWriteOnePPS (sWelsEncCtx* pCtx, const int32_t kiPpsIdx, int32_t& iNalSize) { |
| 3144 | //TODO | 3146 | //TODO |
| 3145 | int32_t iNal = pCtx->pOut->iNalIndex; | 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 | return ENC_RETURN_SUCCESS; | 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 | * \brief write all parameter sets introduced in SVC extension | 3188 | * \brief write all parameter sets introduced in SVC extension |
| 3164 | * \return writing results, success or error | 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 | /* write all PPS */ | 3272 | /* write all PPS */ |
| 3248 | iIdx = 0; | ||
| 3249 | if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) { | 3273 | if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) { |
| 3250 | assert (pCtx->iPpsNum <= MAX_DQ_LAYER_NUM); | 3274 | UpdatePpsList (pCtx); |
| 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; | ||
| 3269 | } | 3275 | } |
| 3270 | 3276 | ||
| 3277 | iIdx = 0; | ||
| 3271 | while (iIdx < pCtx->iPpsNum) { | 3278 | while (iIdx < pCtx->iPpsNum) { |
| 3272 | if ((INCREASING_ID & pCtx->pSvcParam->eSpsPpsIdStrategy)) { | 3279 | if ((INCREASING_ID & pCtx->pSvcParam->eSpsPpsIdStrategy)) { |
| 3273 | //para_set_type = 2: PPS, use MAX_PPS_COUNT | 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 | iCountNal = 1; | 3486 | iCountNal = 1; |
| 3480 | //finish writing one NAL | 3487 | //finish writing one NAL |
| 3481 | 3488 | ||
| 3482 | |||
| 3483 | pLayerBsInfo->uiSpatialId = iIdx; | 3489 | pLayerBsInfo->uiSpatialId = iIdx; |
| 3484 | pLayerBsInfo->uiTemporalId = 0; | 3490 | pLayerBsInfo->uiTemporalId = 0; |
| 3485 | pLayerBsInfo->uiQualityId = 0; | 3491 | pLayerBsInfo->uiQualityId = 0; |
| @@ -3511,7 +3517,6 @@ int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t kiSpatialNum, · 25 unmodified lines | |||
| 3511 | iCountNal = 1; | 3517 | iCountNal = 1; |
| 3512 | //finish writing one NAL | 3518 | //finish writing one NAL |
| 3513 | 3519 | ||
| 3514 | |||
| 3515 | pLayerBsInfo->uiSpatialId = iIdx; | 3520 | pLayerBsInfo->uiSpatialId = iIdx; |
| 3516 | pLayerBsInfo->uiTemporalId = 0; | 3521 | pLayerBsInfo->uiTemporalId = 0; |
| 3517 | pLayerBsInfo->uiQualityId = 0; | 3522 | pLayerBsInfo->uiQualityId = 0; |
| @@ -3538,6 +3543,87 @@ int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t kiSpatialNum, · 20 unmodified lines | |||
| 3538 | return iReturn; | 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 | * \brief core svc encoding process | 3629 | * \brief core svc encoding process |
| @@ -3637,9 +3723,13 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour · 93 unmodified lines | |||
| 3637 | ++ pCtx->uiIdrPicId; | 3723 | ++ pCtx->uiIdrPicId; |
| 3638 | // write parameter sets bitstream or SEI/SSEI (if any) here | 3724 | // write parameter sets bitstream or SEI/SSEI (if any) here |
| 3639 | // TODO: use function pointer instead | 3725 | // TODO: use function pointer instead |
| 3640 | pCtx->iEncoderError = ((!pSvcParam->bSimulcastAVC) | 3726 | if (! (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy)) { |
| 3641 | ? (WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize)) | 3727 | pCtx->iEncoderError = ((!pSvcParam->bSimulcastAVC) |
| 3642 | : (WriteSavcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize))); | 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 | WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS) | 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 | pFbi->eFrameType = eFrameType; | 4308 | pFbi->eFrameType = eFrameType; |
| 4219 | pFbi->iFrameSizeInBytes = iFrameSize; | 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 | return ENC_RETURN_SUCCESS; | 4337 | return ENC_RETURN_SUCCESS; |
| 4221 | } | 4338 | } |
| 4222 | 4339 | ||