xref: /rockchip-linux_mpp/mpp/codec/enc/h265/h265e_slice.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2015 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka  *
4*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka  * You may obtain a copy of the License at
7*437bfbebSnyanmisaka  *
8*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka  *
10*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka  * limitations under the License.
15*437bfbebSnyanmisaka  */
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #define MODULE_TAG "h265e_slice"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <string.h>
20*437bfbebSnyanmisaka 
21*437bfbebSnyanmisaka #include "mpp_debug.h"
22*437bfbebSnyanmisaka #include "h265e_codec.h"
23*437bfbebSnyanmisaka #include "h265e_slice.h"
24*437bfbebSnyanmisaka 
get_ref_pic(H265eDpbFrm * frame_list,RK_S32 poc)25*437bfbebSnyanmisaka H265eDpbFrm* get_ref_pic(H265eDpbFrm *frame_list, RK_S32 poc)
26*437bfbebSnyanmisaka {
27*437bfbebSnyanmisaka     RK_S32 index = 0;
28*437bfbebSnyanmisaka     H265eDpbFrm *frame = NULL;
29*437bfbebSnyanmisaka 
30*437bfbebSnyanmisaka     h265e_dbg_func("enter\n");
31*437bfbebSnyanmisaka     for (index = 0; index < MAX_REFS; index++) {
32*437bfbebSnyanmisaka         frame = &frame_list[index];
33*437bfbebSnyanmisaka         if (frame->inited && frame->poc == poc) {
34*437bfbebSnyanmisaka             break;
35*437bfbebSnyanmisaka         }
36*437bfbebSnyanmisaka     }
37*437bfbebSnyanmisaka     h265e_dbg_func("leave\n");
38*437bfbebSnyanmisaka     return frame;
39*437bfbebSnyanmisaka }
40*437bfbebSnyanmisaka 
get_lt_ref_pic(H265eDpbFrm * frame_list,H265eSlice * slice,RK_S32 poc,RK_U32 pocHasMsb)41*437bfbebSnyanmisaka H265eDpbFrm* get_lt_ref_pic(H265eDpbFrm *frame_list, H265eSlice *slice, RK_S32 poc, RK_U32 pocHasMsb)
42*437bfbebSnyanmisaka {
43*437bfbebSnyanmisaka     RK_S32 index = 0;
44*437bfbebSnyanmisaka     H265eDpbFrm *frame = NULL;
45*437bfbebSnyanmisaka     H265eDpbFrm* stPic = &frame_list[MAX_REFS - 1];
46*437bfbebSnyanmisaka     RK_S32 pocCycle = 1 << slice->m_sps->m_bitsForPOC;
47*437bfbebSnyanmisaka 
48*437bfbebSnyanmisaka     h265e_dbg_func("enter\n");
49*437bfbebSnyanmisaka     if (!pocHasMsb) {
50*437bfbebSnyanmisaka         poc = poc % pocCycle;
51*437bfbebSnyanmisaka     }
52*437bfbebSnyanmisaka 
53*437bfbebSnyanmisaka     for (index = MAX_REFS - 1 ; index >= 0; index--) {
54*437bfbebSnyanmisaka         frame = &frame_list[index];
55*437bfbebSnyanmisaka         if (frame->on_used && frame->poc != slice->poc && frame->slice->is_referenced) {
56*437bfbebSnyanmisaka             RK_S32 picPoc = frame->poc;
57*437bfbebSnyanmisaka             if (!pocHasMsb) {
58*437bfbebSnyanmisaka                 picPoc = picPoc % pocCycle;
59*437bfbebSnyanmisaka             }
60*437bfbebSnyanmisaka 
61*437bfbebSnyanmisaka             if (poc == picPoc) {
62*437bfbebSnyanmisaka                 if (frame->is_long_term) {
63*437bfbebSnyanmisaka                     return frame;
64*437bfbebSnyanmisaka                 } else {
65*437bfbebSnyanmisaka                     stPic = frame;
66*437bfbebSnyanmisaka                 }
67*437bfbebSnyanmisaka             }
68*437bfbebSnyanmisaka         }
69*437bfbebSnyanmisaka 
70*437bfbebSnyanmisaka     }
71*437bfbebSnyanmisaka     h265e_dbg_func("leave\n");
72*437bfbebSnyanmisaka     return stPic;
73*437bfbebSnyanmisaka }
74*437bfbebSnyanmisaka 
h265e_slice_set_ref_list(H265eDpbFrm * frame_list,H265eSlice * slice)75*437bfbebSnyanmisaka void h265e_slice_set_ref_list(H265eDpbFrm *frame_list, H265eSlice *slice)
76*437bfbebSnyanmisaka {
77*437bfbebSnyanmisaka     H265eReferencePictureSet *rps = slice->m_rps;
78*437bfbebSnyanmisaka     H265eDpbFrm* refPic = NULL;
79*437bfbebSnyanmisaka     H265eDpbFrm* refPicSetStCurr0[MAX_REFS];
80*437bfbebSnyanmisaka     H265eDpbFrm* refPicSetStCurr1[MAX_REFS];
81*437bfbebSnyanmisaka     H265eDpbFrm* refPicSetLtCurr[MAX_REFS];
82*437bfbebSnyanmisaka     RK_S32 numPocStCurr0 = 0;
83*437bfbebSnyanmisaka     RK_S32 numPocStCurr1 = 0;
84*437bfbebSnyanmisaka     RK_S32 numPocLtCurr = 0;
85*437bfbebSnyanmisaka     RK_S32 i, cIdx = 0, rIdx = 0;
86*437bfbebSnyanmisaka 
87*437bfbebSnyanmisaka     h265e_dbg_func("enter\n");
88*437bfbebSnyanmisaka     if (slice->m_sliceType == I_SLICE) {
89*437bfbebSnyanmisaka         memset(slice->m_refPicList, 0, sizeof(slice->m_refPicList));
90*437bfbebSnyanmisaka         memset(slice->m_numRefIdx,  0, sizeof(slice->m_numRefIdx));
91*437bfbebSnyanmisaka         return;
92*437bfbebSnyanmisaka     }
93*437bfbebSnyanmisaka     for (i = 0; i < rps->num_negative_pic; i++) {
94*437bfbebSnyanmisaka         if (rps->m_used[i]) {
95*437bfbebSnyanmisaka             refPic = get_ref_pic(frame_list, slice->poc + rps->delta_poc[i]);
96*437bfbebSnyanmisaka             refPic->is_long_term = 0;
97*437bfbebSnyanmisaka             refPicSetStCurr0[numPocStCurr0] = refPic;
98*437bfbebSnyanmisaka             numPocStCurr0++;
99*437bfbebSnyanmisaka             refPic->check_lt_msb = 0;
100*437bfbebSnyanmisaka         }
101*437bfbebSnyanmisaka     }
102*437bfbebSnyanmisaka 
103*437bfbebSnyanmisaka     for (; i < rps->num_negative_pic + rps->num_positive_pic; i++) {
104*437bfbebSnyanmisaka         if (rps->m_used[i]) {
105*437bfbebSnyanmisaka             refPic = get_ref_pic(frame_list,  slice->poc + rps->delta_poc[i]);
106*437bfbebSnyanmisaka             refPic->is_long_term = 0;
107*437bfbebSnyanmisaka             refPicSetStCurr1[numPocStCurr1] = refPic;
108*437bfbebSnyanmisaka             numPocStCurr1++;
109*437bfbebSnyanmisaka             refPic->check_lt_msb = 0;
110*437bfbebSnyanmisaka         }
111*437bfbebSnyanmisaka     }
112*437bfbebSnyanmisaka 
113*437bfbebSnyanmisaka     for (i = rps->num_negative_pic + rps->num_positive_pic + rps->num_long_term_pic - 1;
114*437bfbebSnyanmisaka          i > rps->num_negative_pic + rps->num_positive_pic - 1; i--) {
115*437bfbebSnyanmisaka         if (rps->m_used[i]) {
116*437bfbebSnyanmisaka             refPic = get_lt_ref_pic(frame_list, slice, rps->m_RealPoc[i], rps->check_lt_msb[i]);
117*437bfbebSnyanmisaka             refPic->is_long_term = 1;
118*437bfbebSnyanmisaka             /*due to only one ref if num_negative_pic > 0 set lt not used*/
119*437bfbebSnyanmisaka             /* if (rps->num_negative_pic > 0) {
120*437bfbebSnyanmisaka                  rps->m_used[i] = 0;
121*437bfbebSnyanmisaka              }*/
122*437bfbebSnyanmisaka             refPicSetLtCurr[numPocLtCurr] = refPic;
123*437bfbebSnyanmisaka             numPocLtCurr++;
124*437bfbebSnyanmisaka         }
125*437bfbebSnyanmisaka         if (refPic == NULL) {
126*437bfbebSnyanmisaka             refPic = get_lt_ref_pic(frame_list, slice, rps->m_RealPoc[i], rps->check_lt_msb[i]);
127*437bfbebSnyanmisaka         }
128*437bfbebSnyanmisaka         refPic->check_lt_msb = rps->check_lt_msb[i];
129*437bfbebSnyanmisaka     }
130*437bfbebSnyanmisaka 
131*437bfbebSnyanmisaka     // ref_pic_list_init
132*437bfbebSnyanmisaka     H265eDpbFrm* rpsCurrList0[MAX_REFS + 1];
133*437bfbebSnyanmisaka     H265eDpbFrm* rpsCurrList1[MAX_REFS + 1];
134*437bfbebSnyanmisaka     RK_S32 numPocTotalCurr = numPocStCurr0 + numPocStCurr1 + numPocLtCurr;
135*437bfbebSnyanmisaka 
136*437bfbebSnyanmisaka     for (i = 0; i < numPocStCurr0; i++, cIdx++) {
137*437bfbebSnyanmisaka         rpsCurrList0[cIdx] = refPicSetStCurr0[i];
138*437bfbebSnyanmisaka     }
139*437bfbebSnyanmisaka 
140*437bfbebSnyanmisaka     for (i = 0; i < numPocStCurr1; i++, cIdx++) {
141*437bfbebSnyanmisaka         rpsCurrList0[cIdx] = refPicSetStCurr1[i];
142*437bfbebSnyanmisaka     }
143*437bfbebSnyanmisaka 
144*437bfbebSnyanmisaka     for (i = 0; i < numPocLtCurr; i++, cIdx++) {
145*437bfbebSnyanmisaka         rpsCurrList0[cIdx] = refPicSetLtCurr[i];
146*437bfbebSnyanmisaka     }
147*437bfbebSnyanmisaka 
148*437bfbebSnyanmisaka     mpp_assert(cIdx == numPocTotalCurr);
149*437bfbebSnyanmisaka 
150*437bfbebSnyanmisaka     if (slice->m_sliceType == B_SLICE) {
151*437bfbebSnyanmisaka         cIdx = 0;
152*437bfbebSnyanmisaka         for (i = 0; i < numPocStCurr1; i++, cIdx++) {
153*437bfbebSnyanmisaka             rpsCurrList1[cIdx] = refPicSetStCurr1[i];
154*437bfbebSnyanmisaka         }
155*437bfbebSnyanmisaka 
156*437bfbebSnyanmisaka         for (i = 0; i < numPocStCurr0; i++, cIdx++) {
157*437bfbebSnyanmisaka             rpsCurrList1[cIdx] = refPicSetStCurr0[i];
158*437bfbebSnyanmisaka         }
159*437bfbebSnyanmisaka 
160*437bfbebSnyanmisaka         for (i = 0; i < numPocLtCurr; i++, cIdx++) {
161*437bfbebSnyanmisaka             rpsCurrList1[cIdx] = refPicSetLtCurr[i];
162*437bfbebSnyanmisaka         }
163*437bfbebSnyanmisaka 
164*437bfbebSnyanmisaka         mpp_assert(cIdx == numPocTotalCurr);
165*437bfbebSnyanmisaka     }
166*437bfbebSnyanmisaka 
167*437bfbebSnyanmisaka     memset(slice->m_bIsUsedAsLongTerm, 0, sizeof(slice->m_bIsUsedAsLongTerm));
168*437bfbebSnyanmisaka 
169*437bfbebSnyanmisaka     for ( rIdx = 0; rIdx < slice->m_numRefIdx[0]; rIdx++) {
170*437bfbebSnyanmisaka         cIdx = slice->m_RefPicListModification.m_refPicListModificationFlagL0 ? slice->m_RefPicListModification.m_RefPicSetIdxL0[rIdx] : (RK_U32)rIdx % numPocTotalCurr;
171*437bfbebSnyanmisaka         mpp_assert(cIdx >= 0 && cIdx < numPocTotalCurr);
172*437bfbebSnyanmisaka         slice->m_refPicList[0][rIdx] = rpsCurrList0[cIdx];
173*437bfbebSnyanmisaka         slice->m_bIsUsedAsLongTerm[0][rIdx] = (cIdx >= numPocStCurr0 + numPocStCurr1);
174*437bfbebSnyanmisaka     }
175*437bfbebSnyanmisaka 
176*437bfbebSnyanmisaka     if (slice->m_sliceType != B_SLICE) {
177*437bfbebSnyanmisaka         slice->m_numRefIdx[1] = 0;
178*437bfbebSnyanmisaka         memset(slice->m_refPicList[1], 0, sizeof(slice->m_refPicList[1]));
179*437bfbebSnyanmisaka     } else {
180*437bfbebSnyanmisaka         for (rIdx = 0; rIdx < slice->m_numRefIdx[1]; rIdx++) {
181*437bfbebSnyanmisaka             cIdx = slice->m_RefPicListModification.m_refPicListModificationFlagL1 ? slice->m_RefPicListModification.m_RefPicSetIdxL1[rIdx] : (RK_U32)rIdx % numPocTotalCurr;
182*437bfbebSnyanmisaka             mpp_assert(cIdx >= 0 && cIdx < numPocTotalCurr);
183*437bfbebSnyanmisaka             slice->m_refPicList[1][rIdx] = rpsCurrList1[cIdx];
184*437bfbebSnyanmisaka             slice->m_bIsUsedAsLongTerm[1][rIdx] = (cIdx >= numPocStCurr0 + numPocStCurr1);
185*437bfbebSnyanmisaka         }
186*437bfbebSnyanmisaka     }
187*437bfbebSnyanmisaka 
188*437bfbebSnyanmisaka     h265e_dbg_func("leave\n");
189*437bfbebSnyanmisaka }
190*437bfbebSnyanmisaka 
h265e_slice_set_ref_poc_list(H265eSlice * slice)191*437bfbebSnyanmisaka void h265e_slice_set_ref_poc_list(H265eSlice *slice)
192*437bfbebSnyanmisaka {
193*437bfbebSnyanmisaka     RK_S32 dir, numRefIdx;
194*437bfbebSnyanmisaka 
195*437bfbebSnyanmisaka     h265e_dbg_func("enter\n");
196*437bfbebSnyanmisaka 
197*437bfbebSnyanmisaka     for (dir = 0; dir < 2; dir++) {
198*437bfbebSnyanmisaka         for (numRefIdx = 0; numRefIdx < slice->m_numRefIdx[dir]; numRefIdx++) {
199*437bfbebSnyanmisaka             slice->m_refPOCList[dir][numRefIdx] = slice->m_refPicList[dir][numRefIdx]->poc;
200*437bfbebSnyanmisaka         }
201*437bfbebSnyanmisaka     }
202*437bfbebSnyanmisaka 
203*437bfbebSnyanmisaka     h265e_dbg_func("leave\n");
204*437bfbebSnyanmisaka }
205*437bfbebSnyanmisaka 
h265e_slice_init(void * ctx,EncFrmStatus curr)206*437bfbebSnyanmisaka void h265e_slice_init(void *ctx, EncFrmStatus curr)
207*437bfbebSnyanmisaka {
208*437bfbebSnyanmisaka     H265eCtx *p = (H265eCtx *)ctx;
209*437bfbebSnyanmisaka     H265eVps *vps = &p->vps;
210*437bfbebSnyanmisaka     H265eSps *sps = &p->sps;
211*437bfbebSnyanmisaka     H265ePps *pps = &p->pps;
212*437bfbebSnyanmisaka     MppEncCfgSet *cfg = p->cfg;
213*437bfbebSnyanmisaka     MppEncH265Cfg *codec = &cfg->h265;
214*437bfbebSnyanmisaka     MppEncPrepCfg *prep_cfg = &cfg->prep;
215*437bfbebSnyanmisaka     H265eSlice *slice = p->dpb->curr->slice;
216*437bfbebSnyanmisaka     p->slice = p->dpb->curr->slice;
217*437bfbebSnyanmisaka     h265e_dbg_func("enter\n");
218*437bfbebSnyanmisaka     memset(slice, 0, sizeof(H265eSlice));
219*437bfbebSnyanmisaka     slice->m_sps = sps;
220*437bfbebSnyanmisaka     slice->m_vps = vps;
221*437bfbebSnyanmisaka     slice->m_pps = pps;
222*437bfbebSnyanmisaka     slice->m_numRefIdx[0] = 0;
223*437bfbebSnyanmisaka     slice->m_numRefIdx[1] = 0;
224*437bfbebSnyanmisaka     slice->m_colFromL0Flag = 1;
225*437bfbebSnyanmisaka     slice->m_colRefIdx = 0;
226*437bfbebSnyanmisaka     slice->m_bCheckLDC = 0;
227*437bfbebSnyanmisaka     slice->m_sliceQpDeltaCb = 0;
228*437bfbebSnyanmisaka     slice->m_sliceQpDeltaCr = 0;
229*437bfbebSnyanmisaka     slice->m_maxNumMergeCand = 5;
230*437bfbebSnyanmisaka     slice->m_bFinalized = 0;
231*437bfbebSnyanmisaka 
232*437bfbebSnyanmisaka     slice->m_cabacInitFlag = 0;
233*437bfbebSnyanmisaka     slice->m_numEntryPointOffsets = 0;
234*437bfbebSnyanmisaka     slice->m_enableTMVPFlag = sps->m_TMVPFlagsPresent;
235*437bfbebSnyanmisaka     slice->m_picOutputFlag = 1;
236*437bfbebSnyanmisaka     p->dpb->curr->is_key_frame = 0;
237*437bfbebSnyanmisaka     if (curr.is_idr) {
238*437bfbebSnyanmisaka         slice->m_sliceType = I_SLICE;
239*437bfbebSnyanmisaka         p->dpb->curr->is_key_frame = 1;
240*437bfbebSnyanmisaka         p->dpb->curr->status.is_intra = 1;
241*437bfbebSnyanmisaka         p->dpb->gop_idx = 0;
242*437bfbebSnyanmisaka     } else {
243*437bfbebSnyanmisaka         slice->m_sliceType = P_SLICE;
244*437bfbebSnyanmisaka         p->dpb->curr->status.is_intra = 0;
245*437bfbebSnyanmisaka     }
246*437bfbebSnyanmisaka 
247*437bfbebSnyanmisaka     p->dpb->curr->status.val = curr.val;
248*437bfbebSnyanmisaka 
249*437bfbebSnyanmisaka     if (slice->m_sliceType  != B_SLICE && !curr.non_recn)
250*437bfbebSnyanmisaka         slice->is_referenced = 1;
251*437bfbebSnyanmisaka 
252*437bfbebSnyanmisaka     if (slice->m_pps->m_deblockingFilterOverrideEnabledFlag) {
253*437bfbebSnyanmisaka         h265e_dbg_slice("to do in this case");
254*437bfbebSnyanmisaka     } else {
255*437bfbebSnyanmisaka         slice->m_deblockingFilterDisable = pps->m_picDisableDeblockingFilterFlag;
256*437bfbebSnyanmisaka         slice->m_deblockingFilterBetaOffsetDiv2 = pps->m_deblockingFilterBetaOffsetDiv2;
257*437bfbebSnyanmisaka         slice->m_deblockingFilterTcOffsetDiv2 = pps->m_deblockingFilterTcOffsetDiv2;
258*437bfbebSnyanmisaka     }
259*437bfbebSnyanmisaka     slice->m_saoEnabledFlag = !codec->sao_cfg.slice_sao_luma_disable;
260*437bfbebSnyanmisaka     slice->m_saoEnabledFlagChroma = (prep_cfg->format == MPP_FMT_YUV400) ?  0 :
261*437bfbebSnyanmisaka                                     !codec->sao_cfg.slice_sao_chroma_disable;
262*437bfbebSnyanmisaka     slice->m_maxNumMergeCand = codec->merge_cfg.max_mrg_cnd;
263*437bfbebSnyanmisaka     slice->m_cabacInitFlag = codec->entropy_cfg.cabac_init_flag;
264*437bfbebSnyanmisaka     slice->m_picOutputFlag = 1;
265*437bfbebSnyanmisaka     slice->m_ppsId = pps->m_PPSId;
266*437bfbebSnyanmisaka     if (slice->m_pps->m_bSliceChromaQpFlag) {
267*437bfbebSnyanmisaka         slice->m_sliceQpDeltaCb = codec->trans_cfg.cb_qp_offset;
268*437bfbebSnyanmisaka         slice->m_sliceQpDeltaCr = codec->trans_cfg.cr_qp_offset;
269*437bfbebSnyanmisaka     }
270*437bfbebSnyanmisaka 
271*437bfbebSnyanmisaka     slice->poc = p->dpb->curr->seq_idx;
272*437bfbebSnyanmisaka     slice->gop_idx = p->dpb->gop_idx;
273*437bfbebSnyanmisaka     slice->temporal_id = p->dpb->curr->status.temporal_id;
274*437bfbebSnyanmisaka     p->dpb->curr->gop_idx =  p->dpb->gop_idx++;
275*437bfbebSnyanmisaka     p->dpb->curr->poc = slice->poc;
276*437bfbebSnyanmisaka     if (curr.is_lt_ref)
277*437bfbebSnyanmisaka         p->dpb->curr->is_long_term = 1;
278*437bfbebSnyanmisaka 
279*437bfbebSnyanmisaka     h265e_dbg_slice("slice->m_sliceType = %d slice->is_referenced = %d \n",
280*437bfbebSnyanmisaka                     slice->m_sliceType, slice->is_referenced);
281*437bfbebSnyanmisaka     h265e_dbg_func("leave\n");
282*437bfbebSnyanmisaka }
283*437bfbebSnyanmisaka 
code_st_refpic_set(MppWriteCtx * bitIf,H265eReferencePictureSet * rps,RK_S32 idx)284*437bfbebSnyanmisaka void code_st_refpic_set(MppWriteCtx *bitIf, H265eReferencePictureSet* rps, RK_S32 idx)
285*437bfbebSnyanmisaka {
286*437bfbebSnyanmisaka     if (idx > 0) {
287*437bfbebSnyanmisaka         mpp_writer_put_bits(bitIf, rps->m_interRPSPrediction, 1); // inter_RPS_prediction_flag
288*437bfbebSnyanmisaka     }
289*437bfbebSnyanmisaka     if (rps->m_interRPSPrediction) {
290*437bfbebSnyanmisaka         RK_S32 deltaRPS = rps->m_deltaRPS;
291*437bfbebSnyanmisaka         RK_S32 j;
292*437bfbebSnyanmisaka 
293*437bfbebSnyanmisaka         mpp_writer_put_ue(bitIf, rps->m_deltaRIdxMinus1); // delta index of the Reference Picture Set used for prediction minus 1
294*437bfbebSnyanmisaka 
295*437bfbebSnyanmisaka         mpp_writer_put_bits(bitIf, (deltaRPS >= 0 ? 0 : 1), 1); //delta_rps_sign
296*437bfbebSnyanmisaka         mpp_writer_put_ue(bitIf, abs(deltaRPS) - 1); // absolute delta RPS minus 1
297*437bfbebSnyanmisaka 
298*437bfbebSnyanmisaka         for (j = 0; j < rps->m_numRefIdc; j++) {
299*437bfbebSnyanmisaka             RK_S32 refIdc = rps->m_refIdc[j];
300*437bfbebSnyanmisaka             mpp_writer_put_bits(bitIf, (refIdc == 1 ? 1 : 0), 1); //first bit is "1" if Idc is 1
301*437bfbebSnyanmisaka             if (refIdc != 1) {
302*437bfbebSnyanmisaka                 mpp_writer_put_bits(bitIf, refIdc >> 1, 1); //second bit is "1" if Idc is 2, "0" otherwise.
303*437bfbebSnyanmisaka             }
304*437bfbebSnyanmisaka         }
305*437bfbebSnyanmisaka     } else {
306*437bfbebSnyanmisaka         mpp_writer_put_ue(bitIf, rps->num_negative_pic);
307*437bfbebSnyanmisaka         mpp_writer_put_ue(bitIf, rps->num_positive_pic);
308*437bfbebSnyanmisaka         RK_S32 prev = 0;
309*437bfbebSnyanmisaka         RK_S32 j;
310*437bfbebSnyanmisaka 
311*437bfbebSnyanmisaka         for (j = 0; j < rps->num_negative_pic; j++) {
312*437bfbebSnyanmisaka             mpp_writer_put_ue(bitIf, prev - rps->delta_poc[j] - 1);
313*437bfbebSnyanmisaka             prev = rps->delta_poc[j];
314*437bfbebSnyanmisaka             mpp_writer_put_bits(bitIf, rps->m_used[j], 1);
315*437bfbebSnyanmisaka         }
316*437bfbebSnyanmisaka 
317*437bfbebSnyanmisaka         prev = 0;
318*437bfbebSnyanmisaka         for (j = rps->num_negative_pic; j < rps->num_negative_pic + rps->num_positive_pic; j++) {
319*437bfbebSnyanmisaka             mpp_writer_put_ue(bitIf, rps->delta_poc[j] - prev - 1);
320*437bfbebSnyanmisaka             prev = rps->delta_poc[j];
321*437bfbebSnyanmisaka             mpp_writer_put_bits(bitIf, rps->m_used[j], 1);
322*437bfbebSnyanmisaka         }
323*437bfbebSnyanmisaka     }
324*437bfbebSnyanmisaka }
325*437bfbebSnyanmisaka 
find_matching_ltrp(H265eSlice * slice,RK_U32 * ltrpsIndex,RK_S32 ltrpPOC,RK_U32 usedFlag)326*437bfbebSnyanmisaka RK_U8 find_matching_ltrp(H265eSlice* slice, RK_U32 *ltrpsIndex, RK_S32 ltrpPOC, RK_U32 usedFlag)
327*437bfbebSnyanmisaka {
328*437bfbebSnyanmisaka     RK_U32 lsb = ltrpPOC % (1 << slice->m_sps->m_bitsForPOC);
329*437bfbebSnyanmisaka     RK_U32 k;
330*437bfbebSnyanmisaka     for (k = 0; k < slice->m_sps->m_numLongTermRefPicSPS; k++) {
331*437bfbebSnyanmisaka         if ((lsb == slice->m_sps->m_ltRefPicPocLsbSps[k]) && (usedFlag == slice->m_sps->m_usedByCurrPicLtSPSFlag[k])) {
332*437bfbebSnyanmisaka             *ltrpsIndex = k;
333*437bfbebSnyanmisaka             return 1;
334*437bfbebSnyanmisaka         }
335*437bfbebSnyanmisaka     }
336*437bfbebSnyanmisaka 
337*437bfbebSnyanmisaka     return 0;
338*437bfbebSnyanmisaka }
339*437bfbebSnyanmisaka 
get_num_rps_cur_templist(H265eReferencePictureSet * rps)340*437bfbebSnyanmisaka RK_S32 get_num_rps_cur_templist(H265eReferencePictureSet* rps)
341*437bfbebSnyanmisaka {
342*437bfbebSnyanmisaka     RK_S32 numRpsCurrTempList = 0;
343*437bfbebSnyanmisaka     RK_S32 i;
344*437bfbebSnyanmisaka     for ( i = 0; i < rps->num_negative_pic + rps->num_positive_pic + rps->num_long_term_pic; i++) {
345*437bfbebSnyanmisaka         if (rps->m_used[i]) {
346*437bfbebSnyanmisaka             numRpsCurrTempList++;
347*437bfbebSnyanmisaka         }
348*437bfbebSnyanmisaka     }
349*437bfbebSnyanmisaka 
350*437bfbebSnyanmisaka     return numRpsCurrTempList;
351*437bfbebSnyanmisaka }
352*437bfbebSnyanmisaka 
353*437bfbebSnyanmisaka 
h265e_code_slice_header(H265eSlice * slice,MppWriteCtx * bitIf,RK_U32 slice_segment_addr)354*437bfbebSnyanmisaka void h265e_code_slice_header(H265eSlice *slice, MppWriteCtx *bitIf,
355*437bfbebSnyanmisaka                              RK_U32 slice_segment_addr)
356*437bfbebSnyanmisaka {
357*437bfbebSnyanmisaka     RK_U32 i = 0;
358*437bfbebSnyanmisaka     RK_U32 slice_address_addr_bits = 0;
359*437bfbebSnyanmisaka     H265eSps *sps = slice->m_sps;
360*437bfbebSnyanmisaka     RK_U32 pic_width_in_ctb = (sps->m_picWidthInLumaSamples + sps->m_maxCUSize - 1) /
361*437bfbebSnyanmisaka                               sps->m_maxCUSize;
362*437bfbebSnyanmisaka     RK_U32 pic_height_in_ctb = (sps->m_picHeightInLumaSamples + sps->m_maxCUSize - 1) /
363*437bfbebSnyanmisaka                                sps->m_maxCUSize;
364*437bfbebSnyanmisaka     RK_U32 max_ctu_num = pic_width_in_ctb * pic_height_in_ctb;
365*437bfbebSnyanmisaka 
366*437bfbebSnyanmisaka     mpp_writer_put_bits(bitIf, (slice_segment_addr == 0), 1); //first_slice_segment_in_pic_flag
367*437bfbebSnyanmisaka     mpp_writer_put_ue(bitIf, slice->m_ppsId);
368*437bfbebSnyanmisaka 
369*437bfbebSnyanmisaka     if (slice_segment_addr != 0) {
370*437bfbebSnyanmisaka         while (max_ctu_num > (RK_U32)(1 << slice_address_addr_bits)) {
371*437bfbebSnyanmisaka             slice_address_addr_bits++;
372*437bfbebSnyanmisaka         }
373*437bfbebSnyanmisaka         //slice_segment_address
374*437bfbebSnyanmisaka         mpp_writer_put_bits(bitIf, slice_segment_addr, slice_address_addr_bits);
375*437bfbebSnyanmisaka     }
376*437bfbebSnyanmisaka 
377*437bfbebSnyanmisaka     H265eReferencePictureSet* rps = slice->m_rps;
378*437bfbebSnyanmisaka     slice->m_enableTMVPFlag = 0;
379*437bfbebSnyanmisaka     if (!slice->m_dependentSliceSegmentFlag) {
380*437bfbebSnyanmisaka         for (i = 0; i < (RK_U32)slice->m_pps->m_numExtraSliceHeaderBits; i++) {
381*437bfbebSnyanmisaka             mpp_writer_put_bits(bitIf, (slice->slice_reserved_flag >> i) & 0x1, 1);
382*437bfbebSnyanmisaka         }
383*437bfbebSnyanmisaka 
384*437bfbebSnyanmisaka         mpp_writer_put_ue(bitIf, slice->m_sliceType);
385*437bfbebSnyanmisaka 
386*437bfbebSnyanmisaka         if (slice->m_pps->m_outputFlagPresentFlag) {
387*437bfbebSnyanmisaka             mpp_writer_put_bits(bitIf, slice->m_picOutputFlag ? 1 : 0, 1);
388*437bfbebSnyanmisaka         }
389*437bfbebSnyanmisaka 
390*437bfbebSnyanmisaka         if (slice->m_sliceType != I_SLICE) { // skip frame can't iDR
391*437bfbebSnyanmisaka             RK_S32 picOrderCntLSB = (slice->poc - slice->last_idr + (1 << slice->m_sps->m_bitsForPOC)) % (1 << slice->m_sps->m_bitsForPOC);
392*437bfbebSnyanmisaka             mpp_writer_put_bits(bitIf, picOrderCntLSB, slice->m_sps->m_bitsForPOC);
393*437bfbebSnyanmisaka             if (slice->m_bdIdx < 0) {
394*437bfbebSnyanmisaka                 mpp_writer_put_bits(bitIf, 0, 1);
395*437bfbebSnyanmisaka                 code_st_refpic_set(bitIf, rps, slice->m_sps->m_RPSList.m_numberOfReferencePictureSets);
396*437bfbebSnyanmisaka             } else {
397*437bfbebSnyanmisaka                 mpp_writer_put_bits(bitIf, 1, 1);
398*437bfbebSnyanmisaka                 RK_S32 numBits = 0;
399*437bfbebSnyanmisaka                 while ((1 << numBits) < slice->m_sps->m_RPSList.m_numberOfReferencePictureSets) {
400*437bfbebSnyanmisaka                     numBits++;
401*437bfbebSnyanmisaka                 }
402*437bfbebSnyanmisaka 
403*437bfbebSnyanmisaka                 if (numBits > 0) {
404*437bfbebSnyanmisaka                     mpp_writer_put_bits(bitIf, slice->m_bdIdx, numBits);
405*437bfbebSnyanmisaka                 }
406*437bfbebSnyanmisaka             }
407*437bfbebSnyanmisaka             if (slice->m_sps->m_bLongTermRefsPresent) {
408*437bfbebSnyanmisaka 
409*437bfbebSnyanmisaka                 RK_S32 numLtrpInSH = rps->m_numberOfPictures;
410*437bfbebSnyanmisaka                 RK_S32 ltrpInSPS[MAX_REFS];
411*437bfbebSnyanmisaka                 RK_S32 numLtrpInSPS = 0;
412*437bfbebSnyanmisaka                 RK_U32 ltrpIndex;
413*437bfbebSnyanmisaka                 RK_S32 counter = 0;
414*437bfbebSnyanmisaka                 RK_S32 k;
415*437bfbebSnyanmisaka                 for (k = rps->m_numberOfPictures - 1; k > rps->m_numberOfPictures - rps->num_long_term_pic - 1; k--) {
416*437bfbebSnyanmisaka                     if (find_matching_ltrp(slice, &ltrpIndex, rps->poc[k], rps->m_used[k])) {
417*437bfbebSnyanmisaka                         ltrpInSPS[numLtrpInSPS] = ltrpIndex;
418*437bfbebSnyanmisaka                         numLtrpInSPS++;
419*437bfbebSnyanmisaka                     } else {
420*437bfbebSnyanmisaka                         counter++;
421*437bfbebSnyanmisaka                     }
422*437bfbebSnyanmisaka                 }
423*437bfbebSnyanmisaka 
424*437bfbebSnyanmisaka                 numLtrpInSH -= rps->m_numberOfPictures - rps->num_long_term_pic;
425*437bfbebSnyanmisaka 
426*437bfbebSnyanmisaka                 RK_S32 bitsForLtrpInSPS = 0;
427*437bfbebSnyanmisaka                 while (slice->m_sps->m_numLongTermRefPicSPS > (RK_U32)(1 << bitsForLtrpInSPS)) {
428*437bfbebSnyanmisaka                     bitsForLtrpInSPS++;
429*437bfbebSnyanmisaka                 }
430*437bfbebSnyanmisaka 
431*437bfbebSnyanmisaka                 if (slice->m_sps->m_numLongTermRefPicSPS > 0) {
432*437bfbebSnyanmisaka                     mpp_writer_put_ue(bitIf, numLtrpInSPS);
433*437bfbebSnyanmisaka                 }
434*437bfbebSnyanmisaka                 mpp_writer_put_ue(bitIf, numLtrpInSH);
435*437bfbebSnyanmisaka                 // Note that the LSBs of the LT ref. pic. POCs must be sorted before.
436*437bfbebSnyanmisaka                 // Not sorted here because LT ref indices will be used in setRefPicList()
437*437bfbebSnyanmisaka                 RK_S32 prevDeltaMSB = 0;
438*437bfbebSnyanmisaka                 RK_S32 offset = rps->num_negative_pic + rps->num_positive_pic;
439*437bfbebSnyanmisaka                 for ( k = rps->m_numberOfPictures - 1; k > offset - 1; k--) {
440*437bfbebSnyanmisaka                     if (counter < numLtrpInSPS) {
441*437bfbebSnyanmisaka                         if (bitsForLtrpInSPS > 0) {
442*437bfbebSnyanmisaka                             mpp_writer_put_bits(bitIf, ltrpInSPS[counter], bitsForLtrpInSPS);
443*437bfbebSnyanmisaka                         }
444*437bfbebSnyanmisaka                     } else {
445*437bfbebSnyanmisaka                         mpp_writer_put_bits(bitIf, rps->m_pocLSBLT[k], slice->m_sps->m_bitsForPOC);
446*437bfbebSnyanmisaka                         mpp_writer_put_bits(bitIf, rps->m_used[k], 1);
447*437bfbebSnyanmisaka                     }
448*437bfbebSnyanmisaka                     mpp_writer_put_bits(bitIf, rps->m_deltaPocMSBPresentFlag[k], 1);
449*437bfbebSnyanmisaka 
450*437bfbebSnyanmisaka                     if (rps->m_deltaPocMSBPresentFlag[k]) {
451*437bfbebSnyanmisaka                         RK_U32 deltaFlag = 0;
452*437bfbebSnyanmisaka                         if ((k == rps->m_numberOfPictures - 1) || (k == rps->m_numberOfPictures - 1 - numLtrpInSPS)) {
453*437bfbebSnyanmisaka                             deltaFlag = 1;
454*437bfbebSnyanmisaka                         }
455*437bfbebSnyanmisaka                         if (deltaFlag) {
456*437bfbebSnyanmisaka                             mpp_writer_put_ue(bitIf, rps->m_deltaPOCMSBCycleLT[k]);
457*437bfbebSnyanmisaka                         } else {
458*437bfbebSnyanmisaka                             RK_S32 differenceInDeltaMSB = rps->m_deltaPOCMSBCycleLT[k] - prevDeltaMSB;
459*437bfbebSnyanmisaka                             mpp_writer_put_ue(bitIf, differenceInDeltaMSB);
460*437bfbebSnyanmisaka                         }
461*437bfbebSnyanmisaka                         prevDeltaMSB = rps->m_deltaPOCMSBCycleLT[k];
462*437bfbebSnyanmisaka                     }
463*437bfbebSnyanmisaka                 }
464*437bfbebSnyanmisaka             }
465*437bfbebSnyanmisaka             if (slice->m_sps->m_TMVPFlagsPresent) {
466*437bfbebSnyanmisaka                 mpp_writer_put_bits(bitIf, slice->m_enableTMVPFlag ? 1 : 0, 1);
467*437bfbebSnyanmisaka             }
468*437bfbebSnyanmisaka         }
469*437bfbebSnyanmisaka 
470*437bfbebSnyanmisaka         if (slice->m_sps->m_bUseSAO) { //skip frame close sao
471*437bfbebSnyanmisaka             mpp_writer_put_bits(bitIf, 0, 1);
472*437bfbebSnyanmisaka             mpp_writer_put_bits(bitIf, 0, 1);
473*437bfbebSnyanmisaka 
474*437bfbebSnyanmisaka         }
475*437bfbebSnyanmisaka         //check if numrefidxes match the defaults. If not, override
476*437bfbebSnyanmisaka 
477*437bfbebSnyanmisaka         if (slice->m_sliceType != I_SLICE) {
478*437bfbebSnyanmisaka             RK_U32 overrideFlag = (slice->m_numRefIdx[0] != (RK_S32)slice->m_pps->m_numRefIdxL0DefaultActive);
479*437bfbebSnyanmisaka             mpp_writer_put_bits(bitIf, overrideFlag ? 1 : 0, 1);
480*437bfbebSnyanmisaka             if (overrideFlag) {
481*437bfbebSnyanmisaka                 mpp_writer_put_ue(bitIf, slice->m_numRefIdx[0] - 1);
482*437bfbebSnyanmisaka                 slice->m_numRefIdx[1] = 0;
483*437bfbebSnyanmisaka             }
484*437bfbebSnyanmisaka         }
485*437bfbebSnyanmisaka 
486*437bfbebSnyanmisaka         if (slice->m_pps->m_listsModificationPresentFlag && get_num_rps_cur_templist(rps) > 1) {
487*437bfbebSnyanmisaka             H265eRefPicListModification* refPicListModification = &slice->m_RefPicListModification;
488*437bfbebSnyanmisaka             mpp_writer_put_bits(bitIf, refPicListModification->m_refPicListModificationFlagL0 ? 1 : 0, 1);
489*437bfbebSnyanmisaka             if (refPicListModification->m_refPicListModificationFlagL0) {
490*437bfbebSnyanmisaka                 RK_S32 numRpsCurrTempList0 = get_num_rps_cur_templist(rps);
491*437bfbebSnyanmisaka                 if (numRpsCurrTempList0 > 1) {
492*437bfbebSnyanmisaka                     RK_S32 length = 1;
493*437bfbebSnyanmisaka                     numRpsCurrTempList0--;
494*437bfbebSnyanmisaka                     while (numRpsCurrTempList0 >>= 1) {
495*437bfbebSnyanmisaka                         length++;
496*437bfbebSnyanmisaka                     }
497*437bfbebSnyanmisaka                     for (i = 0; i < (RK_U32)slice->m_numRefIdx[0]; i++) {
498*437bfbebSnyanmisaka                         mpp_writer_put_bits(bitIf, refPicListModification->m_RefPicSetIdxL0[i], length);
499*437bfbebSnyanmisaka                     }
500*437bfbebSnyanmisaka                 }
501*437bfbebSnyanmisaka             }
502*437bfbebSnyanmisaka         }
503*437bfbebSnyanmisaka 
504*437bfbebSnyanmisaka         if (slice->m_pps->m_cabacInitPresentFlag) {
505*437bfbebSnyanmisaka             mpp_writer_put_bits(bitIf, slice->m_cabacInitFlag, 1);
506*437bfbebSnyanmisaka         }
507*437bfbebSnyanmisaka 
508*437bfbebSnyanmisaka         if (slice->m_enableTMVPFlag) {
509*437bfbebSnyanmisaka 
510*437bfbebSnyanmisaka             if (slice->m_sliceType != I_SLICE &&
511*437bfbebSnyanmisaka                 ((slice->m_colFromL0Flag == 1 && slice->m_numRefIdx[0] > 1) ||
512*437bfbebSnyanmisaka                  (slice->m_colFromL0Flag == 0 && slice->m_numRefIdx[1] > 1))) {
513*437bfbebSnyanmisaka                 mpp_writer_put_ue(bitIf, slice->m_colRefIdx);
514*437bfbebSnyanmisaka             }
515*437bfbebSnyanmisaka         }
516*437bfbebSnyanmisaka 
517*437bfbebSnyanmisaka         if (slice->m_sliceType != I_SLICE) {
518*437bfbebSnyanmisaka             RK_S32 flag = MRG_MAX_NUM_CANDS - slice->m_maxNumMergeCand;
519*437bfbebSnyanmisaka             flag = flag == 5 ? 4 : flag;
520*437bfbebSnyanmisaka             mpp_writer_put_ue(bitIf, flag);
521*437bfbebSnyanmisaka         }
522*437bfbebSnyanmisaka         RK_S32 code = slice->m_sliceQp - (slice->m_pps->m_picInitQPMinus26 + 26);
523*437bfbebSnyanmisaka         mpp_writer_put_se(bitIf, code);
524*437bfbebSnyanmisaka         if (slice->m_pps->m_bSliceChromaQpFlag) {
525*437bfbebSnyanmisaka             code = slice->m_sliceQpDeltaCb;
526*437bfbebSnyanmisaka             mpp_writer_put_se(bitIf, code);
527*437bfbebSnyanmisaka             code = slice->m_sliceQpDeltaCr;
528*437bfbebSnyanmisaka             mpp_writer_put_se(bitIf, code);
529*437bfbebSnyanmisaka         }
530*437bfbebSnyanmisaka         if (slice->m_pps->m_deblockingFilterControlPresentFlag) {
531*437bfbebSnyanmisaka             if (slice->m_pps->m_deblockingFilterOverrideEnabledFlag) {
532*437bfbebSnyanmisaka                 mpp_writer_put_bits(bitIf, slice->m_deblockingFilterOverrideFlag, 1);
533*437bfbebSnyanmisaka             }
534*437bfbebSnyanmisaka             if (slice->m_deblockingFilterOverrideFlag) {
535*437bfbebSnyanmisaka                 mpp_writer_put_bits(bitIf, slice->m_deblockingFilterDisable, 1);
536*437bfbebSnyanmisaka                 if (!slice->m_deblockingFilterDisable) {
537*437bfbebSnyanmisaka                     mpp_writer_put_se(bitIf, slice->m_deblockingFilterBetaOffsetDiv2);
538*437bfbebSnyanmisaka                     mpp_writer_put_se(bitIf, slice->m_deblockingFilterTcOffsetDiv2);
539*437bfbebSnyanmisaka                 }
540*437bfbebSnyanmisaka             }
541*437bfbebSnyanmisaka         }
542*437bfbebSnyanmisaka     }
543*437bfbebSnyanmisaka     if (slice->m_pps->m_tiles_enabled_flag) {
544*437bfbebSnyanmisaka         mpp_writer_put_ue(bitIf, 0);    // num_entry_point_offsets
545*437bfbebSnyanmisaka     }
546*437bfbebSnyanmisaka     if (slice->m_pps->m_sliceHeaderExtensionPresentFlag) {
547*437bfbebSnyanmisaka         mpp_writer_put_ue(bitIf, slice->slice_header_extension_length);
548*437bfbebSnyanmisaka         for (i = 0; i < slice->slice_header_extension_length; i++) {
549*437bfbebSnyanmisaka             mpp_writer_put_bits(bitIf, 0, 8);
550*437bfbebSnyanmisaka         }
551*437bfbebSnyanmisaka     }
552*437bfbebSnyanmisaka     h265e_dbg_func("leave\n");
553*437bfbebSnyanmisaka }
554*437bfbebSnyanmisaka 
code_skip_flag(H265eSlice * slice,RK_U32 abs_part_idx,DataCu * cu)555*437bfbebSnyanmisaka void code_skip_flag(H265eSlice *slice, RK_U32 abs_part_idx, DataCu *cu)
556*437bfbebSnyanmisaka {
557*437bfbebSnyanmisaka     // get context function is here
558*437bfbebSnyanmisaka     H265eCabacCtx *cabac_ctx = &slice->m_cabac;
559*437bfbebSnyanmisaka     H265eSps *sps = slice->m_sps;
560*437bfbebSnyanmisaka     RK_U32  ctxSkip;
561*437bfbebSnyanmisaka     RK_U32 tpelx = cu->pixelX + sps->raster2pelx[sps->zscan2raster[abs_part_idx]];
562*437bfbebSnyanmisaka     RK_U32 tpely = cu->pixelY + sps->raster2pely[sps->zscan2raster[abs_part_idx]];
563*437bfbebSnyanmisaka     //RK_U32 ctxSkip = cu->getCtxSkipFlag(abs_part_idx);
564*437bfbebSnyanmisaka 
565*437bfbebSnyanmisaka     h265e_dbg_skip("tpelx = %d", tpelx);
566*437bfbebSnyanmisaka     if (cu->cur_addr == 0 ) {
567*437bfbebSnyanmisaka         ctxSkip = 0;
568*437bfbebSnyanmisaka     } else if ((tpely == 0) || (tpelx == cu->tile_start_x)) {
569*437bfbebSnyanmisaka         ctxSkip = 1;
570*437bfbebSnyanmisaka     } else {
571*437bfbebSnyanmisaka         ctxSkip = 2;
572*437bfbebSnyanmisaka     }
573*437bfbebSnyanmisaka     h265e_dbg_skip("ctxSkip = %d", ctxSkip);
574*437bfbebSnyanmisaka     h265e_cabac_encodeBin(cabac_ctx, &slice->m_contextModels[OFF_SKIP_FLAG_CTX + ctxSkip], 1);
575*437bfbebSnyanmisaka }
576*437bfbebSnyanmisaka 
code_merge_index(H265eSlice * slice)577*437bfbebSnyanmisaka static void code_merge_index(H265eSlice *slice)
578*437bfbebSnyanmisaka {
579*437bfbebSnyanmisaka     H265eCabacCtx *cabac_ctx = &slice->m_cabac;
580*437bfbebSnyanmisaka 
581*437bfbebSnyanmisaka     h265e_cabac_encodeBin(cabac_ctx, &slice->m_contextModels[OFF_MERGE_IDX_EXT_CTX], 0);
582*437bfbebSnyanmisaka }
583*437bfbebSnyanmisaka 
code_split_flag(H265eSlice * slice,RK_U32 abs_part_idx,RK_U32 depth,DataCu * cu)584*437bfbebSnyanmisaka static void code_split_flag(H265eSlice *slice, RK_U32 abs_part_idx, RK_U32 depth, DataCu *cu)
585*437bfbebSnyanmisaka {
586*437bfbebSnyanmisaka     H265eSps *sps = slice->m_sps;
587*437bfbebSnyanmisaka 
588*437bfbebSnyanmisaka     if (depth == slice->m_sps->m_maxCUDepth - slice->m_sps->m_addCUDepth)
589*437bfbebSnyanmisaka         return;
590*437bfbebSnyanmisaka 
591*437bfbebSnyanmisaka     h265e_dbg_skip("depth %d cu->m_cuDepth %d", depth, cu->m_cuDepth[sps->zscan2raster[abs_part_idx]]);
592*437bfbebSnyanmisaka 
593*437bfbebSnyanmisaka     H265eCabacCtx *cabac_ctx = &slice->m_cabac;
594*437bfbebSnyanmisaka     RK_U32 currSplitFlag = (cu->m_cuDepth[sps->zscan2raster[abs_part_idx]] > depth) ? 1 : 0;
595*437bfbebSnyanmisaka 
596*437bfbebSnyanmisaka     h265e_cabac_encodeBin(cabac_ctx, &slice->m_contextModels[OFF_SPLIT_FLAG_CTX], currSplitFlag);
597*437bfbebSnyanmisaka }
598*437bfbebSnyanmisaka 
encode_cu(H265eSlice * slice,RK_U32 abs_part_idx,RK_U32 depth,DataCu * cu)599*437bfbebSnyanmisaka static void encode_cu(H265eSlice *slice, RK_U32 abs_part_idx, RK_U32 depth, DataCu *cu)
600*437bfbebSnyanmisaka {
601*437bfbebSnyanmisaka     H265eSps *sps = slice->m_sps;
602*437bfbebSnyanmisaka     RK_U32 bBoundary = 0;
603*437bfbebSnyanmisaka     RK_U32 lpelx = cu->pixelX + sps->raster2pelx[sps->zscan2raster[abs_part_idx]];
604*437bfbebSnyanmisaka     RK_U32 rpelx = lpelx + (sps->m_maxCUSize >> depth) - 1;
605*437bfbebSnyanmisaka     RK_U32 tpely = cu->pixelY + sps->raster2pely[sps->zscan2raster[abs_part_idx]];
606*437bfbebSnyanmisaka     RK_U32 bpely = tpely + (sps->m_maxCUSize >> depth) - 1;
607*437bfbebSnyanmisaka 
608*437bfbebSnyanmisaka     h265e_dbg_skip("EncodeCU depth %d, abs_part_idx %d", depth, abs_part_idx);
609*437bfbebSnyanmisaka 
610*437bfbebSnyanmisaka     if ((rpelx <= cu->tile_end_x) && (bpely <= cu->tile_end_y)) {
611*437bfbebSnyanmisaka         h265e_dbg_skip("code_split_flag in depth %d", depth);
612*437bfbebSnyanmisaka         code_split_flag(slice, abs_part_idx, depth, cu);
613*437bfbebSnyanmisaka     } else {
614*437bfbebSnyanmisaka         h265e_dbg_skip("boundary flag found");
615*437bfbebSnyanmisaka         bBoundary = 1;
616*437bfbebSnyanmisaka     }
617*437bfbebSnyanmisaka 
618*437bfbebSnyanmisaka     h265e_dbg_skip("m_cuDepth[%d] = %d maxCUDepth %d, m_addCUDepth %d", abs_part_idx, cu->m_cuDepth[sps->zscan2raster[abs_part_idx]], sps->m_maxCUDepth, sps->m_addCUDepth);
619*437bfbebSnyanmisaka 
620*437bfbebSnyanmisaka     if ((depth < cu->m_cuDepth[sps->zscan2raster[abs_part_idx]] && (depth < (sps->m_maxCUDepth - sps->m_addCUDepth))) || bBoundary) {
621*437bfbebSnyanmisaka         RK_U32 numPartions = 1 << (sps->m_maxCUDepth << 1);
622*437bfbebSnyanmisaka         RK_U32 qNumParts = (numPartions >> (depth << 1)) >> 2;
623*437bfbebSnyanmisaka         RK_U32 partUnitIdx = 0;
624*437bfbebSnyanmisaka 
625*437bfbebSnyanmisaka         for (partUnitIdx = 0; partUnitIdx < 4; partUnitIdx++, abs_part_idx += qNumParts) {
626*437bfbebSnyanmisaka             h265e_dbg_skip("depth %d partUnitIdx = %d, qNumParts %d, abs_part_idx %d", depth, partUnitIdx, qNumParts, abs_part_idx);
627*437bfbebSnyanmisaka             lpelx = cu->pixelX + sps->raster2pelx[sps->zscan2raster[abs_part_idx]];
628*437bfbebSnyanmisaka             tpely = cu->pixelY + sps->raster2pely[sps->zscan2raster[abs_part_idx]];
629*437bfbebSnyanmisaka             if ((lpelx <= cu->tile_end_x) && (tpely <= cu->tile_end_y)) {
630*437bfbebSnyanmisaka                 encode_cu(slice, abs_part_idx, depth + 1, cu);
631*437bfbebSnyanmisaka             }
632*437bfbebSnyanmisaka         }
633*437bfbebSnyanmisaka         return;
634*437bfbebSnyanmisaka     }
635*437bfbebSnyanmisaka 
636*437bfbebSnyanmisaka     h265e_dbg_skip("code_skip_flag in depth %d", depth);
637*437bfbebSnyanmisaka     code_skip_flag(slice, abs_part_idx, cu);
638*437bfbebSnyanmisaka     h265e_dbg_skip("code_merge_index in depth %d", depth);
639*437bfbebSnyanmisaka     code_merge_index(slice);
640*437bfbebSnyanmisaka     return;
641*437bfbebSnyanmisaka }
642*437bfbebSnyanmisaka 
proc_cu8(DataCu * cu,RK_S32 nSubPart,RK_S32 cuDepth,RK_S32 puIdx)643*437bfbebSnyanmisaka static void proc_cu8(DataCu *cu, RK_S32 nSubPart, RK_S32 cuDepth, RK_S32 puIdx)
644*437bfbebSnyanmisaka {
645*437bfbebSnyanmisaka     h265e_dbg_skip("8 ctu puIdx %d no need split", puIdx);
646*437bfbebSnyanmisaka 
647*437bfbebSnyanmisaka     memset(cu->m_cuDepth + puIdx * nSubPart, cuDepth, nSubPart);
648*437bfbebSnyanmisaka }
649*437bfbebSnyanmisaka 
proc_cu16(DataCu * cu,RK_U32 pos_x,RK_U32 pos_y,RK_S32 nSubPart,RK_S32 cuDepth,RK_S32 puIdx)650*437bfbebSnyanmisaka static void proc_cu16(DataCu *cu, RK_U32 pos_x, RK_U32 pos_y,
651*437bfbebSnyanmisaka                       RK_S32 nSubPart, RK_S32 cuDepth, RK_S32 puIdx)
652*437bfbebSnyanmisaka {
653*437bfbebSnyanmisaka     RK_U32 m;
654*437bfbebSnyanmisaka     RK_S32 newPuIdx;
655*437bfbebSnyanmisaka 
656*437bfbebSnyanmisaka     h265e_dbg_skip("cu 16 pos_x %d pos_y %d", pos_x, pos_y);
657*437bfbebSnyanmisaka 
658*437bfbebSnyanmisaka     if ((cu->pixelX + pos_x + 15 <= cu->tile_end_x) &&
659*437bfbebSnyanmisaka         (cu->pixelY + pos_y + 15 <= cu->tile_end_y)) {
660*437bfbebSnyanmisaka         h265e_dbg_skip("16 ctu puIdx %d no need split", puIdx);
661*437bfbebSnyanmisaka         memset(cu->m_cuDepth + puIdx * nSubPart, cuDepth, nSubPart);
662*437bfbebSnyanmisaka         return;
663*437bfbebSnyanmisaka     } else if ((cu->pixelX + pos_x > cu->tile_end_x) ||
664*437bfbebSnyanmisaka                (cu->pixelY + pos_y > cu->tile_end_y)) {
665*437bfbebSnyanmisaka         h265e_dbg_skip("16 ctu puIdx %d out of pic", puIdx);
666*437bfbebSnyanmisaka         memset(cu->m_cuDepth + puIdx * nSubPart, cuDepth, nSubPart);
667*437bfbebSnyanmisaka         return;
668*437bfbebSnyanmisaka     }
669*437bfbebSnyanmisaka 
670*437bfbebSnyanmisaka     for (m = 0; m < 4; m ++) {
671*437bfbebSnyanmisaka         newPuIdx = puIdx * 4 + m;
672*437bfbebSnyanmisaka         proc_cu8(cu, nSubPart / 4, cuDepth + 1, newPuIdx);
673*437bfbebSnyanmisaka     }
674*437bfbebSnyanmisaka }
675*437bfbebSnyanmisaka 
proc_cu32(DataCu * cu,RK_U32 pos_x,RK_U32 pos_y,RK_S32 nSubPart,RK_S32 cuDepth,RK_S32 puIdx)676*437bfbebSnyanmisaka static void proc_cu32(DataCu *cu, RK_U32 pos_x, RK_U32 pos_y,
677*437bfbebSnyanmisaka                       RK_S32 nSubPart, RK_S32 cuDepth, RK_S32 puIdx)
678*437bfbebSnyanmisaka {
679*437bfbebSnyanmisaka     RK_U32 m;
680*437bfbebSnyanmisaka     RK_S32 nSize = 32;
681*437bfbebSnyanmisaka     RK_U32 cu_x_1, cu_y_1;
682*437bfbebSnyanmisaka     RK_S32 newPuIdx;
683*437bfbebSnyanmisaka 
684*437bfbebSnyanmisaka     h265e_dbg_skip("cu 32 pos_x %d pos_y %d", pos_x, pos_y);
685*437bfbebSnyanmisaka 
686*437bfbebSnyanmisaka     if ((cu->pixelX + pos_x + 31 <= cu->tile_end_x) &&
687*437bfbebSnyanmisaka         (cu->pixelY + pos_y + 31 <= cu->tile_end_y)) {
688*437bfbebSnyanmisaka         h265e_dbg_skip("32 ctu puIdx %d no need split", puIdx);
689*437bfbebSnyanmisaka         memset(cu->m_cuDepth + puIdx * nSubPart, cuDepth, nSubPart);
690*437bfbebSnyanmisaka         return;
691*437bfbebSnyanmisaka     } else if ((cu->pixelX + pos_x > cu->tile_end_x) ||
692*437bfbebSnyanmisaka                (cu->pixelY + pos_y > cu->tile_end_y)) {
693*437bfbebSnyanmisaka         h265e_dbg_skip("32 ctu puIdx %d out of pic", puIdx);
694*437bfbebSnyanmisaka         memset(cu->m_cuDepth + puIdx * nSubPart, cuDepth, nSubPart);
695*437bfbebSnyanmisaka         return;
696*437bfbebSnyanmisaka     }
697*437bfbebSnyanmisaka 
698*437bfbebSnyanmisaka     for (m = 0; m < 4; m ++) {
699*437bfbebSnyanmisaka         cu_x_1 = pos_x + (m & 1) * (nSize >> 1);
700*437bfbebSnyanmisaka         cu_y_1 = pos_y + (m >> 1) * (nSize >> 1);
701*437bfbebSnyanmisaka         newPuIdx = puIdx * 4 + m;
702*437bfbebSnyanmisaka         proc_cu16(cu, cu_x_1, cu_y_1, nSubPart / 4, cuDepth + 1, newPuIdx);
703*437bfbebSnyanmisaka     }
704*437bfbebSnyanmisaka }
705*437bfbebSnyanmisaka 
proc_ctu64(H265eSlice * slice,DataCu * cu)706*437bfbebSnyanmisaka static void proc_ctu64(H265eSlice *slice, DataCu *cu)
707*437bfbebSnyanmisaka {
708*437bfbebSnyanmisaka     H265eSps *sps = slice->m_sps;
709*437bfbebSnyanmisaka     RK_U32 k, m;
710*437bfbebSnyanmisaka     RK_U32 cu_x_1, cu_y_1;
711*437bfbebSnyanmisaka     RK_U32 m_nCtuSize = sps->m_maxCUSize;
712*437bfbebSnyanmisaka     RK_U32 lpelx = cu->pixelX;
713*437bfbebSnyanmisaka     RK_U32 rpelx = lpelx + m_nCtuSize - 1;
714*437bfbebSnyanmisaka     RK_U32 tpely = cu->pixelY;
715*437bfbebSnyanmisaka     RK_U32 bpely = tpely + m_nCtuSize - 1;
716*437bfbebSnyanmisaka     RK_U32 numPartions = 1 << (sps->m_maxCUDepth << 1);
717*437bfbebSnyanmisaka     RK_S32 cuDepth = 0;
718*437bfbebSnyanmisaka 
719*437bfbebSnyanmisaka     for (k = 0; k < numPartions; k++) {
720*437bfbebSnyanmisaka         cu->m_cuDepth[k] = 0;
721*437bfbebSnyanmisaka         cu->m_cuSize[k] = m_nCtuSize;
722*437bfbebSnyanmisaka     }
723*437bfbebSnyanmisaka     if ((rpelx <= cu->tile_end_x) && (bpely <= cu->tile_end_y))
724*437bfbebSnyanmisaka         return;
725*437bfbebSnyanmisaka 
726*437bfbebSnyanmisaka     for (m = 0; m < 4; m ++) {
727*437bfbebSnyanmisaka         cu_x_1 = (m & 1) * (m_nCtuSize >> 1);
728*437bfbebSnyanmisaka         cu_y_1 = (m >> 1) * (m_nCtuSize >> 1);
729*437bfbebSnyanmisaka         proc_cu32(cu, cu_x_1, cu_y_1, numPartions / 4, cuDepth + 1, m);
730*437bfbebSnyanmisaka     }
731*437bfbebSnyanmisaka 
732*437bfbebSnyanmisaka     for (k = 0; k < numPartions; k++) {
733*437bfbebSnyanmisaka         switch (cu->m_cuDepth[k]) {
734*437bfbebSnyanmisaka         case 0: cu->m_cuSize[k] = 64; break;
735*437bfbebSnyanmisaka         case 1: cu->m_cuSize[k] = 32; break;
736*437bfbebSnyanmisaka         case 2: cu->m_cuSize[k] = 16; break;
737*437bfbebSnyanmisaka         case 3: cu->m_cuSize[k] = 8;  break;
738*437bfbebSnyanmisaka         }
739*437bfbebSnyanmisaka     }
740*437bfbebSnyanmisaka }
741*437bfbebSnyanmisaka 
h265e_write_nal(MppWriteCtx * bitIf,RK_S32 temporal_id)742*437bfbebSnyanmisaka static void h265e_write_nal(MppWriteCtx *bitIf, RK_S32 temporal_id)
743*437bfbebSnyanmisaka {
744*437bfbebSnyanmisaka     h265e_dbg_func("enter\n");
745*437bfbebSnyanmisaka 
746*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bitIf, 0x0, 24);
747*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bitIf, 0x01, 8);
748*437bfbebSnyanmisaka     mpp_writer_put_bits(bitIf, 0, 1);   //forbidden_zero_bit
749*437bfbebSnyanmisaka     mpp_writer_put_bits(bitIf, 1, 6);   //nal_unit_type
750*437bfbebSnyanmisaka     mpp_writer_put_bits(bitIf, 0, 6);   //nuh_reserved_zero_6bits
751*437bfbebSnyanmisaka     mpp_writer_put_bits(bitIf, temporal_id + 1, 3); //nuh_temporal_id_plus1
752*437bfbebSnyanmisaka 
753*437bfbebSnyanmisaka     h265e_dbg_func("leave\n");
754*437bfbebSnyanmisaka }
755*437bfbebSnyanmisaka 
h265e_write_algin(MppWriteCtx * bitIf)756*437bfbebSnyanmisaka static void h265e_write_algin(MppWriteCtx *bitIf)
757*437bfbebSnyanmisaka {
758*437bfbebSnyanmisaka     h265e_dbg_func("enter\n");
759*437bfbebSnyanmisaka     mpp_writer_put_bits(bitIf, 1, 1);
760*437bfbebSnyanmisaka     mpp_writer_align_zero(bitIf);
761*437bfbebSnyanmisaka     h265e_dbg_func("leave\n");
762*437bfbebSnyanmisaka }
763*437bfbebSnyanmisaka 
proc_ctu32(H265eSlice * slice,DataCu * cu)764*437bfbebSnyanmisaka static void proc_ctu32(H265eSlice *slice, DataCu *cu)
765*437bfbebSnyanmisaka {
766*437bfbebSnyanmisaka     H265eSps *sps = slice->m_sps;
767*437bfbebSnyanmisaka     RK_U32 k, m;
768*437bfbebSnyanmisaka     RK_U32 cu_x_1, cu_y_1;
769*437bfbebSnyanmisaka     RK_U32 m_nCtuSize = sps->m_maxCUSize;
770*437bfbebSnyanmisaka     RK_U32 lpelx = cu->pixelX;
771*437bfbebSnyanmisaka     RK_U32 rpelx = lpelx + m_nCtuSize - 1;
772*437bfbebSnyanmisaka     RK_U32 tpely = cu->pixelY;
773*437bfbebSnyanmisaka     RK_U32 bpely = tpely + m_nCtuSize - 1;
774*437bfbebSnyanmisaka     RK_U32 numPartions = 1 << (sps->m_maxCUDepth << 1);
775*437bfbebSnyanmisaka     RK_S32 cuDepth = 0;
776*437bfbebSnyanmisaka 
777*437bfbebSnyanmisaka     for (k = 0; k < numPartions; k++) {
778*437bfbebSnyanmisaka         cu->m_cuDepth[k] = 0;
779*437bfbebSnyanmisaka         cu->m_cuSize[k] = m_nCtuSize;
780*437bfbebSnyanmisaka     }
781*437bfbebSnyanmisaka     if ((rpelx <= cu->tile_end_x) && (bpely <= cu->tile_end_y))
782*437bfbebSnyanmisaka         return;
783*437bfbebSnyanmisaka 
784*437bfbebSnyanmisaka     for (m = 0; m < 4; m ++) {
785*437bfbebSnyanmisaka         cu_x_1 = (m & 1) * (m_nCtuSize >> 1);
786*437bfbebSnyanmisaka         cu_y_1 = (m >> 1) * (m_nCtuSize >> 1);
787*437bfbebSnyanmisaka         proc_cu16(cu, cu_x_1, cu_y_1, numPartions / 4, cuDepth + 1, m);
788*437bfbebSnyanmisaka     }
789*437bfbebSnyanmisaka 
790*437bfbebSnyanmisaka     for (k = 0; k < numPartions; k++) {
791*437bfbebSnyanmisaka         switch (cu->m_cuDepth[k]) {
792*437bfbebSnyanmisaka         case 0: cu->m_cuSize[k] = 32; break;
793*437bfbebSnyanmisaka         case 1: cu->m_cuSize[k] = 16; break;
794*437bfbebSnyanmisaka         case 2: cu->m_cuSize[k] = 8;  break;
795*437bfbebSnyanmisaka         }
796*437bfbebSnyanmisaka     }
797*437bfbebSnyanmisaka }
798*437bfbebSnyanmisaka 
h265e_code_skip_tile(void * ctx,H265eSlice * slice,MppWriteCtx * bitIf,TileInfo * tile)799*437bfbebSnyanmisaka static void h265e_code_skip_tile(void *ctx, H265eSlice *slice, MppWriteCtx *bitIf, TileInfo *tile)
800*437bfbebSnyanmisaka {
801*437bfbebSnyanmisaka     DataCu cu;
802*437bfbebSnyanmisaka     void (*proc_ctu)(H265eSlice *, DataCu *);
803*437bfbebSnyanmisaka     H265eCtx *p = (H265eCtx *)ctx;
804*437bfbebSnyanmisaka     H265eSps *sps = &p->sps;
805*437bfbebSnyanmisaka     H265eCabacCtx *cabac_ctx = &slice->m_cabac;
806*437bfbebSnyanmisaka     RK_U32 cu_cnt;
807*437bfbebSnyanmisaka     RK_U32 offset_x = tile->tile_start_x;
808*437bfbebSnyanmisaka     RK_U32 offset_y = tile->tile_start_y;
809*437bfbebSnyanmisaka 
810*437bfbebSnyanmisaka     if (sps->m_maxCUSize == 32)
811*437bfbebSnyanmisaka         /* rk3528 maxCUSize[32] depth[3], other chips maxCUSize[64] depth[4],
812*437bfbebSnyanmisaka            So special handling is required */
813*437bfbebSnyanmisaka         proc_ctu = proc_ctu32;
814*437bfbebSnyanmisaka     else
815*437bfbebSnyanmisaka         proc_ctu = proc_ctu64;
816*437bfbebSnyanmisaka 
817*437bfbebSnyanmisaka     h265e_write_nal(bitIf, slice->temporal_id);
818*437bfbebSnyanmisaka     h265e_code_slice_header(slice, bitIf, tile->ctu_addr);
819*437bfbebSnyanmisaka     h265e_write_algin(bitIf);
820*437bfbebSnyanmisaka     h265e_reset_enctropy((void*)slice);
821*437bfbebSnyanmisaka     h265e_cabac_init(cabac_ctx, bitIf);
822*437bfbebSnyanmisaka 
823*437bfbebSnyanmisaka     slice->is_referenced = 0;
824*437bfbebSnyanmisaka     cu.tile_start_x = tile->tile_start_x;
825*437bfbebSnyanmisaka     cu.tile_end_x = tile->tile_end_x;
826*437bfbebSnyanmisaka     cu.tile_end_y = tile->tile_end_y;
827*437bfbebSnyanmisaka     for (cu_cnt = 0; cu_cnt < tile->mb_total - 1; cu_cnt++) {
828*437bfbebSnyanmisaka         cu.pixelX = offset_x;
829*437bfbebSnyanmisaka         cu.pixelY = offset_y;
830*437bfbebSnyanmisaka         cu.cur_addr = cu_cnt;
831*437bfbebSnyanmisaka         proc_ctu(slice, &cu);
832*437bfbebSnyanmisaka         encode_cu(slice, 0, 0, &cu);
833*437bfbebSnyanmisaka         h265e_cabac_encodeBinTrm(cabac_ctx, 0);
834*437bfbebSnyanmisaka         offset_x += sps->m_maxCUSize;
835*437bfbebSnyanmisaka         if (offset_x > tile->tile_end_x) {
836*437bfbebSnyanmisaka             offset_x = tile->tile_start_x;
837*437bfbebSnyanmisaka             offset_y += sps->m_maxCUSize;
838*437bfbebSnyanmisaka         }
839*437bfbebSnyanmisaka     }
840*437bfbebSnyanmisaka     /* The last CTU handled independently, reducing the cost */
841*437bfbebSnyanmisaka     cu.pixelX = offset_x;
842*437bfbebSnyanmisaka     cu.pixelY = offset_y;
843*437bfbebSnyanmisaka     cu.cur_addr = cu_cnt;
844*437bfbebSnyanmisaka     proc_ctu(slice, &cu);
845*437bfbebSnyanmisaka     encode_cu(slice, 0, 0, &cu);
846*437bfbebSnyanmisaka     h265e_cabac_encodeBinTrm(cabac_ctx, 1);
847*437bfbebSnyanmisaka     h265e_cabac_finish(cabac_ctx);
848*437bfbebSnyanmisaka     h265e_write_algin(bitIf);
849*437bfbebSnyanmisaka }
850*437bfbebSnyanmisaka 
h265e_code_slice_skip_frame(void * ctx,H265eSlice * slice,RK_U8 * buf,RK_S32 len)851*437bfbebSnyanmisaka RK_S32 h265e_code_slice_skip_frame(void *ctx, H265eSlice *slice, RK_U8 *buf, RK_S32 len)
852*437bfbebSnyanmisaka {
853*437bfbebSnyanmisaka     H265eCtx *p = (H265eCtx *)ctx;
854*437bfbebSnyanmisaka     H265eSps *sps = &p->sps;
855*437bfbebSnyanmisaka     H265ePps *pps = &p->pps;
856*437bfbebSnyanmisaka     TileInfo tile;
857*437bfbebSnyanmisaka     MppWriteCtx bitIf;
858*437bfbebSnyanmisaka     RK_U32 mb_wd;
859*437bfbebSnyanmisaka     RK_U32 mb_h;
860*437bfbebSnyanmisaka     RK_S32 i;
861*437bfbebSnyanmisaka 
862*437bfbebSnyanmisaka     h265e_dbg_func("enter\n");
863*437bfbebSnyanmisaka     if (!buf || !len) {
864*437bfbebSnyanmisaka         mpp_err("buf or size no set");
865*437bfbebSnyanmisaka         return MPP_NOK;
866*437bfbebSnyanmisaka     }
867*437bfbebSnyanmisaka 
868*437bfbebSnyanmisaka     mpp_writer_init(&bitIf, buf, len);
869*437bfbebSnyanmisaka     tile.ctu_addr = 0;
870*437bfbebSnyanmisaka     tile.tile_start_y = 0;
871*437bfbebSnyanmisaka     tile.tile_end_y = sps->m_picHeightInLumaSamples - 1;
872*437bfbebSnyanmisaka 
873*437bfbebSnyanmisaka     if (pps->m_nNumTileColumnsMinus1) {
874*437bfbebSnyanmisaka         tile.tile_start_x = 0;
875*437bfbebSnyanmisaka         for (i = 0; i <= pps->m_nNumTileColumnsMinus1; i++) {
876*437bfbebSnyanmisaka             tile.mb_total = pps->m_nTileColumnWidthArray[i] * pps->m_nTileRowHeightArray[i];
877*437bfbebSnyanmisaka             if (i != pps->m_nNumTileColumnsMinus1)
878*437bfbebSnyanmisaka                 tile.tile_end_x = tile.tile_start_x +
879*437bfbebSnyanmisaka                                   (pps->m_nTileColumnWidthArray[i] * sps->m_maxCUSize) - 1;
880*437bfbebSnyanmisaka             else
881*437bfbebSnyanmisaka                 tile.tile_end_x = sps->m_picWidthInLumaSamples - 1;
882*437bfbebSnyanmisaka             h265e_code_skip_tile(ctx, slice, &bitIf, &tile);
883*437bfbebSnyanmisaka             tile.tile_start_x += (pps->m_nTileColumnWidthArray[i] * sps->m_maxCUSize);
884*437bfbebSnyanmisaka             tile.ctu_addr += pps->m_nTileColumnWidthArray[i];
885*437bfbebSnyanmisaka         }
886*437bfbebSnyanmisaka     } else {
887*437bfbebSnyanmisaka         mb_wd = (sps->m_picWidthInLumaSamples + sps->m_maxCUSize - 1) / sps->m_maxCUSize;
888*437bfbebSnyanmisaka         mb_h = (sps->m_picHeightInLumaSamples + sps->m_maxCUSize - 1) / sps->m_maxCUSize;
889*437bfbebSnyanmisaka         tile.mb_total = mb_wd * mb_h;
890*437bfbebSnyanmisaka         tile.tile_start_x = 0;
891*437bfbebSnyanmisaka         tile.tile_end_x = sps->m_picWidthInLumaSamples - 1;
892*437bfbebSnyanmisaka         h265e_code_skip_tile(ctx, slice, &bitIf, &tile);
893*437bfbebSnyanmisaka     }
894*437bfbebSnyanmisaka 
895*437bfbebSnyanmisaka     h265e_dbg_func("leave\n");
896*437bfbebSnyanmisaka     return mpp_writer_bytes(&bitIf);
897*437bfbebSnyanmisaka }
898