[Encoder] Implementation of bSimulcastAVC and UT
Showing the changes to codec/encoder/core/src/encoder_ext.cpp (1 of 3 files). Show all
Unified · Split
| @@ -339,6 +339,13 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa · 338 unmodified lines | ||
| 339 | 339 | pCodingParam->eSpsPpsIdStrategy = CONSTANT_ID; |
| 340 | 340 | } |
| 341 | 341 | |
| 342 | + if (pCodingParam->bSimulcastAVC && (SPS_LISTING & pCodingParam->eSpsPpsIdStrategy)) { | |
| 343 | + WelsLog (pLogCtx, WELS_LOG_INFO, | |
| 344 | + "ParamValidationExt(), eSpsPpsIdStrategy(%d) under bSimulcastAVC(%d) not supported yet, adjusted to INCREASING_ID", | |
| 345 | + pCodingParam->eSpsPpsIdStrategy, pCodingParam->bSimulcastAVC); | |
| 346 | + pCodingParam->eSpsPpsIdStrategy = INCREASING_ID; | |
| 347 | + } | |
| 348 | + | |
| 342 | 349 | for (i = 0; i < pCodingParam->iSpatialLayerNum; ++ i) { |
| 343 | 350 | SSpatialLayerConfig* pSpatialLayer = &pCodingParam->sSpatialLayers[i]; |
| 344 | 351 | const int32_t kiPicWidth = pSpatialLayer->iVideoWidth; |
| @@ -1182,29 +1189,36 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p · 837 unmodified lines | ||
| 1182 | 1189 | |
| 1183 | 1190 | // for dynamically malloc for parameter sets memory instead of maximal items for standard to reduce size, 3/18/2010 |
| 1184 | 1191 | // SPS |
| 1185 | − if (! (SPS_LISTING & pParam->eSpsPpsIdStrategy)) { | |
| 1186 | − (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (sizeof (SWelsSPS), "pSpsArray"); | |
| 1187 | − WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx)) | |
| 1188 | − if (iDlayerCount > 1) { | |
| 1189 | − (*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc ((iDlayerCount - 1) * sizeof (SSubsetSps), "pSubsetArray"); | |
| 1192 | + if (!pParam->bSimulcastAVC) { | |
| 1193 | + if (! (SPS_LISTING & pParam->eSpsPpsIdStrategy)) { | |
| 1194 | + (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (sizeof (SWelsSPS), "pSpsArray"); | |
| 1195 | + WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx)) | |
| 1196 | + if (iDlayerCount > 1) { | |
| 1197 | + (*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc ((iDlayerCount - 1) * sizeof (SSubsetSps), "pSubsetArray"); | |
| 1198 | + WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx)) | |
| 1199 | + } | |
| 1200 | + } else { | |
| 1201 | + // pParam->eSpsPpsIdStrategy == SPS_LISTING_AND_PPS_INCREASING | |
| 1202 | + // new memory | |
| 1203 | + (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SWelsSPS), "pSpsArray"); | |
| 1204 | + WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx)) | |
| 1205 | + | |
| 1206 | + (*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SSubsetSps), "pSubsetArray"); | |
| 1190 | 1207 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx)) |
| 1208 | + | |
| 1209 | + // copy from existing if the pointer exists | |
| 1210 | + if (NULL != pExistingParasetList) { | |
| 1211 | + (*ppCtx)->sPSOVector.uiInUseSpsNum = pExistingParasetList->uiInUseSpsNum; | |
| 1212 | + (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = pExistingParasetList->uiInUseSubsetSpsNum; | |
| 1213 | + memcpy ((*ppCtx)->pSpsArray, pExistingParasetList->sSps, MAX_SPS_COUNT * sizeof (SWelsSPS)); | |
| 1214 | + memcpy ((*ppCtx)->pSubsetArray, pExistingParasetList->sSubsetSps, MAX_SPS_COUNT * sizeof (SSubsetSps)); | |
| 1215 | + } | |
| 1191 | 1216 | } |
| 1192 | 1217 | } else { |
| 1193 | − // pParam->eSpsPpsIdStrategy == SPS_LISTING_AND_PPS_INCREASING | |
| 1194 | − // new memory | |
| 1195 | − (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SWelsSPS), "pSpsArray"); | |
| 1218 | + //bSimulcastAVC | |
| 1219 | + (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (iDlayerCount * sizeof (SWelsSPS), "pSpsArray"); | |
| 1196 | 1220 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx)) |
| 1197 | − | |
| 1198 | − (*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SSubsetSps), "pSubsetArray"); | |
| 1199 | − WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx)) | |
| 1200 | − | |
| 1201 | − // copy from existing if the pointer exists | |
| 1202 | − if (NULL != pExistingParasetList) { | |
| 1203 | − (*ppCtx)->sPSOVector.uiInUseSpsNum = pExistingParasetList->uiInUseSpsNum; | |
| 1204 | − (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = pExistingParasetList->uiInUseSubsetSpsNum; | |
| 1205 | − memcpy ((*ppCtx)->pSpsArray, pExistingParasetList->sSps, MAX_SPS_COUNT * sizeof (SWelsSPS)); | |
| 1206 | − memcpy ((*ppCtx)->pSubsetArray, pExistingParasetList->sSubsetSps, MAX_SPS_COUNT * sizeof (SSubsetSps)); | |
| 1207 | − } | |
| 1221 | + (*ppCtx)->pSubsetArray = NULL; | |
| 1208 | 1222 | } |
| 1209 | 1223 | // PPS |
| 1210 | 1224 | if (! (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy)) { |
| @@ -1234,7 +1248,7 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p · 23 unmodified lines | ||
| 1234 | 1248 | iDlayerIndex = 0; |
| 1235 | 1249 | while (iDlayerIndex < iDlayerCount) { |
| 1236 | 1250 | SDqIdc* pDqIdc = & (*ppCtx)->pDqIdcMap[iDlayerIndex]; |
| 1237 | − const bool bUseSubsetSps = (iDlayerIndex > BASE_DEPENDENCY_ID); | |
| 1251 | + const bool bUseSubsetSps = (!pParam->bSimulcastAVC) && (iDlayerIndex > BASE_DEPENDENCY_ID); | |
| 1238 | 1252 | SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex]; |
| 1239 | 1253 | |
| 1240 | 1254 | pDqIdc->uiSpatialId = iDlayerIndex; |
| @@ -1334,7 +1348,7 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p · 93 unmodified lines | ||
| 1334 | 1348 | |
| 1335 | 1349 | (*ppCtx)->sPSOVector.bPpsIdMappingIntoSubsetsps[iPpsId] = bUseSubsetSps; |
| 1336 | 1350 | |
| 1337 | − if (bUseSubsetSps) | |
| 1351 | + if ((pParam->bSimulcastAVC) || (bUseSubsetSps)) | |
| 1338 | 1352 | ++ iSpsId; |
| 1339 | 1353 | ++ iPpsId; |
| 1340 | 1354 | if (bUseSubsetSps) { |
| @@ -2786,7 +2800,7 @@ void WelsInitCurrentLayer (sWelsEncCtx* pCtx, · 1445 unmodified lines | ||
| 2786 | 2800 | SSlice* pBaseSlice = &pCurDq->sLayerInfo.pSliceInLayer[0]; |
| 2787 | 2801 | SSlice* pSlice = NULL; |
| 2788 | 2802 | const uint8_t kiCurDid = pCtx->uiDependencyId; |
| 2789 | − const bool kbUseSubsetSpsFlag = (kiCurDid > BASE_DEPENDENCY_ID); | |
| 2803 | + const bool kbUseSubsetSpsFlag = (!pParam->bSimulcastAVC) && (kiCurDid > BASE_DEPENDENCY_ID); | |
| 2790 | 2804 | SSpatialLayerConfig* fDlp = &pParam->sSpatialLayers[kiCurDid]; |
| 2791 | 2805 | SNalUnitHeaderExt* pNalHdExt = &pCurDq->sLayerInfo.sNalHeaderExt; |
| 2792 | 2806 | SNalUnitHeader* pNalHd = &pNalHdExt->sNalHeader; |
| @@ -3105,6 +3119,42 @@ void ParasetIdAdditionIdAdjust (SParaSetOffsetVariable* sParaSetOffsetVariable, · 312 unmodified lines | ||
| 3105 | 3119 | sParaSetOffsetVariable->uiNextParaSetIdToUseInBs = uiNextIdInBs; |
| 3106 | 3120 | } |
| 3107 | 3121 | |
| 3122 | +int32_t WelsWriteOneSPS (sWelsEncCtx* pCtx, const int32_t kiSpsIdx, int32_t& iNalSize) { | |
| 3123 | + int iNal = pCtx->pOut->iNalIndex; | |
| 3124 | + WelsLoadNal (pCtx->pOut, NAL_UNIT_SPS, NRI_PRI_HIGHEST); | |
| 3125 | + | |
| 3126 | + WelsWriteSpsNal (&pCtx->pSpsArray[kiSpsIdx], &pCtx->pOut->sBsWrite, | |
| 3127 | + & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS].iParaSetIdDelta[0])); | |
| 3128 | + WelsUnloadNal (pCtx->pOut); | |
| 3129 | + | |
| 3130 | + int32_t iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, | |
| 3131 | + pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length | |
| 3132 | + pCtx->pFrameBs + pCtx->iPosBsBuffer, | |
| 3133 | + &iNalSize); | |
| 3134 | + WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS) | |
| 3135 | + | |
| 3136 | + pCtx->iPosBsBuffer += iNalSize; | |
| 3137 | + return ENC_RETURN_SUCCESS; | |
| 3138 | +} | |
| 3139 | +int32_t WelsWriteOnePPS (sWelsEncCtx* pCtx, const int32_t kiPpsIdx, int32_t& iNalSize) { | |
| 3140 | + //TODO | |
| 3141 | + int32_t iNal = pCtx->pOut->iNalIndex; | |
| 3142 | + /* generate picture parameter set */ | |
| 3143 | + WelsLoadNal (pCtx->pOut, NAL_UNIT_PPS, NRI_PRI_HIGHEST); | |
| 3144 | + WelsWritePpsSyntax (&pCtx->pPPSArray[kiPpsIdx], &pCtx->pOut->sBsWrite, | |
| 3145 | + ((SPS_PPS_LISTING != pCtx->pSvcParam->eSpsPpsIdStrategy)) ? (& (pCtx->sPSOVector)) : NULL); | |
| 3146 | + WelsUnloadNal (pCtx->pOut); | |
| 3147 | + | |
| 3148 | + int32_t iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, | |
| 3149 | + pCtx->iFrameBsSize - pCtx->iPosBsBuffer, | |
| 3150 | + pCtx->pFrameBs + pCtx->iPosBsBuffer, | |
| 3151 | + &iNalSize); | |
| 3152 | + WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS) | |
| 3153 | + | |
| 3154 | + pCtx->iPosBsBuffer += iNalSize; | |
| 3155 | + return ENC_RETURN_SUCCESS; | |
| 3156 | +} | |
| 3157 | + | |
| 3108 | 3158 | /*! |
| 3109 | 3159 | * \brief write all parameter sets introduced in SVC extension |
| 3110 | 3160 | * \return writing results, success or error |
| @@ -3125,8 +3175,7 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 14 unmodified lines | ||
| 3125 | 3175 | /* write all SPS */ |
| 3126 | 3176 | iIdx = 0; |
| 3127 | 3177 | while (iIdx < pCtx->iSpsNum) { |
| 3128 | − iNal = pCtx->pOut->iNalIndex; | |
| 3129 | − | |
| 3178 | + // TODO (Sijia) wrap different operation of eSpsPpsIdStrategy to classes to hide the details | |
| 3130 | 3179 | if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) { |
| 3131 | 3180 | #if _DEBUG |
| 3132 | 3181 | pCtx->sPSOVector.eSpsPpsIdStrategy = INCREASING_ID; |
| @@ -3143,19 +3192,9 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 10 unmodified lines | ||
| 3143 | 3192 | /* generate sequence parameters set */ |
| 3144 | 3193 | iId = (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy) ? iIdx : 0; |
| 3145 | 3194 | |
| 3146 | − WelsLoadNal (pCtx->pOut, NAL_UNIT_SPS, NRI_PRI_HIGHEST); | |
| 3147 | − WelsWriteSpsNal (&pCtx->pSpsArray[iId], &pCtx->pOut->sBsWrite, | |
| 3148 | − & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS].iParaSetIdDelta[0])); | |
| 3149 | − WelsUnloadNal (pCtx->pOut); | |
| 3195 | + WelsWriteOneSPS (pCtx, iId, iNalLength); | |
| 3150 | 3196 | |
| 3151 | − iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, | |
| 3152 | − pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length | |
| 3153 | − pCtx->pFrameBs + pCtx->iPosBsBuffer, | |
| 3154 | − &iNalLength); | |
| 3155 | − WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS) | |
| 3156 | 3197 | pNalLen[iCountNal] = iNalLength; |
| 3157 | − | |
| 3158 | − pCtx->iPosBsBuffer += iNalLength; | |
| 3159 | 3198 | iSize += iNalLength; |
| 3160 | 3199 | |
| 3161 | 3200 | ++ iIdx; |
| @@ -3232,20 +3271,9 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 70 unmodified lines | ||
| 3232 | 3271 | MAX_PPS_COUNT); |
| 3233 | 3272 | } |
| 3234 | 3273 | |
| 3235 | − iNal = pCtx->pOut->iNalIndex; | |
| 3236 | − /* generate picture parameter set */ | |
| 3237 | − WelsLoadNal (pCtx->pOut, NAL_UNIT_PPS, NRI_PRI_HIGHEST); | |
| 3238 | − WelsWritePpsSyntax (&pCtx->pPPSArray[iIdx], &pCtx->pOut->sBsWrite, | |
| 3239 | − ((SPS_PPS_LISTING != pCtx->pSvcParam->eSpsPpsIdStrategy)) ? (& (pCtx->sPSOVector)) : NULL); | |
| 3240 | − WelsUnloadNal (pCtx->pOut); | |
| 3274 | + WelsWriteOnePPS (pCtx, iIdx, iNalLength); | |
| 3241 | 3275 | |
| 3242 | − iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, | |
| 3243 | − pCtx->iFrameBsSize - pCtx->iPosBsBuffer, | |
| 3244 | − pCtx->pFrameBs + pCtx->iPosBsBuffer, | |
| 3245 | − &iNalLength); | |
| 3246 | − WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS) | |
| 3247 | 3276 | pNalLen[iCountNal] = iNalLength; |
| 3248 | − pCtx->iPosBsBuffer += iNalLength; | |
| 3249 | 3277 | iSize += iNalLength; |
| 3250 | 3278 | |
| 3251 | 3279 | ++ iIdx; |
| @@ -3405,6 +3433,107 @@ int32_t GetSubSequenceId (sWelsEncCtx* pCtx, EVideoFrameType eFrameType) { · 153 unmodified lines | ||
| 3405 | 3433 | return iSubSeqId; |
| 3406 | 3434 | } |
| 3407 | 3435 | |
| 3436 | +int32_t WriteSsvcParaset (sWelsEncCtx* pCtx, const int32_t kiSpatialNum, | |
| 3437 | + SLayerBSInfo*& pLayerBsInfo, int32_t& iLayerNum, int32_t& iFrameSize) { | |
| 3438 | + int32_t iNonVclSize = 0, iCountNal = 0, iReturn; | |
| 3439 | + iReturn = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal, &iNonVclSize); | |
| 3440 | + WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS) | |
| 3441 | + | |
| 3442 | + pLayerBsInfo->uiSpatialId = 0; | |
| 3443 | + pLayerBsInfo->uiTemporalId = 0; | |
| 3444 | + pLayerBsInfo->uiQualityId = 0; | |
| 3445 | + pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER; | |
| 3446 | + pLayerBsInfo->iNalCount = iCountNal; | |
| 3447 | + | |
| 3448 | + //point to next pLayerBsInfo | |
| 3449 | + ++ pLayerBsInfo; | |
| 3450 | + pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer; | |
| 3451 | + pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal; | |
| 3452 | + //update for external countings | |
| 3453 | + ++ iLayerNum; | |
| 3454 | + iFrameSize += iNonVclSize; | |
| 3455 | + return iReturn; | |
| 3456 | +} | |
| 3457 | + | |
| 3458 | +int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t kiSpatialNum, | |
| 3459 | + SLayerBSInfo*& pLayerBsInfo, int32_t& iLayerNum, int32_t& iFrameSize) { | |
| 3460 | + int32_t iNonVclSize = 0, iCountNal = 0, iReturn; | |
| 3461 | + | |
| 3462 | + // write SPS | |
| 3463 | + iNonVclSize = 0; | |
| 3464 | + assert (kiSpatialNum == pCtx->iSpsNum); | |
| 3465 | + | |
| 3466 | + for (int32_t iIdx = 0; iIdx < pCtx->iSpsNum; iIdx++) { | |
| 3467 | + //writing one NAL | |
| 3468 | + int32_t iNalSize = 0; | |
| 3469 | + iReturn = WelsWriteOneSPS (pCtx, iIdx, iNalSize); | |
| 3470 | + WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS) | |
| 3471 | + | |
| 3472 | + pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize; | |
| 3473 | + iNonVclSize += iNalSize; | |
| 3474 | + iCountNal = 1; | |
| 3475 | + //finish writing one NAL | |
| 3476 | + | |
| 3477 | + | |
| 3478 | + pLayerBsInfo->uiSpatialId = iIdx; | |
| 3479 | + pLayerBsInfo->uiTemporalId = 0; | |
| 3480 | + pLayerBsInfo->uiQualityId = 0; | |
| 3481 | + pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER; | |
| 3482 | + pLayerBsInfo->iNalCount = iCountNal; | |
| 3483 | + | |
| 3484 | + //point to next pLayerBsInfo | |
| 3485 | + ++ pLayerBsInfo; | |
| 3486 | + pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer; | |
| 3487 | + pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal; | |
| 3488 | + //update for external countings | |
| 3489 | + iCountNal = 0; | |
| 3490 | + ++ iLayerNum; | |
| 3491 | + | |
| 3492 | + } | |
| 3493 | + | |
| 3494 | + // write PPS | |
| 3495 | + | |
| 3496 | + //TODO: under new strategy, will PPS be correctly updated? | |
| 3497 | + | |
| 3498 | + for (int32_t iIdx = 0; iIdx < pCtx->iPpsNum; iIdx++) { | |
| 3499 | + //writing one NAL | |
| 3500 | + int32_t iNalSize = 0; | |
| 3501 | + iReturn = WelsWriteOnePPS (pCtx, iIdx, iNalSize); | |
| 3502 | + WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS) | |
| 3503 | + | |
| 3504 | + pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize; | |
| 3505 | + iNonVclSize += iNalSize; | |
| 3506 | + iCountNal = 1; | |
| 3507 | + //finish writing one NAL | |
| 3508 | + | |
| 3509 | + | |
| 3510 | + pLayerBsInfo->uiSpatialId = iIdx; | |
| 3511 | + pLayerBsInfo->uiTemporalId = 0; | |
| 3512 | + pLayerBsInfo->uiQualityId = 0; | |
| 3513 | + pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER; | |
| 3514 | + pLayerBsInfo->iNalCount = iCountNal; | |
| 3515 | + | |
| 3516 | + //point to next pLayerBsInfo | |
| 3517 | + ++ pLayerBsInfo; | |
| 3518 | + pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer; | |
| 3519 | + pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal; | |
| 3520 | + //update for external countings | |
| 3521 | + iCountNal = 0; | |
| 3522 | + ++ iLayerNum; | |
| 3523 | + } | |
| 3524 | + | |
| 3525 | + // to check number of layers / nals / slices dependencies | |
| 3526 | + if (iLayerNum > MAX_LAYER_NUM_OF_FRAME) { | |
| 3527 | + WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR, "WriteSavcParaset(), iLayerNum(%d) > MAX_LAYER_NUM_OF_FRAME(%d)!", | |
| 3528 | + iLayerNum, MAX_LAYER_NUM_OF_FRAME); | |
| 3529 | + return 1; | |
| 3530 | + } | |
| 3531 | + | |
| 3532 | + iFrameSize += iNonVclSize; | |
| 3533 | + return iReturn; | |
| 3534 | +} | |
| 3535 | + | |
| 3536 | + | |
| 3408 | 3537 | /*! |
| 3409 | 3538 | * \brief core svc encoding process |
| 3410 | 3539 | * |
| @@ -3501,25 +3630,12 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour · 90 unmodified lines | ||
| 3501 | 3630 | |
| 3502 | 3631 | if (eFrameType == videoFrameTypeIDR) { |
| 3503 | 3632 | ++ pCtx->uiIdrPicId; |
| 3504 | − //if ( pSvcParam->bEnableSSEI ) | |
| 3505 | − | |
| 3506 | − // write parameter sets bitstream here | |
| 3507 | − int32_t iNonVclSize = 0; | |
| 3508 | − pCtx->iEncoderError = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal, &iNonVclSize); | |
| 3633 | + // write parameter sets bitstream or SEI/SSEI (if any) here | |
| 3634 | + // TODO: use function pointer instead | |
| 3635 | + pCtx->iEncoderError = ((!pSvcParam->bSimulcastAVC) | |
| 3636 | + ? (WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize)) | |
| 3637 | + : (WriteSavcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize))); | |
| 3509 | 3638 | WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS) |
| 3510 | − | |
| 3511 | − pLayerBsInfo->uiSpatialId = 0; | |
| 3512 | − pLayerBsInfo->uiTemporalId = 0; | |
| 3513 | − pLayerBsInfo->uiQualityId = 0; | |
| 3514 | − pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER; | |
| 3515 | − pLayerBsInfo->iNalCount = iCountNal; | |
| 3516 | − | |
| 3517 | − ++ pLayerBsInfo; | |
| 3518 | − pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer; | |
| 3519 | − pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal; | |
| 3520 | − ++ iLayerNum; | |
| 3521 | − | |
| 3522 | − iFrameSize += iNonVclSize; | |
| 3523 | 3639 | } |
| 3524 | 3640 | |
| 3525 | 3641 | pCtx->pCurDqLayer = pCtx->ppDqLayerList[pSpatialIndexMap->iDid]; |
| @@ -3574,7 +3690,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour · 48 unmodified lines | ||
| 3574 | 3690 | } |
| 3575 | 3691 | |
| 3576 | 3692 | iNalIdxInLayer = 0; |
| 3577 | − bAvcBased = (iCurDid == BASE_DEPENDENCY_ID); | |
| 3693 | + bAvcBased = ((pSvcParam->bSimulcastAVC) || (iCurDid == BASE_DEPENDENCY_ID)); | |
| 3578 | 3694 | pCtx->bNeedPrefixNalFlag = (bAvcBased && |
| 3579 | 3695 | (pSvcParam->bPrefixNalAddingCtrl || |
| 3580 | 3696 | (pSvcParam->iSpatialLayerNum > 1))); |
| @@ -4074,6 +4190,13 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour · 493 unmodified lines | ||
| 4074 | 4190 | |
| 4075 | 4191 | #endif//ENABLE_FRAME_DUMP |
| 4076 | 4192 | |
| 4193 | + // to check number of layers / nals / slices dependencies | |
| 4194 | + if (iLayerNum > MAX_LAYER_NUM_OF_FRAME) { | |
| 4195 | + WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR, "WelsEncoderEncodeExt(), iLayerNum(%d) > MAX_LAYER_NUM_OF_FRAME(%d)!", | |
| 4196 | + iLayerNum, MAX_LAYER_NUM_OF_FRAME); | |
| 4197 | + return 1; | |
| 4198 | + } | |
| 4199 | + | |
| 4077 | 4200 | ++ pCtx->iCodingIndex; |
| 4078 | 4201 | pCtx->eLastNalPriority = eNalRefIdc; |
| 4079 | 4202 | pFbi->iLayerNum = iLayerNum; |