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 (¶m, 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