[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 | pCodingParam->eSpsPpsIdStrategy = CONSTANT_ID; | 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 | for (i = 0; i < pCodingParam->iSpatialLayerNum; ++ i) { | 349 | for (i = 0; i < pCodingParam->iSpatialLayerNum; ++ i) { |
| 343 | SSpatialLayerConfig* pSpatialLayer = &pCodingParam->sSpatialLayers[i]; | 350 | SSpatialLayerConfig* pSpatialLayer = &pCodingParam->sSpatialLayers[i]; |
| 344 | const int32_t kiPicWidth = pSpatialLayer->iVideoWidth; | 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 | // for dynamically malloc for parameter sets memory instead of maximal items for standard to reduce size, 3/18/2010 | 1190 | // for dynamically malloc for parameter sets memory instead of maximal items for standard to reduce size, 3/18/2010 |
| 1184 | // SPS | 1191 | // SPS |
| 1185 | if (! (SPS_LISTING & pParam->eSpsPpsIdStrategy)) { | 1192 | if (!pParam->bSimulcastAVC) { |
| 1186 | (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (sizeof (SWelsSPS), "pSpsArray"); | 1193 | if (! (SPS_LISTING & pParam->eSpsPpsIdStrategy)) { |
| 1187 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx)) | 1194 | (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (sizeof (SWelsSPS), "pSpsArray"); |
| 1188 | if (iDlayerCount > 1) { | 1195 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx)) |
| 1189 | (*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc ((iDlayerCount - 1) * sizeof (SSubsetSps), "pSubsetArray"); | 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 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx)) | 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 | } else { | 1217 | } else { |
| 1193 | // pParam->eSpsPpsIdStrategy == SPS_LISTING_AND_PPS_INCREASING | 1218 | //bSimulcastAVC |
| 1194 | // new memory | 1219 | (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (iDlayerCount * sizeof (SWelsSPS), "pSpsArray"); |
| 1195 | (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SWelsSPS), "pSpsArray"); | ||
| 1196 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx)) | 1220 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx)) |
| 1197 | 1221 | (*ppCtx)->pSubsetArray = NULL; | |
| 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 | } | ||
| 1208 | } | 1222 | } |
| 1209 | // PPS | 1223 | // PPS |
| 1210 | if (! (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy)) { | 1224 | if (! (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy)) { |
| @@ -1234,7 +1248,7 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p · 23 unmodified lines | |||
| 1234 | iDlayerIndex = 0; | 1248 | iDlayerIndex = 0; |
| 1235 | while (iDlayerIndex < iDlayerCount) { | 1249 | while (iDlayerIndex < iDlayerCount) { |
| 1236 | SDqIdc* pDqIdc = & (*ppCtx)->pDqIdcMap[iDlayerIndex]; | 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 | SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex]; | 1252 | SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex]; |
| 1239 | 1253 | ||
| 1240 | pDqIdc->uiSpatialId = iDlayerIndex; | 1254 | pDqIdc->uiSpatialId = iDlayerIndex; |
| @@ -1334,7 +1348,7 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p · 93 unmodified lines | |||
| 1334 | 1348 | ||
| 1335 | (*ppCtx)->sPSOVector.bPpsIdMappingIntoSubsetsps[iPpsId] = bUseSubsetSps; | 1349 | (*ppCtx)->sPSOVector.bPpsIdMappingIntoSubsetsps[iPpsId] = bUseSubsetSps; |
| 1336 | 1350 | ||
| 1337 | if (bUseSubsetSps) | 1351 | if ((pParam->bSimulcastAVC) || (bUseSubsetSps)) |
| 1338 | ++ iSpsId; | 1352 | ++ iSpsId; |
| 1339 | ++ iPpsId; | 1353 | ++ iPpsId; |
| 1340 | if (bUseSubsetSps) { | 1354 | if (bUseSubsetSps) { |
| @@ -2786,7 +2800,7 @@ void WelsInitCurrentLayer (sWelsEncCtx* pCtx, · 1445 unmodified lines | |||
| 2786 | SSlice* pBaseSlice = &pCurDq->sLayerInfo.pSliceInLayer[0]; | 2800 | SSlice* pBaseSlice = &pCurDq->sLayerInfo.pSliceInLayer[0]; |
| 2787 | SSlice* pSlice = NULL; | 2801 | SSlice* pSlice = NULL; |
| 2788 | const uint8_t kiCurDid = pCtx->uiDependencyId; | 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 | SSpatialLayerConfig* fDlp = &pParam->sSpatialLayers[kiCurDid]; | 2804 | SSpatialLayerConfig* fDlp = &pParam->sSpatialLayers[kiCurDid]; |
| 2791 | SNalUnitHeaderExt* pNalHdExt = &pCurDq->sLayerInfo.sNalHeaderExt; | 2805 | SNalUnitHeaderExt* pNalHdExt = &pCurDq->sLayerInfo.sNalHeaderExt; |
| 2792 | SNalUnitHeader* pNalHd = &pNalHdExt->sNalHeader; | 2806 | SNalUnitHeader* pNalHd = &pNalHdExt->sNalHeader; |
| @@ -3105,6 +3119,42 @@ void ParasetIdAdditionIdAdjust (SParaSetOffsetVariable* sParaSetOffsetVariable, · 312 unmodified lines | |||
| 3105 | sParaSetOffsetVariable->uiNextParaSetIdToUseInBs = uiNextIdInBs; | 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 | * \brief write all parameter sets introduced in SVC extension | 3159 | * \brief write all parameter sets introduced in SVC extension |
| 3110 | * \return writing results, success or error | 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 | /* write all SPS */ | 3175 | /* write all SPS */ |
| 3126 | iIdx = 0; | 3176 | iIdx = 0; |
| 3127 | while (iIdx < pCtx->iSpsNum) { | 3177 | while (iIdx < pCtx->iSpsNum) { |
| 3128 | iNal = pCtx->pOut->iNalIndex; | 3178 | // TODO (Sijia) wrap different operation of eSpsPpsIdStrategy to classes to hide the details |
| 3129 | |||
| 3130 | if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) { | 3179 | if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) { |
| 3131 | #if _DEBUG | 3180 | #if _DEBUG |
| 3132 | pCtx->sPSOVector.eSpsPpsIdStrategy = INCREASING_ID; | 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 | /* generate sequence parameters set */ | 3192 | /* generate sequence parameters set */ |
| 3144 | iId = (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy) ? iIdx : 0; | 3193 | iId = (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy) ? iIdx : 0; |
| 3145 | 3194 | ||
| 3146 | WelsLoadNal (pCtx->pOut, NAL_UNIT_SPS, NRI_PRI_HIGHEST); | 3195 | WelsWriteOneSPS (pCtx, iId, iNalLength); |
| 3147 | WelsWriteSpsNal (&pCtx->pSpsArray[iId], &pCtx->pOut->sBsWrite, | ||
| 3148 | & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS].iParaSetIdDelta[0])); | ||
| 3149 | WelsUnloadNal (pCtx->pOut); | ||
| 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 | pNalLen[iCountNal] = iNalLength; | 3197 | pNalLen[iCountNal] = iNalLength; |
| 3157 | |||
| 3158 | pCtx->iPosBsBuffer += iNalLength; | ||
| 3159 | iSize += iNalLength; | 3198 | iSize += iNalLength; |
| 3160 | 3199 | ||
| 3161 | ++ iIdx; | 3200 | ++ iIdx; |
| @@ -3232,20 +3271,9 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 70 unmodified lines | |||
| 3232 | MAX_PPS_COUNT); | 3271 | MAX_PPS_COUNT); |
| 3233 | } | 3272 | } |
| 3234 | 3273 | ||
| 3235 | iNal = pCtx->pOut->iNalIndex; | 3274 | WelsWriteOnePPS (pCtx, iIdx, iNalLength); |
| 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); | ||
| 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 | pNalLen[iCountNal] = iNalLength; | 3276 | pNalLen[iCountNal] = iNalLength; |
| 3248 | pCtx->iPosBsBuffer += iNalLength; | ||
| 3249 | iSize += iNalLength; | 3277 | iSize += iNalLength; |
| 3250 | 3278 | ||
| 3251 | ++ iIdx; | 3279 | ++ iIdx; |
| @@ -3405,6 +3433,107 @@ int32_t GetSubSequenceId (sWelsEncCtx* pCtx, EVideoFrameType eFrameType) { · 153 unmodified lines | |||
| 3405 | return iSubSeqId; | 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 | * \brief core svc encoding process | 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 | if (eFrameType == videoFrameTypeIDR) { | 3631 | if (eFrameType == videoFrameTypeIDR) { |
| 3503 | ++ pCtx->uiIdrPicId; | 3632 | ++ pCtx->uiIdrPicId; |
| 3504 | //if ( pSvcParam->bEnableSSEI ) | 3633 | // write parameter sets bitstream or SEI/SSEI (if any) here |
| 3505 | 3634 | // TODO: use function pointer instead | |
| 3506 | // write parameter sets bitstream here | 3635 | pCtx->iEncoderError = ((!pSvcParam->bSimulcastAVC) |
| 3507 | int32_t iNonVclSize = 0; | 3636 | ? (WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize)) |
| 3508 | pCtx->iEncoderError = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal, &iNonVclSize); | 3637 | : (WriteSavcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize))); |
| 3509 | WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS) | 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 | pCtx->pCurDqLayer = pCtx->ppDqLayerList[pSpatialIndexMap->iDid]; | 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 | iNalIdxInLayer = 0; | 3692 | iNalIdxInLayer = 0; |
| 3577 | bAvcBased = (iCurDid == BASE_DEPENDENCY_ID); | 3693 | bAvcBased = ((pSvcParam->bSimulcastAVC) || (iCurDid == BASE_DEPENDENCY_ID)); |
| 3578 | pCtx->bNeedPrefixNalFlag = (bAvcBased && | 3694 | pCtx->bNeedPrefixNalFlag = (bAvcBased && |
| 3579 | (pSvcParam->bPrefixNalAddingCtrl || | 3695 | (pSvcParam->bPrefixNalAddingCtrl || |
| 3580 | (pSvcParam->iSpatialLayerNum > 1))); | 3696 | (pSvcParam->iSpatialLayerNum > 1))); |
| @@ -4074,6 +4190,13 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour · 493 unmodified lines | |||
| 4074 | 4190 | ||
| 4075 | #endif//ENABLE_FRAME_DUMP | 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 | ++ pCtx->iCodingIndex; | 4200 | ++ pCtx->iCodingIndex; |
| 4078 | pCtx->eLastNalPriority = eNalRefIdc; | 4201 | pCtx->eLastNalPriority = eNalRefIdc; |
| 4079 | pFbi->iLayerNum = iLayerNum; | 4202 | pFbi->iLayerNum = iLayerNum; |