• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*!
2  * \copy
3  *     Copyright (c)  2009-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  * \file    param_svc.h
33  *
34  * \brief   Configurable parameters in H.264/SVC Encoder
35  *
36  * \date    4/20/2009 Created
37  *
38  *************************************************************************************
39  */
40 #if !defined(WELS_ENCODER_PARAMETER_SVC_H__)
41 #define WELS_ENCODER_PARAMETER_SVC_H__
42 
43 #include <string.h>
44 #include <math.h>
45 #include "typedefs.h"
46 #include "codec_def.h"
47 #include "macros.h"
48 #include "wels_const.h"
49 #include "rc.h"
50 #include "svc_enc_slice_segment.h"
51 #include "as264_common.h"
52 
53 namespace WelsEnc {
54 
55 #define   INVALID_TEMPORAL_ID   ((uint8_t)0xff)
56 
57 extern const uint8_t   g_kuiTemporalIdListTable[MAX_TEMPORAL_LEVEL][MAX_GOP_SIZE + 1];
58 
59 /*!
60 * \brief    get Logarithms base 2 of (upper/base)
61 * \param    base    based scaler
62 * \param    upper   input upper value
63 * \return   2 based scaling factor
64 */
GetLogFactor(float base,float upper)65 static inline uint32_t GetLogFactor (float base, float upper) {
66 #if defined(_M_X64) && _MSC_VER == 1800
67   _set_FMA3_enable(0);
68 #endif
69   const double dLog2factor      = log10 (1.0 * upper / base) / log10 (2.0);
70   const double dEpsilon         = 0.0001;
71   const double dRound           = floor (dLog2factor + 0.5);
72 
73   if (dLog2factor < dRound + dEpsilon && dRound < dLog2factor + dEpsilon) {
74     return (uint32_t) (dRound);
75   }
76   return UINT_MAX;
77 }
78 
79 /*
80  *  Dependency Layer Parameter
81  */
82 typedef struct TagDLayerParam {
83   int32_t       iActualWidth;                   // input source picture actual width
84   int32_t       iActualHeight;                  // input source picture actual height
85   int32_t       iTemporalResolution;
86   int32_t       iDecompositionStages;
87   uint8_t       uiCodingIdx2TemporalId[ (1 << MAX_TEMPORAL_LEVEL) + 1];
88 
89   int8_t        iHighestTemporalId;
90   float         fInputFrameRate;                // input frame rate
91   float         fOutputFrameRate;               // output frame rate
92   uint16_t          uiIdrPicId;           // IDR picture id: [0, 65535], this one is used for LTR
93   int32_t           iCodingIndex;
94   int32_t           iFrameIndex;            // count how many frames elapsed during coding context currently
95   bool              bEncCurFrmAsIdrFlag;
96   int32_t           iFrameNum;              // current frame number coding
97   int32_t           iPOC;                   // frame iPOC
98 #ifdef ENABLE_FRAME_DUMP
99   char          sRecFileName[MAX_FNAME_LEN];    // file to be constructed
100 #endif//ENABLE_FRAME_DUMP
101 } SSpatialLayerInternal;
102 
103 /*
104  *  Cisco OpenH264 Encoder Parameter Configuration
105  */
106 typedef struct TagWelsSvcCodingParam: SEncParamExt {
107   SSpatialLayerInternal sDependencyLayers[MAX_DEPENDENCY_LAYER];
108 
109   /* General */
110   uint32_t uiGopSize;                      // GOP size (at maximal frame rate: 16)
111   struct {
112     int32_t iLeft;
113     int32_t iTop;
114     int32_t iWidth;
115     int32_t iHeight;
116   } SUsedPicRect;       // the rect in input picture that encoder actually used
117 
118   char*       pCurPath; // record current lib path such as:/pData/pData/com.wels.enc/lib/
119 
120   bool      bDeblockingParallelFlag;        // deblocking filter parallelization control flag
121   int32_t   iBitsVaryPercentage;
122 
123   int8_t   iDecompStages;          // GOP size dependency
124   int32_t  iMaxNumRefFrame;
125 
126  public:
TagWelsSvcCodingParamTagWelsSvcCodingParam127   TagWelsSvcCodingParam() {
128     FillDefault();
129   }
~TagWelsSvcCodingParamTagWelsSvcCodingParam130   ~TagWelsSvcCodingParam() {}
131 
FillDefaultTagWelsSvcCodingParam132   static void FillDefault (SEncParamExt& param) {
133     memset (&param, 0, sizeof (param));
134     param.uiIntraPeriod         = 0;                    // intra period (multiple of GOP size as desired)
135     param.iNumRefFrame          = AUTO_REF_PIC_COUNT;// number of reference frame used
136 
137     param.iPicWidth             = 0;    //   actual input picture width
138     param.iPicHeight            = 0;    //   actual input picture height
139 
140     param.fMaxFrameRate         = MAX_FRAME_RATE;       // maximal frame rate [Hz / fps]
141 
142     param.iComplexityMode       = LOW_COMPLEXITY;
143     param.iTargetBitrate        = UNSPECIFIED_BIT_RATE; // overall target bitrate introduced in RC module
144     param.iMaxBitrate           = UNSPECIFIED_BIT_RATE;
145     param.iMultipleThreadIdc    = 1;
146     param.bUseLoadBalancing = true;
147 
148     param.iLTRRefNum            = 0;
149     param.iLtrMarkPeriod        = 30;   //the min distance of two int32_t references
150 
151     param.bEnableSSEI           = false;
152     param.bSimulcastAVC         = false;
153     param.bEnableFrameCroppingFlag = true; // enable frame cropping flag: true alwayse in application
154     // false: Streaming Video Sharing; true: Video Conferencing Meeting;
155 
156     /* Deblocking loop filter */
157     param.iLoopFilterDisableIdc         = 0;    // 0: on, 1: off, 2: on except for slice boundaries
158     param.iLoopFilterAlphaC0Offset      = 0;    // AlphaOffset: valid range [-6, 6], default 0
159     param.iLoopFilterBetaOffset         = 0;    // BetaOffset:  valid range [-6, 6], default 0
160 
161     /* Rate Control */
162     param.iRCMode                       = RC_QUALITY_MODE;
163     param.iPaddingFlag                  = 0;
164     param.iEntropyCodingModeFlag        = 0;
165     param.bEnableDenoise                = false;        // denoise control
166     param.bEnableSceneChangeDetect      = true;         // scene change detection control
167     param.bEnableBackgroundDetection    = true;         // background detection control
168     param.bEnableAdaptiveQuant          = true;         // adaptive quantization control
169     param.bEnableFrameSkip              = true;         // frame skipping
170     param.bEnableLongTermReference      = false;        // long term reference control
171     param.eSpsPpsIdStrategy             = INCREASING_ID;// pSps pPps id addition control
172     param.bPrefixNalAddingCtrl          = false;        // prefix NAL adding control
173     param.iSpatialLayerNum              = 1;            // number of dependency(Spatial/CGS) layers used to be encoded
174     param.iTemporalLayerNum             = 1;            // number of temporal layer specified
175 
176     param.iMaxQp = QP_MAX_VALUE;
177     param.iMinQp = QP_MIN_VALUE;
178     param.iUsageType = CAMERA_VIDEO_REAL_TIME;
179     param.uiMaxNalSize = 0;
180     param.bIsLosslessLink = false;
181     param.bFixRCOverShoot = true;
182     param.iIdrBitrateRatio = IDR_BITRATE_RATIO * 100;
183     for (int32_t iLayer = 0; iLayer < MAX_SPATIAL_LAYER_NUM; iLayer++) {
184       param.sSpatialLayers[iLayer].uiProfileIdc = PRO_UNKNOWN;
185       param.sSpatialLayers[iLayer].uiLevelIdc = LEVEL_UNKNOWN;
186       param.sSpatialLayers[iLayer].iDLayerQp = SVC_QUALITY_BASE_QP;
187       param.sSpatialLayers[iLayer].fFrameRate = param.fMaxFrameRate;
188 
189       param.sSpatialLayers[iLayer].iMaxSpatialBitrate = UNSPECIFIED_BIT_RATE;
190 
191       param.sSpatialLayers[iLayer].sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;
192       param.sSpatialLayers[iLayer].sSliceArgument.uiSliceNum = 0; //AUTO, using number of CPU cores
193       param.sSpatialLayers[iLayer].sSliceArgument.uiSliceSizeConstraint = 1500;
194 
195       param.sSpatialLayers[iLayer].bAspectRatioPresent = false; // do not write any of the following information to the header
196       param.sSpatialLayers[iLayer].eAspectRatio = ASP_UNSPECIFIED;
197       param.sSpatialLayers[iLayer].sAspectRatioExtWidth = 0;
198       param.sSpatialLayers[iLayer].sAspectRatioExtHeight = 0;
199 
200       const int32_t kiLesserSliceNum = ((MAX_SLICES_NUM < MAX_SLICES_NUM_TMP) ? MAX_SLICES_NUM : MAX_SLICES_NUM_TMP);
201       for (int32_t idx = 0; idx < kiLesserSliceNum; idx++)
202         param.sSpatialLayers[iLayer].sSliceArgument.uiSliceMbNum[idx] = 0; //default, using one row a slice if uiSliceMode is SM_RASTER_MODE
203 
204       // See codec_app_def.h for more info about members bVideoSignalTypePresent through uiColorMatrix.  The default values
205       // used below preserve the previous behavior; i.e., no additional information will be written to the output file.
206       param.sSpatialLayers[iLayer].bVideoSignalTypePresent = false;			// do not write any of the following information to the header
207       param.sSpatialLayers[iLayer].uiVideoFormat = VF_UNDEF;				// undefined
208       param.sSpatialLayers[iLayer].bFullRange = false;						// analog video data range [16, 235]
209       param.sSpatialLayers[iLayer].bColorDescriptionPresent = false;		// do not write any of the following three items to the header
210       param.sSpatialLayers[iLayer].uiColorPrimaries = CP_UNDEF;				// undefined
211       param.sSpatialLayers[iLayer].uiTransferCharacteristics = TRC_UNDEF;	// undefined
212       param.sSpatialLayers[iLayer].uiColorMatrix = CM_UNDEF;				// undefined
213     }
214   }
215 
FillDefaultTagWelsSvcCodingParam216   void FillDefault() {
217     FillDefault (*this);
218     uiGopSize = 1;                      // GOP size (at maximal frame rate: 16)
219     iMaxNumRefFrame = AUTO_REF_PIC_COUNT;
220     SUsedPicRect.iLeft =
221       SUsedPicRect.iTop =
222         SUsedPicRect.iWidth =
223           SUsedPicRect.iHeight = 0;     // the rect in input picture that encoder actually used
224 
225     pCurPath                    = NULL; // record current lib path such as:/pData/pData/com.wels.enc/lib/
226 
227     bDeblockingParallelFlag     = false;// deblocking filter parallelization control flag
228 
229     iDecompStages               = 0;    // GOP size dependency, unknown here and be revised later
230     iBitsVaryPercentage = 10;
231   }
232 
ParamBaseTranscodeTagWelsSvcCodingParam233   int32_t ParamBaseTranscode (const SEncParamBase& pCodingParam) {
234 
235     fMaxFrameRate  = WELS_CLIP3 (pCodingParam.fMaxFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
236     iTargetBitrate = pCodingParam.iTargetBitrate;
237     iUsageType  = pCodingParam.iUsageType;
238     iPicWidth   = pCodingParam.iPicWidth;
239     iPicHeight  = pCodingParam.iPicHeight;
240 
241     SUsedPicRect.iLeft = 0;
242     SUsedPicRect.iTop  = 0;
243     SUsedPicRect.iWidth = ((iPicWidth >> 1) * (1 << 1));
244     SUsedPicRect.iHeight = ((iPicHeight >> 1) * (1 << 1));
245 
246     iRCMode = pCodingParam.iRCMode;    // rc mode
247 
248     int8_t iIdxSpatial = 0;
249     EProfileIdc uiProfileIdc = PRO_UNKNOWN;
250     if (iEntropyCodingModeFlag)
251       uiProfileIdc = PRO_MAIN;
252     SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
253 
254     while (iIdxSpatial < iSpatialLayerNum) {
255 
256       sSpatialLayers->uiProfileIdc              = uiProfileIdc;
257       sSpatialLayers->uiLevelIdc                = LEVEL_UNKNOWN;
258       sSpatialLayers[iIdxSpatial].fFrameRate    = WELS_CLIP3 (pCodingParam.fMaxFrameRate,
259           MIN_FRAME_RATE, MAX_FRAME_RATE);
260       pDlp->fInputFrameRate =
261         pDlp->fOutputFrameRate = WELS_CLIP3 (sSpatialLayers[iIdxSpatial].fFrameRate, MIN_FRAME_RATE,
262                                              MAX_FRAME_RATE);
263 #ifdef ENABLE_FRAME_DUMP
264       pDlp->sRecFileName[0] = '\0'; // file to be constructed
265 #endif//ENABLE_FRAME_DUMP
266       pDlp->iActualWidth = sSpatialLayers[iIdxSpatial].iVideoWidth = iPicWidth;
267       pDlp->iActualHeight = sSpatialLayers[iIdxSpatial].iVideoHeight = iPicHeight;
268 
269       sSpatialLayers->iSpatialBitrate =
270         sSpatialLayers[iIdxSpatial].iSpatialBitrate = pCodingParam.iTargetBitrate; // target bitrate for current spatial layer
271 
272       sSpatialLayers->iMaxSpatialBitrate = UNSPECIFIED_BIT_RATE;
273       sSpatialLayers->iDLayerQp = SVC_QUALITY_BASE_QP;
274 
275       uiProfileIdc = (!bSimulcastAVC) ? PRO_SCALABLE_BASELINE : uiProfileIdc;
276       ++ pDlp;
277       ++ iIdxSpatial;
278     }
279     SetActualPicResolution();
280 
281     return 0;
282   }
GetBaseParamsTagWelsSvcCodingParam283   void GetBaseParams (SEncParamBase* pCodingParam) {
284     pCodingParam->iUsageType     = iUsageType;
285     pCodingParam->iPicWidth      = iPicWidth;
286     pCodingParam->iPicHeight     = iPicHeight;
287     pCodingParam->iTargetBitrate = iTargetBitrate;
288     pCodingParam->iRCMode        = iRCMode;
289     pCodingParam->fMaxFrameRate  = fMaxFrameRate;
290   }
ParamTranscodeTagWelsSvcCodingParam291   int32_t ParamTranscode (const SEncParamExt& pCodingParam) {
292     float fParamMaxFrameRate = WELS_CLIP3 (pCodingParam.fMaxFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
293     iUsageType = pCodingParam.iUsageType;
294     iPicWidth   = pCodingParam.iPicWidth;
295     iPicHeight  = pCodingParam.iPicHeight;
296     fMaxFrameRate = fParamMaxFrameRate;
297     iComplexityMode = pCodingParam.iComplexityMode;
298 
299     SUsedPicRect.iLeft = 0;
300     SUsedPicRect.iTop  = 0;
301     SUsedPicRect.iWidth = ((iPicWidth >> 1) << 1);
302     SUsedPicRect.iHeight = ((iPicHeight >> 1) << 1);
303 
304     iMultipleThreadIdc = pCodingParam.iMultipleThreadIdc;
305     bUseLoadBalancing = pCodingParam.bUseLoadBalancing;
306 
307     /* Deblocking loop filter */
308     iLoopFilterDisableIdc       = pCodingParam.iLoopFilterDisableIdc;      // 0: on, 1: off, 2: on except for slice boundaries,
309     iLoopFilterAlphaC0Offset    = pCodingParam.iLoopFilterAlphaC0Offset;   // AlphaOffset: valid range [-6, 6], default 0
310     iLoopFilterBetaOffset       = pCodingParam.iLoopFilterBetaOffset;      // BetaOffset:  valid range [-6, 6], default 0
311     iEntropyCodingModeFlag      = pCodingParam.iEntropyCodingModeFlag;
312     bEnableFrameCroppingFlag    = pCodingParam.bEnableFrameCroppingFlag;
313 
314     /* Rate Control */
315     iRCMode = pCodingParam.iRCMode;    // rc mode
316     bSimulcastAVC = pCodingParam.bSimulcastAVC;
317     iPaddingFlag = pCodingParam.iPaddingFlag;
318 
319     iTargetBitrate      = pCodingParam.iTargetBitrate;  // target bitrate
320     iMaxBitrate         = pCodingParam.iMaxBitrate;
321     if ((iMaxBitrate != UNSPECIFIED_BIT_RATE) && (iMaxBitrate < iTargetBitrate)) {
322       iMaxBitrate  = iTargetBitrate;
323     }
324     iMaxQp = pCodingParam.iMaxQp;
325     iMinQp = pCodingParam.iMinQp;
326     uiMaxNalSize          = pCodingParam.uiMaxNalSize;
327     /* Denoise Control */
328     bEnableDenoise = pCodingParam.bEnableDenoise ? true : false;    // Denoise Control  // only support 0 or 1 now
329 
330     /* Scene change detection control */
331     bEnableSceneChangeDetect   = pCodingParam.bEnableSceneChangeDetect;
332 
333     /* Background detection Control */
334     bEnableBackgroundDetection = pCodingParam.bEnableBackgroundDetection ? true : false;
335 
336     /* Adaptive quantization control */
337     bEnableAdaptiveQuant       = pCodingParam.bEnableAdaptiveQuant ? true : false;
338 
339     /* Frame skipping */
340     bEnableFrameSkip           = pCodingParam.bEnableFrameSkip ? true : false;
341 
342     /* Enable int32_t term reference */
343     bEnableLongTermReference   = pCodingParam.bEnableLongTermReference ? true : false;
344     iLtrMarkPeriod = pCodingParam.iLtrMarkPeriod;
345     bIsLosslessLink = pCodingParam.bIsLosslessLink;
346     bFixRCOverShoot = pCodingParam.bFixRCOverShoot;
347     iIdrBitrateRatio = pCodingParam.iIdrBitrateRatio;
348     if (iUsageType == SCREEN_CONTENT_REAL_TIME && !bIsLosslessLink && bEnableLongTermReference) {
349       bEnableLongTermReference = false;
350     }
351 
352     /* For ssei information */
353     bEnableSSEI         = pCodingParam.bEnableSSEI;
354     bSimulcastAVC       = pCodingParam.bSimulcastAVC;
355 
356     /* Layer definition */
357     iSpatialLayerNum = (int8_t)WELS_CLIP3 (pCodingParam.iSpatialLayerNum, 1,
358                                             MAX_DEPENDENCY_LAYER); // number of dependency(Spatial/CGS) layers used to be encoded
359     iTemporalLayerNum = (int8_t)WELS_CLIP3 (pCodingParam.iTemporalLayerNum, 1,
360                           MAX_TEMPORAL_LEVEL); // number of temporal layer specified
361 
362     uiGopSize           = 1 << (iTemporalLayerNum - 1); // Override GOP size based temporal layer
363     iDecompStages       = iTemporalLayerNum - 1;        // WELS_LOG2( uiGopSize );// GOP size dependency
364     uiIntraPeriod       = pCodingParam.uiIntraPeriod;// intra period (multiple of GOP size as desired)
365     if (uiIntraPeriod == (uint32_t) (-1))
366       uiIntraPeriod = 0;
367     else if (uiIntraPeriod & (uiGopSize - 1)) // none multiple of GOP size
368       uiIntraPeriod = ((uiIntraPeriod + uiGopSize - 1) / uiGopSize) * uiGopSize;
369 
370     if (((pCodingParam.iNumRefFrame != AUTO_REF_PIC_COUNT)
371          && !((pCodingParam.iNumRefFrame > MAX_REF_PIC_COUNT) || (pCodingParam.iNumRefFrame < MIN_REF_PIC_COUNT)))
372         || ((iNumRefFrame != AUTO_REF_PIC_COUNT) && (pCodingParam.iNumRefFrame == AUTO_REF_PIC_COUNT))) {
373       iNumRefFrame  = pCodingParam.iNumRefFrame;
374     }
375     if ((iNumRefFrame != AUTO_REF_PIC_COUNT) && (iNumRefFrame > iMaxNumRefFrame)) {
376       iMaxNumRefFrame = iNumRefFrame;
377     }
378     iLTRRefNum  = (pCodingParam.bEnableLongTermReference ? pCodingParam.iLTRRefNum : 0);
379     iLtrMarkPeriod  = pCodingParam.iLtrMarkPeriod;
380 
381     bPrefixNalAddingCtrl = pCodingParam.bPrefixNalAddingCtrl;
382 
383     if ( (CONSTANT_ID == pCodingParam.eSpsPpsIdStrategy)
384         || (INCREASING_ID == pCodingParam.eSpsPpsIdStrategy)
385         || (SPS_LISTING == pCodingParam.eSpsPpsIdStrategy)
386         || (SPS_LISTING_AND_PPS_INCREASING == pCodingParam.eSpsPpsIdStrategy)
387         || (SPS_PPS_LISTING == pCodingParam.eSpsPpsIdStrategy)) {
388     eSpsPpsIdStrategy =
389       pCodingParam.eSpsPpsIdStrategy;//For SVC meeting application, to avoid mosaic issue caused by cross-IDR reference.
390     //SHOULD enable this feature.
391     } else {
392       // keep the default value
393     }
394 
395     SSpatialLayerInternal* pDlp        = &sDependencyLayers[0];
396     SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
397     EProfileIdc uiProfileIdc           = iEntropyCodingModeFlag ? PRO_HIGH : PRO_BASELINE;
398     int8_t iIdxSpatial  = 0;
399     while (iIdxSpatial < iSpatialLayerNum) {
400       pSpatialLayer->uiProfileIdc      = (pCodingParam.sSpatialLayers[iIdxSpatial].uiProfileIdc == PRO_UNKNOWN) ? uiProfileIdc :
401                                       pCodingParam.sSpatialLayers[iIdxSpatial].uiProfileIdc;
402       pSpatialLayer->uiLevelIdc        = pCodingParam.sSpatialLayers[iIdxSpatial].uiLevelIdc;
403 
404       float fLayerFrameRate     = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].fFrameRate,
405                                           MIN_FRAME_RATE, fParamMaxFrameRate);
406       pDlp->fInputFrameRate     = fParamMaxFrameRate;
407       pSpatialLayer->fFrameRate =
408         pDlp->fOutputFrameRate  = WELS_CLIP3 (fLayerFrameRate, MIN_FRAME_RATE, fParamMaxFrameRate);
409 
410 #ifdef ENABLE_FRAME_DUMP
411       pDlp->sRecFileName[0]     = '\0'; // file to be constructed
412 #endif//ENABLE_FRAME_DUMP
413       pSpatialLayer->iVideoWidth = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoWidth, 0,
414                                    iPicWidth);  // frame width
415       pSpatialLayer->iVideoHeight = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoHeight, 0,
416                                     iPicHeight);// frame height
417 
418       pSpatialLayer->iSpatialBitrate    =
419         pCodingParam.sSpatialLayers[iIdxSpatial].iSpatialBitrate;       // target bitrate for current spatial layer
420       pSpatialLayer->iMaxSpatialBitrate =
421         pCodingParam.sSpatialLayers[iIdxSpatial].iMaxSpatialBitrate;
422 
423       if ((iSpatialLayerNum==1) && (iIdxSpatial==0)) {
424         if (pSpatialLayer->iVideoWidth == 0) {
425           pSpatialLayer->iVideoWidth = iPicWidth;
426         }
427         if (pSpatialLayer->iVideoHeight == 0) {
428           pSpatialLayer->iVideoHeight = iPicHeight;
429         }
430         if (pSpatialLayer->iSpatialBitrate == 0) {
431           pSpatialLayer->iSpatialBitrate = iTargetBitrate;
432         }
433         if (pSpatialLayer->iMaxSpatialBitrate == 0) {
434           pSpatialLayer->iMaxSpatialBitrate = iMaxBitrate;
435         }
436       }
437 
438       //multi slice
439       pSpatialLayer->sSliceArgument = pCodingParam.sSpatialLayers[iIdxSpatial].sSliceArgument;
440 
441       memcpy (&(pSpatialLayer->sSliceArgument),
442               &(pCodingParam.sSpatialLayers[iIdxSpatial].sSliceArgument), // confirmed_safe_unsafe_usage
443               sizeof (SSliceArgument)) ;
444 
445       pSpatialLayer->iDLayerQp = pCodingParam.sSpatialLayers[iIdxSpatial].iDLayerQp;
446 
447       // See codec_app_def.h and parameter_sets.h for more info about members bVideoSignalTypePresent through uiColorMatrix.
448       pSpatialLayer->bVideoSignalTypePresent =   pCodingParam.sSpatialLayers[iIdxSpatial].bVideoSignalTypePresent;
449       pSpatialLayer->uiVideoFormat =             pCodingParam.sSpatialLayers[iIdxSpatial].uiVideoFormat;
450       pSpatialLayer->bFullRange =                pCodingParam.sSpatialLayers[iIdxSpatial].bFullRange;
451       pSpatialLayer->bColorDescriptionPresent =  pCodingParam.sSpatialLayers[iIdxSpatial].bColorDescriptionPresent;
452       pSpatialLayer->uiColorPrimaries =          pCodingParam.sSpatialLayers[iIdxSpatial].uiColorPrimaries;
453       pSpatialLayer->uiTransferCharacteristics = pCodingParam.sSpatialLayers[iIdxSpatial].uiTransferCharacteristics;
454       pSpatialLayer->uiColorMatrix =             pCodingParam.sSpatialLayers[iIdxSpatial].uiColorMatrix;
455 
456       pSpatialLayer->bAspectRatioPresent = pCodingParam.sSpatialLayers[iIdxSpatial].bAspectRatioPresent;
457       pSpatialLayer->eAspectRatio = pCodingParam.sSpatialLayers[iIdxSpatial].eAspectRatio;
458       pSpatialLayer->sAspectRatioExtWidth = pCodingParam.sSpatialLayers[iIdxSpatial].sAspectRatioExtWidth;
459       pSpatialLayer->sAspectRatioExtHeight = pCodingParam.sSpatialLayers[iIdxSpatial].sAspectRatioExtHeight;
460 
461       uiProfileIdc = (!bSimulcastAVC) ? PRO_SCALABLE_BASELINE : uiProfileIdc; //it is used in the D>0 layer if SVC is applied, so set to PRO_SCALABLE_BASELINE
462       ++ pDlp;
463       ++ pSpatialLayer;
464       ++ iIdxSpatial;
465     }
466 
467     SetActualPicResolution();
468 
469     return 0;
470   }
471 
472 // assuming that the width/height ratio of all spatial layers are the same
473 
SetActualPicResolutionTagWelsSvcCodingParam474   void SetActualPicResolution() {
475     int32_t iSpatialIdx = iSpatialLayerNum - 1;
476     for (; iSpatialIdx >= 0; iSpatialIdx --) {
477       SSpatialLayerInternal* pDlayerInternal = &sDependencyLayers[iSpatialIdx];
478       SSpatialLayerConfig* pDlayer =  &sSpatialLayers[iSpatialIdx];
479 
480       pDlayerInternal->iActualWidth = pDlayer->iVideoWidth;
481       pDlayerInternal->iActualHeight = pDlayer->iVideoHeight;
482       pDlayer->iVideoWidth = WELS_ALIGN (pDlayerInternal->iActualWidth, MB_WIDTH_LUMA);
483       pDlayer->iVideoHeight = WELS_ALIGN (pDlayerInternal->iActualHeight, MB_HEIGHT_LUMA);
484     }
485   }
486 
487   /*!
488   * \brief  determined key coding tables for temporal scalability, uiProfileIdc etc for each spatial layer settings
489   * \param  SWelsSvcCodingParam, and carried with known GOP size, max, input and output frame rate of each spatial
490   * \return NONE (should ensure valid parameter before this procedure)
491   */
DetermineTemporalSettingsTagWelsSvcCodingParam492   int32_t DetermineTemporalSettings() {
493     const int32_t iDecStages = WELS_LOG2 (uiGopSize); // (int8_t)GetLogFactor(1.0f, 1.0f * pcfg->uiGopSize);  //log2(uiGopSize)
494     const uint8_t* pTemporalIdList = &g_kuiTemporalIdListTable[iDecStages][0];
495     SSpatialLayerInternal* pDlp    = &sDependencyLayers[0];
496     SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
497     int8_t i = 0;
498 
499     while (i < iSpatialLayerNum) {
500       const uint32_t kuiLogFactorInOutRate = GetLogFactor (pDlp->fOutputFrameRate, pDlp->fInputFrameRate);
501       const uint32_t kuiLogFactorMaxInRate = GetLogFactor (pDlp->fInputFrameRate, fMaxFrameRate);
502       if (UINT_MAX == kuiLogFactorInOutRate || UINT_MAX == kuiLogFactorMaxInRate) {
503         return ENC_RETURN_INVALIDINPUT;
504       }
505       int32_t iNotCodedMask = 0;
506       int8_t iMaxTemporalId = 0;
507 
508       memset (pDlp->uiCodingIdx2TemporalId, INVALID_TEMPORAL_ID, sizeof (pDlp->uiCodingIdx2TemporalId));
509       iNotCodedMask = (1 << (kuiLogFactorInOutRate + kuiLogFactorMaxInRate)) - 1;
510       for (uint32_t uiFrameIdx = 0; uiFrameIdx <= uiGopSize; ++ uiFrameIdx) {
511         if (0 == (uiFrameIdx & iNotCodedMask)) {
512           const int8_t kiTemporalId = pTemporalIdList[uiFrameIdx];
513           pDlp->uiCodingIdx2TemporalId[uiFrameIdx] = kiTemporalId;
514           if (kiTemporalId > iMaxTemporalId) {
515             iMaxTemporalId = kiTemporalId;
516           }
517         }
518       }
519 
520       pDlp->iHighestTemporalId   = iMaxTemporalId;
521       pDlp->iTemporalResolution  = kuiLogFactorMaxInRate + kuiLogFactorInOutRate;
522       pDlp->iDecompositionStages = iDecStages - kuiLogFactorMaxInRate - kuiLogFactorInOutRate;
523       if (pDlp->iDecompositionStages < 0) {
524         return ENC_RETURN_INVALIDINPUT;
525       }
526       ++ pDlp;
527       ++ pSpatialLayer;
528       ++ i;
529     }
530     iDecompStages = (int8_t)iDecStages;
531     return ENC_RETURN_SUCCESS;
532   }
533 
534 } SWelsSvcCodingParam;
535 
536 
537 typedef struct TagExistingParasetList {
538   SWelsSPS            sSps[MAX_SPS_COUNT];
539   SSubsetSps          sSubsetSps[MAX_SPS_COUNT];
540   SWelsPPS            sPps[MAX_PPS_COUNT];
541 
542   uint32_t            uiInUseSpsNum;
543   uint32_t            uiInUseSubsetSpsNum;
544   uint32_t            uiInUsePpsNum;
545 } SExistingParasetList;
546 
547 
FreeCodingParam(SWelsSvcCodingParam ** pParam,CMemoryAlign * pMa)548 static inline int32_t FreeCodingParam (SWelsSvcCodingParam** pParam, CMemoryAlign* pMa) {
549   if (pParam == NULL || *pParam == NULL || pMa == NULL)
550     return 1;
551   pMa->WelsFree (*pParam, "SWelsSvcCodingParam");
552   *pParam = NULL;
553   return 0;
554 }
555 
AllocCodingParam(SWelsSvcCodingParam ** pParam,CMemoryAlign * pMa)556 static inline int32_t AllocCodingParam (SWelsSvcCodingParam** pParam, CMemoryAlign* pMa) {
557   if (pParam == NULL || pMa == NULL)
558     return 1;
559   if (*pParam != NULL) {
560     FreeCodingParam (pParam, pMa);
561   }
562   SWelsSvcCodingParam* pCodingParam = (SWelsSvcCodingParam*)pMa->WelsMallocz (sizeof (SWelsSvcCodingParam),
563                                       "SWelsSvcCodingParam");
564   if (NULL == pCodingParam)
565     return 1;
566   *pParam = pCodingParam;
567   return 0;
568 }
569 
570 }//end of namespace WelsEnc
571 
572 #endif//WELS_ENCODER_PARAMETER_SVC_H__
573