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, <rpIndex, 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