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_dpb"
18
19 #include <string.h>
20
21 #include "mpp_mem.h"
22 #include "mpp_debug.h"
23 #include "mpp_common.h"
24
25 #include "h265e_codec.h"
26 #include "h265e_dpb.h"
27
h265e_dpb_set_ref_list(H265eRpsList * RpsList,H265eReferencePictureSet * m_pRps,RK_S32 delta_poc)28 void h265e_dpb_set_ref_list(H265eRpsList *RpsList, H265eReferencePictureSet *m_pRps, RK_S32 delta_poc)
29 {
30 RK_S32 i;
31 RK_S32 ref_idx = -1;
32 H265eRefPicListModification* refPicListModification = RpsList->m_RefPicListModification;
33
34 h265e_dbg_func("enter\n");
35 refPicListModification->m_refPicListModificationFlagL0 = 0;
36 refPicListModification->m_refPicListModificationFlagL1 = 0;
37
38 for (i = 0; i < REF_PIC_LIST_NUM_IDX; i ++) {
39 refPicListModification->m_RefPicSetIdxL0[i] = 0;
40 refPicListModification->m_RefPicSetIdxL0[i] = 0;
41 }
42
43 refPicListModification->m_refPicListModificationFlagL0 = 0;
44
45 if (m_pRps->m_numberOfPictures > 1) {
46 for (i = 0; i < m_pRps->m_numberOfPictures; i++) {
47 h265e_dbg_dpb("m_pRps->delta_poc[%d] = %d", i, m_pRps->delta_poc[i]);
48 if (m_pRps->delta_poc[i] == delta_poc) {
49 ref_idx = i;
50 h265e_dbg_dpb("get ref ref_idx %d", ref_idx);
51 break;
52 }
53 }
54 if (-1 == ref_idx) {
55 mpp_err("Did not find the right reference picture");
56 return;
57 } else if (ref_idx != 0) {
58 refPicListModification->m_refPicListModificationFlagL0 = 1;
59 refPicListModification->m_RefPicSetIdxL0[0] = ref_idx;
60 for ( i = 1; i < m_pRps->m_numberOfPictures - 1; i++) {
61 if (i != ref_idx)
62 refPicListModification->m_RefPicSetIdxL0[i] = i;
63 }
64 refPicListModification->m_RefPicSetIdxL0[ref_idx] = 0;
65 }
66 }
67 refPicListModification->m_refPicListModificationFlagL1 = 0;
68 h265e_dbg_func("leave\n");
69 }
70
71 /* get buffer at init */
h265e_dpb_init_curr(H265eDpb * dpb,H265eDpbFrm * frm)72 MPP_RET h265e_dpb_init_curr(H265eDpb *dpb, H265eDpbFrm *frm)
73 {
74 h265e_dbg_func("enter\n");
75 mpp_assert(!frm->on_used);
76
77 frm->dpb = dpb;
78
79 if (!frm->slice) {
80 frm->slice = mpp_calloc(H265eSlice, 1);
81 }
82
83 frm->inited = 1;
84 frm->on_used = 1;
85 frm->seq_idx = dpb->seq_idx;
86 dpb->seq_idx++;
87
88 h265e_dbg_func("leave\n");
89 return MPP_OK;
90 }
91
h265e_dpb_get_curr(H265eDpb * dpb)92 MPP_RET h265e_dpb_get_curr(H265eDpb *dpb)
93 {
94 RK_U32 i;
95
96 h265e_dbg_func("enter\n");
97 for (i = 0; i < MPP_ARRAY_ELEMS(dpb->frame_list); i++) {
98 if (!dpb->frame_list[i].on_used) {
99 dpb->curr = &dpb->frame_list[i];
100 h265e_dbg_dpb("get free dpb slot_index %d", dpb->curr->slot_idx);
101 break;
102 }
103 }
104 h265e_dpb_init_curr(dpb, dpb->curr);
105 h265e_dbg_func("leave\n");
106 return MPP_OK;
107 }
108
109 /* put buffer at deinit */
h265e_dpb_frm_deinit(H265eDpbFrm * frm)110 MPP_RET h265e_dpb_frm_deinit(H265eDpbFrm *frm)
111 {
112
113 MPP_FREE(frm->slice);
114 frm->inited = 0;
115 h265e_dbg_func("leave\n");
116 return MPP_OK;
117 }
118
h265e_dpb_init(H265eDpb ** dpb)119 MPP_RET h265e_dpb_init(H265eDpb **dpb)
120 {
121 MPP_RET ret = MPP_OK;
122 H265eDpb *p = NULL;
123 RK_U32 i;
124
125 h265e_dbg_func("enter\n");
126 if (NULL == dpb) {
127 mpp_err_f("invalid parameter %p \n", dpb);
128 return MPP_ERR_VALUE;
129 }
130
131 p = mpp_calloc_size(H265eDpb, sizeof(H265eDpb));
132
133 if (NULL == p)
134 return MPP_ERR_MALLOC;
135
136 p->last_idr = 0;
137 p->poc_cra = 0;
138 p->max_ref_l0 = 1;
139 p->max_ref_l1 = 0;
140
141 H265eRpsList *rps_list = &p->RpsList;
142
143 rps_list->lt_num = 0;
144 rps_list->st_num = 0;
145
146 memset(rps_list->poc, 0, sizeof(rps_list->poc));
147
148 rps_list->m_RefPicListModification = mpp_calloc(H265eRefPicListModification, 1);
149
150
151 for (i = 0; i < MPP_ARRAY_ELEMS(p->frame_list); i++)
152 p->frame_list[i].slot_idx = i;
153
154 mpp_assert(dpb);
155 *dpb = p;
156 h265e_dbg_func("leave\n");
157 return ret;
158 }
159
h265e_dpb_deinit(H265eDpb * dpb)160 MPP_RET h265e_dpb_deinit(H265eDpb *dpb)
161 {
162 RK_U32 i;
163
164 if (NULL == dpb)
165 return MPP_OK;
166
167 h265e_dbg_func("enter\n");
168 for (i = 0; i < MPP_ARRAY_ELEMS(dpb->frame_list); i++) {
169 if (dpb->frame_list[i].inited)
170 h265e_dpb_frm_deinit(&dpb->frame_list[i]);
171 }
172
173 MPP_FREE(dpb->RpsList.m_RefPicListModification);
174
175 MPP_FREE(dpb);
176
177 h265e_dbg_func("leave\n");
178 return MPP_OK;
179 }
180
get_nal_unit_type(H265eDpb * dpb,int curPOC)181 enum NALUnitType get_nal_unit_type(H265eDpb *dpb, int curPOC)
182 {
183 h265e_dbg_func("enter\n");
184 if (curPOC == 0) {
185 return NAL_IDR_W_RADL;
186 }
187 if (dpb->curr->is_key_frame) {
188 return NAL_IDR_W_RADL;
189 }
190 if (dpb->poc_cra > 0) {
191 if (curPOC < dpb->poc_cra) {
192 // All leading pictures are being marked as TFD pictures here since current encoder uses all
193 // reference pictures while encoding leading pictures. An encoder can ensure that a leading
194 // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by
195 // controlling the reference pictures used for encoding that leading picture. Such a leading
196 // picture need not be marked as a TFD picture.
197 return NAL_RASL_R;
198 }
199 }
200 if (dpb->last_idr > 0) {
201 if (curPOC < dpb->last_idr) {
202 return NAL_RADL_R;
203 }
204 }
205
206 h265e_dbg_func("leave\n");
207 return NAL_TRAIL_R;
208 }
209
getLSB(int poc,int maxLSB)210 static inline int getLSB(int poc, int maxLSB)
211 {
212 if (poc >= 0) {
213 return poc % maxLSB;
214 } else {
215 return (maxLSB - ((-poc) % maxLSB)) % maxLSB;
216 }
217 }
218
sort_delta_poc(H265eReferencePictureSet * rps)219 void sort_delta_poc(H265eReferencePictureSet *rps)
220 {
221 // sort in increasing order (smallest first)
222 RK_S32 j, k;
223 for (j = 1; j < rps->m_numberOfPictures; j++) {
224 RK_S32 deltaPOC = rps->delta_poc[j];
225 RK_U32 used = rps->m_used[j];
226 RK_U32 refed = rps->m_ref[j];
227 for (k = j - 1; k >= 0; k--) {
228 int temp = rps->delta_poc[k];
229 if (deltaPOC < temp) {
230 rps->delta_poc[k + 1] = temp;
231 rps->m_used[k + 1] = rps->m_used[k];
232 rps->m_ref[k + 1] = rps->m_ref[k];
233 rps->delta_poc[k] = deltaPOC;
234 rps->m_used[k] = used;
235 rps->m_ref[k] = refed;
236 }
237 }
238 }
239
240 // flip the negative values to largest first
241 RK_S32 numNegPics = rps->num_negative_pic;
242 for (j = 0, k = numNegPics - 1; j < numNegPics >> 1; j++, k--) {
243 RK_S32 deltaPOC = rps->delta_poc[j];
244 RK_U32 used = rps->m_used[j];
245 RK_U32 refed = rps->m_ref[j];
246 rps->delta_poc[j] = rps->delta_poc[k];
247 rps->m_used[j] = rps->m_used[k];
248 rps->m_ref[j] = rps->m_ref[k];
249 rps->delta_poc[k] = deltaPOC;
250 rps->m_used[k] = used;
251 rps->m_ref[k] = refed;
252 }
253 }
254
255
h265e_dpb_apply_rps(H265eDpb * dpb,H265eReferencePictureSet * rps,int curPoc)256 void h265e_dpb_apply_rps(H265eDpb *dpb, H265eReferencePictureSet *rps, int curPoc)
257 {
258 H265eDpbFrm *outPic = NULL;
259 RK_S32 i, isReference;
260 // loop through all pictures in the reference picture buffer
261 RK_U32 index = 0;
262 H265eDpbFrm *frame_list = &dpb->frame_list[0];
263 h265e_dbg_func("enter\n");
264 for (index = 0; index < MPP_ARRAY_ELEMS(dpb->frame_list); index++) {
265 outPic = &frame_list[index];
266 if (!outPic->inited || !outPic->slice->is_referenced) {
267 continue;
268 }
269
270 isReference = 0;
271 // loop through all pictures in the Reference Picture Set
272 // to see if the picture should be kept as reference picture
273 for (i = 0; i < rps->num_positive_pic + rps->num_negative_pic; i++) {
274 h265e_dbg_dpb("outPic->slice->poc %d,curPoc %d dealt %d", outPic->slice->poc, curPoc, rps->delta_poc[i]);
275 if (!outPic->is_long_term && outPic->slice->poc == curPoc + rps->delta_poc[i]) {
276 isReference = 1;
277 outPic->used_by_cur = (rps->m_used[i] == 1);
278 outPic->is_long_term = 0;
279 }
280 }
281
282 for (; i < rps->m_numberOfPictures; i++) {
283 if (rps->check_lt_msb[i] == 0) {
284 if (outPic->is_long_term && (outPic->slice->poc == rps->m_RealPoc[i])) {
285 isReference = 1;
286 outPic->used_by_cur = (rps->m_used[i] == 1);
287 }
288 } else {
289 if (outPic->is_long_term && (outPic->slice->poc == rps->m_RealPoc[i])) {
290 isReference = 1;
291 outPic->used_by_cur = (rps->m_used[i] == 1);
292 }
293 }
294 }
295
296 // mark the picture as "unused for reference" if it is not in
297 // the Reference Picture Set
298 if (outPic->slice->poc != curPoc && isReference == 0) {
299 h265e_dbg_dpb("free unreference buf poc %d", outPic->slice->poc);
300 outPic->slice->is_referenced = 0;
301 outPic->used_by_cur = 0;
302 outPic->on_used = 0;
303 outPic->is_long_term = 0;
304 }
305 }
306 h265e_dbg_func("leave\n");
307 }
308
h265e_dpb_dec_refresh_marking(H265eDpb * dpb,RK_S32 poc_cur,enum NALUnitType nalUnitType)309 void h265e_dpb_dec_refresh_marking(H265eDpb *dpb, RK_S32 poc_cur, enum NALUnitType nalUnitType)
310 {
311 RK_U32 index = 0;
312
313 h265e_dbg_func("enter\n");
314
315 if (nalUnitType == NAL_BLA_W_LP
316 || nalUnitType == NAL_BLA_W_RADL
317 || nalUnitType == NAL_BLA_N_LP
318 || nalUnitType == NAL_IDR_W_RADL
319 || nalUnitType == NAL_IDR_N_LP) { // IDR or BLA picture
320 // mark all pictures as not used for reference
321 H265eDpbFrm *frame_List = &dpb->frame_list[0];
322 for (index = 0; index < MPP_ARRAY_ELEMS(dpb->frame_list); index++) {
323 H265eDpbFrm *frame = &frame_List[index];
324 if (frame->inited && (frame->poc != poc_cur)) {
325 frame->slice->is_referenced = 0;
326 frame->is_long_term = 0;
327 if (frame->poc < poc_cur) {
328 frame->used_by_cur = 0;
329 frame->on_used = 0;
330 frame->status.val = 0;
331 }
332 }
333 }
334
335 if (nalUnitType == NAL_BLA_W_LP
336 || nalUnitType == NAL_BLA_W_RADL
337 || nalUnitType == NAL_BLA_N_LP) {
338 dpb->poc_cra = poc_cur;
339 }
340 } else { // CRA or No DR
341 if (dpb->refresh_pending == 1 && poc_cur > dpb->poc_cra) { // CRA reference marking pending
342 H265eDpbFrm *frame_list = &dpb->frame_list[0];
343 for (index = 0; index < MPP_ARRAY_ELEMS(dpb->frame_list); index++) {
344
345 H265eDpbFrm *frame = &frame_list[index];
346 if (frame->inited && frame->poc != poc_cur && frame->poc != dpb->poc_cra) {
347 frame->slice->is_referenced = 0;
348 frame->on_used = 0;
349 }
350 }
351
352 dpb->refresh_pending = 0;
353 }
354 if (nalUnitType == NAL_CRA_NUT) { // CRA picture found
355 dpb->refresh_pending = 1;
356 dpb->poc_cra = poc_cur;
357 }
358 }
359 h265e_dbg_func("leave\n");
360 }
361
362 // Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt,
363 // and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value
h265e_dpb_arrange_lt_rps(H265eDpb * dpb,H265eSlice * slice)364 void h265e_dpb_arrange_lt_rps(H265eDpb *dpb, H265eSlice *slice)
365 {
366 H265eReferencePictureSet *rps = slice->m_rps;
367 RK_U32 tempArray[MAX_REFS];
368 RK_S32 offset = rps->num_negative_pic + rps->num_positive_pic;
369 RK_S32 i, j, ctr = 0;
370 RK_S32 maxPicOrderCntLSB = 1 << slice->m_sps->m_bitsForPOC;
371 RK_S32 numLongPics;
372 RK_S32 currMSB = 0, currLSB = 0;
373 (void)dpb;
374
375 // Arrange long-term reference pictures in the correct order of LSB and MSB,
376 // and assign values for pocLSBLT and MSB present flag
377 RK_S32 longtermPicsPoc[MAX_REFS], longtermPicsLSB[MAX_REFS], indices[MAX_REFS];
378 RK_S32 longtermPicsRealPoc[MAX_REFS];
379 RK_S32 longtermPicsMSB[MAX_REFS];
380 RK_U32 mSBPresentFlag[MAX_REFS];
381
382 h265e_dbg_func("enter\n");
383 if (!rps->num_long_term_pic) {
384 return;
385 }
386 memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc)); // Store POC values of LTRP
387 memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB)); // Store POC LSB values of LTRP
388 memset(longtermPicsMSB, 0, sizeof(longtermPicsMSB)); // Store POC LSB values of LTRP
389 memset(longtermPicsRealPoc, 0, sizeof(longtermPicsRealPoc));
390 memset(indices, 0, sizeof(indices)); // Indices to aid in tracking sorted LTRPs
391 memset(mSBPresentFlag, 0, sizeof(mSBPresentFlag)); // Indicate if MSB needs to be present
392
393 // Get the long-term reference pictures
394
395 for (i = rps->m_numberOfPictures - 1; i >= offset; i--, ctr++) {
396 longtermPicsPoc[ctr] = rps->poc[i]; // LTRP POC
397 longtermPicsRealPoc[ctr] = rps->m_RealPoc[i];
398 longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
399 indices[ctr] = i;
400 longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr];
401 }
402
403 numLongPics = rps->num_long_term_pic;
404 mpp_assert(ctr == numLongPics);
405
406 // Arrange pictures in decreasing order of MSB;
407 for (i = 0; i < numLongPics; i++) {
408 for (j = 0; j < numLongPics - 1; j++) {
409 if (longtermPicsMSB[j] < longtermPicsMSB[j + 1]) {
410 MPP_SWAP(RK_S32, longtermPicsPoc[j], longtermPicsPoc[j + 1]);
411 MPP_SWAP(RK_S32, longtermPicsRealPoc[j], longtermPicsRealPoc[j + 1]);
412 MPP_SWAP(RK_S32, longtermPicsLSB[j], longtermPicsLSB[j + 1]);
413 MPP_SWAP(RK_S32, longtermPicsMSB[j], longtermPicsMSB[j + 1]);
414 MPP_SWAP(RK_S32, indices[j], indices[j + 1]);
415 }
416 }
417 }
418
419 for (i = 0; i < numLongPics; i++) {
420 if (slice->gop_idx / maxPicOrderCntLSB > 0) {
421 mSBPresentFlag[i] = 1;
422 }
423 }
424
425 // tempArray for usedByCurr flag
426 memset(tempArray, 0, sizeof(tempArray));
427 for (i = 0; i < numLongPics; i++) {
428 tempArray[i] = rps->m_used[indices[i]] ? 1 : 0;
429 }
430
431 // Now write the final values;
432 ctr = 0;
433 // currPicPoc = currMSB + currLSB
434 currLSB = getLSB(slice->gop_idx, maxPicOrderCntLSB);
435 currMSB = slice->gop_idx - currLSB;
436
437 for (i = rps->m_numberOfPictures - 1; i >= offset; i--, ctr++) {
438 rps->poc[i] = longtermPicsPoc[ctr];
439 rps->delta_poc[i] = -slice->poc + longtermPicsRealPoc[ctr];
440
441 rps->m_used[i] = tempArray[ctr];
442 rps->m_pocLSBLT[i] = longtermPicsLSB[ctr];
443 rps->m_deltaPOCMSBCycleLT[i] = (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB;
444 rps->m_deltaPocMSBPresentFlag[i] = mSBPresentFlag[ctr];
445
446 mpp_assert(rps->m_deltaPOCMSBCycleLT[i] >= 0); // Non-negative value
447 }
448
449 for (i = rps->m_numberOfPictures - 1, ctr = 1; i >= offset; i--, ctr++) {
450 for (j = rps->m_numberOfPictures - 1 - ctr; j >= offset; j--) {
451 // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we
452 // don't have to check the MSB present flag values for this constraint.
453 mpp_assert(rps->m_RealPoc[i] != rps->m_RealPoc[j]); // If assert fails, LTRP entry repeated in RPS!!!
454 }
455 }
456
457 h265e_dbg_func("leave\n");
458 }
459
h265e_find_cpb_in_dpb(H265eDpbFrm * frms,RK_S32 cnt,EncFrmStatus * frm)460 static H265eDpbFrm *h265e_find_cpb_in_dpb(H265eDpbFrm *frms, RK_S32 cnt, EncFrmStatus *frm)
461 {
462 RK_S32 seq_idx = frm->seq_idx;
463 RK_S32 i;
464
465 if (!frm->valid)
466 return NULL;
467
468 h265e_dbg_dpb("frm %d start finding slot \n", frm->seq_idx);
469 for (i = 0; i < cnt; i++) {
470 if (!frms[i].inited) {
471 continue;
472 }
473 EncFrmStatus *p = &frms[i].status;
474
475 if (p->valid && p->seq_idx == seq_idx) {
476 h265e_dbg_dpb("frm %d match slot %d valid %d\n",
477 p->seq_idx, i, p->valid);
478 return &frms[i];
479 }
480 }
481 mpp_err_f("can not find match frm %d\n", seq_idx);
482 return NULL;
483 }
484
h265e_find_cpb_frame(H265eDpbFrm * frms,RK_S32 cnt,EncFrmStatus * frm)485 static H265eDpbFrm *h265e_find_cpb_frame(H265eDpbFrm *frms, RK_S32 cnt, EncFrmStatus *frm)
486 {
487 RK_S32 seq_idx = frm->seq_idx;
488 RK_S32 i;
489
490 if (!frm->valid)
491 return NULL;
492
493 h265e_dbg_dpb("frm %d start finding slot \n", frm->seq_idx);
494 for (i = 0; i < cnt; i++) {
495 if (!frms[i].on_used) {
496 continue;
497 }
498
499 EncFrmStatus *p = &frms[i].status;
500
501 if (p->valid && p->seq_idx == seq_idx) {
502 h265e_dbg_dpb("frm %d match slot %d valid %d\n",
503 p->seq_idx, i, p->valid);
504 mpp_assert(p->is_non_ref == frm->is_non_ref);
505 mpp_assert(p->is_lt_ref == frm->is_lt_ref);
506 mpp_assert(p->lt_idx == frm->lt_idx);
507 mpp_assert(p->temporal_id == frm->temporal_id);
508 return &frms[i];
509 }
510 }
511
512 mpp_err_f("can not find match frm %d\n", seq_idx);
513
514 return NULL;
515 }
516
h265e_check_frame_cpb(H265eDpbFrm * frm,RK_S32 cnt,EncFrmStatus * frms)517 static MPP_RET h265e_check_frame_cpb(H265eDpbFrm *frm, RK_S32 cnt, EncFrmStatus *frms)
518 {
519 EncFrmStatus *p = &frm->status;
520 RK_S32 seq_idx, i;
521 MPP_RET ret = MPP_NOK;
522 h265e_dbg_func("enter\n");
523
524 seq_idx = p->seq_idx;
525 for (i = 0; i < cnt; i++) {
526
527 if (!frms[i].valid) {
528 continue;
529 }
530
531 if (frms[i].seq_idx == seq_idx) {
532 ret = MPP_OK;
533 }
534 }
535
536 h265e_dbg_func("leave\n");
537 return ret;
538 }
539
540
h265e_dpb_cpb2rps(H265eDpb * dpb,RK_S32 curPoc,H265eSlice * slice,EncCpbStatus * cpb)541 void h265e_dpb_cpb2rps(H265eDpb *dpb, RK_S32 curPoc, H265eSlice *slice, EncCpbStatus *cpb)
542 {
543 h265e_dbg_func("enter\n");
544 RK_S32 i;
545 RK_S32 st_size = 0;
546 RK_S32 lt_size = 0;
547 RK_S32 nLongTermRefPicPoc[MAX_NUM_LONG_TERM_REF_PIC_POC];
548 RK_S32 nLongTermRefPicRealPoc[MAX_NUM_LONG_TERM_REF_PIC_POC];
549 RK_S32 nLongTermDealtPoc[MAX_NUM_LONG_TERM_REF_PIC_POC];
550 RK_U32 isMsbValid[MAX_NUM_LONG_TERM_REF_PIC_POC];
551 RK_U32 isShortTermValid[MAX_REFS];
552 H265eRpsList *RpsList = &dpb->RpsList;
553 H265eReferencePictureSet * rps = (H265eReferencePictureSet*)&slice->m_localRPS;
554 RK_S32 idx_rps;
555 H265eDpbFrm *p = NULL;
556 RK_S32 ref_dealt_poc = 0;
557 slice->m_bdIdx = -1;
558
559 memset(isShortTermValid, 1, sizeof(RK_U32)*MAX_REFS);
560 memset(rps, 0, sizeof(H265eReferencePictureSet));
561 for (idx_rps = 0; idx_rps < 16; idx_rps++) {
562 rps->delta_poc[idx_rps] = 0;
563 rps->m_used[idx_rps] = 0;
564 rps->m_ref[idx_rps] = 0;
565 }
566
567 memset(rps->delta_poc, 0, MAX_REFS * sizeof(int));
568
569 if (cpb->curr.is_lt_ref)
570 mpp_assert(slice->m_sps->m_bLongTermRefsPresent);
571
572 idx_rps = 0;
573 for (i = 0; i < MAX_CPB_REFS; i++) {
574 EncFrmStatus *frm = &cpb->init[i];
575
576 if (!frm->valid)
577 continue;
578
579 mpp_assert(!frm->is_non_ref);
580
581 h265e_dbg_dpb("idx %d frm %d valid %d is_non_ref %d lt_ref %d\n",
582 i, frm->seq_idx, frm->valid, frm->is_non_ref, frm->is_lt_ref);
583
584 p = h265e_find_cpb_frame(dpb->frame_list, MAX_REFS, frm);
585 if (p) {
586 if (!frm->is_lt_ref) {
587 p->status.val = frm->val;
588 rps->delta_poc[idx_rps] = p->poc - curPoc;
589 rps->m_used[idx_rps] = 1;
590 idx_rps++;
591 st_size++;
592 h265e_dbg_dpb("found st %d st_size %d %p deat_poc %d\n", i, st_size,
593 frm, rps->delta_poc[idx_rps - 1]);
594 } else {
595 nLongTermRefPicPoc[lt_size] = p->gop_idx;
596 nLongTermRefPicRealPoc[lt_size] = p->poc;
597 nLongTermDealtPoc[lt_size] = p->poc - curPoc;
598 isMsbValid[lt_size] = p->gop_idx >= (RK_S32)(1 << p->slice->m_sps->m_bitsForPOC);
599 p->status.val = frm->val;
600 h265e_dbg_dpb("found lt %d lt_size %d %p dealt poc %d\n", i, lt_size,
601 frm, nLongTermDealtPoc[lt_size]);
602 lt_size++;
603 }
604 }
605 }
606 sort_delta_poc(rps);
607
608 if (slice->m_sliceType == I_SLICE) {
609 rps->m_interRPSPrediction = 0;
610 rps->num_long_term_pic = 0;
611 rps->num_negative_pic = 0;
612 rps->num_positive_pic = 0;
613 rps->m_numberOfPictures = 0;
614
615 } else {
616 p = h265e_find_cpb_frame(dpb->frame_list, MAX_REFS, &cpb->refr);
617 if (p == NULL) {
618 mpp_err("ref frame no found in refer index %d", cpb->refr.seq_idx);
619 } else {
620 ref_dealt_poc = p->poc - curPoc;
621 }
622
623 for (i = 0; i < st_size; i++) {
624 rps->m_ref[i] = (rps->delta_poc[i] == ref_dealt_poc);
625 }
626 }
627
628 if (lt_size > 0) {
629 for ( i = 0; i < lt_size; i++) {
630 h265e_dbg_dpb("numLongTermRefPic %d nShortTerm %d", lt_size, st_size);
631 rps->poc[i + st_size] = nLongTermRefPicPoc[i];
632 rps->m_RealPoc[i + st_size] = nLongTermRefPicRealPoc[i];
633 rps->m_used[i + st_size] = 1;
634 rps->m_ref[i + st_size] = p->is_long_term;
635 rps->delta_poc[i + st_size] = nLongTermDealtPoc[i];
636 rps->check_lt_msb[i + st_size] = isMsbValid[i];
637 }
638 }
639
640 rps->num_negative_pic = st_size;
641 rps->num_positive_pic = 0;
642 rps->num_long_term_pic = lt_size;
643 rps->m_numberOfPictures = st_size + lt_size;
644 slice->m_rps = rps;
645 h265e_dpb_apply_rps(dpb, slice->m_rps, curPoc);
646 h265e_dpb_arrange_lt_rps(dpb, slice);
647 h265e_dpb_set_ref_list(RpsList, rps, ref_dealt_poc);
648 memcpy(&slice->m_RefPicListModification, RpsList->m_RefPicListModification,
649 sizeof(H265eRefPicListModification));
650 h265e_dbg_func("leave\n");
651 }
652
h265e_dpb_free_unsed(H265eDpb * dpb,EncCpbStatus * cpb)653 void h265e_dpb_free_unsed(H265eDpb *dpb, EncCpbStatus *cpb)
654 {
655 RK_S32 i = 0;
656
657 h265e_dbg_func("enter\n");
658
659 if (cpb->curr.is_non_ref) {
660 H265eDpbFrm *frm = h265e_find_cpb_frame(dpb->frame_list, MAX_REFS, &cpb->curr);
661 if (frm) {
662 h265e_dbg_dpb("free curr unreference buf poc %d", frm->slice->poc);
663 frm->is_long_term = 0;
664 frm->used_by_cur = 0;
665 frm->on_used = 0;
666 frm->slice->is_referenced = 0;
667 }
668 }
669
670 for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(dpb->frame_list); i++) {
671 H265eDpbFrm *frm = &dpb->frame_list[i];
672 if (!frm->on_used)
673 continue;
674 if (h265e_check_frame_cpb(frm, MAX_REFS, &cpb->final[0])) {
675 h265e_dbg_dpb("cpb final unreference buf poc %d", frm->slice->poc);
676 frm->is_long_term = 0;
677 frm->used_by_cur = 0;
678 frm->on_used = 0;
679 frm->slice->is_referenced = 0;
680 }
681 }
682
683 h265e_dbg_func("leave\n");
684 }
685
h265e_dpb_proc_cpb(H265eDpb * dpb,EncCpbStatus * cpb)686 void h265e_dpb_proc_cpb(H265eDpb *dpb, EncCpbStatus *cpb)
687 {
688 EncFrmStatus *curr = &cpb->curr;
689 RK_U32 index = 0, i = 0;
690 H265eDpbFrm *p = NULL;
691 RK_U32 need_rebuild = 0;
692 RK_S32 max_gop_id = 0, max_poc = 0;
693
694 if (!dpb || !cpb)
695 return;
696
697 if (curr->is_idr) {
698 for (index = 0; index < MPP_ARRAY_ELEMS(dpb->frame_list); index++) {
699 H265eDpbFrm *frame = &dpb->frame_list[index];
700 if (frame->inited) {
701 frame->slice->is_referenced = 0;
702 frame->is_long_term = 0;
703 frame->used_by_cur = 0;
704 frame->on_used = 0;
705 frame->status.val = 0;
706 }
707 }
708 return;
709 }
710
711 for (i = 0; i < MAX_CPB_REFS; i++) {
712 EncFrmStatus *frm = &cpb->init[i];
713
714 if (!frm->valid)
715 continue;
716
717 mpp_assert(!frm->is_non_ref);
718
719 h265e_dbg_dpb("idx %d frm %d valid %d is_non_ref %d lt_ref %d\n",
720 i, frm->seq_idx, frm->valid, frm->is_non_ref, frm->is_lt_ref);
721
722 p = h265e_find_cpb_in_dpb(dpb->frame_list, MAX_REFS, frm);
723 if (!p->on_used) {
724 p->on_used = 1;
725 p->status.val = frm->val;
726 p->slice->is_referenced = 1;
727 need_rebuild = 1;
728 }
729 }
730
731 if (need_rebuild) {
732 h265e_dbg_dpb("cpb roll back found");
733 for (index = 0; index < MPP_ARRAY_ELEMS(dpb->frame_list); index++) {
734 H265eDpbFrm *frame = &dpb->frame_list[index];
735 if (frame->on_used) {
736 if (max_poc < frame->slice->poc) {
737 max_poc = frame->slice->poc;
738 }
739 if (max_gop_id < frame->slice->gop_idx) {
740 max_gop_id = frame->slice->gop_idx;
741 }
742 }
743 }
744 H265eDpbFrm *frame = dpb->curr;
745 if (frame->inited) {
746 frame->slice->is_referenced = 0;
747 frame->is_long_term = 0;
748 frame->used_by_cur = 0;
749 frame->on_used = 0;
750 frame->status.val = 0;
751 }
752 dpb->seq_idx = max_poc;
753 dpb->gop_idx = max_gop_id;
754 }
755
756 for (index = 0; index < MPP_ARRAY_ELEMS(dpb->frame_list); index++) {
757 H265eDpbFrm *frame = &dpb->frame_list[index];
758 if (frame->inited && !frame->on_used) {
759 h265e_dbg_dpb("reset index %d frame->inited %d rame->on_used %d",
760 index, frame->inited, frame->on_used);
761 frame->status.val = 0;
762 }
763 }
764 }
765
h265e_dpb_build_list(H265eDpb * dpb,EncCpbStatus * cpb)766 void h265e_dpb_build_list(H265eDpb *dpb, EncCpbStatus *cpb)
767 {
768 RK_S32 poc_cur = dpb->curr->slice->poc;
769 H265eSlice* slice = dpb->curr->slice;
770 RK_U32 bGPBcheck = 0;
771 RK_S32 i;
772
773 h265e_dbg_func("enter\n");
774 if (get_nal_unit_type(dpb, poc_cur) == NAL_IDR_W_RADL ||
775 get_nal_unit_type(dpb, poc_cur) == NAL_IDR_N_LP) {
776 dpb->last_idr = poc_cur;
777 }
778
779 slice->last_idr = dpb->last_idr;
780 slice->m_temporalLayerNonReferenceFlag = !slice->is_referenced;
781 // Set the nal unit type
782 slice->m_nalUnitType = get_nal_unit_type(dpb, poc_cur);
783
784 // If the slice is un-referenced, change from _R "referenced" to _N "non-referenced" NAL unit type
785 if (slice->m_temporalLayerNonReferenceFlag) {
786 switch (slice->m_nalUnitType) {
787 case NAL_TRAIL_R:
788 slice->m_nalUnitType = NAL_TRAIL_N;
789 break;
790 case NAL_RADL_R:
791 slice->m_nalUnitType = NAL_RADL_N;
792 break;
793 case NAL_RASL_R:
794 slice->m_nalUnitType = NAL_RASL_N;
795 break;
796 default:
797 break;
798 }
799 }
800
801 // Do decoding refresh marking if any
802 h265e_dpb_dec_refresh_marking(dpb, poc_cur, slice->m_nalUnitType);
803 h265e_dpb_cpb2rps(dpb, poc_cur, slice, cpb);
804
805 slice->m_numRefIdx[L0] = MPP_MIN(dpb->max_ref_l0, slice->m_rps->m_numberOfPictures); // Ensuring L0 contains just the -ve POC
806 slice->m_numRefIdx[L1] = MPP_MIN(dpb->max_ref_l1, slice->m_rps->m_numberOfPictures);
807
808 h265e_slice_set_ref_list(dpb->frame_list, slice);
809
810 // Slice type refinement
811 if ((slice->m_sliceType == B_SLICE) && (slice->m_numRefIdx[L1] == 0)) {
812 slice->m_sliceType = P_SLICE;
813 }
814
815 if (slice->m_sliceType == B_SLICE) {
816 // TODO: Can we estimate this from lookahead?
817 slice->m_colFromL0Flag = 0;
818
819 RK_U32 bLowDelay = 1;
820 RK_S32 curPOC = slice->poc;
821 RK_S32 refIdx = 0;
822
823 for (refIdx = 0; refIdx < slice->m_numRefIdx[L0] && bLowDelay; refIdx++) {
824 if (slice->m_refPicList[L0][refIdx]->poc > curPOC) {
825 bLowDelay = 0;
826 }
827 }
828
829 for (refIdx = 0; refIdx < slice->m_numRefIdx[L1] && bLowDelay; refIdx++) {
830 if (slice->m_refPicList[L1][refIdx]->poc > curPOC) {
831 bLowDelay = 0;
832 }
833 }
834
835 slice->m_bCheckLDC = bLowDelay;
836 } else {
837 slice->m_bCheckLDC = 1;
838 }
839
840 h265e_slice_set_ref_poc_list(slice);
841 if (slice->m_sliceType == B_SLICE) {
842 if (slice->m_numRefIdx[L0] == slice->m_numRefIdx[L1]) {
843 bGPBcheck = 0;
844 for (i = 0; i < slice->m_numRefIdx[L1]; i++) {
845 if (slice->m_refPOCList[L1][i] != slice->m_refPOCList[L0][i]) {
846 bGPBcheck = 0;
847 break;
848 }
849 }
850 }
851 }
852
853 slice->m_bLMvdL1Zero = bGPBcheck;
854 slice->m_nextSlice = 0;
855 if (slice->m_sliceType == I_SLICE) {
856 slice->tot_poc_num = 0;
857 } else {
858 slice->tot_poc_num = slice->m_localRPS.m_numberOfPictures;
859 }
860 h265e_dpb_free_unsed(dpb, cpb);
861 h265e_dbg_func("leave\n");
862 }
863