• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*!
2  * \copy
3  *     Copyright (c)  2013, Cisco Systems
4  *     All rights reserved.
5  *
6  *     Redistribution and use in source and binary forms, with or without
7  *     modification, are permitted provided that the following conditions
8  *     are met:
9  *
10  *        * Redistributions of source code must retain the above copyright
11  *          notice, this list of conditions and the following disclaimer.
12  *
13  *        * Redistributions in binary form must reproduce the above copyright
14  *          notice, this list of conditions and the following disclaimer in
15  *          the documentation and/or other materials provided with the
16  *          distribution.
17  *
18  *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24  *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26  *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28  *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  *     POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 #include "au_set.h"
34 #include "encoder_context.h"
35 #include "paraset_strategy.h"
36 
37 namespace WelsEnc {
38 
39 
CreateParametersetStrategy(EParameterSetStrategy eSpsPpsIdStrategy,bool bSimulcastAVC,const int32_t kiSpatialLayerNum)40 IWelsParametersetStrategy*   IWelsParametersetStrategy::CreateParametersetStrategy (
41   EParameterSetStrategy eSpsPpsIdStrategy, bool bSimulcastAVC,
42   const int32_t kiSpatialLayerNum) {
43 
44   IWelsParametersetStrategy* pParametersetStrategy = NULL;
45   switch (eSpsPpsIdStrategy) {
46   case INCREASING_ID:
47     pParametersetStrategy = WELS_NEW_OP (CWelsParametersetIdIncreasing (bSimulcastAVC, kiSpatialLayerNum),
48                                          CWelsParametersetIdIncreasing);
49     WELS_VERIFY_RETURN_IF (NULL, NULL == pParametersetStrategy)
50     break;
51   case SPS_LISTING:
52     pParametersetStrategy = WELS_NEW_OP (CWelsParametersetSpsListing (bSimulcastAVC, kiSpatialLayerNum),
53                                          CWelsParametersetSpsListing);
54     WELS_VERIFY_RETURN_IF (NULL, NULL == pParametersetStrategy)
55     break;
56   case SPS_LISTING_AND_PPS_INCREASING:
57     pParametersetStrategy = WELS_NEW_OP (CWelsParametersetSpsListingPpsIncreasing (bSimulcastAVC, kiSpatialLayerNum),
58                                          CWelsParametersetSpsListingPpsIncreasing);
59     WELS_VERIFY_RETURN_IF (NULL, NULL == pParametersetStrategy)
60     break;
61   case SPS_PPS_LISTING:
62     pParametersetStrategy = WELS_NEW_OP (CWelsParametersetSpsPpsListing (bSimulcastAVC, kiSpatialLayerNum),
63                                          CWelsParametersetSpsPpsListing);
64     WELS_VERIFY_RETURN_IF (NULL, NULL == pParametersetStrategy)
65     break;
66   case CONSTANT_ID:
67   default:
68     pParametersetStrategy = WELS_NEW_OP (CWelsParametersetIdConstant (bSimulcastAVC, kiSpatialLayerNum),
69                                          CWelsParametersetIdConstant);
70     WELS_VERIFY_RETURN_IF (NULL, NULL == pParametersetStrategy)
71     break;
72   }
73 
74   return pParametersetStrategy;
75 }
76 
77 
WelsGenerateNewSps(sWelsEncCtx * pCtx,const bool kbUseSubsetSps,const int32_t iDlayerIndex,const int32_t iDlayerCount,const int32_t kiSpsId,SWelsSPS * & pSps,SSubsetSps * & pSubsetSps,bool bSVCBaselayer)78 static int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
79                                    const int32_t iDlayerCount, const int32_t kiSpsId,
80                                    SWelsSPS*& pSps, SSubsetSps*& pSubsetSps, bool bSVCBaselayer) {
81   int32_t iRet = 0;
82 
83   if (!kbUseSubsetSps) {
84     pSps        = & (pCtx->pSpsArray[kiSpsId]);
85   } else {
86     pSubsetSps  = & (pCtx->pSubsetArray[kiSpsId]);
87     pSps        = &pSubsetSps->pSps;
88   }
89 
90   SWelsSvcCodingParam* pParam = pCtx->pSvcParam;
91   SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex];
92   // Need port pSps/pPps initialization due to spatial scalability changed
93   if (!kbUseSubsetSps) {
94     iRet = WelsInitSps (pSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
95                         pParam->iMaxNumRefFrame,
96                         kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount,
97                         bSVCBaselayer);
98   } else {
99     iRet = WelsInitSubsetSps (pSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
100                               pParam->iMaxNumRefFrame,
101                               kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount);
102   }
103   return iRet;
104 }
105 
CheckMatchedSps(SWelsSPS * const pSps1,SWelsSPS * const pSps2)106 static bool CheckMatchedSps (SWelsSPS* const pSps1, SWelsSPS* const pSps2) {
107 
108   if ((pSps1->iMbWidth != pSps2->iMbWidth)
109       || (pSps1->iMbHeight != pSps2->iMbHeight)) {
110     return false;
111   }
112 
113   if ((pSps1->uiLog2MaxFrameNum != pSps2->uiLog2MaxFrameNum)
114       || (pSps1->iLog2MaxPocLsb != pSps2->iLog2MaxPocLsb)) {
115     return false;
116   }
117 
118   if (pSps1->iNumRefFrames != pSps2->iNumRefFrames) {
119     return false;
120   }
121 
122   if ((pSps1->bFrameCroppingFlag != pSps2->bFrameCroppingFlag)
123       || (pSps1->sFrameCrop.iCropLeft != pSps2->sFrameCrop.iCropLeft)
124       || (pSps1->sFrameCrop.iCropRight != pSps2->sFrameCrop.iCropRight)
125       || (pSps1->sFrameCrop.iCropTop != pSps2->sFrameCrop.iCropTop)
126       || (pSps1->sFrameCrop.iCropBottom != pSps2->sFrameCrop.iCropBottom)
127      ) {
128     return false;
129   }
130 
131   if ((pSps1->uiProfileIdc != pSps2->uiProfileIdc)
132       || (pSps1->bConstraintSet0Flag != pSps2->bConstraintSet0Flag)
133       || (pSps1->bConstraintSet1Flag != pSps2->bConstraintSet1Flag)
134       || (pSps1->bConstraintSet2Flag != pSps2->bConstraintSet2Flag)
135       || (pSps1->bConstraintSet3Flag != pSps2->bConstraintSet3Flag)
136       || (pSps1->iLevelIdc != pSps2->iLevelIdc)) {
137     return false;
138   }
139 
140   return true;
141 }
142 
CheckMatchedSubsetSps(SSubsetSps * const pSubsetSps1,SSubsetSps * const pSubsetSps2)143 static bool CheckMatchedSubsetSps (SSubsetSps* const pSubsetSps1, SSubsetSps* const pSubsetSps2) {
144   if (!CheckMatchedSps (&pSubsetSps1->pSps, &pSubsetSps2->pSps)) {
145     return false;
146   }
147 
148   if ((pSubsetSps1->sSpsSvcExt.iExtendedSpatialScalability      != pSubsetSps2->sSpsSvcExt.iExtendedSpatialScalability)
149       || (pSubsetSps1->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag  != pSubsetSps2->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag)
150       || (pSubsetSps1->sSpsSvcExt.bSeqTcoeffLevelPredFlag != pSubsetSps2->sSpsSvcExt.bSeqTcoeffLevelPredFlag)
151       || (pSubsetSps1->sSpsSvcExt.bSliceHeaderRestrictionFlag != pSubsetSps2->sSpsSvcExt.bSliceHeaderRestrictionFlag)) {
152     return false;
153   }
154 
155   return true;
156 }
157 
158 /*!
159  * \brief   check if the current parameter can found a presenting sps
160  * \param   pParam          the current encoding paramter in SWelsSvcCodingParam
161  * \param   kbUseSubsetSps  bool
162  * \param   iDlayerIndex    int, the index of current D layer
163  * \param   iDlayerCount    int, the number of total D layer
164  * \param pSpsArray         array of all the stored SPSs
165  * \param   pSubsetArray    array of all the stored Subset-SPSs
166  * \return  0 - successful
167  *         -1 - cannot find existing SPS for current encoder parameter
168  */
FindExistingSps(SWelsSvcCodingParam * pParam,const bool kbUseSubsetSps,const int32_t iDlayerIndex,const int32_t iDlayerCount,const int32_t iSpsNumInUse,SWelsSPS * pSpsArray,SSubsetSps * pSubsetArray,bool bSVCBaseLayer)169 int32_t FindExistingSps (SWelsSvcCodingParam* pParam, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
170                          const int32_t iDlayerCount, const int32_t iSpsNumInUse,
171                          SWelsSPS* pSpsArray,
172                          SSubsetSps* pSubsetArray, bool bSVCBaseLayer) {
173   SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex];
174 
175   assert (iSpsNumInUse <= MAX_SPS_COUNT);
176   if (!kbUseSubsetSps) {
177     SWelsSPS sTmpSps;
178     WelsInitSps (&sTmpSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
179                  pParam->iMaxNumRefFrame,
180                  0, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount,
181                  bSVCBaseLayer);
182     for (int32_t iId = 0; iId < iSpsNumInUse; iId++) {
183       if (CheckMatchedSps (&sTmpSps, &pSpsArray[iId])) {
184         return iId;
185       }
186     }
187   } else {
188     SSubsetSps sTmpSubsetSps;
189     WelsInitSubsetSps (&sTmpSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
190                        pParam->iMaxNumRefFrame,
191                        0, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount);
192 
193     for (int32_t iId = 0; iId < iSpsNumInUse; iId++) {
194       if (CheckMatchedSubsetSps (&sTmpSubsetSps, &pSubsetArray[iId])) {
195         return iId;
196       }
197     }
198   }
199 
200   return INVALID_ID;
201 }
202 
CWelsParametersetIdConstant(const bool bSimulcastAVC,const int32_t kiSpatialLayerNum)203 CWelsParametersetIdConstant::CWelsParametersetIdConstant (const bool bSimulcastAVC, const int32_t kiSpatialLayerNum) {
204   memset (&m_sParaSetOffset, 0, sizeof (m_sParaSetOffset));
205 
206   m_bSimulcastAVC = bSimulcastAVC;
207   m_iSpatialLayerNum = kiSpatialLayerNum;
208 
209   m_iBasicNeededSpsNum = 1;
210   m_iBasicNeededPpsNum = (1 + m_iSpatialLayerNum);
211 }
212 
~CWelsParametersetIdConstant()213 CWelsParametersetIdConstant::~CWelsParametersetIdConstant() {
214 }
215 
GetPpsIdOffset(const int32_t iPpsId)216 int32_t CWelsParametersetIdConstant::GetPpsIdOffset (const int32_t iPpsId) {
217   return 0;
218 };
GetSpsIdOffset(const int32_t iPpsId,const int32_t iSpsId)219 int32_t CWelsParametersetIdConstant::GetSpsIdOffset (const int32_t iPpsId, const int32_t iSpsId) {
220   return 0;
221 };
222 
GetSpsIdOffsetList(const int iParasetType)223 int32_t* CWelsParametersetIdConstant::GetSpsIdOffsetList (const int iParasetType) {
224   return & (m_sParaSetOffset.sParaSetOffsetVariable[iParasetType].iParaSetIdDelta[0]);
225 }
226 
GetAllNeededParasetNum()227 uint32_t CWelsParametersetIdConstant::GetAllNeededParasetNum() {
228   return (GetNeededSpsNum()
229           + GetNeededSubsetSpsNum()
230           + GetNeededPpsNum());
231 }
232 
GetNeededSpsNum()233 uint32_t CWelsParametersetIdConstant::GetNeededSpsNum() {
234   if (0 >= m_sParaSetOffset.uiNeededSpsNum) {
235     m_sParaSetOffset.uiNeededSpsNum = m_iBasicNeededSpsNum * ((m_bSimulcastAVC) ? (m_iSpatialLayerNum) : (1));
236   }
237   return m_sParaSetOffset.uiNeededSpsNum;
238 }
239 
240 
GetNeededSubsetSpsNum()241 uint32_t CWelsParametersetIdConstant::GetNeededSubsetSpsNum() {
242   if (0 >= m_sParaSetOffset.uiNeededSubsetSpsNum) {
243     m_sParaSetOffset.uiNeededSubsetSpsNum = (m_bSimulcastAVC ? 0 : (m_iSpatialLayerNum - 1));
244   }
245   return m_sParaSetOffset.uiNeededSubsetSpsNum;
246 }
247 
GetNeededPpsNum()248 uint32_t CWelsParametersetIdConstant::GetNeededPpsNum() {
249   if (0 == m_sParaSetOffset.uiNeededPpsNum) {
250     m_sParaSetOffset.uiNeededPpsNum = m_iBasicNeededPpsNum * ((m_bSimulcastAVC) ? (m_iSpatialLayerNum) :
251                                       (1));
252   }
253   return m_sParaSetOffset.uiNeededPpsNum;
254 }
255 
LoadPrevious(SExistingParasetList * pExistingParasetList,SWelsSPS * pSpsArray,SSubsetSps * pSubsetArray,SWelsPPS * pPpsArray)256 void CWelsParametersetIdConstant::LoadPrevious (SExistingParasetList* pExistingParasetList,  SWelsSPS* pSpsArray,
257     SSubsetSps*       pSubsetArray, SWelsPPS* pPpsArray) {
258   return;
259 }
260 
Update(const uint32_t kuiId,const int iParasetType)261 void CWelsParametersetIdConstant::Update (const uint32_t kuiId, const int iParasetType) {
262   memset (&m_sParaSetOffset, 0, sizeof (SParaSetOffset));
263 }
264 
GenerateNewSps(sWelsEncCtx * pCtx,const bool kbUseSubsetSps,const int32_t iDlayerIndex,const int32_t iDlayerCount,uint32_t kuiSpsId,SWelsSPS * & pSps,SSubsetSps * & pSubsetSps,bool bSVCBaselayer)265 uint32_t CWelsParametersetIdConstant::GenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps,
266     const int32_t iDlayerIndex,
267     const int32_t iDlayerCount, uint32_t kuiSpsId,
268     SWelsSPS*& pSps, SSubsetSps*& pSubsetSps, bool bSVCBaselayer) {
269   WelsGenerateNewSps (pCtx, kbUseSubsetSps, iDlayerIndex,
270                       iDlayerCount, kuiSpsId,
271                       pSps, pSubsetSps, bSVCBaselayer);
272   return kuiSpsId;
273 }
274 
275 
InitPps(sWelsEncCtx * pCtx,uint32_t kiSpsId,SWelsSPS * pSps,SSubsetSps * pSubsetSps,uint32_t kuiPpsId,const bool kbDeblockingFilterPresentFlag,const bool kbUsingSubsetSps,const bool kbEntropyCodingModeFlag)276 uint32_t CWelsParametersetIdConstant::InitPps (sWelsEncCtx* pCtx, uint32_t kiSpsId,
277     SWelsSPS* pSps,
278     SSubsetSps* pSubsetSps,
279     uint32_t kuiPpsId,
280     const bool kbDeblockingFilterPresentFlag,
281     const bool kbUsingSubsetSps,
282     const bool kbEntropyCodingModeFlag) {
283   WelsInitPps (& pCtx->pPPSArray[kuiPpsId], pSps, pSubsetSps, kuiPpsId, true, kbUsingSubsetSps, kbEntropyCodingModeFlag);
284   SetUseSubsetFlag (kuiPpsId, kbUsingSubsetSps);
285   return kuiPpsId;
286 }
287 
SetUseSubsetFlag(const uint32_t iPpsId,const bool bUseSubsetSps)288 void CWelsParametersetIdConstant::SetUseSubsetFlag (const uint32_t iPpsId, const bool bUseSubsetSps) {
289   m_sParaSetOffset.bPpsIdMappingIntoSubsetsps[iPpsId] = bUseSubsetSps;
290 }
291 
OutputCurrentStructure(SParaSetOffsetVariable * pParaSetOffsetVariable,int32_t * pPpsIdList,sWelsEncCtx * pCtx,SExistingParasetList * pExistingParasetList)292 void CWelsParametersetIdNonConstant::OutputCurrentStructure (SParaSetOffsetVariable* pParaSetOffsetVariable,
293     int32_t* pPpsIdList, sWelsEncCtx* pCtx, SExistingParasetList* pExistingParasetList) {
294   for (int32_t k = 0; k < PARA_SET_TYPE; k++) {
295     memset ((m_sParaSetOffset.sParaSetOffsetVariable[k].bUsedParaSetIdInBs), 0, MAX_PPS_COUNT * sizeof (bool));
296   }
297   memcpy (pParaSetOffsetVariable, m_sParaSetOffset.sParaSetOffsetVariable,
298           (PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
299 }
LoadPreviousStructure(SParaSetOffsetVariable * pParaSetOffsetVariable,int32_t * pPpsIdList)300 void CWelsParametersetIdNonConstant::LoadPreviousStructure (SParaSetOffsetVariable* pParaSetOffsetVariable,
301     int32_t* pPpsIdList) {
302   memcpy (m_sParaSetOffset.sParaSetOffsetVariable, pParaSetOffsetVariable,
303           (PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
304 }
305 
306 //
307 //CWelsParametersetIdIncreasing
308 //
309 
DebugSpsPps(const int32_t kiPpsId,const int32_t kiSpsId)310 void CWelsParametersetIdIncreasing::DebugSpsPps (const int32_t kiPpsId, const int32_t kiSpsId) {
311 #if _DEBUG
312   //SParaSetOffset use, 110421
313   //if ( (INCREASING_ID & eSpsPpsIdStrategy)) {
314   const int32_t kiParameterSetType = (m_sParaSetOffset.bPpsIdMappingIntoSubsetsps[kiPpsId] ?
315                                       PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS) ;
316 
317   const int32_t kiTmpSpsIdInBs = kiSpsId +
318                                  m_sParaSetOffset.sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[kiSpsId];
319   const int32_t tmp_pps_id_in_bs = kiPpsId +
320                                    m_sParaSetOffset.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[kiPpsId];
321   assert (MAX_SPS_COUNT > kiTmpSpsIdInBs);
322   assert (MAX_PPS_COUNT > tmp_pps_id_in_bs);
323   assert (m_sParaSetOffset.sParaSetOffsetVariable[kiParameterSetType].bUsedParaSetIdInBs[kiTmpSpsIdInBs]);
324   //}
325 #endif
326 }
DebugPps(const int32_t kiPpsId)327 void CWelsParametersetIdIncreasing::DebugPps (const int32_t kiPpsId) {
328 #if _DEBUG
329   const int32_t kiTmpPpsIdInBs = kiPpsId +
330                                  m_sParaSetOffset.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[ kiPpsId ];
331   assert (MAX_PPS_COUNT > kiTmpPpsIdInBs);
332 
333   //when activated need to sure there is avialable PPS
334   assert (m_sParaSetOffset.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].bUsedParaSetIdInBs[kiTmpPpsIdInBs]);
335 #endif
336 }
337 
ParasetIdAdditionIdAdjust(SParaSetOffsetVariable * sParaSetOffsetVariable,const int32_t kiCurEncoderParaSetId,const uint32_t kuiMaxIdInBs)338 void ParasetIdAdditionIdAdjust (SParaSetOffsetVariable* sParaSetOffsetVariable,
339                                 const int32_t kiCurEncoderParaSetId,
340                                 const uint32_t kuiMaxIdInBs) { //paraset_type = 0: SPS; =1: PPS
341   //SPS_ID in avc_sps and pSubsetSps will be different using this
342   //SPS_ID case example:
343   //1st enter:  next_spsid_in_bs == 0; spsid == 0; delta==0;            //actual spsid_in_bs == 0
344   //1st finish: next_spsid_in_bs == 1;
345   //2nd enter:  next_spsid_in_bs == 1; spsid == 0; delta==1;            //actual spsid_in_bs == 1
346   //2nd finish: next_spsid_in_bs == 2;
347   //31st enter: next_spsid_in_bs == 31; spsid == 0~2; delta==31~29;     //actual spsid_in_bs == 31
348   //31st finish:next_spsid_in_bs == 0;
349   //31st enter: next_spsid_in_bs == 0; spsid == 0~2; delta==-2~0;       //actual spsid_in_bs == 0
350   //31st finish:next_spsid_in_bs == 1;
351 
352   const int32_t kiEncId = kiCurEncoderParaSetId;
353   uint32_t uiNextIdInBs = sParaSetOffsetVariable->uiNextParaSetIdToUseInBs;
354 
355   //update current layer's pCodingParam
356   sParaSetOffsetVariable->iParaSetIdDelta[kiEncId] = uiNextIdInBs -
357       kiEncId;  //for current parameter set, change its id_delta
358   //write pso pData for next update:
359   sParaSetOffsetVariable->bUsedParaSetIdInBs[uiNextIdInBs] = true; //   update current used_id
360 
361   //prepare for next update:
362   //   find the next avaibable iId
363   ++uiNextIdInBs;
364   if (uiNextIdInBs >= kuiMaxIdInBs) {
365     uiNextIdInBs = 0;//ensure the SPS_ID wound not exceed MAX_SPS_COUNT
366   }
367   //   update next_id
368   sParaSetOffsetVariable->uiNextParaSetIdToUseInBs = uiNextIdInBs;
369 }
370 
Update(const uint32_t kuiId,const int iParasetType)371 void CWelsParametersetIdIncreasing::Update (const uint32_t kuiId, const int iParasetType) {
372 #if _DEBUG
373   m_sParaSetOffset.eSpsPpsIdStrategy = INCREASING_ID;
374   assert (kuiId < MAX_DQ_LAYER_NUM);
375 #endif
376 
377   ParasetIdAdditionIdAdjust (& (m_sParaSetOffset.sParaSetOffsetVariable[iParasetType]),
378                              kuiId,
379                              (iParasetType != PARA_SET_TYPE_PPS) ? MAX_SPS_COUNT : MAX_PPS_COUNT);
380 }
381 //((SPS_PPS_LISTING != pEncCtx->pSvcParam->eSpsPpsIdStrategy) ? (&
382 //  (pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[0])) : NULL)
383 
GetPpsIdOffset(const int32_t kiPpsId)384 int32_t CWelsParametersetIdIncreasing::GetPpsIdOffset (const int32_t kiPpsId) {
385 #if _DEBUG
386   DebugPps (kiPpsId);
387 #endif
388   return (m_sParaSetOffset.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[kiPpsId]);
389 }
390 
GetSpsIdOffset(const int32_t kiPpsId,const int32_t kiSpsId)391 int32_t CWelsParametersetIdIncreasing::GetSpsIdOffset (const int32_t kiPpsId, const int32_t kiSpsId) {
392   const int32_t kiParameterSetType = (m_sParaSetOffset.bPpsIdMappingIntoSubsetsps[kiPpsId] ?
393                                       PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS);
394 #if _DEBUG
395   DebugSpsPps (kiPpsId, kiSpsId);
396 #endif
397   return (m_sParaSetOffset.sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[kiSpsId]);
398 }
399 
400 //
401 //CWelsParametersetSpsListing
402 //
403 
CWelsParametersetSpsListing(const bool bSimulcastAVC,const int32_t kiSpatialLayerNum)404 CWelsParametersetSpsListing::CWelsParametersetSpsListing (const bool bSimulcastAVC,
405     const int32_t kiSpatialLayerNum) : CWelsParametersetIdNonConstant (bSimulcastAVC, kiSpatialLayerNum) {
406   memset (&m_sParaSetOffset, 0, sizeof (m_sParaSetOffset));
407 
408   m_bSimulcastAVC = bSimulcastAVC;
409   m_iSpatialLayerNum = kiSpatialLayerNum;
410 
411   m_iBasicNeededSpsNum = MAX_SPS_COUNT;
412   m_iBasicNeededPpsNum = 1;
413 }
414 
GetNeededSubsetSpsNum()415 uint32_t CWelsParametersetSpsListing::GetNeededSubsetSpsNum() {
416   if (0 >= m_sParaSetOffset.uiNeededSubsetSpsNum) {
417     //      sPSOVector.uiNeededSubsetSpsNum = ((pSvcParam->bSimulcastAVC) ? (0) :((SPS_LISTING & pSvcParam->eSpsPpsIdStrategy) ? (MAX_SPS_COUNT) : (pSvcParam->iSpatialLayerNum - 1)));
418     m_sParaSetOffset.uiNeededSubsetSpsNum = ((m_bSimulcastAVC) ? (0) :
419                                             (MAX_SPS_COUNT));
420   }
421   return m_sParaSetOffset.uiNeededSubsetSpsNum;
422 }
423 
LoadPreviousSps(SExistingParasetList * pExistingParasetList,SWelsSPS * pSpsArray,SSubsetSps * pSubsetArray)424 void CWelsParametersetSpsListing::LoadPreviousSps (SExistingParasetList* pExistingParasetList, SWelsSPS* pSpsArray,
425     SSubsetSps*       pSubsetArray) {
426   //if ((SPS_LISTING & pParam->eSpsPpsIdStrategy) && (NULL != pExistingParasetList)) {
427   m_sParaSetOffset.uiInUseSpsNum = pExistingParasetList->uiInUseSpsNum;
428   memcpy (pSpsArray, pExistingParasetList->sSps, MAX_SPS_COUNT * sizeof (SWelsSPS));
429 
430   if (GetNeededSubsetSpsNum() > 0) {
431     m_sParaSetOffset.uiInUseSubsetSpsNum = pExistingParasetList->uiInUseSubsetSpsNum;
432     memcpy (pSubsetArray, pExistingParasetList->sSubsetSps, MAX_SPS_COUNT * sizeof (SSubsetSps));
433   } else {
434     m_sParaSetOffset.uiInUseSubsetSpsNum = 0;
435   }
436   //}
437 
438 }
LoadPrevious(SExistingParasetList * pExistingParasetList,SWelsSPS * pSpsArray,SSubsetSps * pSubsetArray,SWelsPPS * pPpsArray)439 void CWelsParametersetSpsListing::LoadPrevious (SExistingParasetList* pExistingParasetList,  SWelsSPS* pSpsArray,
440     SSubsetSps*       pSubsetArray, SWelsPPS* pPpsArray) {
441   if (NULL == pExistingParasetList) {
442     return;
443   }
444   LoadPreviousSps (pExistingParasetList, pSpsArray, pSubsetArray);
445   LoadPreviousPps (pExistingParasetList, pPpsArray);
446 }
447 
CheckParamCompatibility(SWelsSvcCodingParam * pCodingParam,SLogContext * pLogCtx)448 bool CWelsParametersetSpsListing::CheckParamCompatibility (SWelsSvcCodingParam* pCodingParam, SLogContext* pLogCtx) {
449   if (pCodingParam->iSpatialLayerNum > 1 && (!pCodingParam->bSimulcastAVC)) {
450     WelsLog (pLogCtx, WELS_LOG_WARNING,
451              "ParamValidationExt(), eSpsPpsIdStrategy setting (%d) with multiple svc SpatialLayers (%d) not supported! eSpsPpsIdStrategy adjusted to CONSTANT_ID",
452              pCodingParam->eSpsPpsIdStrategy, pCodingParam->iSpatialLayerNum);
453     pCodingParam->eSpsPpsIdStrategy = CONSTANT_ID;
454     return false;
455   }
456   return true;
457 }
458 
CheckPpsGenerating()459 bool CWelsParametersetSpsListing::CheckPpsGenerating() {
460   return true;
461 }
SpsReset(sWelsEncCtx * pCtx,bool kbUseSubsetSps)462 int32_t CWelsParametersetSpsListing::SpsReset (sWelsEncCtx* pCtx, bool kbUseSubsetSps) {
463 
464   // reset current list
465   if (!kbUseSubsetSps) {
466     m_sParaSetOffset.uiInUseSpsNum = 1;
467     memset (pCtx->pSpsArray, 0, MAX_SPS_COUNT * sizeof (SWelsSPS));
468   } else {
469     m_sParaSetOffset.uiInUseSubsetSpsNum = 1;
470     memset (pCtx->pSubsetArray, 0, MAX_SPS_COUNT * sizeof (SSubsetSps));
471   }
472 
473   //iSpsId = 0;
474   return 0;
475 }
GenerateNewSps(sWelsEncCtx * pCtx,const bool kbUseSubsetSps,const int32_t iDlayerIndex,const int32_t iDlayerCount,uint32_t kuiSpsId,SWelsSPS * & pSps,SSubsetSps * & pSubsetSps,bool bSvcBaselayer)476 uint32_t CWelsParametersetSpsListing::GenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps,
477     const int32_t iDlayerIndex,
478     const int32_t iDlayerCount, uint32_t kuiSpsId,
479     SWelsSPS*& pSps, SSubsetSps*& pSubsetSps, bool bSvcBaselayer) {
480   //check if the current param can fit in an existing SPS
481   const int32_t kiFoundSpsId = FindExistingSps (pCtx->pSvcParam, kbUseSubsetSps, iDlayerIndex, iDlayerCount,
482                                kbUseSubsetSps ? (m_sParaSetOffset.uiInUseSubsetSpsNum) : (m_sParaSetOffset.uiInUseSpsNum),
483                                pCtx->pSpsArray,
484                                pCtx->pSubsetArray, bSvcBaselayer);
485 
486 
487   if (INVALID_ID != kiFoundSpsId) {
488     //if yes, set pSps or pSubsetSps to it
489     kuiSpsId = kiFoundSpsId;
490     if (!kbUseSubsetSps) {
491       pSps = & (pCtx->pSpsArray[kiFoundSpsId]);
492     } else {
493       pSubsetSps = & (pCtx->pSubsetArray[kiFoundSpsId]);
494     }
495   } else {
496     //if no, generate a new SPS as usual
497     if (!CheckPpsGenerating()) {
498       return -1;
499     }
500 
501     kuiSpsId = (!kbUseSubsetSps) ? (m_sParaSetOffset.uiInUseSpsNum++) : (m_sParaSetOffset.uiInUseSubsetSpsNum++);
502     if (kuiSpsId >= MAX_SPS_COUNT) {
503       if (SpsReset (pCtx, kbUseSubsetSps) < 0) {
504         return -1;
505       }
506       kuiSpsId = 0;
507     }
508 
509     WelsGenerateNewSps (pCtx, kbUseSubsetSps, iDlayerIndex,
510                         iDlayerCount, kuiSpsId, pSps, pSubsetSps, bSvcBaselayer);
511   }
512   return kuiSpsId;
513 }
514 
UpdateParaSetNum(sWelsEncCtx * pCtx)515 void CWelsParametersetSpsListing::UpdateParaSetNum (sWelsEncCtx* pCtx) {
516   pCtx->iSpsNum = m_sParaSetOffset.uiInUseSpsNum;
517   pCtx->iSubsetSpsNum = m_sParaSetOffset.uiInUseSubsetSpsNum;
518 };
519 
OutputCurrentStructure(SParaSetOffsetVariable * pParaSetOffsetVariable,int32_t * pPpsIdList,sWelsEncCtx * pCtx,SExistingParasetList * pExistingParasetList)520 void CWelsParametersetSpsListing::OutputCurrentStructure (SParaSetOffsetVariable* pParaSetOffsetVariable,
521     int32_t* pPpsIdList, sWelsEncCtx* pCtx, SExistingParasetList* pExistingParasetList) {
522   CWelsParametersetIdNonConstant::OutputCurrentStructure (pParaSetOffsetVariable, pPpsIdList, pCtx, pExistingParasetList);
523   pExistingParasetList->uiInUseSpsNum = m_sParaSetOffset.uiInUseSpsNum;
524 
525   memcpy (pExistingParasetList->sSps, pCtx->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS));
526   if (NULL != pCtx->pSubsetArray) {
527     pExistingParasetList->uiInUseSubsetSpsNum = m_sParaSetOffset.uiInUseSubsetSpsNum;
528     memcpy (pExistingParasetList->sSubsetSps, pCtx->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps));
529   } else {
530     pExistingParasetList->uiInUseSubsetSpsNum = 0;
531   }
532 }
533 
534 //
535 //CWelsParametersetSpsPpsListing
536 //
537 
CWelsParametersetSpsPpsListing(const bool bSimulcastAVC,const int32_t kiSpatialLayerNum)538 CWelsParametersetSpsPpsListing::CWelsParametersetSpsPpsListing (const bool bSimulcastAVC,
539     const int32_t kiSpatialLayerNum): CWelsParametersetSpsListing (bSimulcastAVC, kiSpatialLayerNum) {
540   memset (&m_sParaSetOffset, 0, sizeof (m_sParaSetOffset));
541 
542   m_bSimulcastAVC = bSimulcastAVC;
543   m_iSpatialLayerNum = kiSpatialLayerNum;
544 
545   m_iBasicNeededSpsNum = MAX_SPS_COUNT;
546   m_iBasicNeededPpsNum = MAX_PPS_COUNT;
547 }
548 
LoadPreviousPps(SExistingParasetList * pExistingParasetList,SWelsPPS * pPpsArray)549 void CWelsParametersetSpsPpsListing::LoadPreviousPps (SExistingParasetList* pExistingParasetList, SWelsPPS* pPpsArray) {
550   // copy from existing if the pointer exists
551   //if ((SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) && (NULL != pExistingParasetList)) {
552   m_sParaSetOffset.uiInUsePpsNum = pExistingParasetList->uiInUsePpsNum;
553   memcpy (pPpsArray, pExistingParasetList->sPps, MAX_PPS_COUNT * sizeof (SWelsPPS));
554   //}
555 }
556 
557 /*  if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) {
558  UpdatePpsList (pCtx);
559  }*/
UpdatePpsList(sWelsEncCtx * pCtx)560 void CWelsParametersetSpsPpsListing::UpdatePpsList (sWelsEncCtx* pCtx) {
561   if (pCtx->iPpsNum >= MAX_PPS_COUNT) {
562     return;
563   }
564   assert (pCtx->iPpsNum <= MAX_DQ_LAYER_NUM);
565 
566   //Generate PPS LIST
567   int32_t iPpsId = 0, iUsePpsNum = pCtx->iPpsNum;
568 
569   for (int32_t iIdrRound = 0; iIdrRound < MAX_PPS_COUNT; iIdrRound++) {
570     for (iPpsId = 0; iPpsId < pCtx->iPpsNum; iPpsId++) {
571       m_sParaSetOffset.iPpsIdList[iPpsId][iIdrRound] = ((iIdrRound * iUsePpsNum + iPpsId) % MAX_PPS_COUNT);
572     }
573   }
574 
575   for (iPpsId = iUsePpsNum; iPpsId < MAX_PPS_COUNT; iPpsId++) {
576     memcpy (& (pCtx->pPPSArray[iPpsId]), & (pCtx->pPPSArray[iPpsId % iUsePpsNum]), sizeof (SWelsPPS));
577     pCtx->pPPSArray[iPpsId].iPpsId = iPpsId;
578     pCtx->iPpsNum++;
579   }
580 
581   assert (pCtx->iPpsNum == MAX_PPS_COUNT);
582   m_sParaSetOffset.uiInUsePpsNum = pCtx->iPpsNum;
583 }
584 
585 
CheckPpsGenerating()586 bool CWelsParametersetSpsPpsListing::CheckPpsGenerating() {
587   /*if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (MAX_PPS_COUNT <= pCtx->sPSOVector.uiInUsePpsNum)) {
588     //check if we can generate new SPS or not
589     WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR,
590              "InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!");
591     return ENC_RETURN_UNSUPPORTED_PARA;
592   }*/
593   if (MAX_PPS_COUNT <= m_sParaSetOffset.uiInUsePpsNum) {
594     return false;
595   }
596 
597   return true;
598 }
SpsReset(sWelsEncCtx * pCtx,bool kbUseSubsetSps)599 int32_t CWelsParametersetSpsPpsListing::SpsReset (sWelsEncCtx* pCtx, bool kbUseSubsetSps) {
600   /*        if (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) {
601    WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR,
602    "InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!");
603    return ENC_RETURN_UNSUPPORTED_PARA;
604    }*/
605   return -1;
606 }
607 
FindExistingPps(SWelsSPS * pSps,SSubsetSps * pSubsetSps,const bool kbUseSubsetSps,const int32_t iSpsId,const bool kbEntropyCodingFlag,const int32_t iPpsNumInUse,SWelsPPS * pPpsArray)608 int32_t FindExistingPps (SWelsSPS* pSps, SSubsetSps* pSubsetSps, const bool kbUseSubsetSps, const int32_t iSpsId,
609                          const bool kbEntropyCodingFlag, const int32_t iPpsNumInUse,
610                          SWelsPPS* pPpsArray) {
611 #if !defined(DISABLE_FMO_FEATURE)
612   // feature not supported yet
613   return INVALID_ID;
614 #endif//!DISABLE_FMO_FEATURE
615 
616   SWelsPPS sTmpPps;
617   WelsInitPps (&sTmpPps,
618                pSps,
619                pSubsetSps,
620                0,
621                true,
622                kbUseSubsetSps,
623                kbEntropyCodingFlag);
624 
625   assert (iPpsNumInUse <= MAX_PPS_COUNT);
626   for (int32_t iId = 0; iId < iPpsNumInUse; iId++) {
627     if ((sTmpPps.iSpsId == pPpsArray[iId].iSpsId)
628         && (sTmpPps.bEntropyCodingModeFlag == pPpsArray[iId].bEntropyCodingModeFlag)
629         && (sTmpPps.iPicInitQp == pPpsArray[iId].iPicInitQp)
630         && (sTmpPps.iPicInitQs == pPpsArray[iId].iPicInitQs)
631         && (sTmpPps.uiChromaQpIndexOffset == pPpsArray[iId].uiChromaQpIndexOffset)
632         && (sTmpPps.bDeblockingFilterControlPresentFlag == pPpsArray[iId].bDeblockingFilterControlPresentFlag)
633        ) {
634       return iId;
635     }
636   }
637 
638   return INVALID_ID;
639 }
640 
InitPps(sWelsEncCtx * pCtx,uint32_t kiSpsId,SWelsSPS * pSps,SSubsetSps * pSubsetSps,uint32_t kuiPpsId,const bool kbDeblockingFilterPresentFlag,const bool kbUsingSubsetSps,const bool kbEntropyCodingModeFlag)641 uint32_t CWelsParametersetSpsPpsListing::InitPps (sWelsEncCtx* pCtx, uint32_t kiSpsId,
642     SWelsSPS* pSps,
643     SSubsetSps* pSubsetSps,
644     uint32_t kuiPpsId,
645     const bool kbDeblockingFilterPresentFlag,
646     const bool kbUsingSubsetSps,
647     const bool kbEntropyCodingModeFlag) {
648   const int32_t kiFoundPpsId = FindExistingPps (pSps, pSubsetSps, kbUsingSubsetSps, kiSpsId,
649                                kbEntropyCodingModeFlag,
650                                m_sParaSetOffset.uiInUsePpsNum,
651                                pCtx->pPPSArray);
652 
653 
654   if (INVALID_ID != kiFoundPpsId) {
655     //if yes, set pPps to it
656     kuiPpsId = kiFoundPpsId;
657   } else {
658     kuiPpsId = (m_sParaSetOffset.uiInUsePpsNum++);
659     WelsInitPps (& pCtx->pPPSArray[kuiPpsId], pSps, pSubsetSps, kuiPpsId, true, kbUsingSubsetSps, kbEntropyCodingModeFlag);
660   }
661   SetUseSubsetFlag (kuiPpsId, kbUsingSubsetSps);
662   return kuiPpsId;
663 }
664 
UpdateParaSetNum(sWelsEncCtx * pCtx)665 void CWelsParametersetSpsPpsListing::UpdateParaSetNum (sWelsEncCtx* pCtx) {
666   CWelsParametersetSpsListing::UpdateParaSetNum (pCtx);
667 
668   //UpdatePpsList (pCtx);
669   pCtx->iPpsNum = m_sParaSetOffset.uiInUsePpsNum;
670 }
671 
GetCurrentPpsId(const int32_t iPpsId,const int32_t iIdrLoop)672 int32_t CWelsParametersetSpsPpsListing::GetCurrentPpsId (const int32_t iPpsId, const int32_t iIdrLoop) {
673   return m_sParaSetOffset.iPpsIdList[iPpsId][iIdrLoop];
674 }
675 
LoadPreviousStructure(SParaSetOffsetVariable * pParaSetOffsetVariable,int32_t * pPpsIdList)676 void CWelsParametersetSpsPpsListing::LoadPreviousStructure (SParaSetOffsetVariable* pParaSetOffsetVariable,
677     int32_t* pPpsIdList) {
678   memcpy (m_sParaSetOffset.sParaSetOffsetVariable, pParaSetOffsetVariable,
679           (PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
680 
681   memcpy ((m_sParaSetOffset.iPpsIdList), pPpsIdList, MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t));
682 
683 }
684 
OutputCurrentStructure(SParaSetOffsetVariable * pParaSetOffsetVariable,int32_t * pPpsIdList,sWelsEncCtx * pCtx,SExistingParasetList * pExistingParasetList)685 void CWelsParametersetSpsPpsListing::OutputCurrentStructure (SParaSetOffsetVariable* pParaSetOffsetVariable,
686     int32_t* pPpsIdList, sWelsEncCtx* pCtx, SExistingParasetList* pExistingParasetList) {
687   CWelsParametersetSpsListing::OutputCurrentStructure (pParaSetOffsetVariable, pPpsIdList, pCtx, pExistingParasetList);
688 
689   pExistingParasetList->uiInUsePpsNum = m_sParaSetOffset.uiInUsePpsNum;
690   memcpy (pExistingParasetList->sPps, pCtx->pPps, MAX_PPS_COUNT * sizeof (SWelsPPS));
691   memcpy (pPpsIdList, (m_sParaSetOffset.iPpsIdList), MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t));
692 }
693 
694 //
695 //CWelsParametersetSpsListingPpsIncreasing
696 //
697 
GetPpsIdOffset(const int32_t kiPpsId)698 int32_t CWelsParametersetSpsListingPpsIncreasing::GetPpsIdOffset (const int32_t kiPpsId) {
699   //same as CWelsParametersetIdIncreasing::GetPpsIdOffset
700   return (m_sParaSetOffset.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[kiPpsId]);
701 }
702 
Update(const uint32_t kuiId,const int iParasetType)703 void CWelsParametersetSpsListingPpsIncreasing::Update (const uint32_t kuiId, const int iParasetType) {
704   //same as CWelsParametersetIdIncreasing::Update
705 #if _DEBUG
706   assert (kuiId < MAX_DQ_LAYER_NUM);
707 #endif
708 
709   ParasetIdAdditionIdAdjust (& (m_sParaSetOffset.sParaSetOffsetVariable[iParasetType]),
710                              kuiId,
711                              (iParasetType != PARA_SET_TYPE_PPS) ? MAX_SPS_COUNT : MAX_PPS_COUNT);
712 }
713 }
714