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