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