Showing the changes to codec/encoder/core/src/encoder_ext.cpp (1 of 17 files). Show all
Unified · Split
| @@ -767,12 +767,15 @@ static inline int32_t AcquireLayersNals (sWelsEncCtx** ppCtx, SWelsSvcCodingPara · 766 unmodified lines | |||
| 767 | ++ iDIndex; | 767 | ++ iDIndex; |
| 768 | } while (iDIndex < iNumDependencyLayers); | 768 | } while (iDIndex < iNumDependencyLayers); |
| 769 | 769 | ||
| 770 | if (NULL == (*ppCtx)->pFuncList || NULL == (*ppCtx)->pFuncList->pParametersetStrategy) { | ||
| 771 | WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR, | ||
| 772 | "AcquireLayersNals(), pFuncList and pParametersetStrategy needed to be initialized first!"); | ||
| 773 | return 1; | ||
| 774 | } | ||
| 770 | // count parasets | 775 | // count parasets |
| 771 | iCountNumNals += 1 + iNumDependencyLayers + (iCountNumLayers << 1) + | 776 | iCountNumNals += 1 + iNumDependencyLayers + (iCountNumLayers << 1) + |
| 772 | iCountNumLayers // plus iCountNumLayers for reserved application | 777 | iCountNumLayers // plus iCountNumLayers for reserved application |
| 773 | + (*ppCtx)->GetNeededSpsNum() | 778 | + (*ppCtx)->pFuncList->pParametersetStrategy->GetAllNeededParasetNum(); |
| 774 | + (*ppCtx)->GetNeededSubsetSpsNum() | ||
| 775 | + (*ppCtx)->GetNeededPpsNum(); | ||
| 776 | 779 | ||
| 777 | // to check number of layers / nals / slices dependencies, 12/8/2010 | 780 | // to check number of layers / nals / slices dependencies, 12/8/2010 |
| 778 | if (iCountNumLayers > MAX_LAYER_NUM_OF_FRAME) { | 781 | if (iCountNumLayers > MAX_LAYER_NUM_OF_FRAME) { |
| @@ -956,152 +959,7 @@ void FreeRefList (SRefList*& pRefList, CMemoryAlign* pMa, const int iMaxNumRefF · 177 unmodified lines | |||
| 956 | pRefList = NULL; | 959 | pRefList = NULL; |
| 957 | } | 960 | } |
| 958 | 961 | ||
| 959 | static int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex, | ||
| 960 | const int32_t iDlayerCount, const int32_t kiSpsId, | ||
| 961 | SWelsSPS*& pSps, SSubsetSps*& pSubsetSps, bool bSVCBaselayer) { | ||
| 962 | int32_t iRet = 0; | ||
| 963 | |||
| 964 | if (!kbUseSubsetSps) { | ||
| 965 | pSps = & (pCtx->pSpsArray[kiSpsId]); | ||
| 966 | } else { | ||
| 967 | pSubsetSps = & (pCtx->pSubsetArray[kiSpsId]); | ||
| 968 | pSps = &pSubsetSps->pSps; | ||
| 969 | } | ||
| 970 | |||
| 971 | SWelsSvcCodingParam* pParam = pCtx->pSvcParam; | ||
| 972 | SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex]; | ||
| 973 | // Need port pSps/pPps initialization due to spatial scalability changed | ||
| 974 | if (!kbUseSubsetSps) { | ||
| 975 | iRet = WelsInitSps (pSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod, | ||
| 976 | pParam->iMaxNumRefFrame, | ||
| 977 | kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount, | ||
| 978 | bSVCBaselayer); | ||
| 979 | } else { | ||
| 980 | iRet = WelsInitSubsetSps (pSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod, | ||
| 981 | pParam->iMaxNumRefFrame, | ||
| 982 | kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount); | ||
| 983 | } | ||
| 984 | return iRet; | ||
| 985 | } | ||
| 986 | |||
| 987 | static bool CheckMatchedSps (SWelsSPS* const pSps1, SWelsSPS* const pSps2) { | ||
| 988 | |||
| 989 | if ((pSps1->iMbWidth != pSps2->iMbWidth) | ||
| 990 | || (pSps1->iMbHeight != pSps2->iMbHeight)) { | ||
| 991 | return false; | ||
| 992 | } | ||
| 993 | |||
| 994 | if ((pSps1->uiLog2MaxFrameNum != pSps2->uiLog2MaxFrameNum) | ||
| 995 | || (pSps1->iLog2MaxPocLsb != pSps2->iLog2MaxPocLsb)) { | ||
| 996 | return false; | ||
| 997 | } | ||
| 998 | |||
| 999 | if (pSps1->iNumRefFrames != pSps2->iNumRefFrames) { | ||
| 1000 | return false; | ||
| 1001 | } | ||
| 1002 | |||
| 1003 | if ((pSps1->bFrameCroppingFlag != pSps2->bFrameCroppingFlag) | ||
| 1004 | || (pSps1->sFrameCrop.iCropLeft != pSps2->sFrameCrop.iCropLeft) | ||
| 1005 | || (pSps1->sFrameCrop.iCropRight != pSps2->sFrameCrop.iCropRight) | ||
| 1006 | || (pSps1->sFrameCrop.iCropTop != pSps2->sFrameCrop.iCropTop) | ||
| 1007 | || (pSps1->sFrameCrop.iCropBottom != pSps2->sFrameCrop.iCropBottom) | ||
| 1008 | ) { | ||
| 1009 | return false; | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | if ((pSps1->uiProfileIdc != pSps2->uiProfileIdc) | ||
| 1013 | || (pSps1->bConstraintSet0Flag != pSps2->bConstraintSet0Flag) | ||
| 1014 | || (pSps1->bConstraintSet1Flag != pSps2->bConstraintSet1Flag) | ||
| 1015 | || (pSps1->bConstraintSet2Flag != pSps2->bConstraintSet2Flag) | ||
| 1016 | || (pSps1->bConstraintSet3Flag != pSps2->bConstraintSet3Flag) | ||
| 1017 | || (pSps1->iLevelIdc != pSps2->iLevelIdc)) { | ||
| 1018 | return false; | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | return true; | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | static bool CheckMatchedSubsetSps (SSubsetSps* const pSubsetSps1, SSubsetSps* const pSubsetSps2) { | ||
| 1025 | if (!CheckMatchedSps (&pSubsetSps1->pSps, &pSubsetSps2->pSps)) { | ||
| 1026 | return false; | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | if ((pSubsetSps1->sSpsSvcExt.iExtendedSpatialScalability != pSubsetSps2->sSpsSvcExt.iExtendedSpatialScalability) | ||
| 1030 | || (pSubsetSps1->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag != pSubsetSps2->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag) | ||
| 1031 | || (pSubsetSps1->sSpsSvcExt.bSeqTcoeffLevelPredFlag != pSubsetSps2->sSpsSvcExt.bSeqTcoeffLevelPredFlag) | ||
| 1032 | || (pSubsetSps1->sSpsSvcExt.bSliceHeaderRestrictionFlag != pSubsetSps2->sSpsSvcExt.bSliceHeaderRestrictionFlag)) { | ||
| 1033 | return false; | ||
| 1034 | } | ||
| 1035 | |||
| 1036 | return true; | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | int32_t FindExistingSps (SWelsSvcCodingParam* pParam, const bool kbUseSubsetSps, const int32_t iDlayerIndex, | ||
| 1040 | const int32_t iDlayerCount, const int32_t iSpsNumInUse, | ||
| 1041 | SWelsSPS* pSpsArray, | ||
| 1042 | SSubsetSps* pSubsetArray, bool bSVCBaseLayer) { | ||
| 1043 | SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex]; | ||
| 1044 | |||
| 1045 | assert (iSpsNumInUse <= MAX_SPS_COUNT); | ||
| 1046 | if (!kbUseSubsetSps) { | ||
| 1047 | SWelsSPS sTmpSps; | ||
| 1048 | WelsInitSps (&sTmpSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod, | ||
| 1049 | pParam->iMaxNumRefFrame, | ||
| 1050 | 0, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount, | ||
| 1051 | bSVCBaseLayer); | ||
| 1052 | for (int32_t iId = 0; iId < iSpsNumInUse; iId++) { | ||
| 1053 | if (CheckMatchedSps (&sTmpSps, &pSpsArray[iId])) { | ||
| 1054 | return iId; | ||
| 1055 | } | ||
| 1056 | } | ||
| 1057 | } else { | ||
| 1058 | SSubsetSps sTmpSubsetSps; | ||
| 1059 | WelsInitSubsetSps (&sTmpSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod, | ||
| 1060 | pParam->iMaxNumRefFrame, | ||
| 1061 | 0, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount); | ||
| 1062 | |||
| 1063 | for (int32_t iId = 0; iId < iSpsNumInUse; iId++) { | ||
| 1064 | if (CheckMatchedSubsetSps (&sTmpSubsetSps, &pSubsetArray[iId])) { | ||
| 1065 | return iId; | ||
| 1066 | } | ||
| 1067 | } | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | return INVALID_ID; | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | int32_t FindExistingPps (SWelsSPS* pSps, SSubsetSps* pSubsetSps, const bool kbUseSubsetSps, const int32_t iSpsId, | ||
| 1074 | const bool kbEntropyCodingFlag, const int32_t iPpsNumInUse, | ||
| 1075 | SWelsPPS* pPpsArray) { | ||
| 1076 | #if !defined(DISABLE_FMO_FEATURE) | ||
| 1077 | // feature not supported yet | ||
| 1078 | return INVALID_ID; | ||
| 1079 | #endif//!DISABLE_FMO_FEATURE | ||
| 1080 | |||
| 1081 | SWelsPPS sTmpPps; | ||
| 1082 | WelsInitPps (&sTmpPps, | ||
| 1083 | pSps, | ||
| 1084 | pSubsetSps, | ||
| 1085 | 0, | ||
| 1086 | true, | ||
| 1087 | kbUseSubsetSps, | ||
| 1088 | kbEntropyCodingFlag); | ||
| 1089 | |||
| 1090 | assert (iPpsNumInUse <= MAX_PPS_COUNT); | ||
| 1091 | for (int32_t iId = 0; iId < iPpsNumInUse; iId++) { | ||
| 1092 | if ((sTmpPps.iSpsId == pPpsArray[iId].iSpsId) | ||
| 1093 | && (sTmpPps.bEntropyCodingModeFlag == pPpsArray[iId].bEntropyCodingModeFlag) | ||
| 1094 | && (sTmpPps.iPicInitQp == pPpsArray[iId].iPicInitQp) | ||
| 1095 | && (sTmpPps.iPicInitQs == pPpsArray[iId].iPicInitQs) | ||
| 1096 | && (sTmpPps.uiChromaQpIndexOffset == pPpsArray[iId].uiChromaQpIndexOffset) | ||
| 1097 | && (sTmpPps.bDeblockingFilterControlPresentFlag == pPpsArray[iId].bDeblockingFilterControlPresentFlag) | ||
| 1098 | ) { | ||
| 1099 | return iId; | ||
| 1100 | } | ||
| 1101 | } | ||
| 1102 | 962 | ||
| 1103 | return INVALID_ID; | ||
| 1104 | } | ||
| 1105 | 963 | ||
| 1106 | static inline int32_t InitSliceList (sWelsEncCtx** ppCtx, | 964 | static inline int32_t InitSliceList (sWelsEncCtx** ppCtx, |
| 1107 | SDqLayer* pDqLayer, | 965 | SDqLayer* pDqLayer, |
| @@ -1248,7 +1106,7 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p · 140 unmodified lines | |||
| 1248 | CMemoryAlign* pMa = NULL; | 1106 | CMemoryAlign* pMa = NULL; |
| 1249 | int32_t iDlayerCount = 0; | 1107 | int32_t iDlayerCount = 0; |
| 1250 | int32_t iDlayerIndex = 0; | 1108 | int32_t iDlayerIndex = 0; |
| 1251 | uint32_t iSpsId = 0; | 1109 | int32_t iSpsId = 0; |
| 1252 | uint32_t iPpsId = 0; | 1110 | uint32_t iPpsId = 0; |
| 1253 | uint32_t iNumRef = 0; | 1111 | uint32_t iNumRef = 0; |
| 1254 | int32_t iResult = 0; | 1112 | int32_t iResult = 0; |
| @@ -1388,8 +1246,10 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p · 133 unmodified lines | |||
| 1388 | } | 1246 | } |
| 1389 | 1247 | ||
| 1390 | // for dynamically malloc for parameter sets memory instead of maximal items for standard to reduce size, 3/18/2010 | 1248 | // for dynamically malloc for parameter sets memory instead of maximal items for standard to reduce size, 3/18/2010 |
| 1391 | const int32_t kiNeededSpsNum = (*ppCtx)->GetNeededSpsNum(); | 1249 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pFuncList), FreeMemorySvc (ppCtx)) |
| 1392 | const int32_t kiNeededSubsetSpsNum = (*ppCtx)->GetNeededSubsetSpsNum(); | 1250 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pFuncList->pParametersetStrategy), FreeMemorySvc (ppCtx)) |
| 1251 | const int32_t kiNeededSpsNum = (*ppCtx)->pFuncList->pParametersetStrategy->GetNeededSpsNum(); | ||
| 1252 | const int32_t kiNeededSubsetSpsNum = (*ppCtx)->pFuncList->pParametersetStrategy->GetNeededSubsetSpsNum(); | ||
| 1393 | (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMallocz (kiNeededSpsNum * sizeof (SWelsSPS), "pSpsArray"); | 1253 | (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMallocz (kiNeededSpsNum * sizeof (SWelsSPS), "pSpsArray"); |
| 1394 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx)) | 1254 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx)) |
| 1395 | if (kiNeededSubsetSpsNum > 0) { | 1255 | if (kiNeededSubsetSpsNum > 0) { |
| @@ -1399,35 +1259,14 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p · 3 unmodified lines | |||
| 1399 | (*ppCtx)->pSubsetArray = NULL; | 1259 | (*ppCtx)->pSubsetArray = NULL; |
| 1400 | } | 1260 | } |
| 1401 | 1261 | ||
| 1402 | if ((SPS_LISTING & pParam->eSpsPpsIdStrategy) && (NULL != pExistingParasetList)) { | ||
| 1403 | (*ppCtx)->sPSOVector.uiInUseSpsNum = pExistingParasetList->uiInUseSpsNum; | ||
| 1404 | memcpy ((*ppCtx)->pSpsArray, pExistingParasetList->sSps, MAX_SPS_COUNT * sizeof (SWelsSPS)); | ||
| 1405 | |||
| 1406 | if (kiNeededSubsetSpsNum > 0) { | ||
| 1407 | (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = pExistingParasetList->uiInUseSubsetSpsNum; | ||
| 1408 | memcpy ((*ppCtx)->pSubsetArray, pExistingParasetList->sSubsetSps, MAX_SPS_COUNT * sizeof (SSubsetSps)); | ||
| 1409 | } else { | ||
| 1410 | (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = 0; | ||
| 1411 | } | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | // PPS | 1262 | // PPS |
| 1415 | const int32_t kiNeededPpsNum = (*ppCtx)->GetNeededPpsNum(); | 1263 | const int32_t kiNeededPpsNum = (*ppCtx)->pFuncList->pParametersetStrategy->GetNeededPpsNum(); |
| 1416 | (*ppCtx)->pPPSArray = (SWelsPPS*)pMa->WelsMallocz (kiNeededPpsNum * sizeof (SWelsPPS), "pPPSArray"); | 1264 | (*ppCtx)->pPPSArray = (SWelsPPS*)pMa->WelsMallocz (kiNeededPpsNum * sizeof (SWelsPPS), "pPPSArray"); |
| 1417 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx)) | 1265 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx)) |
| 1418 | 1266 | ||
| 1419 | // copy from existing if the pointer exists | 1267 | (*ppCtx)->pFuncList->pParametersetStrategy->LoadPrevious (pExistingParasetList, (*ppCtx)->pSpsArray, |
| 1420 | if ((SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) && (NULL != pExistingParasetList)) { | 1268 | (*ppCtx)->pSubsetArray, (*ppCtx)->pPPSArray); |
| 1421 | (*ppCtx)->sPSOVector.uiInUsePpsNum = pExistingParasetList->uiInUsePpsNum; | ||
| 1422 | memcpy ((*ppCtx)->pPPSArray, pExistingParasetList->sPps, MAX_PPS_COUNT * sizeof (SWelsPPS)); | ||
| 1423 | } | ||
| 1424 | |||
| 1425 | 1269 | ||
| 1426 | if (INCREASING_ID & pParam->eSpsPpsIdStrategy) { | ||
| 1427 | (*ppCtx)->pPSOVector = & ((*ppCtx)->sPSOVector); | ||
| 1428 | } else { | ||
| 1429 | (*ppCtx)->pPSOVector = NULL; | ||
| 1430 | } | ||
| 1431 | 1270 | ||
| 1432 | (*ppCtx)->pDqIdcMap = (SDqIdc*)pMa->WelsMallocz (iDlayerCount * sizeof (SDqIdc), "pDqIdcMap"); | 1271 | (*ppCtx)->pDqIdcMap = (SDqIdc*)pMa->WelsMallocz (iDlayerCount * sizeof (SDqIdc), "pDqIdcMap"); |
| 1433 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pDqIdcMap), FreeMemorySvc (ppCtx)) | 1272 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pDqIdcMap), FreeMemorySvc (ppCtx)) |
| @@ -1441,79 +1280,18 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p · 7 unmodified lines | |||
| 1441 | && (iDlayerIndex == BASE_DEPENDENCY_ID); | 1280 | && (iDlayerIndex == BASE_DEPENDENCY_ID); |
| 1442 | pDqIdc->uiSpatialId = iDlayerIndex; | 1281 | pDqIdc->uiSpatialId = iDlayerIndex; |
| 1443 | 1282 | ||
| 1444 | if (! (SPS_LISTING & pParam->eSpsPpsIdStrategy)) { | 1283 | iSpsId = (*ppCtx)->pFuncList->pParametersetStrategy->GenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex, |
| 1445 | WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex, | 1284 | iDlayerCount, iSpsId, pSps, pSubsetSps, bSvcBaselayer); |
| 1446 | iDlayerCount, iSpsId, pSps, pSubsetSps, bSvcBaselayer); | 1285 | WELS_VERIFY_RETURN_IF (ENC_RETURN_UNSUPPORTED_PARA, (0 > iSpsId)) |
| 1286 | if (!bUseSubsetSps) { | ||
| 1287 | pSps = & ((*ppCtx)->pSpsArray[iSpsId]); | ||
| 1447 | } else { | 1288 | } else { |
| 1448 | //SPS_LISTING_AND_PPS_INCREASING == pParam->eSpsPpsIdStrategy | 1289 | pSubsetSps = & ((*ppCtx)->pSubsetArray[iSpsId]); |
| 1449 | //check if the current param can fit in an existing SPS | ||
| 1450 | const int32_t kiFoundSpsId = FindExistingSps ((*ppCtx)->pSvcParam, bUseSubsetSps, iDlayerIndex, iDlayerCount, | ||
| 1451 | bUseSubsetSps ? ((*ppCtx)->sPSOVector.uiInUseSubsetSpsNum) : ((*ppCtx)->sPSOVector.uiInUseSpsNum), | ||
| 1452 | (*ppCtx)->pSpsArray, | ||
| 1453 | (*ppCtx)->pSubsetArray, bSvcBaselayer); | ||
| 1454 | |||
| 1455 | |||
| 1456 | if (INVALID_ID != kiFoundSpsId) { | ||
| 1457 | //if yes, set pSps or pSubsetSps to it | ||
| 1458 | iSpsId = kiFoundSpsId; | ||
| 1459 | if (!bUseSubsetSps) { | ||
| 1460 | pSps = & ((*ppCtx)->pSpsArray[kiFoundSpsId]); | ||
| 1461 | } else { | ||
| 1462 | pSubsetSps = & ((*ppCtx)->pSubsetArray[kiFoundSpsId]); | ||
| 1463 | } | ||
| 1464 | } else { | ||
| 1465 | //if no, generate a new SPS as usual | ||
| 1466 | if ((SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) && (MAX_PPS_COUNT <= (*ppCtx)->sPSOVector.uiInUsePpsNum)) { | ||
| 1467 | //check if we can generate new SPS or not | ||
| 1468 | WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR, | ||
| 1469 | "InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!"); | ||
| 1470 | return ENC_RETURN_UNSUPPORTED_PARA; | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | iSpsId = (!bUseSubsetSps) ? ((*ppCtx)->sPSOVector.uiInUseSpsNum++) : ((*ppCtx)->sPSOVector.uiInUseSubsetSpsNum++); | ||
| 1474 | if (iSpsId >= MAX_SPS_COUNT) { | ||
| 1475 | if (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) { | ||
| 1476 | WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR, | ||
| 1477 | "InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!"); | ||
| 1478 | return ENC_RETURN_UNSUPPORTED_PARA; | ||
| 1479 | } | ||
| 1480 | // reset current list | ||
| 1481 | if (!bUseSubsetSps) { | ||
| 1482 | (*ppCtx)->sPSOVector.uiInUseSpsNum = 1; | ||
| 1483 | memset ((*ppCtx)->pSpsArray, 0, MAX_SPS_COUNT * sizeof (SWelsSPS)); | ||
| 1484 | } else { | ||
| 1485 | (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = 1; | ||
| 1486 | memset ((*ppCtx)->pSubsetArray, 0, MAX_SPS_COUNT * sizeof (SSubsetSps)); | ||
| 1487 | } | ||
| 1488 | iSpsId = 0; | ||
| 1489 | } | ||
| 1490 | |||
| 1491 | WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex, | ||
| 1492 | iDlayerCount, iSpsId, pSps, pSubsetSps, bSvcBaselayer); | ||
| 1493 | } | ||
| 1494 | } | 1290 | } |
| 1495 | 1291 | ||
| 1496 | if (! (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy)) { | 1292 | iPpsId = (*ppCtx)->pFuncList->pParametersetStrategy->InitPps ((*ppCtx), iSpsId, pSps, pSubsetSps, iPpsId, true, |
| 1497 | pPps = & (*ppCtx)->pPPSArray[iPpsId]; | 1293 | bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0); |
| 1498 | // initialize pPps | 1294 | pPps = & ((*ppCtx)->pPPSArray[iPpsId]); |
| 1499 | WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0); | ||
| 1500 | } else { | ||
| 1501 | const int32_t kiFoundPpsId = FindExistingPps (pSps, pSubsetSps, bUseSubsetSps, iSpsId, | ||
| 1502 | pParam->iEntropyCodingModeFlag != 0, | ||
| 1503 | (*ppCtx)->sPSOVector.uiInUsePpsNum, | ||
| 1504 | (*ppCtx)->pPPSArray); | ||
| 1505 | |||
| 1506 | |||
| 1507 | if (INVALID_ID != kiFoundPpsId) { | ||
| 1508 | //if yes, set pPps to it | ||
| 1509 | iPpsId = kiFoundPpsId; | ||
| 1510 | pPps = & ((*ppCtx)->pPPSArray[kiFoundPpsId]); | ||
| 1511 | } else { | ||
| 1512 | iPpsId = ((*ppCtx)->sPSOVector.uiInUsePpsNum++); | ||
| 1513 | pPps = & (*ppCtx)->pPPSArray[iPpsId]; | ||
| 1514 | WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0); | ||
| 1515 | } | ||
| 1516 | } | ||
| 1517 | 1295 | ||
| 1518 | // Not using FMO in SVC coding so far, come back if need FMO | 1296 | // Not using FMO in SVC coding so far, come back if need FMO |
| 1519 | { | 1297 | { |
| @@ -1533,8 +1311,6 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p · 13 unmodified lines | |||
| 1533 | pDqIdc->iSpsId = iSpsId; | 1311 | pDqIdc->iSpsId = iSpsId; |
| 1534 | pDqIdc->iPpsId = iPpsId; | 1312 | pDqIdc->iPpsId = iPpsId; |
| 1535 | 1313 | ||
| 1536 | (*ppCtx)->sPSOVector.bPpsIdMappingIntoSubsetsps[iPpsId] = bUseSubsetSps; | ||
| 1537 | |||
| 1538 | if ((pParam->bSimulcastAVC) || (bUseSubsetSps)) | 1314 | if ((pParam->bSimulcastAVC) || (bUseSubsetSps)) |
| 1539 | ++ iSpsId; | 1315 | ++ iSpsId; |
| 1540 | ++ iPpsId; | 1316 | ++ iPpsId; |
| @@ -1547,13 +1323,8 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p · 6 unmodified lines | |||
| 1547 | 1323 | ||
| 1548 | ++ iDlayerIndex; | 1324 | ++ iDlayerIndex; |
| 1549 | } | 1325 | } |
| 1550 | if (SPS_LISTING & pParam->eSpsPpsIdStrategy) { | 1326 | |
| 1551 | (*ppCtx)->iSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum; | 1327 | (*ppCtx)->pFuncList->pParametersetStrategy->UpdateParaSetNum ((*ppCtx)); |
| 1552 | (*ppCtx)->iSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum; | ||
| 1553 | } | ||
| 1554 | if (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) { | ||
| 1555 | (*ppCtx)->iPpsNum = (*ppCtx)->sPSOVector.uiInUsePpsNum; | ||
| 1556 | } | ||
| 1557 | return ENC_RETURN_SUCCESS; | 1328 | return ENC_RETURN_SUCCESS; |
| 1558 | } | 1329 | } |
| 1559 | 1330 | ||
| @@ -1908,8 +1679,8 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingPa · 348 unmodified lines | |||
| 1908 | return 1; | 1679 | return 1; |
| 1909 | } | 1680 | } |
| 1910 | 1681 | ||
| 1911 | const int32_t kiSpsSize = (*ppCtx)->GetNeededSpsNum() * SPS_BUFFER_SIZE; | 1682 | const int32_t kiSpsSize = (*ppCtx)->pFuncList->pParametersetStrategy->GetNeededSpsNum() * SPS_BUFFER_SIZE; |
| 1912 | const int32_t kiPpsSize = (*ppCtx)->GetNeededPpsNum() * PPS_BUFFER_SIZE; | 1683 | const int32_t kiPpsSize = (*ppCtx)->pFuncList->pParametersetStrategy->GetNeededPpsNum() * PPS_BUFFER_SIZE; |
| 1913 | iNonVclLayersBsSizeCount = SSEI_BUFFER_SIZE + kiSpsSize + kiPpsSize; | 1684 | iNonVclLayersBsSizeCount = SSEI_BUFFER_SIZE + kiSpsSize + kiPpsSize; |
| 1914 | 1685 | ||
| 1915 | bool bDynamicSlice = false; | 1686 | bool bDynamicSlice = false; |
| @@ -2316,6 +2087,10 @@ void FreeMemorySvc (sWelsEncCtx** ppCtx) { · 400 unmodified lines | |||
| 2316 | 2087 | ||
| 2317 | FreeCodingParam (&pCtx->pSvcParam, pMa); | 2088 | FreeCodingParam (&pCtx->pSvcParam, pMa); |
| 2318 | if (NULL != pCtx->pFuncList) { | 2089 | if (NULL != pCtx->pFuncList) { |
| 2090 | if (NULL != pCtx->pFuncList->pParametersetStrategy) { | ||
| 2091 | WELS_DELETE_OP (pCtx->pFuncList->pParametersetStrategy); | ||
| 2092 | } | ||
| 2093 | |||
| 2319 | pMa->WelsFree (pCtx->pFuncList, "SWelsFuncPtrList"); | 2094 | pMa->WelsFree (pCtx->pFuncList, "SWelsFuncPtrList"); |
| 2320 | pCtx->pFuncList = NULL; | 2095 | pCtx->pFuncList = NULL; |
| 2321 | } | 2096 | } |
| @@ -2867,9 +2642,8 @@ void WelsInitCurrentLayer (sWelsEncCtx* pCtx, · 545 unmodified lines | |||
| 2867 | int32_t iCurPpsId = pDqIdc->iPpsId; | 2642 | int32_t iCurPpsId = pDqIdc->iPpsId; |
| 2868 | int32_t iCurSpsId = pDqIdc->iSpsId; | 2643 | int32_t iCurSpsId = pDqIdc->iSpsId; |
| 2869 | 2644 | ||
| 2870 | if (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) { | 2645 | iCurPpsId = pCtx->pFuncList->pParametersetStrategy->GetCurrentPpsId (iCurPpsId, |
| 2871 | iCurPpsId = pCtx->sPSOVector.iPpsIdList[pDqIdc->iPpsId][WELS_ABS (pCtx->uiIdrPicId - 1) % MAX_PPS_COUNT]; | 2646 | WELS_ABS (pCtx->uiIdrPicId - 1) % MAX_PPS_COUNT); |
| 2872 | } | ||
| 2873 | 2647 | ||
| 2874 | pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId = iCurPpsId; | 2648 | pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId = iCurPpsId; |
| 2875 | pCurDq->sLayerInfo.pPpsP = | 2649 | pCurDq->sLayerInfo.pPpsP = |
| @@ -3148,45 +2922,12 @@ static inline void PrefetchReferencePicture (sWelsEncCtx* pCtx, const EVideoFram · 272 unmodified lines | |||
| 3148 | } | 2922 | } |
| 3149 | } | 2923 | } |
| 3150 | 2924 | ||
| 3151 | |||
| 3152 | void ParasetIdAdditionIdAdjust (SParaSetOffsetVariable* sParaSetOffsetVariable, const int32_t kiCurEncoderParaSetId, | ||
| 3153 | const uint32_t kuiMaxIdInBs) { //paraset_type = 0: SPS; =1: PPS | ||
| 3154 | //SPS_ID in avc_sps and pSubsetSps will be different using this | ||
| 3155 | //SPS_ID case example: | ||
| 3156 | //1st enter: next_spsid_in_bs == 0; spsid == 0; delta==0; //actual spsid_in_bs == 0 | ||
| 3157 | //1st finish: next_spsid_in_bs == 1; | ||
| 3158 | //2nd enter: next_spsid_in_bs == 1; spsid == 0; delta==1; //actual spsid_in_bs == 1 | ||
| 3159 | //2nd finish: next_spsid_in_bs == 2; | ||
| 3160 | //31st enter: next_spsid_in_bs == 31; spsid == 0~2; delta==31~29; //actual spsid_in_bs == 31 | ||
| 3161 | //31st finish:next_spsid_in_bs == 0; | ||
| 3162 | //31st enter: next_spsid_in_bs == 0; spsid == 0~2; delta==-2~0; //actual spsid_in_bs == 0 | ||
| 3163 | //31st finish:next_spsid_in_bs == 1; | ||
| 3164 | |||
| 3165 | const int32_t kiEncId = kiCurEncoderParaSetId; | ||
| 3166 | uint32_t uiNextIdInBs = sParaSetOffsetVariable->uiNextParaSetIdToUseInBs; | ||
| 3167 | |||
| 3168 | //update current layer's pCodingParam | ||
| 3169 | sParaSetOffsetVariable->iParaSetIdDelta[kiEncId] = uiNextIdInBs - | ||
| 3170 | kiEncId; //for current parameter set, change its id_delta | ||
| 3171 | //write pso pData for next update: | ||
| 3172 | sParaSetOffsetVariable->bUsedParaSetIdInBs[uiNextIdInBs] = true; // update current used_id | ||
| 3173 | |||
| 3174 | //prepare for next update: | ||
| 3175 | // find the next avaibable iId | ||
| 3176 | ++uiNextIdInBs; | ||
| 3177 | if (uiNextIdInBs >= kuiMaxIdInBs) { | ||
| 3178 | uiNextIdInBs = 0;//ensure the SPS_ID wound not exceed MAX_SPS_COUNT | ||
| 3179 | } | ||
| 3180 | // update next_id | ||
| 3181 | sParaSetOffsetVariable->uiNextParaSetIdToUseInBs = uiNextIdInBs; | ||
| 3182 | } | ||
| 3183 | |||
| 3184 | int32_t WelsWriteOneSPS (sWelsEncCtx* pCtx, const int32_t kiSpsIdx, int32_t& iNalSize) { | 2925 | int32_t WelsWriteOneSPS (sWelsEncCtx* pCtx, const int32_t kiSpsIdx, int32_t& iNalSize) { |
| 3185 | int iNal = pCtx->pOut->iNalIndex; | 2926 | int iNal = pCtx->pOut->iNalIndex; |
| 3186 | WelsLoadNal (pCtx->pOut, NAL_UNIT_SPS, NRI_PRI_HIGHEST); | 2927 | WelsLoadNal (pCtx->pOut, NAL_UNIT_SPS, NRI_PRI_HIGHEST); |
| 3187 | 2928 | ||
| 3188 | WelsWriteSpsNal (&pCtx->pSpsArray[kiSpsIdx], &pCtx->pOut->sBsWrite, | 2929 | WelsWriteSpsNal (&pCtx->pSpsArray[kiSpsIdx], &pCtx->pOut->sBsWrite, |
| 3189 | & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS].iParaSetIdDelta[0])); | 2930 | pCtx->pFuncList->pParametersetStrategy->GetSpsIdOffsetList (PARA_SET_TYPE_AVCSPS)); |
| 3190 | WelsUnloadNal (pCtx->pOut); | 2931 | WelsUnloadNal (pCtx->pOut); |
| 3191 | 2932 | ||
| 3192 | int32_t iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, | 2933 | int32_t iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, |
| @@ -3204,8 +2945,9 @@ int32_t WelsWriteOnePPS (sWelsEncCtx* pCtx, const int32_t kiPpsIdx, int32_t& iNa · 11 unmodified lines | |||
| 3204 | int32_t iNal = pCtx->pOut->iNalIndex; | 2945 | int32_t iNal = pCtx->pOut->iNalIndex; |
| 3205 | /* generate picture parameter set */ | 2946 | /* generate picture parameter set */ |
| 3206 | WelsLoadNal (pCtx->pOut, NAL_UNIT_PPS, NRI_PRI_HIGHEST); | 2947 | WelsLoadNal (pCtx->pOut, NAL_UNIT_PPS, NRI_PRI_HIGHEST); |
| 2948 | |||
| 3207 | WelsWritePpsSyntax (&pCtx->pPPSArray[kiPpsIdx], &pCtx->pOut->sBsWrite, | 2949 | WelsWritePpsSyntax (&pCtx->pPPSArray[kiPpsIdx], &pCtx->pOut->sBsWrite, |
| 3208 | ((SPS_PPS_LISTING != pCtx->pSvcParam->eSpsPpsIdStrategy)) ? (& (pCtx->sPSOVector)) : NULL); | 2950 | pCtx->pFuncList->pParametersetStrategy); |
| 3209 | WelsUnloadNal (pCtx->pOut); | 2951 | WelsUnloadNal (pCtx->pOut); |
| 3210 | 2952 | ||
| 3211 | int32_t iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, | 2953 | int32_t iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, |
| @@ -3218,43 +2960,6 @@ int32_t WelsWriteOnePPS (sWelsEncCtx* pCtx, const int32_t kiPpsIdx, int32_t& iNa · 6 unmodified lines | |||
| 3218 | return ENC_RETURN_SUCCESS; | 2960 | return ENC_RETURN_SUCCESS; |
| 3219 | } | 2961 | } |
| 3220 | 2962 | ||
| 3221 | void UpdatePpsList (sWelsEncCtx* pCtx) { | ||
| 3222 | assert (pCtx->iPpsNum <= MAX_DQ_LAYER_NUM); | ||
| 3223 | |||
| 3224 | //Generate PPS LIST | ||
| 3225 | int32_t iPpsId = 0, iUsePpsNum = pCtx->iPpsNum; | ||
| 3226 | |||
| 3227 | for (int32_t iIdrRound = 0; iIdrRound < MAX_PPS_COUNT; iIdrRound++) { | ||
| 3228 | for (iPpsId = 0; iPpsId < pCtx->iPpsNum; iPpsId++) { | ||
| 3229 | pCtx->sPSOVector.iPpsIdList[iPpsId][iIdrRound] = ((iIdrRound * iUsePpsNum + iPpsId) % MAX_PPS_COUNT); | ||
| 3230 | } | ||
| 3231 | } | ||
| 3232 | |||
| 3233 | for (iPpsId = iUsePpsNum; iPpsId < MAX_PPS_COUNT; iPpsId++) { | ||
| 3234 | memcpy (& (pCtx->pPPSArray[iPpsId]), & (pCtx->pPPSArray[iPpsId % iUsePpsNum]), sizeof (SWelsPPS)); | ||
| 3235 | pCtx->pPPSArray[iPpsId].iPpsId = iPpsId; | ||
| 3236 | pCtx->iPpsNum++; | ||
| 3237 | } | ||
| 3238 | |||
| 3239 | assert (pCtx->iPpsNum == MAX_PPS_COUNT); | ||
| 3240 | pCtx->sPSOVector.uiInUsePpsNum = pCtx->iPpsNum; | ||
| 3241 | |||
| 3242 | } | ||
| 3243 | |||
| 3244 | void UpdateSpsPpsIdStrategyWithIncreasingId (SParaSetOffset* pPSOVector, const uint32_t kuiId, const int iParasetType) { | ||
| 3245 | #if _DEBUG | ||
| 3246 | pPSOVector->eSpsPpsIdStrategy = INCREASING_ID; | ||
| 3247 | assert (kuiId < MAX_DQ_LAYER_NUM); | ||
| 3248 | #endif | ||
| 3249 | |||
| 3250 | ParasetIdAdditionIdAdjust (& (pPSOVector->sParaSetOffsetVariable[iParasetType]), | ||
| 3251 | kuiId, | ||
| 3252 | (iParasetType != PARA_SET_TYPE_PPS) ? MAX_SPS_COUNT : MAX_PPS_COUNT); | ||
| 3253 | } | ||
| 3254 | |||
| 3255 | void UpdateSpsPpsIdStrategyWithConstantId (SParaSetOffset* pPSOVector, const uint32_t kuiId, const int iParasetType) { | ||
| 3256 | memset (pPSOVector, 0, sizeof (SParaSetOffset)); | ||
| 3257 | } | ||
| 3258 | 2963 | ||
| 3259 | /*! | 2964 | /*! |
| 3260 | * \brief write all parameter sets introduced in SVC extension | 2965 | * \brief write all parameter sets introduced in SVC extension |
| @@ -3269,22 +2974,16 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 8 unmodified lines | |||
| 3269 | int32_t iNalLength = 0; | 2974 | int32_t iNalLength = 0; |
| 3270 | int32_t iReturn = ENC_RETURN_SUCCESS; | 2975 | int32_t iReturn = ENC_RETURN_SUCCESS; |
| 3271 | 2976 | ||
| 3272 | if (NULL == pCtx || NULL == pNalLen || NULL == pNumNal) | 2977 | if (NULL == pCtx || NULL == pNalLen || NULL == pNumNal || NULL == pCtx->pFuncList->pParametersetStrategy) |
| 3273 | return ENC_RETURN_UNEXPECTED; | 2978 | return ENC_RETURN_UNEXPECTED; |
| 3274 | 2979 | ||
| 3275 | *pTotalLength = 0; | 2980 | *pTotalLength = 0; |
| 3276 | /* write all SPS */ | 2981 | /* write all SPS */ |
| 3277 | iIdx = 0; | 2982 | iIdx = 0; |
| 3278 | while (iIdx < pCtx->iSpsNum) { | 2983 | while (iIdx < pCtx->iSpsNum) { |
| 3279 | // TODO (Sijia) wrap different operation of eSpsPpsIdStrategy to classes to hide the details | 2984 | pCtx->pFuncList->pParametersetStrategy->Update (pCtx->pSpsArray[iIdx].uiSpsId, PARA_SET_TYPE_AVCSPS); |
| 3280 | if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) { | ||
| 3281 | UpdateSpsPpsIdStrategyWithIncreasingId (& (pCtx->sPSOVector), pCtx->pSpsArray[0].uiSpsId, PARA_SET_TYPE_AVCSPS); | ||
| 3282 | } else if (CONSTANT_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) { | ||
| 3283 | UpdateSpsPpsIdStrategyWithConstantId (& (pCtx->sPSOVector), pCtx->pSpsArray[0].uiSpsId, PARA_SET_TYPE_AVCSPS); | ||
| 3284 | } | ||
| 3285 | |||
| 3286 | /* generate sequence parameters set */ | 2985 | /* generate sequence parameters set */ |
| 3287 | iId = (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy) ? iIdx : 0; | 2986 | iId = pCtx->pFuncList->pParametersetStrategy->GetSpsIdx (iIdx); |
| 3288 | 2987 | ||
| 3289 | WelsWriteOneSPS (pCtx, iId, iNalLength); | 2988 | WelsWriteOneSPS (pCtx, iId, iNalLength); |
| 3290 | 2989 | ||
| @@ -3300,11 +2999,7 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 9 unmodified lines | |||
| 3300 | while (iIdx < pCtx->iSubsetSpsNum) { | 2999 | while (iIdx < pCtx->iSubsetSpsNum) { |
| 3301 | iNal = pCtx->pOut->iNalIndex; | 3000 | iNal = pCtx->pOut->iNalIndex; |
| 3302 | 3001 | ||
| 3303 | if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) { | 3002 | pCtx->pFuncList->pParametersetStrategy->Update (pCtx->pSubsetArray[iIdx].pSps.uiSpsId, PARA_SET_TYPE_SUBSETSPS); |
| 3304 | UpdateSpsPpsIdStrategyWithIncreasingId (& (pCtx->sPSOVector), pCtx->pSubsetArray[iIdx].pSps.uiSpsId, | ||
| 3305 | PARA_SET_TYPE_SUBSETSPS); | ||
| 3306 | } | ||
| 3307 | |||
| 3308 | 3003 | ||
| 3309 | iId = iIdx; | 3004 | iId = iIdx; |
| 3310 | 3005 | ||
| @@ -3312,7 +3007,7 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 1 unmodified line | |||
| 3312 | WelsLoadNal (pCtx->pOut, NAL_UNIT_SUBSET_SPS, NRI_PRI_HIGHEST); | 3007 | WelsLoadNal (pCtx->pOut, NAL_UNIT_SUBSET_SPS, NRI_PRI_HIGHEST); |
| 3313 | 3008 | ||
| 3314 | WelsWriteSubsetSpsSyntax (&pCtx->pSubsetArray[iId], &pCtx->pOut->sBsWrite, | 3009 | WelsWriteSubsetSpsSyntax (&pCtx->pSubsetArray[iId], &pCtx->pOut->sBsWrite, |
| 3315 | & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_SUBSETSPS].iParaSetIdDelta[0])); | 3010 | pCtx->pFuncList->pParametersetStrategy->GetSpsIdOffsetList (PARA_SET_TYPE_SUBSETSPS)); |
| 3316 | WelsUnloadNal (pCtx->pOut); | 3011 | WelsUnloadNal (pCtx->pOut); |
| 3317 | 3012 | ||
| 3318 | iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, | 3013 | iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, |
| @@ -3329,16 +3024,11 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 10 unmodified lines | |||
| 3329 | ++ iCountNal; | 3024 | ++ iCountNal; |
| 3330 | } | 3025 | } |
| 3331 | 3026 | ||
| 3332 | /* write all PPS */ | 3027 | pCtx->pFuncList->pParametersetStrategy->UpdatePpsList (pCtx); |
| 3333 | if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) { | ||
| 3334 | UpdatePpsList (pCtx); | ||
| 3335 | } | ||
| 3336 | 3028 | ||
| 3337 | iIdx = 0; | 3029 | iIdx = 0; |
| 3338 | while (iIdx < pCtx->iPpsNum) { | 3030 | while (iIdx < pCtx->iPpsNum) { |
| 3339 | if ((INCREASING_ID & pCtx->pSvcParam->eSpsPpsIdStrategy)) { | 3031 | pCtx->pFuncList->pParametersetStrategy->Update (pCtx->pPPSArray[iIdx].iPpsId, PARA_SET_TYPE_PPS); |
| 3340 | UpdateSpsPpsIdStrategyWithIncreasingId (& (pCtx->sPSOVector), pCtx->pPPSArray[iIdx].iPpsId, PARA_SET_TYPE_PPS); | ||
| 3341 | } | ||
| 3342 | 3032 | ||
| 3343 | WelsWriteOnePPS (pCtx, iIdx, iNalLength); | 3033 | WelsWriteOnePPS (pCtx, iIdx, iNalLength); |
| 3344 | 3034 | ||
| @@ -3552,10 +3242,9 @@ int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t iIdx, · 207 unmodified lines | |||
| 3552 | int32_t iNalSize = 0; | 3242 | int32_t iNalSize = 0; |
| 3553 | iCountNal = 0; | 3243 | iCountNal = 0; |
| 3554 | 3244 | ||
| 3555 | if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) { | 3245 | |
| 3556 | UpdateSpsPpsIdStrategyWithIncreasingId (& (pCtx->sPSOVector), pCtx->pSpsArray[iIdx].uiSpsId, PARA_SET_TYPE_AVCSPS); | 3246 | if (pCtx->pFuncList->pParametersetStrategy) { |
| 3557 | } else if (CONSTANT_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) { | 3247 | pCtx->pFuncList->pParametersetStrategy->Update (pCtx->pSpsArray[iIdx].uiSpsId, PARA_SET_TYPE_AVCSPS); |
| 3558 | UpdateSpsPpsIdStrategyWithConstantId (& (pCtx->sPSOVector), pCtx->pSpsArray[iIdx].uiSpsId, PARA_SET_TYPE_AVCSPS); | ||
| 3559 | } | 3248 | } |
| 3560 | 3249 | ||
| 3561 | iReturn = WelsWriteOneSPS (pCtx, iIdx, iNalSize); | 3250 | iReturn = WelsWriteOneSPS (pCtx, iIdx, iNalSize); |
| @@ -3589,10 +3278,8 @@ int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t iIdx, · 27 unmodified lines | |||
| 3589 | iNalSize = 0; | 3278 | iNalSize = 0; |
| 3590 | iCountNal = 0; | 3279 | iCountNal = 0; |
| 3591 | 3280 | ||
| 3592 | if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) { | 3281 | if (pCtx->pFuncList->pParametersetStrategy) { |
| 3593 | UpdateSpsPpsIdStrategyWithIncreasingId (& (pCtx->sPSOVector), pCtx->pPPSArray[iIdx].iPpsId, PARA_SET_TYPE_PPS); | 3282 | pCtx->pFuncList->pParametersetStrategy->Update (pCtx->pPPSArray[iIdx].iPpsId, PARA_SET_TYPE_PPS); |
| 3594 | } else if (CONSTANT_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) { | ||
| 3595 | UpdateSpsPpsIdStrategyWithConstantId (& (pCtx->sPSOVector), pCtx->pPPSArray[iIdx].iPpsId, PARA_SET_TYPE_PPS); | ||
| 3596 | } | 3283 | } |
| 3597 | 3284 | ||
| 3598 | iReturn = WelsWriteOnePPS (pCtx, iIdx, iNalSize); | 3285 | iReturn = WelsWriteOnePPS (pCtx, iIdx, iNalSize); |
| @@ -3666,9 +3353,7 @@ int32_t WriteSavcParaset_Listing (sWelsEncCtx* pCtx, const int32_t kiSpatialNum, · 67 unmodified lines | |||
| 3666 | } | 3353 | } |
| 3667 | 3354 | ||
| 3668 | // write PPS | 3355 | // write PPS |
| 3669 | if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) { | 3356 | pCtx->pFuncList->pParametersetStrategy->UpdatePpsList (pCtx); |
| 3670 | UpdatePpsList (pCtx); | ||
| 3671 | } | ||
| 3672 | 3357 | ||
| 3673 | //TODO: under new strategy, will PPS be correctly updated? | 3358 | //TODO: under new strategy, will PPS be correctly updated? |
| 3674 | for (int32_t iSpatialId = 0; iSpatialId < kiSpatialNum; iSpatialId++) { | 3359 | for (int32_t iSpatialId = 0; iSpatialId < kiSpatialNum; iSpatialId++) { |
| @@ -3811,22 +3496,29 @@ EVideoFrameType PrepareEncodeFrame (sWelsEncCtx* pCtx, SLayerBSInfo*& pLayerBsIn · 136 unmodified lines | |||
| 3811 | pCtx->iContinualSkipFrames = 0; | 3496 | pCtx->iContinualSkipFrames = 0; |
| 3812 | iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[iCurDid], pParamInternal->iCodingIndex, | 3497 | iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[iCurDid], pParamInternal->iCodingIndex, |
| 3813 | pSvcParam->uiGopSize); | 3498 | pSvcParam->uiGopSize); |
| 3814 | pCtx->uiTemporalId = iCurTid; | 3499 | //skip this spatial layer |
| 3815 | if (eFrameType == videoFrameTypeIDR) { | 3500 | if (iCurTid == INVALID_TEMPORAL_ID) { |
| 3816 | // write parameter sets bitstream or SEI/SSEI (if any) here | 3501 | pParamInternal->iCodingIndex ++; |
| 3817 | // TODO: use function pointer instead | 3502 | eFrameType = videoFrameTypeSkip; |
| 3818 | if (! (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy)) { | 3503 | pLayerBsInfo->eFrameType = videoFrameTypeSkip; |
| 3819 | if (pSvcParam->bSimulcastAVC) { | 3504 | } else { |
| 3820 | pCtx->iEncoderError = WriteSavcParaset (pCtx, iCurDid, pLayerBsInfo, iLayerNum, iFrameSize); | 3505 | pCtx->uiTemporalId = iCurTid; |
| 3821 | ++ pCtx->uiIdrPicId; | 3506 | if (eFrameType == videoFrameTypeIDR) { |
| 3507 | // write parameter sets bitstream or SEI/SSEI (if any) here | ||
| 3508 | // TODO: use function pointer instead | ||
| 3509 | if (! (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy)) { | ||
| 3510 | if (pSvcParam->bSimulcastAVC) { | ||
| 3511 | pCtx->iEncoderError = WriteSavcParaset (pCtx, iCurDid, pLayerBsInfo, iLayerNum, iFrameSize); | ||
| 3512 | ++ pCtx->uiIdrPicId; | ||
| 3513 | } else { | ||
| 3514 | pCtx->iEncoderError = WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize); | ||
| 3515 | ++ pCtx->uiIdrPicId; | ||
| 3516 | } | ||
| 3822 | } else { | 3517 | } else { |
| 3823 | pCtx->iEncoderError = WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize); | 3518 | pCtx->iEncoderError = WriteSavcParaset_Listing (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize); |
| 3519 | |||
| 3824 | ++ pCtx->uiIdrPicId; | 3520 | ++ pCtx->uiIdrPicId; |
| 3825 | } | 3521 | } |
| 3826 | } else { | ||
| 3827 | pCtx->iEncoderError = WriteSavcParaset_Listing (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize); | ||
| 3828 | |||
| 3829 | ++ pCtx->uiIdrPicId; | ||
| 3830 | } | 3522 | } |
| 3831 | } | 3523 | } |
| 3832 | 3524 | ||
| @@ -3931,12 +3623,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour · 98 unmodified lines | |||
| 3931 | int32_t iDecompositionStages = pSvcParam->sDependencyLayers[iCurDid].iDecompositionStages; | 3623 | int32_t iDecompositionStages = pSvcParam->sDependencyLayers[iCurDid].iDecompositionStages; |
| 3932 | pCtx->pCurDqLayer = pCtx->ppDqLayerList[iCurDid]; | 3624 | pCtx->pCurDqLayer = pCtx->ppDqLayerList[iCurDid]; |
| 3933 | pCtx->uiDependencyId = iCurDid; | 3625 | pCtx->uiDependencyId = iCurDid; |
| 3934 | //skip this spatial layer | 3626 | |
| 3935 | if (GetTemporalLevel (pParamInternal, pParamInternal->iCodingIndex, pSvcParam->uiGopSize) == INVALID_TEMPORAL_ID) { | ||
| 3936 | ++iSpatialIdx; | ||
| 3937 | pParamInternal->iCodingIndex ++; | ||
| 3938 | continue; | ||
| 3939 | } | ||
| 3940 | if (pSvcParam->bSimulcastAVC) { | 3627 | if (pSvcParam->bSimulcastAVC) { |
| 3941 | eFrameType = PrepareEncodeFrame (pCtx, pLayerBsInfo, iSpatialNum , iCurDid, iCurTid, iLayerNum, iFrameSize, | 3628 | eFrameType = PrepareEncodeFrame (pCtx, pLayerBsInfo, iSpatialNum , iCurDid, iCurTid, iLayerNum, iFrameSize, |
| 3942 | pFbi->uiTimeStamp); | 3629 | pFbi->uiTimeStamp); |
| @@ -4659,46 +4346,16 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa · 716 unmodified lines | |||
| 4659 | SExistingParasetList sExistingParasetList; | 4346 | SExistingParasetList sExistingParasetList; |
| 4660 | SExistingParasetList* pExistingParasetList = NULL; | 4347 | SExistingParasetList* pExistingParasetList = NULL; |
| 4661 | 4348 | ||
| 4662 | if ((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->eSpsPpsIdStrategy)) { | 4349 | if (((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->eSpsPpsIdStrategy))) { |
| 4663 | for (int32_t k = 0; k < PARA_SET_TYPE; k++) { | 4350 | (*ppCtx)->pFuncList->pParametersetStrategy->OutputCurrentStructure (sTmpPsoVariable, iTmpPpsIdList, (*ppCtx), |
| 4664 | memset (((*ppCtx)->sPSOVector.sParaSetOffsetVariable[k].bUsedParaSetIdInBs), 0, MAX_PPS_COUNT * sizeof (bool)); | 4351 | &sExistingParasetList); |
| 4665 | } | ||
| 4666 | memcpy (sTmpPsoVariable, (*ppCtx)->sPSOVector.sParaSetOffsetVariable, | ||
| 4667 | (PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage | ||
| 4668 | 4352 | ||
| 4669 | if ((SPS_LISTING & iOldSpsPpsIdStrategy) | 4353 | if ((SPS_LISTING & iOldSpsPpsIdStrategy) |
| 4670 | && (SPS_LISTING & pNewParam->eSpsPpsIdStrategy)) { | 4354 | && (SPS_LISTING & pNewParam->eSpsPpsIdStrategy)) { |
| 4671 | pExistingParasetList = &sExistingParasetList; | 4355 | pExistingParasetList = &sExistingParasetList; |
| 4672 | sExistingParasetList.uiInUseSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum; | ||
| 4673 | memcpy (sExistingParasetList.sSps, (*ppCtx)->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS)); | ||
| 4674 | if (NULL != (*ppCtx)->pSubsetArray) { | ||
| 4675 | sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum; | ||
| 4676 | memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps)); | ||
| 4677 | } else { | ||
| 4678 | sExistingParasetList.uiInUseSubsetSpsNum = 0; | ||
| 4679 | } | ||
| 4680 | } | ||
| 4681 | |||
| 4682 | if ((SPS_PPS_LISTING == iOldSpsPpsIdStrategy) | ||
| 4683 | && (SPS_PPS_LISTING == pNewParam->eSpsPpsIdStrategy)) { | ||
| 4684 | pExistingParasetList = &sExistingParasetList; | ||
| 4685 | sExistingParasetList.uiInUseSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum; | ||
| 4686 | sExistingParasetList.uiInUsePpsNum = (*ppCtx)->sPSOVector.uiInUsePpsNum; | ||
| 4687 | memcpy (sExistingParasetList.sSps, (*ppCtx)->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS)); | ||
| 4688 | memcpy (sExistingParasetList.sPps, (*ppCtx)->pPps, MAX_PPS_COUNT * sizeof (SWelsPPS)); | ||
| 4689 | |||
| 4690 | if (NULL != (*ppCtx)->pSubsetArray) { | ||
| 4691 | sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum; | ||
| 4692 | memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps)); | ||
| 4693 | } else { | ||
| 4694 | sExistingParasetList.uiInUseSubsetSpsNum = 0; | ||
| 4695 | } | ||
| 4696 | |||
| 4697 | memcpy (iTmpPpsIdList, ((*ppCtx)->sPSOVector.iPpsIdList), MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t)); | ||
| 4698 | } | 4356 | } |
| 4699 | } | 4357 | } |
| 4700 | 4358 | ||
| 4701 | |||
| 4702 | WelsUninitEncoderExt (ppCtx); | 4359 | WelsUninitEncoderExt (ppCtx); |
| 4703 | 4360 | ||
| 4704 | /* Update new parameters */ | 4361 | /* Update new parameters */ |
| @@ -4711,14 +4368,10 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa · 6 unmodified lines | |||
| 4711 | //for sEncoderStatistics | 4368 | //for sEncoderStatistics |
| 4712 | memcpy ((*ppCtx)->sEncoderStatistics, sTempEncoderStatistics, sizeof (sTempEncoderStatistics)); | 4369 | memcpy ((*ppCtx)->sEncoderStatistics, sTempEncoderStatistics, sizeof (sTempEncoderStatistics)); |
| 4713 | //load back the needed structure for eSpsPpsIdStrategy | 4370 | //load back the needed structure for eSpsPpsIdStrategy |
| 4714 | if ((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->eSpsPpsIdStrategy)) { | 4371 | if (((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->eSpsPpsIdStrategy)) |
| 4715 | memcpy ((*ppCtx)->sPSOVector.sParaSetOffsetVariable, sTmpPsoVariable, | 4372 | || ((SPS_PPS_LISTING == iOldSpsPpsIdStrategy) |
| 4716 | (PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage | 4373 | && (SPS_PPS_LISTING == pNewParam->eSpsPpsIdStrategy))) { |
| 4717 | } | 4374 | (*ppCtx)->pFuncList->pParametersetStrategy->LoadPreviousStructure (sTmpPsoVariable, iTmpPpsIdList); |
| 4718 | |||
| 4719 | if ((SPS_PPS_LISTING == iOldSpsPpsIdStrategy) | ||
| 4720 | && (SPS_PPS_LISTING == pNewParam->eSpsPpsIdStrategy)) { | ||
| 4721 | memcpy (((*ppCtx)->sPSOVector.iPpsIdList), iTmpPpsIdList, MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t)); | ||
| 4722 | } | 4375 | } |
| 4723 | } else { | 4376 | } else { |
| 4724 | /* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */ | 4377 | /* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */ |