xref: /OK3568_Linux_fs/external/mpp/mpp/codec/enc/h265/h265e_ps.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright 2015 Rockchip Electronics Co. LTD
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define MODULE_TAG "h265e_ps"
18 
19 #include <string.h>
20 
21 #include "mpp_mem.h"
22 #include "mpp_soc.h"
23 #include "mpp_common.h"
24 
25 #include "h265e_ps.h"
26 
27 #define MAX_UINT        0xFFFFFFFFU
28 
29 typedef struct H265levelspec_t {
30     RK_U32 maxLumaSamples;
31     RK_U32 maxLumaSamplesPerSecond;
32     RK_U32 maxBitrateMain;
33     RK_U32 maxBitrateHigh;
34     RK_U32 maxCpbSizeMain;
35     RK_U32 maxCpbSizeHigh;
36     RK_U32 minCompressionRatio;
37     RK_S32 levelEnum;
38     const char* name;
39     RK_S32 levelIdc;
40 } H265levelspec;
41 
42 H265levelspec levels[] = {
43     { 36864,    552960,     128,      MAX_UINT, 350,    MAX_UINT, 2, H265_LEVEL1,   "1",   10 },
44     { 122880,   3686400,    1500,     MAX_UINT, 1500,   MAX_UINT, 2, H265_LEVEL2,   "2",   20 },
45     { 245760,   7372800,    3000,     MAX_UINT, 3000,   MAX_UINT, 2, H265_LEVEL2_1, "2.1", 21 },
46     { 552960,   16588800,   6000,     MAX_UINT, 6000,   MAX_UINT, 2, H265_LEVEL3,   "3",   30 },
47     { 983040,   33177600,   10000,    MAX_UINT, 10000,  MAX_UINT, 2, H265_LEVEL3_1, "3.1", 31 },
48     { 2228224,  66846720,   12000,    30000,    12000,  30000,    4, H265_LEVEL4,   "4",   40 },
49     { 2228224,  133693440,  20000,    50000,    20000,  50000,    4, H265_LEVEL4_1, "4.1", 41 },
50     { 8912896,  267386880,  25000,    100000,   25000,  100000,   6, H265_LEVEL5,   "5",   50 },
51     { 8912896,  534773760,  40000,    160000,   40000,  160000,   8, H265_LEVEL5_1, "5.1", 51 },
52     { 8912896,  1069547520, 60000,    240000,   60000,  240000,   8, H265_LEVEL5_2, "5.2", 52 },
53     { 35651584, 1069547520, 60000,    240000,   60000,  240000,   8, H265_LEVEL6,   "6",   60 },
54     { 35651584, 2139095040, 120000,   480000,   120000, 480000,   8, H265_LEVEL6_1, "6.1", 61 },
55     { 35651584, 4278190080U, 240000,  800000,   240000, 800000,   6, H265_LEVEL6_2, "6.2", 62 },
56     { MAX_UINT, MAX_UINT, MAX_UINT, MAX_UINT, MAX_UINT, MAX_UINT, 1, H265_LEVEL8_5, "8.5", 85 },
57 };
58 
init_zscan2raster(RK_S32 maxDepth,RK_S32 depth,RK_U32 startVal,RK_U32 ** curIdx)59 void init_zscan2raster(RK_S32 maxDepth, RK_S32 depth, RK_U32 startVal, RK_U32** curIdx)
60 {
61     RK_S32 stride = 1 << (maxDepth - 1);
62     if (depth == maxDepth) {
63         (*curIdx)[0] = startVal;
64         (*curIdx)++;
65     } else {
66         RK_S32 step = stride >> depth;
67         init_zscan2raster(maxDepth, depth + 1, startVal,                        curIdx);
68         init_zscan2raster(maxDepth, depth + 1, startVal + step,                 curIdx);
69         init_zscan2raster(maxDepth, depth + 1, startVal + step * stride,        curIdx);
70         init_zscan2raster(maxDepth, depth + 1, startVal + step * stride + step, curIdx);
71     }
72 }
73 
init_raster2zscan(RK_U32 maxCUSize,RK_U32 maxDepth,RK_U32 * raster2zscan,RK_U32 * zscan2raster)74 void init_raster2zscan(RK_U32 maxCUSize, RK_U32 maxDepth, RK_U32 *raster2zscan, RK_U32 *zscan2raster)
75 {
76     RK_U32  unitSize = maxCUSize  >> (maxDepth - 1);
77     RK_U32  numPartInCUSize  = (RK_U32)maxCUSize / unitSize;
78     RK_U32  i;
79 
80     for ( i = 0; i < numPartInCUSize * numPartInCUSize; i++) {
81         raster2zscan[zscan2raster[i]] = i;
82     }
83 }
84 
init_raster2pelxy(RK_U32 maxCUSize,RK_U32 maxDepth,RK_U32 * raster2pelx,RK_U32 * raster2pely)85 void init_raster2pelxy(RK_U32 maxCUSize, RK_U32 maxDepth, RK_U32 *raster2pelx, RK_U32 *raster2pely)
86 {
87     RK_U32 i;
88 
89     RK_U32* tempx = &raster2pelx[0];
90     RK_U32* tempy = &raster2pely[0];
91 
92     RK_U32  unitSize  = maxCUSize >> (maxDepth - 1);
93 
94     RK_U32  numPartInCUSize = maxCUSize / unitSize;
95 
96     tempx[0] = 0;
97     tempx++;
98     for (i = 1; i < numPartInCUSize; i++) {
99         tempx[0] = tempx[-1] + unitSize;
100         tempy++;
101     }
102 
103     for (i = 1; i < numPartInCUSize; i++) {
104         memcpy(tempx, tempx - numPartInCUSize, sizeof(RK_U32) * numPartInCUSize);
105         tempx += numPartInCUSize;
106     }
107 
108     for (i = 1; i < numPartInCUSize * numPartInCUSize; i++) {
109         tempy[i] = (i / numPartInCUSize) * unitSize;
110     }
111 }
112 
h265e_set_vps(H265eCtx * ctx,H265eVps * vps)113 MPP_RET h265e_set_vps(H265eCtx *ctx, H265eVps *vps)
114 {
115     RK_S32 i;
116     MppEncH265Cfg *codec = &ctx->cfg->codec.h265;
117     ProfileTierLevel *profileTierLevel = &vps->m_ptl.m_generalPTL;
118     MppEncPrepCfg *prep = &ctx->cfg->prep;
119     RK_U32 maxlumas = prep->width * prep->height;
120     RK_S32 level_idc = H265_LEVEL_NONE;
121 
122     vps->m_VPSId = 0;
123     vps->m_maxTLayers = 1;
124     vps->m_maxLayers = 1;
125     vps->m_bTemporalIdNestingFlag = 1;
126     vps->m_numHrdParameters = 0;
127     vps->m_maxNuhReservedZeroLayerId = 0;
128     vps->m_hrdParameters = NULL;
129     vps->m_hrdOpSetIdx = NULL;
130     vps->m_cprmsPresentFlag = NULL;
131     for (i = 0; i < MAX_SUB_LAYERS; i++) {
132         vps->m_numReorderPics[i] =  0;
133         vps->m_maxDecPicBuffering[i] = MPP_MIN(MAX_REFS, MPP_MAX((vps->m_numReorderPics[i] + 3), codec->num_ref) + vps->m_numReorderPics[i]);
134         vps->m_maxLatencyIncrease[i] = 0;
135     }
136     memset(profileTierLevel->m_profileCompatibilityFlag, 0, sizeof(profileTierLevel->m_profileCompatibilityFlag));
137     memset(vps->m_ptl.m_subLayerProfilePresentFlag, 0, sizeof(vps->m_ptl.m_subLayerProfilePresentFlag));
138     memset(vps->m_ptl.m_subLayerLevelPresentFlag,   0, sizeof(vps->m_ptl.m_subLayerLevelPresentFlag));
139     for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(levels); i++) {
140         if (levels[i].maxLumaSamples >= maxlumas) {
141             level_idc = levels[i].levelEnum;
142             break;
143         }
144     }
145 
146     profileTierLevel->m_profileSpace = 0;
147     if (codec->level < level_idc) {
148         profileTierLevel->m_levelIdc = level_idc;
149     } else {
150         profileTierLevel->m_levelIdc = codec->level;
151     }
152     profileTierLevel->m_tierFlag = codec->tier ? 1 : 0;
153     profileTierLevel->m_profileIdc = codec->profile;
154 
155     profileTierLevel->m_profileCompatibilityFlag[codec->profile] = 1;
156     profileTierLevel->m_profileCompatibilityFlag[2] = 1;
157 
158     profileTierLevel->m_progressiveSourceFlag = 1;
159     profileTierLevel->m_nonPackedConstraintFlag = 0;
160     profileTierLevel->m_frameOnlyConstraintFlag = 0;
161     return MPP_OK;
162 }
163 
h265e_set_sps(H265eCtx * ctx,H265eSps * sps,H265eVps * vps)164 MPP_RET h265e_set_sps(H265eCtx *ctx, H265eSps *sps, H265eVps *vps)
165 {
166     RK_U32 i, c;
167     MppEncH265Cfg *codec = &ctx->cfg->codec.h265;
168     MppEncPrepCfg *prep = &ctx->cfg->prep;
169     MppEncRcCfg *rc = &ctx->cfg->rc;
170     MppEncRefCfg ref_cfg = ctx->cfg->ref_cfg;
171     MppEncH265VuiCfg *vui = &codec->vui;
172     RK_S32 i_timebase_num = rc->fps_out_denorm;
173     RK_S32 i_timebase_den = rc->fps_out_num;
174     RK_U8  convertToBit[MAX_CU_SIZE + 1];
175     RK_U32 maxCUDepth, minCUDepth, addCUDepth;
176     RK_S32 pad[2] = {0};
177     RK_S32 minCUSize, log2MinCUSize;
178     RK_S32 tuQTMinLog2Size = 2, tuQTMaxLog2Size;
179     MppEncCpbInfo *cpb_info = mpp_enc_ref_cfg_get_cpb_info(ref_cfg);
180     RK_U32 *tmp = &sps->zscan2raster[0];
181 
182     memset(convertToBit, -1, sizeof(convertToBit));
183     c = 0;
184     for (i = 4; i <= MAX_CU_SIZE; i *= 2) {
185         convertToBit[i] = c;
186         c++;
187     }
188 
189     maxCUDepth = (uint32_t)convertToBit[codec->max_cu_size];
190 
191     minCUDepth = (codec->max_cu_size >> (maxCUDepth - 1));
192 
193     tuQTMaxLog2Size = convertToBit[codec->max_cu_size] + 2 - 1;
194 
195     addCUDepth = 0;
196     while ((RK_U32)(codec->max_cu_size >> maxCUDepth) > (1u << (tuQTMinLog2Size + addCUDepth))) {
197         addCUDepth++;
198     }
199 
200     maxCUDepth += addCUDepth;
201     addCUDepth++;
202     init_zscan2raster(maxCUDepth + 1, 1, 0, &tmp );
203     init_raster2zscan(codec->max_cu_size, maxCUDepth + 1, &sps->raster2zscan[0], &sps->zscan2raster[0]);
204     init_raster2pelxy(codec->max_cu_size, maxCUDepth + 1, &sps->raster2pelx[0], &sps->raster2pely[0]);
205 
206     memset(&sps->m_conformanceWindow, 0, sizeof(H265eCropInfo));
207     if ((prep->width % minCUDepth) != 0) {
208         RK_U32 padsize = 0;
209         RK_U32 rem = prep->width % minCUDepth;
210         padsize = minCUDepth - rem;
211         pad[0] = padsize; //pad width
212 
213         /* set the confirmation window offsets  */
214         sps->m_conformanceWindow.m_enabledFlag = 1;
215         sps->m_conformanceWindow.m_winRightOffset = pad[0];
216     }
217 
218     if ((prep->height % minCUDepth) != 0) {
219         RK_U32 padsize = 0;
220         RK_U32 rem = prep->height % minCUDepth;
221         padsize = minCUDepth - rem;
222         pad[1] = padsize; //pad height
223 
224         /* set the confirmation window offsets  */
225         sps->m_conformanceWindow.m_enabledFlag = 1;
226         sps->m_conformanceWindow.m_winBottomOffset = pad[1];
227     }
228     // pad[0] = p->sourceWidth - p->oldSourceWidth;
229     // pad[1] = p->sourceHeight - p->oldSourceHeight;
230 
231     sps->m_SPSId = 0;
232     sps->m_VPSId = 0;
233     sps->m_chromaFormatIdc = 0x1; //RKVE_CSP2_I420;
234     sps->m_maxTLayers = 1;
235     sps->m_picWidthInLumaSamples = prep->width + pad[0];
236     sps->m_picHeightInLumaSamples = prep->height + pad[1];
237     sps->m_log2MinCodingBlockSize = 0;
238     sps->m_log2DiffMaxMinCodingBlockSize = 0 ;
239     sps->m_maxCUSize = codec->max_cu_size;
240     sps->m_maxCUDepth = maxCUDepth;
241     sps->m_addCUDepth = addCUDepth;
242     sps->m_RPSList.m_numberOfReferencePictureSets = 0;
243     sps->m_RPSList.m_referencePictureSets = NULL;
244 
245     minCUSize = sps->m_maxCUSize >> (sps->m_maxCUDepth - addCUDepth);
246     log2MinCUSize = 0;
247     while (minCUSize > 1) {
248         minCUSize >>= 1;
249         log2MinCUSize++;
250     }
251     sps->m_log2MinCodingBlockSize = log2MinCUSize;
252     sps->m_log2DiffMaxMinCodingBlockSize = sps->m_maxCUDepth - addCUDepth;
253 
254     sps->m_pcmLog2MaxSize = 5;
255     sps->m_usePCM = 0;
256     sps->m_pcmLog2MinSize = 3;
257 
258 
259     sps->m_bLongTermRefsPresent = 0;
260     sps->m_quadtreeTULog2MaxSize =  tuQTMaxLog2Size;
261     sps->m_quadtreeTULog2MinSize = tuQTMinLog2Size;
262     sps->m_quadtreeTUMaxDepthInter = 1;     //tuQTMaxInterDepth
263     sps->m_quadtreeTUMaxDepthIntra = 1;     //tuQTMaxIntraDepth
264     sps->m_useLossless = 0;
265 
266     for (i = 0; i < (maxCUDepth - addCUDepth); i++) {
267         sps->m_iAMPAcc[i] = codec->amp_enable;
268     }
269     sps->m_useAMP = codec->amp_enable;
270     for (i = maxCUDepth - addCUDepth; i < maxCUDepth; i++) {
271         sps->m_iAMPAcc[i] = codec->amp_enable;
272     }
273 
274     sps->m_bitDepthY = 8;
275     sps->m_bitDepthC = 8;
276     sps->m_qpBDOffsetY = 0;
277     sps->m_qpBDOffsetC = 0;
278 
279     sps->m_bUseSAO = codec->sao_enable;
280 
281     sps->m_maxTLayers = 1;
282 
283     sps->m_bTemporalIdNestingFlag = 1;
284 
285     for (i = 0; i < sps->m_maxTLayers; i++) {
286         sps->m_maxDecPicBuffering[i] = vps->m_maxDecPicBuffering[i];
287         sps->m_numReorderPics[i] = vps->m_numReorderPics[i];
288     }
289 
290     sps->m_pcmBitDepthLuma = 8;
291     sps->m_pcmBitDepthChroma = 8;
292 
293     sps->m_bPCMFilterDisableFlag = 0;
294     sps->m_scalingListEnabledFlag = codec->trans_cfg.defalut_ScalingList_enable == 0 ? 0 : 1;
295 
296     sps->m_bitsForPOC = 16;
297     sps->m_numLongTermRefPicSPS = 0;
298     sps->m_maxTrSize = 32;
299     sps->m_bLongTermRefsPresent = 0;
300     sps->m_TMVPFlagsPresent = codec->tmvp_enable;
301     sps->m_useStrongIntraSmoothing = codec->cu_cfg.strong_intra_smoothing_enabled_flag;
302     if (cpb_info->max_lt_cnt) {
303         sps->m_numLongTermRefPicSPS = cpb_info->max_lt_cnt;
304         sps->m_bLongTermRefsPresent = 1;
305         sps->m_TMVPFlagsPresent = 0;
306         codec->tmvp_enable = 0;
307     } else if (cpb_info->max_st_tid) {
308         sps->m_TMVPFlagsPresent = 0;
309     }
310     sps->m_ptl = &vps->m_ptl;
311     sps->m_vuiParametersPresentFlag = 1;
312     if (sps->m_vuiParametersPresentFlag) {
313         sps->vui.m_aspectRatioInfoPresentFlag = 0;
314         sps->vui.m_aspectRatioIdc = 0;
315         sps->vui.m_sarWidth = 0;
316         sps->vui.m_sarHeight = 0;
317         sps->vui.m_overscanInfoPresentFlag = 0;
318         sps->vui.m_overscanAppropriateFlag = 0;
319         sps->vui.m_videoSignalTypePresentFlag = 0;
320         sps->vui.m_videoFormat = MPP_FRAME_VIDEO_FMT_UNSPECIFIED;
321         if (prep->range == MPP_FRAME_RANGE_JPEG) {
322             sps->vui.m_videoFullRangeFlag = 1;
323             sps->vui.m_videoSignalTypePresentFlag = 1;
324         }
325 
326         if ((prep->colorprim <= MPP_FRAME_PRI_JEDEC_P22 &&
327              prep->colorprim != MPP_FRAME_PRI_UNSPECIFIED) ||
328             (prep->colortrc <= MPP_FRAME_TRC_ARIB_STD_B67 &&
329              prep->colortrc != MPP_FRAME_TRC_UNSPECIFIED) ||
330             (prep->color <= MPP_FRAME_SPC_ICTCP &&
331              prep->color != MPP_FRAME_SPC_UNSPECIFIED)) {
332             sps->vui.m_videoSignalTypePresentFlag = 1;
333             sps->vui.m_colourDescriptionPresentFlag = 1;
334             sps->vui.m_colourPrimaries = prep->colorprim;
335             sps->vui.m_transferCharacteristics = prep->colortrc;
336             sps->vui.m_matrixCoefficients = prep->color;
337         }
338 
339         sps->vui.m_chromaLocInfoPresentFlag = 0;
340         sps->vui.m_chromaSampleLocTypeTopField = 0;
341         sps->vui.m_chromaSampleLocTypeBottomField = 0;
342         sps->vui.m_neutralChromaIndicationFlag = 0;
343         sps->vui.m_fieldSeqFlag = 0;
344         sps->vui.m_frameFieldInfoPresentFlag = 0;
345         sps->vui.m_hrdParametersPresentFlag = 0;
346         sps->vui.m_bitstreamRestrictionFlag = 0;
347         sps->vui.m_tilesFixedStructureFlag = 0;
348         sps->vui.m_motionVectorsOverPicBoundariesFlag = 1;
349         sps->vui.m_restrictedRefPicListsFlag = 1;
350         sps->vui.m_minSpatialSegmentationIdc = 0;
351         sps->vui.m_maxBytesPerPicDenom = 2;
352         sps->vui.m_maxBitsPerMinCuDenom = 1;
353         sps->vui.m_log2MaxMvLengthHorizontal = 15;
354         sps->vui.m_log2MaxMvLengthVertical = 15;
355         if (vui->vui_aspect_ratio) {
356             sps->vui.m_aspectRatioInfoPresentFlag = !!vui->vui_aspect_ratio;
357             sps->vui.m_aspectRatioIdc = vui->vui_aspect_ratio;
358         }
359         sps->vui.m_timingInfo.m_timingInfoPresentFlag = 1;
360         sps->vui.m_timingInfo.m_numUnitsInTick = i_timebase_num;
361         sps->vui.m_timingInfo.m_timeScale = i_timebase_den;
362     }
363 
364 
365 
366     for (i = 0; i < MAX_SUB_LAYERS; i++) {
367         sps->m_maxLatencyIncrease[i] = 0;
368     }
369     //  sps->m_scalingList = NULL;
370     memset(sps->m_ltRefPicPocLsbSps, 0, sizeof(sps->m_ltRefPicPocLsbSps));
371     memset(sps->m_usedByCurrPicLtSPSFlag, 0, sizeof(sps->m_usedByCurrPicLtSPSFlag));
372     return 0;
373 }
374 
h265e_set_pps(H265eCtx * ctx,H265ePps * pps,H265eSps * sps)375 MPP_RET h265e_set_pps(H265eCtx  *ctx, H265ePps *pps, H265eSps *sps)
376 {
377     MppEncH265Cfg *codec = &ctx->cfg->codec.h265;
378     MppEncRcCfg *rc = &ctx->cfg->rc;
379     pps->m_bConstrainedIntraPred = 0;
380     pps->m_PPSId = 0;
381     pps->m_SPSId = 0;
382     pps->m_picInitQPMinus26 = 0;
383     pps->m_useDQP = 0;
384     if (rc->rc_mode != MPP_ENC_RC_MODE_FIXQP) {
385         pps->m_useDQP = 1;
386         pps->m_maxCuDQPDepth = 0;
387         pps->m_minCuDQPSize = (sps->m_maxCUSize >> pps->m_maxCuDQPDepth);
388     }
389 
390     pps->m_sps = sps;
391     pps->m_bSliceChromaQpFlag = 0;
392     pps->m_chromaCbQpOffset = codec->trans_cfg.cb_qp_offset;
393     /* rkvenc hw only support one color qp offset. Set all offset to cb offset*/
394     pps->m_chromaCrQpOffset = codec->trans_cfg.cb_qp_offset;
395 
396     pps->m_entropyCodingSyncEnabledFlag = 0;
397     pps->m_bUseWeightPred = 0;
398     pps->m_useWeightedBiPred = 0;
399     pps->m_outputFlagPresentFlag = 0;
400     pps->m_signHideFlag = 0;
401     pps->m_picInitQPMinus26 = codec->intra_qp - 26;
402     pps->m_LFCrossSliceBoundaryFlag = codec->lpf_acs_sli_en;
403     pps->m_deblockingFilterControlPresentFlag = !codec->dblk_cfg.slice_deblocking_filter_disabled_flag;
404     if (pps->m_deblockingFilterControlPresentFlag) {
405         pps->m_deblockingFilterOverrideEnabledFlag = 0;
406         pps->m_picDisableDeblockingFilterFlag = 0;
407         if (!pps->m_picDisableDeblockingFilterFlag) {
408             pps->m_deblockingFilterBetaOffsetDiv2 = codec->dblk_cfg.slice_beta_offset_div2;
409             pps->m_deblockingFilterTcOffsetDiv2 = codec->dblk_cfg.slice_tc_offset_div2;
410         }
411     } else {
412         pps->m_deblockingFilterOverrideEnabledFlag = 0;
413         pps->m_picDisableDeblockingFilterFlag = 0;
414         pps->m_deblockingFilterBetaOffsetDiv2 = 0;
415         pps->m_deblockingFilterTcOffsetDiv2 = 0;
416     }
417 
418     pps->m_listsModificationPresentFlag = 1;
419     pps->m_log2ParallelMergeLevelMinus2 = 0;
420     pps->m_numRefIdxL0DefaultActive = 1;
421     pps->m_numRefIdxL1DefaultActive = 1;
422     pps->m_transquantBypassEnableFlag = codec->trans_cfg.transquant_bypass_enabled_flag;
423     pps->m_useTransformSkip = codec->trans_cfg.transform_skip_enabled_flag;
424 
425     pps->m_entropyCodingSyncEnabledFlag = 0;
426     pps->m_signHideFlag = 0;
427     pps->m_cabacInitPresentFlag = codec->entropy_cfg.cabac_init_flag;
428     pps->m_encCABACTableIdx = I_SLICE;
429     pps->m_sliceHeaderExtensionPresentFlag = 0;
430     pps->m_numExtraSliceHeaderBits = 0;
431     pps->m_tiles_enabled_flag = 0;
432     pps->m_bTileUniformSpacing = 0;
433     pps->m_nNumTileRowsMinus1 = 0;
434     pps->m_nNumTileColumnsMinus1 = 0;
435     pps->m_loopFilterAcrossTilesEnabledFlag = !codec->lpf_acs_tile_disable;
436     {
437         const char *soc_name = mpp_get_soc_name();
438         /* check tile support on rk3566 and rk3568 */
439         if (strstr(soc_name, "rk3566") || strstr(soc_name, "rk3568")) {
440             pps->m_nNumTileColumnsMinus1 = (sps->m_picWidthInLumaSamples - 1) / 1920 ;
441         } else if (strstr(soc_name, "rk3588")) {
442             if (sps->m_picWidthInLumaSamples > 8192) {
443                 /* 4 tile for over 8k encoding */
444                 pps->m_nNumTileColumnsMinus1 = 3;
445             } else if (sps->m_picWidthInLumaSamples > 4096) {
446                 /* 2 tile for 4k ~ 8k encoding */
447                 pps->m_nNumTileColumnsMinus1 = 1;
448             } else {
449                 /* 1 tile for less 4k encoding and use 2 tile on auto tile enabled */
450                 pps->m_nNumTileColumnsMinus1 = codec->auto_tile ? 1 : 0;
451             }
452         }
453         if (pps->m_nNumTileColumnsMinus1) {
454             pps->m_tiles_enabled_flag = 1;
455             pps->m_bTileUniformSpacing = 1;
456             pps->m_loopFilterAcrossTilesEnabledFlag = !codec->lpf_acs_tile_disable;;
457         }
458     }
459 
460     return 0;
461 }
462