xref: /rockchip-linux_mpp/mpp/codec/dec/h264/h264d_init.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /*
2 *
3 * Copyright 2015 Rockchip Electronics Co. LTD
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 
18 #define MODULE_TAG "h264d_init"
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "mpp_mem.h"
25 #include "mpp_compat_impl.h"
26 #include "mpp_frame_impl.h"
27 
28 #include "h264d_global.h"
29 #include "h264d_init.h"
30 #include "h264d_dpb.h"
31 #include "h264d_scalist.h"
32 #include "h264d_fill.h"
33 #include "h264d_slice.h"
34 
decode_poc(H264dVideoCtx_t * p_Vid,H264_SLICE_t * pSlice)35 static MPP_RET decode_poc(H264dVideoCtx_t *p_Vid, H264_SLICE_t *pSlice)
36 {
37     RK_S32 i = 0;
38     RK_U32 MaxPicOrderCntLsb = 0;
39     MPP_RET ret = MPP_ERR_UNKNOW;
40     H264_SPS_t *active_sps = p_Vid->active_sps;
41     // for POC mode 0:
42     MaxPicOrderCntLsb = (1 << (active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
43 
44     switch (active_sps->pic_order_cnt_type) {
45     case 0: // POC MODE 0
46         // 1st
47         if (pSlice->idr_flag) {
48             p_Vid->PrevPicOrderCntMsb = 0;
49             p_Vid->PrevPicOrderCntLsb = 0;
50         } else {
51             if (p_Vid->last_has_mmco_5) {
52                 if (p_Vid->last_pic_bottom_field) {
53                     p_Vid->PrevPicOrderCntMsb = 0;
54                     p_Vid->PrevPicOrderCntLsb = 0;
55                 } else {
56                     p_Vid->PrevPicOrderCntMsb = 0;
57                     p_Vid->PrevPicOrderCntLsb = pSlice->toppoc;
58                 }
59             }
60         }
61         // Calculate the MSBs of current picture
62         if (pSlice->pic_order_cnt_lsb  <  p_Vid->PrevPicOrderCntLsb &&
63             (p_Vid->PrevPicOrderCntLsb - pSlice->pic_order_cnt_lsb) >= (RK_S32)(MaxPicOrderCntLsb / 2)) {
64             pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb + MaxPicOrderCntLsb;
65         } else if (pSlice->pic_order_cnt_lsb  >  p_Vid->PrevPicOrderCntLsb &&
66                    (pSlice->pic_order_cnt_lsb - p_Vid->PrevPicOrderCntLsb) > (RK_S32)(MaxPicOrderCntLsb / 2)) {
67             pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb - MaxPicOrderCntLsb;
68         } else {
69             pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb;
70         }
71         // 2nd
72         if (pSlice->field_pic_flag == 0) {
73             //frame pix
74             pSlice->toppoc = pSlice->PicOrderCntMsb + pSlice->pic_order_cnt_lsb;
75             pSlice->bottompoc = pSlice->toppoc + pSlice->delta_pic_order_cnt_bottom;
76             pSlice->ThisPOC = pSlice->framepoc = (pSlice->toppoc < pSlice->bottompoc) ? pSlice->toppoc : pSlice->bottompoc; // POC200301
77         } else if (pSlice->bottom_field_flag == 0) {
78             //top field
79             pSlice->ThisPOC = pSlice->toppoc = pSlice->PicOrderCntMsb + pSlice->pic_order_cnt_lsb;
80         } else {
81             //bottom field
82             pSlice->ThisPOC = pSlice->bottompoc = pSlice->PicOrderCntMsb + pSlice->pic_order_cnt_lsb;
83         }
84         pSlice->framepoc = pSlice->ThisPOC;
85         p_Vid->ThisPOC = pSlice->ThisPOC;
86         //if ( pSlice->frame_num != p_Vid->PreviousFrameNum) //Seems redundant
87         p_Vid->PreviousFrameNum = pSlice->frame_num;
88         if (pSlice->nal_reference_idc) {
89             p_Vid->PrevPicOrderCntLsb = pSlice->pic_order_cnt_lsb;
90             p_Vid->PrevPicOrderCntMsb = pSlice->PicOrderCntMsb;
91         }
92         break;
93 
94     case 1: // POC MODE 1
95         // 1st
96         if (pSlice->idr_flag) {
97             p_Vid->FrameNumOffset = 0;     //  first pix of IDRGOP,
98             VAL_CHECK(ret, 0 == pSlice->frame_num);
99         } else {
100             if (p_Vid->last_has_mmco_5) {
101                 p_Vid->PreviousFrameNumOffset = 0;
102                 p_Vid->PreviousFrameNum = 0;
103             }
104             if (pSlice->frame_num < (RK_S32)p_Vid->PreviousFrameNum) {
105                 //not first pix of IDRGOP
106                 p_Vid->FrameNumOffset = p_Vid->PreviousFrameNumOffset + p_Vid->max_frame_num;
107             } else {
108                 p_Vid->FrameNumOffset = p_Vid->PreviousFrameNumOffset;
109             }
110         }
111         // 2nd
112         if (active_sps->num_ref_frames_in_pic_order_cnt_cycle) {
113             pSlice->AbsFrameNum = p_Vid->FrameNumOffset + pSlice->frame_num;
114         } else {
115             pSlice->AbsFrameNum = 0;
116         }
117         if ((!pSlice->nal_reference_idc) && pSlice->AbsFrameNum > 0) {
118             pSlice->AbsFrameNum--;
119         }
120         // 3rd
121         p_Vid->ExpectedDeltaPerPicOrderCntCycle = 0;
122         if (active_sps->num_ref_frames_in_pic_order_cnt_cycle) {
123             for (i = 0; i < (RK_S32)active_sps->num_ref_frames_in_pic_order_cnt_cycle; i++) {
124                 p_Vid->ExpectedDeltaPerPicOrderCntCycle += active_sps->offset_for_ref_frame[i];
125             }
126         }
127         if (pSlice->AbsFrameNum) {
128             p_Vid->PicOrderCntCycleCnt = (pSlice->AbsFrameNum - 1) / active_sps->num_ref_frames_in_pic_order_cnt_cycle;
129             p_Vid->FrameNumInPicOrderCntCycle = (pSlice->AbsFrameNum - 1) % active_sps->num_ref_frames_in_pic_order_cnt_cycle;
130             p_Vid->ExpectedPicOrderCnt = p_Vid->PicOrderCntCycleCnt * p_Vid->ExpectedDeltaPerPicOrderCntCycle;
131             for (i = 0; i <= (RK_S32)p_Vid->FrameNumInPicOrderCntCycle; i++)
132                 p_Vid->ExpectedPicOrderCnt += active_sps->offset_for_ref_frame[i];
133         } else {
134             p_Vid->ExpectedPicOrderCnt = 0;
135         }
136         if (!pSlice->nal_reference_idc) {
137             p_Vid->ExpectedPicOrderCnt += active_sps->offset_for_non_ref_pic;
138         }
139         if (pSlice->field_pic_flag == 0) {
140             //frame pix
141             pSlice->toppoc = p_Vid->ExpectedPicOrderCnt + pSlice->delta_pic_order_cnt[0];
142             pSlice->bottompoc = pSlice->toppoc + active_sps->offset_for_top_to_bottom_field + pSlice->delta_pic_order_cnt[1];
143             pSlice->ThisPOC = pSlice->framepoc = (pSlice->toppoc < pSlice->bottompoc) ? pSlice->toppoc : pSlice->bottompoc; // POC200301
144         } else if (pSlice->bottom_field_flag == 0) {
145             //top field
146             pSlice->ThisPOC = pSlice->toppoc = p_Vid->ExpectedPicOrderCnt + pSlice->delta_pic_order_cnt[0];
147         } else {
148             //bottom field
149             pSlice->ThisPOC = pSlice->bottompoc = p_Vid->ExpectedPicOrderCnt + active_sps->offset_for_top_to_bottom_field + pSlice->delta_pic_order_cnt[0];
150         }
151         pSlice->framepoc = pSlice->ThisPOC;
152         p_Vid->PreviousFrameNum = pSlice->frame_num;
153         p_Vid->PreviousFrameNumOffset = p_Vid->FrameNumOffset;
154         break;
155 
156 
157     case 2: // POC MODE 2
158         if (pSlice->idr_flag) { // IDR picture
159             p_Vid->FrameNumOffset = 0;     //  first pix of IDRGOP,
160             pSlice->ThisPOC = pSlice->framepoc = pSlice->toppoc = pSlice->bottompoc = 0;
161             VAL_CHECK(ret, 0 == pSlice->frame_num);
162         } else {
163             if (p_Vid->last_has_mmco_5) {
164                 p_Vid->PreviousFrameNum = 0;
165                 p_Vid->PreviousFrameNumOffset = 0;
166             }
167             if (pSlice->frame_num < (RK_S32)p_Vid->PreviousFrameNum) {
168                 p_Vid->FrameNumOffset = p_Vid->PreviousFrameNumOffset + p_Vid->max_frame_num;
169             } else {
170                 p_Vid->FrameNumOffset = p_Vid->PreviousFrameNumOffset;
171             }
172             pSlice->AbsFrameNum = p_Vid->FrameNumOffset + pSlice->frame_num;
173             if (!pSlice->nal_reference_idc) {
174                 pSlice->ThisPOC = (2 * pSlice->AbsFrameNum - 1);
175             } else {
176                 pSlice->ThisPOC = (2 * pSlice->AbsFrameNum);
177             }
178             if (pSlice->field_pic_flag == 0) {
179                 pSlice->toppoc = pSlice->bottompoc = pSlice->framepoc = pSlice->ThisPOC;
180             } else if (pSlice->bottom_field_flag == 0) {
181                 pSlice->toppoc = pSlice->framepoc = pSlice->ThisPOC;
182             } else {
183                 pSlice->bottompoc = pSlice->framepoc = pSlice->ThisPOC;
184             }
185         }
186         p_Vid->PreviousFrameNum = pSlice->frame_num;
187         p_Vid->PreviousFrameNumOffset = p_Vid->FrameNumOffset;
188         break;
189     default:
190         ret = MPP_NOK;
191         goto __FAILED;
192     }
193     return ret = MPP_OK;
194 
195 __FAILED:
196     return ret;
197 }
198 
store_proc_picture_in_dpb(H264_DpbBuf_t * p_Dpb,H264_StorePic_t * p)199 static MPP_RET store_proc_picture_in_dpb(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p)
200 {
201     MPP_RET ret = MPP_ERR_UNKNOW;
202     H264dVideoCtx_t *p_Vid = p_Dpb->p_Vid;
203     H264_FrameStore_t *fs = p_Dpb->fs_ilref[0];
204     H264_DecCtx_t *p_Dec = p_Dpb->p_Vid->p_Dec;
205 
206     VAL_CHECK(ret, NULL != p);
207     if (p_Dpb->used_size_il > 0) {
208         if (fs->frame) {
209             free_storable_picture(p_Dec, fs->frame);
210             fs->frame = NULL;
211         }
212         if (fs->top_field) {
213             free_storable_picture(p_Dec, fs->top_field);
214             fs->top_field = NULL;
215         }
216         if (fs->bottom_field) {
217             free_storable_picture(p_Dec, fs->bottom_field);
218             fs->bottom_field = NULL;
219         }
220         fs->is_used = 0;
221         fs->is_reference = 0;
222         p_Dpb->used_size_il--;
223     }
224     if (fs->is_used > 0) { //checking;
225         if (p->structure == FRAME) {
226             VAL_CHECK(ret, fs->frame == NULL);
227         } else if (p->structure == TOP_FIELD) {
228             VAL_CHECK(ret, fs->top_field == NULL);
229         } else if (p->structure == BOTTOM_FIELD) {
230             VAL_CHECK(ret, fs->bottom_field == NULL);
231         }
232     }
233     FUN_CHECK(ret = insert_picture_in_dpb(p_Vid, fs, p, 0));
234     if ((p->structure == FRAME && fs->is_used == 3)
235         || (p->structure != FRAME && fs->is_used && fs->is_used < 3)) {
236         p_Dpb->used_size_il++;
237     }
238 
239     return ret = MPP_OK;
240 __FAILED:
241     return ret;
242 }
243 
dpb_mark_add_used(H264_DpbMark_t * p_mark,RK_S32 structure)244 static void dpb_mark_add_used(H264_DpbMark_t *p_mark, RK_S32 structure)
245 {
246     //!<---- index add ----
247     if (structure == FRAME || structure == TOP_FIELD) {
248         p_mark->top_used += 1;
249     }
250     if (structure == FRAME || structure == BOTTOM_FIELD) {
251         p_mark->bot_used += 1;
252     }
253 }
254 
clone_storable_picture(H264dVideoCtx_t * p_Vid,H264_StorePic_t * p_pic)255 static H264_StorePic_t* clone_storable_picture(H264dVideoCtx_t *p_Vid, H264_StorePic_t *p_pic)
256 {
257     MPP_RET ret = MPP_ERR_UNKNOW;
258     H264_StorePic_t *p_stored_pic = alloc_storable_picture(p_Vid, p_Vid->structure);
259 
260     MEM_CHECK(ret, p_stored_pic);
261     p_stored_pic->mem_malloc_type = Mem_Clone;
262     p_stored_pic->mem_mark = p_pic->mem_mark;
263     dpb_mark_add_used(p_stored_pic->mem_mark, p_stored_pic->structure);
264     p_stored_pic->colmv_no_used_flag = 1;  // clone, colmv is not be used
265 
266     p_stored_pic->pic_num = p_pic->pic_num;
267     p_stored_pic->frame_num = p_pic->frame_num;
268     p_stored_pic->long_term_frame_idx = p_pic->long_term_frame_idx;
269     p_stored_pic->long_term_pic_num = p_pic->long_term_pic_num;
270     p_stored_pic->is_long_term = 0;
271     p_stored_pic->non_existing = p_pic->non_existing;
272     p_stored_pic->max_slice_id = p_pic->max_slice_id;
273     p_stored_pic->structure = p_pic->structure;
274 
275     p_stored_pic->mb_aff_frame_flag = p_pic->mb_aff_frame_flag;
276     p_stored_pic->poc = p_pic->poc;
277     p_stored_pic->top_poc = p_pic->top_poc;
278     p_stored_pic->bottom_poc = p_pic->bottom_poc;
279     p_stored_pic->frame_poc = p_pic->frame_poc;
280     p_stored_pic->is_mmco_5 = p_pic->is_mmco_5;
281     p_stored_pic->poc_mmco5 = p_pic->poc_mmco5;
282     p_stored_pic->top_poc_mmco5 = p_pic->top_poc_mmco5;
283     p_stored_pic->bot_poc_mmco5 = p_pic->bot_poc_mmco5;
284     p_stored_pic->pic_num = p_pic->pic_num;
285     p_stored_pic->frame_num = p_pic->frame_num;
286     p_stored_pic->slice_type = p_pic->slice_type;
287     p_stored_pic->idr_flag = p_pic->idr_flag;
288     p_stored_pic->no_output_of_prior_pics_flag = p_pic->no_output_of_prior_pics_flag;
289     p_stored_pic->long_term_reference_flag = 0;
290     p_stored_pic->adaptive_ref_pic_buffering_flag = 0;
291     p_stored_pic->dec_ref_pic_marking_buffer = NULL;
292     p_stored_pic->PicWidthInMbs = p_pic->PicWidthInMbs;
293 
294     p_stored_pic->chroma_format_idc = p_pic->chroma_format_idc;
295     p_stored_pic->frame_mbs_only_flag = p_pic->frame_mbs_only_flag;
296     p_stored_pic->frame_cropping_flag = p_pic->frame_cropping_flag;
297     if (p_stored_pic->frame_cropping_flag) {
298         p_stored_pic->frame_crop_left_offset = p_pic->frame_crop_left_offset;
299         p_stored_pic->frame_crop_right_offset = p_pic->frame_crop_right_offset;
300         p_stored_pic->frame_crop_top_offset = p_pic->frame_crop_top_offset;
301         p_stored_pic->frame_crop_bottom_offset = p_pic->frame_crop_bottom_offset;
302     }
303     // MVC-related parameters
304     p_stored_pic->inter_view_flag = p_pic->inter_view_flag;
305     p_stored_pic->anchor_pic_flag = 0;
306     p_stored_pic->view_id = p_pic->view_id;
307     p_stored_pic->layer_id = p_pic->layer_id;
308     p_stored_pic->proc_flag = 1;
309     p_stored_pic->is_output = 1;
310     p_stored_pic->used_for_reference = 1;
311 
312     return p_stored_pic;
313 __FAILED:
314     (void)ret;
315     return NULL;
316 }
317 
init_mvc_picture(H264_SLICE_t * currSlice)318 static MPP_RET init_mvc_picture(H264_SLICE_t *currSlice)
319 {
320     RK_U32 i = 0;
321     RK_S32 poc = 0;
322     MPP_RET ret = MPP_ERR_UNKNOW;
323     H264dVideoCtx_t *p_Vid = currSlice->p_Vid;
324     H264_DpbBuf_t *p_Dpb = p_Vid->p_Dpb_layer[0];
325     H264_StorePic_t *p_pic = NULL;
326     H264_FrameStore_t *fs = NULL;
327     H264_StorePic_t *p_clone = NULL;
328 
329     // find BL reconstructed picture
330     if (currSlice->structure == FRAME) {
331         for (i = 0; i < p_Dpb->used_size; i++) {
332             fs = p_Dpb->fs[i];
333             if (fs->frame) {
334                 poc = fs->frame->is_mmco_5 ? fs->frame->poc_mmco5 : fs->frame->poc;
335             }
336             if (fs->frame && (fs->frame->layer_id == 0) && (poc == currSlice->framepoc)) {
337                 p_pic = fs->frame;
338                 if (!fs->frame->is_mmco_5) {
339                     break;
340                 }
341             }
342         }
343     } else if (currSlice->structure == TOP_FIELD) {
344         for (i = 0; i < p_Dpb->used_size; i++) {
345             fs = p_Dpb->fs[i];
346             if (fs->top_field) {
347                 poc = fs->top_field->is_mmco_5 ? fs->top_field->top_poc_mmco5 : fs->top_field->top_poc;
348             }
349             if (fs->top_field && (fs->top_field->layer_id == 0) && (poc == currSlice->toppoc)) {
350                 p_pic = fs->top_field;
351                 if (!fs->top_field->is_mmco_5) {
352                     break;
353                 }
354             }
355         }
356     } else {
357         for (i = 0; i < p_Dpb->used_size; i++) {
358             fs = p_Dpb->fs[i];
359             if (fs->bottom_field) {
360                 poc = fs->bottom_field->is_mmco_5 ? fs->bottom_field->bot_poc_mmco5 : fs->bottom_field->bottom_poc;
361             }
362             if (fs->bottom_field && (fs->bottom_field->layer_id == 0) && (poc == currSlice->bottompoc)) {
363                 p_pic = fs->bottom_field;
364                 if (!fs->bottom_field->is_mmco_5) {
365                     break;
366                 }
367             }
368         }
369     }
370     if (p_pic) {
371         p_clone = clone_storable_picture(p_Vid, p_pic);
372         MEM_CHECK(ret, p_clone);
373         FUN_CHECK(ret = store_proc_picture_in_dpb(currSlice->p_Dpb, p_clone));
374     }
375 
376     return ret = MPP_OK;
377 __FAILED:
378     return ret;
379 }
380 
rkv_len_align_422(RK_U32 val)381 static inline RK_U32 rkv_len_align_422(RK_U32 val)
382 {
383     return ((5 * MPP_ALIGN(val, 16)) / 2);
384 }
385 
hor_align_64(RK_U32 val)386 static RK_U32 hor_align_64(RK_U32 val)
387 {
388     return MPP_ALIGN(val, 64);
389 }
390 
dpb_mark_malloc(H264dVideoCtx_t * p_Vid,H264_StorePic_t * dec_pic)391 static MPP_RET dpb_mark_malloc(H264dVideoCtx_t *p_Vid, H264_StorePic_t *dec_pic)
392 {
393     MPP_RET ret = MPP_ERR_UNKNOW;
394     H264_DpbMark_t *cur_mark = NULL;
395     H264_DecCtx_t *p_Dec = p_Vid->p_Dec;
396     H264_DpbMark_t *p_mark = p_Vid->p_Dec->dpb_mark;
397     RK_S32 structure = dec_pic->structure;
398     RK_S32 layer_id = dec_pic->layer_id;
399 
400     if (!dec_pic->combine_flag) {
401         RK_U8 idx = 0;
402         while (p_mark[idx].out_flag || p_mark[idx].top_used
403                || p_mark[idx].bot_used) {
404             idx++;
405             ASSERT(MAX_MARK_SIZE > idx);
406         }
407 
408         mpp_buf_slot_get_unused(p_Vid->p_Dec->frame_slots, &p_mark[idx].slot_idx);
409         if (p_mark[idx].slot_idx < 0) {
410             H264D_WARNNING("[dpb_mark_malloc] error, buf_slot has not get.");
411             ret = MPP_NOK;
412             goto __FAILED;
413         }
414         cur_mark = &p_mark[idx];
415 
416         cur_mark->out_flag = 1;
417         {
418             RK_U32 hor_stride, ver_stride;
419             MppFrameFormat fmt = MPP_FMT_YUV_BUTT;
420             MppFrameFormat out_fmt = p_Dec->cfg->base.out_fmt;
421             MppFrameImpl *impl = (MppFrameImpl *)p_Dec->curframe;
422 
423             if ((H264_CHROMA_400 == p_Vid->yuv_format) && (8 == p_Vid->bit_depth_luma)) {
424                 fmt = MPP_FMT_YUV400;
425             } else if ((H264_CHROMA_420 == p_Vid->yuv_format) && (8 == p_Vid->bit_depth_luma)) {
426                 fmt = MPP_FMT_YUV420SP;
427             } else if ((H264_CHROMA_420 == p_Vid->yuv_format) && (10 == p_Vid->bit_depth_luma)) {
428                 fmt = MPP_FMT_YUV420SP_10BIT;
429             } else if ((H264_CHROMA_422 == p_Vid->yuv_format) && (8 == p_Vid->bit_depth_luma)) {
430                 fmt = MPP_FMT_YUV422SP;
431                 mpp_slots_set_prop(p_Dec->frame_slots, SLOTS_LEN_ALIGN, rkv_len_align_422);
432             } else if ((H264_CHROMA_422 == p_Vid->yuv_format) && (10 == p_Vid->bit_depth_luma)) {
433                 fmt = MPP_FMT_YUV422SP_10BIT;
434                 mpp_slots_set_prop(p_Dec->frame_slots, SLOTS_LEN_ALIGN, rkv_len_align_422);
435             }
436 
437             if (MPP_FRAME_FMT_IS_FBC(out_fmt)) {
438                 do {
439                     /*
440                      * field mode can not use FBC, but VOP only support fbc fmt for 10bit source.
441                      * Generally, there is no 10bit field source.
442                      */
443                     if (!p_Vid->frame_mbs_only_flag && p_Vid->bit_depth_luma < 10)
444                         break;
445 
446                     /*
447                      * When iep working on detection mode disable fbc output mode
448                      */
449                     if ((p_Dec->cfg->base.enable_vproc & MPP_VPROC_MODE_DETECTION) &&
450                         p_Vid->width <= 1920 && p_Vid->height <= 1088 && p_Vid->bit_depth_luma == 8)
451                         break;
452 
453                     mpp_slots_set_prop(p_Dec->frame_slots, SLOTS_HOR_ALIGN, hor_align_64);
454                     fmt |= (out_fmt & MPP_FRAME_FBC_MASK);
455                 } while (0);
456 
457                 p_Dec->cfg->base.out_fmt = fmt;
458                 out_fmt = fmt;
459             } else if (MPP_FRAME_FMT_IS_TILE(out_fmt)) {
460                 fmt |= (out_fmt & MPP_FRAME_TILE_FLAG);
461                 p_Dec->cfg->base.out_fmt = fmt;
462                 out_fmt = fmt;
463             }
464             impl->fmt = fmt;
465 
466             hor_stride = MPP_ALIGN(p_Vid->width * p_Vid->bit_depth_luma, 8) / 8;
467             ver_stride = p_Vid->height;
468             /* Before cropping */
469             impl->hor_stride = hor_stride;
470             impl->ver_stride = ver_stride;
471 
472             /* After cropped */
473             impl->width = p_Vid->width_after_crop;
474             impl->height = p_Vid->height_after_crop;
475             impl->pts = p_Vid->p_Cur->last_pts;
476             impl->dts = p_Vid->p_Cur->last_dts;
477 
478             if (MPP_FRAME_FMT_IS_FBC(out_fmt)) {
479                 impl->offset_x = 0;
480                 impl->offset_y = 4;
481 
482                 if (*compat_ext_fbc_buf_size)
483                     impl->ver_stride += 16;
484 
485                 impl->fbc_hdr_stride =  MPP_ALIGN(impl->width, 64);
486                 if (*compat_ext_fbc_hdr_256_odd)
487                     impl->fbc_hdr_stride =  MPP_ALIGN(impl->width, 256) | 256;
488             }
489 
490             /* Setting the interlace mode for the picture */
491             switch (structure) {
492             case FRAME:
493                 impl->mode = MPP_FRAME_FLAG_FRAME;
494                 /* When vproc detection is enabled set frame to field mode */
495                 if ((p_Dec->cfg->base.enable_vproc & MPP_VPROC_MODE_DETECTION) &&
496                     p_Vid->width <= 1920 && p_Vid->height <= 1088 && p_Vid->bit_depth_luma == 8)
497                     impl->mode = MPP_FRAME_FLAG_DEINTERLACED;
498                 break;
499             case TOP_FIELD:
500                 impl->mode = MPP_FRAME_FLAG_PAIRED_FIELD | MPP_FRAME_FLAG_TOP_FIRST;
501                 break;
502             case BOTTOM_FIELD:
503                 impl->mode = MPP_FRAME_FLAG_PAIRED_FIELD | MPP_FRAME_FLAG_BOT_FIRST;
504                 break;
505             default:
506                 H264D_DBG(H264D_DBG_FIELD_PAIRED, "Unknown interlace mode");
507                 mpp_assert(0);
508             }
509 
510             if (p_Dec->svc_valid) {
511                 struct h264_slice_t *slice = &p_Dec->p_Cur->slice;
512                 struct h264_nalu_svc_ext_t *svcExt = &slice->svcExt;
513 
514                 if (svcExt->valid && impl->meta)
515                     mpp_meta_set_s32(impl->meta, KEY_TEMPORAL_ID, svcExt->temporal_id);
516             }
517 
518             if (p_Vid->p_Cur->sei &&
519                 ((p_Vid->active_sps->vui_parameters_present_flag &&
520                   p_Vid->active_sps->vui_seq_parameters.pic_struct_present_flag &&
521                   p_Vid->p_Cur->sei->type == H264_SEI_PIC_TIMING) ||
522                  p_Vid->p_Cur->sei->pic_timing.pic_struct != 0)) {
523                 if (p_Vid->p_Cur->sei->pic_timing.pic_struct == 3 ||
524                     p_Vid->p_Cur->sei->pic_timing.pic_struct == 5)
525                     impl->mode = MPP_FRAME_FLAG_PAIRED_FIELD | MPP_FRAME_FLAG_TOP_FIRST;
526                 if (p_Vid->p_Cur->sei->pic_timing.pic_struct == 4 ||
527                     p_Vid->p_Cur->sei->pic_timing.pic_struct == 6)
528                     impl->mode = MPP_FRAME_FLAG_PAIRED_FIELD | MPP_FRAME_FLAG_BOT_FIRST;
529             }
530 
531             if (p_Dec->cfg->base.enable_thumbnail && p_Dec->hw_info->cap_down_scale)
532                 mpp_frame_set_thumbnail_en(p_Dec->curframe, p_Dec->cfg->base.enable_thumbnail);
533             else
534                 mpp_frame_set_thumbnail_en(p_Dec->curframe, 0);
535 
536             //!< set display parameter
537             if (p_Vid->active_sps->vui_parameters_present_flag) {
538                 H264_VUI_t *p = &p_Vid->active_sps->vui_seq_parameters;
539 
540                 if (p->video_signal_type_present_flag && p->video_full_range_flag)
541                     impl->color_range = MPP_FRAME_RANGE_JPEG;
542                 else
543                     impl->color_range = MPP_FRAME_RANGE_MPEG;
544 
545                 if (p->colour_description_present_flag) {
546                     impl->color_primaries = p->colour_primaries;
547                     impl->color_trc = p->transfer_characteristics;
548                     impl->colorspace = p->matrix_coefficients;
549                     if (impl->color_trc == MPP_FRAME_TRC_SMPTEST2084)
550                         impl->fmt |= MPP_FRAME_HDR;
551                 } else {
552                     impl->color_primaries = MPP_FRAME_PRI_UNSPECIFIED;
553                     impl->color_trc = MPP_FRAME_TRC_UNSPECIFIED;
554                     impl->colorspace = MPP_FRAME_SPC_UNSPECIFIED;
555                 }
556             }
557 
558             if (p_Vid->p_Cur->hdr_dynamic && p_Vid->p_Cur->hdr_dynamic_meta) {
559                 impl->hdr_dynamic_meta = p_Vid->p_Cur->hdr_dynamic_meta;
560                 p_Vid->p_Cur->hdr_dynamic = 0;
561                 impl->fmt |= MPP_FRAME_HDR;
562             }
563 
564             impl->poc = dec_pic->poc;
565             impl->viewid = dec_pic->layer_id;
566             impl->status.is_intra = dec_pic->slice_type == H264_I_SLICE;
567             impl->status.is_idr = dec_pic->idr_flag;
568             impl->status.is_non_ref = !dec_pic->used_for_reference;
569             impl->status.is_lt_ref = dec_pic->long_term_reference_flag;
570             impl->status.is_b_frame = ((dec_pic->slice_type % 5) == H264_B_SLICE);
571 
572             mpp_buf_slot_set_prop(p_Dec->frame_slots, cur_mark->slot_idx, SLOT_FRAME, p_Dec->curframe);
573             mpp_buf_slot_get_prop(p_Dec->frame_slots, cur_mark->slot_idx, SLOT_FRAME_PTR, &cur_mark->mframe);
574         }
575 
576         p_Vid->active_dpb_mark[layer_id] = cur_mark;
577     }
578     cur_mark = p_Vid->active_dpb_mark[layer_id];
579     if (cur_mark->slot_idx < 0) {
580         H264D_WARNNING("[dpb_mark_malloc] error, current mark slot idx is nagative.");
581         ret = MPP_NOK;
582         goto __FAILED;
583     }
584     if (structure == FRAME || structure == TOP_FIELD) {
585         cur_mark->top_used += 1;
586     }
587     if (structure == FRAME || structure == BOTTOM_FIELD) {
588         cur_mark->bot_used += 1;
589     }
590     H264D_DBG(H264D_DBG_DPB_MALLIC,
591               "[DPB_malloc] g_framecnt=%d, com_flag=%d, mark_idx=%d, slot_idx=%d, slice_type=%d, struct=%d, lay_id=%d\n",
592               p_Vid->g_framecnt, dec_pic->combine_flag, cur_mark->mark_idx,
593               cur_mark->slot_idx, dec_pic->slice_type, dec_pic->structure,
594               layer_id);
595 
596     p_Vid->p_Dec->in_task->output = cur_mark->slot_idx;
597     mpp_buf_slot_set_flag(p_Dec->frame_slots, cur_mark->slot_idx, SLOT_HAL_OUTPUT);
598     p_Dec->last_frame_slot_idx = cur_mark->slot_idx;
599     dec_pic->mem_mark = p_Vid->active_dpb_mark[layer_id];
600     dec_pic->mem_mark->pic = dec_pic;
601 
602     return ret = MPP_OK;
603 __FAILED:
604     dec_pic->mem_mark = NULL;
605     return ret;
606 }
607 
check_dpb_discontinuous(H264_StorePic_t * p_last,H264_StorePic_t * dec_pic,H264_SLICE_t * currSlice)608 static MPP_RET check_dpb_discontinuous(H264_StorePic_t *p_last, H264_StorePic_t *dec_pic, H264_SLICE_t *currSlice)
609 {
610     MPP_RET ret = MPP_ERR_UNKNOW;
611 
612     if (p_last && dec_pic && (dec_pic->slice_type != H264_I_SLICE)
613         && (currSlice->p_Cur->sps.gaps_in_frame_num_value_allowed_flag == 0)) {
614         RK_U32 error_flag = 0;
615 
616         if (dec_pic->combine_flag) {
617             if (dec_pic->frame_num != p_last->frame_num)
618                 error_flag = 1;
619         } else {
620             RK_U32 frame_num = currSlice->p_Vid->last_ref_frame_num;
621 
622             if (dec_pic->frame_num != frame_num &&
623                 dec_pic->frame_num != ((frame_num + 1) % currSlice->p_Vid->max_frame_num))
624                 error_flag = 1;
625         }
626 
627         currSlice->p_Dec->errctx.cur_err_flag |= error_flag ? 1 : 0;
628         currSlice->p_Dec->errctx.dpb_err_flag |= error_flag ? 1 : 0;
629 
630         H264D_DBG(H264D_DBG_DISCONTINUOUS, "[discontinuous] last_slice=%d, cur_slice=%d, last_fnum=%d, cur_fnum=%d, last_poc=%d, cur_poc=%d",
631                   p_last->slice_type, dec_pic->slice_type, p_last->frame_num, dec_pic->frame_num, p_last->poc, dec_pic->poc);
632     }
633 
634     if (dec_pic->idr_flag || dec_pic->used_for_reference)
635         currSlice->p_Vid->last_ref_frame_num = dec_pic->frame_num;
636     return ret = MPP_OK;
637 }
638 
alloc_decpic(H264_SLICE_t * currSlice)639 static MPP_RET alloc_decpic(H264_SLICE_t *currSlice)
640 {
641     MPP_RET ret = MPP_ERR_UNKNOW;
642     H264_StorePic_t *dec_pic = NULL;
643 
644     H264dVideoCtx_t *p_Vid = currSlice->p_Vid;
645     H264_SPS_t *active_sps = p_Vid->active_sps;
646     H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb;
647     H264_DecCtx_t *p_Dec = p_Vid->p_Dec;
648 
649     dec_pic = alloc_storable_picture(p_Vid, currSlice->structure);
650     MEM_CHECK(ret, dec_pic);
651     currSlice->toppoc    = p_Vid->last_toppoc[currSlice->layer_id];
652     currSlice->bottompoc = p_Vid->last_bottompoc[currSlice->layer_id];
653     currSlice->framepoc  = p_Vid->last_framepoc[currSlice->layer_id];
654     currSlice->ThisPOC   = p_Vid->last_thispoc[currSlice->layer_id];
655     FUN_CHECK(ret = decode_poc(p_Vid, currSlice));  //!< calculate POC
656 
657     dec_pic->top_poc    = currSlice->toppoc;
658     dec_pic->bottom_poc = currSlice->bottompoc;
659     dec_pic->frame_poc  = currSlice->framepoc;
660     dec_pic->ThisPOC    = currSlice->ThisPOC;
661 
662     p_Vid->last_toppoc[currSlice->layer_id]    = currSlice->toppoc;
663     p_Vid->last_bottompoc[currSlice->layer_id] = currSlice->bottompoc;
664     p_Vid->last_framepoc[currSlice->layer_id]  = currSlice->framepoc;
665     p_Vid->last_thispoc[currSlice->layer_id]   = currSlice->ThisPOC;
666 
667     if (currSlice->structure == FRAME) {
668         if (currSlice->mb_aff_frame_flag) {
669             dec_pic->iCodingType = FRAME_MB_PAIR_CODING;
670         } else {
671             dec_pic->iCodingType = FRAME_CODING;
672         }
673     } else {
674         dec_pic->iCodingType = FIELD_CODING;
675     }
676     dec_pic->layer_id = currSlice->layer_id;
677     dec_pic->view_id  = currSlice->view_id;
678     dec_pic->inter_view_flag = currSlice->inter_view_flag;
679     dec_pic->anchor_pic_flag = currSlice->anchor_pic_flag;
680     if (dec_pic->layer_id == 1) {
681         if ((p_Vid->profile_idc == H264_PROFILE_MVC_HIGH) || (p_Vid->profile_idc == H264_PROFILE_STEREO_HIGH)) {
682             FUN_CHECK(ret = init_mvc_picture(currSlice));
683         }
684     }
685     if (currSlice->structure == TOP_FIELD) {
686         dec_pic->poc = currSlice->toppoc;
687     } else if (currSlice->structure == BOTTOM_FIELD) {
688         dec_pic->poc = currSlice->bottompoc;
689     } else if (currSlice->structure == FRAME) {
690         dec_pic->poc = currSlice->framepoc;
691     } else {
692         ret = MPP_NOK;
693         goto __FAILED;
694     }
695     dec_pic->slice_type = p_Vid->type;
696     dec_pic->used_for_reference = (currSlice->nal_reference_idc != 0);
697     dec_pic->idr_flag = currSlice->idr_flag;
698     dec_pic->no_output_of_prior_pics_flag = currSlice->no_output_of_prior_pics_flag;
699     dec_pic->long_term_reference_flag = currSlice->long_term_reference_flag;
700     dec_pic->adaptive_ref_pic_buffering_flag = currSlice->adaptive_ref_pic_buffering_flag;
701     dec_pic->dec_ref_pic_marking_buffer = currSlice->dec_ref_pic_marking_buffer;
702 
703     currSlice->dec_ref_pic_marking_buffer = NULL;
704     dec_pic->mb_aff_frame_flag = currSlice->mb_aff_frame_flag;
705     dec_pic->PicWidthInMbs = p_Vid->PicWidthInMbs;
706     dec_pic->pic_num = currSlice->frame_num;
707     dec_pic->frame_num = currSlice->frame_num;
708     dec_pic->chroma_format_idc = active_sps->chroma_format_idc;
709 
710     dec_pic->frame_mbs_only_flag = active_sps->frame_mbs_only_flag;
711     dec_pic->frame_cropping_flag = active_sps->frame_cropping_flag;
712     if (dec_pic->frame_cropping_flag) {
713         dec_pic->frame_crop_left_offset = active_sps->frame_crop_left_offset;
714         dec_pic->frame_crop_right_offset = active_sps->frame_crop_right_offset;
715         dec_pic->frame_crop_top_offset = active_sps->frame_crop_top_offset;
716         dec_pic->frame_crop_bottom_offset = active_sps->frame_crop_bottom_offset;
717     } else {
718         dec_pic->frame_crop_left_offset = 0;
719         dec_pic->frame_crop_right_offset = 0;
720         dec_pic->frame_crop_top_offset = 0;
721         dec_pic->frame_crop_bottom_offset = 0;
722     }
723     dec_pic->width = p_Vid->width;
724     dec_pic->height = p_Vid->height;
725     dec_pic->width_after_crop = p_Vid->width_after_crop;
726     dec_pic->height_after_crop = p_Vid->height_after_crop;
727     dec_pic->combine_flag = get_field_dpb_combine_flag(p_Dpb->last_picture, dec_pic);
728     /* malloc dpb_memory */
729     FUN_CHECK(ret = dpb_mark_malloc(p_Vid, dec_pic));
730     if (!p_Dec->cfg->base.disable_dpb_chk) {
731         FUN_CHECK(ret = check_dpb_discontinuous(p_Vid->last_pic, dec_pic, currSlice));
732     }
733     dec_pic->mem_malloc_type = Mem_Malloc;
734     dec_pic->colmv_no_used_flag = 0;
735     p_Vid->dec_pic = dec_pic;
736 
737     return ret = MPP_OK;
738 __FAILED:
739     mpp_mem_pool_put_f(p_Vid->pic_st, dec_pic);
740     p_Vid->dec_pic = NULL;
741 
742     return ret;
743 }
744 
update_pic_num(H264_SLICE_t * currSlice)745 static void update_pic_num(H264_SLICE_t *currSlice)
746 {
747     RK_U32 i = 0;
748     H264dVideoCtx_t *p_Vid = currSlice->p_Vid;
749     H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb;
750     H264_SPS_t *active_sps = p_Vid->active_sps;
751 
752     RK_S32 add_top = 0, add_bottom = 0;
753     RK_S32 max_frame_num = 1 << (active_sps->log2_max_frame_num_minus4 + 4);
754 
755     if (currSlice->idr_flag) {
756         return;
757     }
758     if (currSlice->structure == FRAME) {
759         for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
760             if (p_Dpb->fs_ref[i]->is_used == 3) {
761                 if ((p_Dpb->fs_ref[i]->frame->used_for_reference) && (!p_Dpb->fs_ref[i]->frame->is_long_term)) {
762                     if ((RK_S32)p_Dpb->fs_ref[i]->frame_num > currSlice->frame_num) {
763                         p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num - max_frame_num;
764                     } else {
765                         p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num;
766                     }
767                     p_Dpb->fs_ref[i]->frame->pic_num = p_Dpb->fs_ref[i]->frame_num_wrap;
768                 }
769             }
770         }
771         //!< update long_term_pic_num
772         for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
773             if (p_Dpb->fs_ltref[i]->is_used == 3) {
774                 if (p_Dpb->fs_ltref[i]->frame->is_long_term) {
775                     p_Dpb->fs_ltref[i]->frame->long_term_pic_num = p_Dpb->fs_ltref[i]->frame->long_term_frame_idx;
776                 }
777             }
778         }
779     } else {
780         if (currSlice->structure == TOP_FIELD) {
781             add_top = 1;
782             add_bottom = 0;
783         } else {
784             add_top = 0;
785             add_bottom = 1;
786         }
787 
788         for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
789             if (p_Dpb->fs_ref[i]->is_reference) {
790                 if ((RK_S32)p_Dpb->fs_ref[i]->frame_num > currSlice->frame_num) {
791                     p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num - max_frame_num;
792                 } else {
793                     p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num;
794                 }
795                 if (p_Dpb->fs_ref[i]->is_reference & 1) {
796                     p_Dpb->fs_ref[i]->top_field->pic_num = (2 * p_Dpb->fs_ref[i]->frame_num_wrap) + add_top;
797                 }
798                 if (p_Dpb->fs_ref[i]->is_reference & 2) {
799                     p_Dpb->fs_ref[i]->bottom_field->pic_num = (2 * p_Dpb->fs_ref[i]->frame_num_wrap) + add_bottom;
800                 }
801             }
802         }
803         //!< update long_term_pic_num
804         for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
805             if (p_Dpb->fs_ltref[i]->is_long_term & 1) {
806                 p_Dpb->fs_ltref[i]->top_field->long_term_pic_num = 2 * p_Dpb->fs_ltref[i]->top_field->long_term_frame_idx + add_top;
807             }
808             if (p_Dpb->fs_ltref[i]->is_long_term & 2) {
809                 p_Dpb->fs_ltref[i]->bottom_field->long_term_pic_num = 2 * p_Dpb->fs_ltref[i]->bottom_field->long_term_frame_idx + add_bottom;
810             }
811         }
812     }
813 }
814 
815 
816 
817 
compare_pic_by_pic_num_desc(const void * arg1,const void * arg2)818 static RK_S32 compare_pic_by_pic_num_desc(const void *arg1, const void *arg2)
819 {
820     RK_S32 pic_num1 = (*(H264_StorePic_t**)arg1)->pic_num;
821     RK_S32 pic_num2 = (*(H264_StorePic_t**)arg2)->pic_num;
822 
823     if (pic_num1 < pic_num2)
824         return 1;
825     if (pic_num1 > pic_num2)
826         return -1;
827     else
828         return 0;
829 }
830 
compare_pic_by_lt_pic_num_asc(const void * arg1,const void * arg2)831 static RK_S32 compare_pic_by_lt_pic_num_asc(const void *arg1, const void *arg2)
832 {
833     RK_S32 long_term_pic_num1 = (*(H264_StorePic_t**)arg1)->long_term_pic_num;
834     RK_S32 long_term_pic_num2 = (*(H264_StorePic_t**)arg2)->long_term_pic_num;
835 
836     if (long_term_pic_num1 < long_term_pic_num2)
837         return -1;
838     if (long_term_pic_num1 > long_term_pic_num2)
839         return 1;
840     else
841         return 0;
842 }
843 
compare_fs_by_frame_num_desc(const void * arg1,const void * arg2)844 static RK_S32 compare_fs_by_frame_num_desc(const void *arg1, const void *arg2)
845 {
846     RK_S32 frame_num_wrap1 = (*(H264_FrameStore_t**)arg1)->frame_num_wrap;
847     RK_S32 frame_num_wrap2 = (*(H264_FrameStore_t**)arg2)->frame_num_wrap;
848     if (frame_num_wrap1 < frame_num_wrap2)
849         return 1;
850     if (frame_num_wrap1 > frame_num_wrap2)
851         return -1;
852     else
853         return 0;
854 }
855 
compare_fs_by_lt_pic_idx_asc(const void * arg1,const void * arg2)856 static RK_S32 compare_fs_by_lt_pic_idx_asc(const void *arg1, const void *arg2)
857 {
858     RK_S32 long_term_frame_idx1 = (*(H264_FrameStore_t**)arg1)->long_term_frame_idx;
859     RK_S32 long_term_frame_idx2 = (*(H264_FrameStore_t**)arg2)->long_term_frame_idx;
860 
861     if (long_term_frame_idx1 < long_term_frame_idx2)
862         return -1;
863     else if (long_term_frame_idx1 > long_term_frame_idx2)
864         return 1;
865     else
866         return 0;
867 }
868 
is_long_ref(H264_StorePic_t * s)869 static RK_U32 is_long_ref(H264_StorePic_t *s)
870 {
871     return ((s->used_for_reference) && (s->is_long_term));
872 }
873 
is_short_ref(H264_StorePic_t * s)874 static RK_U32 is_short_ref(H264_StorePic_t *s)
875 {
876     return ((s->used_for_reference) && (!(s->is_long_term)));
877 }
878 
gen_pic_list_from_frame_list(RK_S32 currStructure,H264_FrameStore_t ** fs_list,RK_S32 list_idx,H264_StorePic_t ** list,RK_U8 * list_size,RK_U32 long_term)879 static void gen_pic_list_from_frame_list(RK_S32 currStructure, H264_FrameStore_t **fs_list,
880                                          RK_S32 list_idx, H264_StorePic_t **list, RK_U8 *list_size, RK_U32 long_term)
881 {
882     RK_S32 top_idx = 0;
883     RK_S32 bot_idx = 0;
884 
885     RK_U32(*is_ref)(H264_StorePic_t * s) = (long_term) ? is_long_ref : is_short_ref;
886 
887     if (currStructure == TOP_FIELD) {
888         while ((top_idx < list_idx) || (bot_idx < list_idx)) {
889             for (; top_idx < list_idx; top_idx++) {
890                 if (fs_list[top_idx]->is_used & 1) {
891                     if (is_ref(fs_list[top_idx]->top_field)) {
892                         //<! short term ref pic
893                         list[(RK_S16)*list_size] = fs_list[top_idx]->top_field;
894                         (*list_size)++;
895                         top_idx++;
896                         break;
897                     }
898                 }
899             }
900             for (; bot_idx < list_idx; bot_idx++) {
901                 if (fs_list[bot_idx]->is_used & 2) {
902                     if (is_ref(fs_list[bot_idx]->bottom_field)) {
903                         //<! short term ref pic
904                         list[(RK_S16)*list_size] = fs_list[bot_idx]->bottom_field;
905                         (*list_size)++;
906                         bot_idx++;
907                         break;
908                     }
909                 }
910             }
911         }
912     }
913     if (currStructure == BOTTOM_FIELD) {
914         while ((top_idx < list_idx) || (bot_idx < list_idx)) {
915             for (; bot_idx < list_idx; bot_idx++) {
916                 if (fs_list[bot_idx]->is_used & 2) {
917                     if (is_ref(fs_list[bot_idx]->bottom_field)) {
918                         // short term ref pic
919                         list[(RK_S16)*list_size] = fs_list[bot_idx]->bottom_field;
920                         (*list_size)++;
921                         bot_idx++;
922                         break;
923                     }
924                 }
925             }
926             for (; top_idx < list_idx; top_idx++) {
927                 if (fs_list[top_idx]->is_used & 1) {
928                     if (is_ref(fs_list[top_idx]->top_field)) {
929                         //!< short term ref pic
930                         list[(RK_S16)*list_size] = fs_list[top_idx]->top_field;
931                         (*list_size)++;
932                         top_idx++;
933                         break;
934                     }
935                 }
936             }
937         }
938     }
939 }
940 
is_view_id_in_ref_view_list(RK_S32 view_id,RK_S32 * ref_view_id,RK_S32 num_ref_views)941 static RK_U32 is_view_id_in_ref_view_list(RK_S32 view_id, RK_S32 *ref_view_id, RK_S32 num_ref_views)
942 {
943     RK_S32 i;
944     for (i = 0; i < num_ref_views; i++) {
945         if (view_id == ref_view_id[i])
946             break;
947     }
948 
949     return (num_ref_views && (i < num_ref_views));
950 }
951 
append_interview_list(H264_DpbBuf_t * p_Dpb,RK_S32 currPicStructure,RK_S32 list_idx,H264_FrameStore_t ** list,RK_S32 * listXsize,RK_S32 currPOC,RK_S32 curr_layer_id,RK_S32 anchor_pic_flag)952 static MPP_RET append_interview_list(H264_DpbBuf_t *p_Dpb,
953                                      RK_S32 currPicStructure, RK_S32 list_idx, H264_FrameStore_t **list,
954                                      RK_S32 *listXsize, RK_S32 currPOC, RK_S32 curr_layer_id, RK_S32 anchor_pic_flag)
955 {
956     RK_S32 poc = 0;
957     RK_S32 fld_idx = 0;
958     RK_U32 pic_avail = 0;
959     RK_S32 num_ref_views = 0;
960     RK_S32 *ref_view_id = NULL;
961     MPP_RET ret = MPP_ERR_UNKNOW;
962     RK_S32 iVOIdx = curr_layer_id;
963     H264_FrameStore_t *fs = p_Dpb->fs_ilref[0];
964     H264dVideoCtx_t *p_Vid = p_Dpb->p_Vid;
965 
966     VAL_CHECK(ret, iVOIdx >= 0); //!< Error: iVOIdx: %d is not less than 0
967     if (anchor_pic_flag) {
968         num_ref_views = list_idx ? p_Vid->active_subsps->num_anchor_refs_l1[iVOIdx] : p_Vid->active_subsps->num_anchor_refs_l0[iVOIdx];
969         ref_view_id = list_idx ? p_Vid->active_subsps->anchor_ref_l1[iVOIdx] : p_Vid->active_subsps->anchor_ref_l0[iVOIdx];
970     } else {
971         num_ref_views = list_idx ? p_Vid->active_subsps->num_non_anchor_refs_l1[iVOIdx] : p_Vid->active_subsps->num_non_anchor_refs_l0[iVOIdx];
972         ref_view_id = list_idx ? p_Vid->active_subsps->non_anchor_ref_l1[iVOIdx] : p_Vid->active_subsps->non_anchor_ref_l0[iVOIdx];
973     }
974 
975     if (currPicStructure == BOTTOM_FIELD)
976         fld_idx = 1;
977     else
978         fld_idx = 0;
979 
980     if (currPicStructure == FRAME) {
981         pic_avail = (fs->is_used == 3);
982         if (pic_avail) {
983             poc = fs->frame->is_mmco_5 ? fs->frame->poc_mmco5 : fs->frame->poc;
984         }
985     } else if (currPicStructure == TOP_FIELD) {
986         pic_avail = fs->is_used & 1;
987         if (pic_avail) {
988             poc = fs->top_field->is_mmco_5 ? fs->top_field->top_poc_mmco5 : fs->top_field->poc;
989         }
990     } else if (currPicStructure == BOTTOM_FIELD) {
991         pic_avail = fs->is_used & 2;
992         if (pic_avail) {
993             poc = fs->bottom_field->is_mmco_5 ? fs->bottom_field->bot_poc_mmco5 : fs->bottom_field->poc;
994         }
995     } else {
996         pic_avail = 0;
997     }
998 
999     if (pic_avail && fs->inter_view_flag[fld_idx]) {
1000         if (poc == currPOC) {
1001             if (is_view_id_in_ref_view_list(fs->view_id, ref_view_id, num_ref_views)) {
1002                 //!< add one inter-view reference;
1003                 list[*listXsize] = fs;
1004                 //!< next;
1005                 (*listXsize)++;
1006             }
1007         }
1008     }
1009     return ret = MPP_OK;
1010 __FAILED:
1011     return ret;
1012 }
1013 
gen_pic_list_from_frame_interview_list(RK_S32 currStructure,H264_FrameStore_t ** fs_list,RK_S32 list_idx,H264_StorePic_t ** list,RK_U8 * list_size)1014 static void gen_pic_list_from_frame_interview_list(RK_S32 currStructure,
1015                                                    H264_FrameStore_t **fs_list, RK_S32 list_idx, H264_StorePic_t **list, RK_U8 *list_size)
1016 {
1017     RK_S32 i;
1018 
1019     if (currStructure == TOP_FIELD) {
1020         for (i = 0; i < list_idx; i++) {
1021             list[(RK_S32)(*list_size)] = fs_list[i]->top_field;
1022             (*list_size)++;
1023         }
1024     }
1025     if (currStructure == BOTTOM_FIELD) {
1026         for (i = 0; i < list_idx; i++) {
1027             list[(RK_S32)(*list_size)] = fs_list[i]->bottom_field;
1028             (*list_size)++;
1029         }
1030     }
1031 }
1032 
compare_pic_by_poc_desc(const void * arg1,const void * arg2)1033 static RK_S32 compare_pic_by_poc_desc(const void *arg1, const void *arg2)
1034 {
1035     RK_S32 poc1 = (*(H264_StorePic_t**)arg1)->poc;
1036     RK_S32 poc2 = (*(H264_StorePic_t**)arg2)->poc;
1037 
1038     if (poc1 < poc2)
1039         return 1;
1040     if (poc1 > poc2)
1041         return -1;
1042     else
1043         return 0;
1044 }
1045 
compare_pic_by_poc_asc(const void * arg1,const void * arg2)1046 static RK_S32 compare_pic_by_poc_asc(const void *arg1, const void *arg2)
1047 {
1048     RK_S32 poc1 = (*(H264_StorePic_t**)arg1)->poc;
1049     RK_S32 poc2 = (*(H264_StorePic_t**)arg2)->poc;
1050 
1051     if (poc1 < poc2)
1052         return -1;
1053     if (poc1 > poc2)
1054         return 1;
1055     else
1056         return 0;
1057 }
1058 
compare_fs_by_poc_desc(const void * arg1,const void * arg2)1059 static RK_S32 compare_fs_by_poc_desc(const void *arg1, const void *arg2)
1060 {
1061     RK_S32 poc1 = (*(H264_FrameStore_t**)arg1)->poc;
1062     RK_S32 poc2 = (*(H264_FrameStore_t**)arg2)->poc;
1063 
1064     if (poc1 < poc2)
1065         return 1;
1066     else if (poc1 > poc2)
1067         return -1;
1068     else
1069         return 0;
1070 }
1071 
compare_fs_by_poc_asc(const void * arg1,const void * arg2)1072 static RK_S32 compare_fs_by_poc_asc(const void *arg1, const void *arg2)
1073 {
1074     RK_S32 poc1 = (*(H264_FrameStore_t**)arg1)->poc;
1075     RK_S32 poc2 = (*(H264_FrameStore_t**)arg2)->poc;
1076 
1077     if (poc1 < poc2)
1078         return -1;
1079     else if (poc1 > poc2)
1080         return 1;
1081     else
1082         return 0;
1083 }
1084 
init_lists_p_slice_mvc(H264_SLICE_t * currSlice)1085 static MPP_RET init_lists_p_slice_mvc(H264_SLICE_t *currSlice)
1086 {
1087     RK_U32 i = 0;
1088     RK_S32 list0idx = 0;
1089     RK_S32 listltidx = 0;
1090     H264_FrameStore_t **fs_list0 = 0;
1091     H264_FrameStore_t **fs_listlt = 0;
1092     MPP_RET ret = MPP_ERR_UNKNOW;
1093     H264dVideoCtx_t *p_Vid = currSlice->p_Vid;
1094     H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb;
1095     RK_S32 currPOC = currSlice->ThisPOC;
1096     RK_S32 anchor_pic_flag = currSlice->anchor_pic_flag;
1097 
1098     currSlice->listXsizeP[0] = 0;
1099     currSlice->listXsizeP[1] = 0;
1100     currSlice->listinterviewidx0 = 0;
1101     currSlice->listinterviewidx1 = 0;
1102 
1103     if (currSlice->structure == FRAME) {
1104         for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
1105             if (p_Dpb->fs_ref[i]->is_used == 3) {
1106                 if ((p_Dpb->fs_ref[i]->frame->used_for_reference) && (!p_Dpb->fs_ref[i]->frame->is_long_term)) {
1107                     currSlice->listP[0][list0idx++] = p_Dpb->fs_ref[i]->frame;
1108                 }
1109             }
1110         }
1111         // order list 0 by PicNum
1112         qsort((void *)currSlice->listP[0], list0idx, sizeof(H264_StorePic_t*), compare_pic_by_pic_num_desc);
1113         currSlice->listXsizeP[0] = (RK_U8)list0idx;
1114         // long term handling
1115         for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
1116             if (p_Dpb->fs_ltref[i]->is_used == 3) {
1117                 if (p_Dpb->fs_ltref[i]->frame->is_long_term) {
1118                     currSlice->listP[0][list0idx++] = p_Dpb->fs_ltref[i]->frame;
1119                 }
1120             }
1121         }
1122         qsort((void *)&currSlice->listP[0][(RK_S16)currSlice->listXsizeP[0]],
1123               list0idx - currSlice->listXsizeP[0], sizeof(H264_StorePic_t*), compare_pic_by_lt_pic_num_asc);
1124         currSlice->listXsizeP[0] = (RK_U8)list0idx;
1125     } else {
1126         fs_list0  = mpp_calloc(H264_FrameStore_t*, p_Dpb->size);
1127         fs_listlt = mpp_calloc(H264_FrameStore_t*, p_Dpb->size);
1128         MEM_CHECK(ret, fs_list0 && fs_listlt);
1129         for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
1130             if (p_Dpb->fs_ref[i]->is_reference) {
1131                 fs_list0[list0idx++] = p_Dpb->fs_ref[i];
1132             }
1133         }
1134         qsort((void *)fs_list0, list0idx, sizeof(H264_FrameStore_t*), compare_fs_by_frame_num_desc);
1135         currSlice->listXsizeP[0] = 0;
1136         gen_pic_list_from_frame_list(currSlice->structure, fs_list0, list0idx, currSlice->listP[0], &currSlice->listXsizeP[0], 0);
1137         // long term handling
1138         for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
1139             fs_listlt[listltidx++] = p_Dpb->fs_ltref[i];
1140         }
1141         qsort((void *)fs_listlt, listltidx, sizeof(H264_FrameStore_t*), compare_fs_by_lt_pic_idx_asc);
1142         gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listP[0], &currSlice->listXsizeP[0], 1);
1143         MPP_FREE(fs_list0);
1144         MPP_FREE(fs_listlt);
1145     }
1146 
1147     currSlice->listXsizeP[1] = 0;
1148     if (currSlice->mvcExt.valid && p_Vid->active_mvc_sps_flag && currSlice->svc_extension_flag == 0) {
1149         RK_S32 curr_layer_id = currSlice->layer_id;
1150         currSlice->fs_listinterview0 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size);
1151         MEM_CHECK(ret, currSlice->fs_listinterview0);
1152         list0idx = currSlice->listXsizeP[0];
1153         if (currSlice->structure == FRAME) {
1154             FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], currSlice->structure, 0,
1155                                                   currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_layer_id, anchor_pic_flag));
1156             for (i = 0; i < (RK_U32)currSlice->listinterviewidx0; i++) {
1157                 currSlice->listP[0][list0idx++] = currSlice->fs_listinterview0[i]->frame;
1158             }
1159             currSlice->listXsizeP[0] = (RK_U8)list0idx;
1160         } else {
1161             FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], currSlice->structure, 0,
1162                                                   currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_layer_id, anchor_pic_flag));
1163             gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview0,
1164                                                    currSlice->listinterviewidx0, currSlice->listP[0], &currSlice->listXsizeP[0]);
1165         }
1166     }
1167     // set the unused list entries to NULL
1168     for (i = currSlice->listXsizeP[0]; i < (MAX_LIST_SIZE); i++) {
1169         currSlice->listP[0][i] = p_Vid->no_ref_pic;
1170     }
1171     for (i = currSlice->listXsizeP[1]; i < (MAX_LIST_SIZE); i++) {
1172         currSlice->listP[1][i] = p_Vid->no_ref_pic;
1173     }
1174     MPP_FREE(currSlice->fs_listinterview0);
1175 
1176     return ret = MPP_OK;
1177 __FAILED:
1178     MPP_FREE(fs_list0);
1179     MPP_FREE(fs_listlt);
1180     MPP_FREE(currSlice->fs_listinterview0);
1181 
1182     return ret;
1183 }
1184 
init_lists_b_slice_mvc(H264_SLICE_t * currSlice)1185 static MPP_RET init_lists_b_slice_mvc(H264_SLICE_t *currSlice)
1186 {
1187     RK_U32 i = 0;
1188     RK_S32 j = 0;
1189     RK_S32 list0idx = 0;
1190     RK_S32 list0idx_1 = 0;
1191     RK_S32 listltidx = 0;
1192     H264_FrameStore_t **fs_list0 = NULL;
1193     H264_FrameStore_t **fs_list1 = NULL;
1194     H264_FrameStore_t **fs_listlt = NULL;
1195     MPP_RET ret = MPP_ERR_UNKNOW;
1196 
1197     H264dVideoCtx_t *p_Vid = currSlice->p_Vid;
1198     H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb;
1199     RK_S32 currPOC = currSlice->ThisPOC;
1200     RK_S32 anchor_pic_flag = currSlice->anchor_pic_flag;
1201 
1202     currSlice->listXsizeB[0] = 0;
1203     currSlice->listXsizeB[1] = 0;
1204     currSlice->listinterviewidx0 = 0;
1205     currSlice->listinterviewidx1 = 0;
1206     // B-Slice
1207     if (currSlice->structure == FRAME) {
1208         for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
1209             if (p_Dpb->fs_ref[i]->is_used == 3) {
1210                 if ((p_Dpb->fs_ref[i]->frame->used_for_reference) && (!p_Dpb->fs_ref[i]->frame->is_long_term)) {
1211                     if (currSlice->framepoc >= p_Dpb->fs_ref[i]->frame->poc) {
1212                         currSlice->listB[0][list0idx++] = p_Dpb->fs_ref[i]->frame;
1213                     }
1214                 }
1215             }
1216         }
1217         qsort((void *)currSlice->listB[0], list0idx, sizeof(H264_StorePic_t*), compare_pic_by_poc_desc);
1218         list0idx_1 = list0idx;
1219         for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
1220             if (p_Dpb->fs_ref[i]->is_used == 3) {
1221                 if ((p_Dpb->fs_ref[i]->frame->used_for_reference) && (!p_Dpb->fs_ref[i]->frame->is_long_term)) {
1222                     if (currSlice->framepoc < p_Dpb->fs_ref[i]->frame->poc) {
1223                         currSlice->listB[0][list0idx++] = p_Dpb->fs_ref[i]->frame;
1224                     }
1225                 }
1226             }
1227         }
1228         qsort((void *)&currSlice->listB[0][list0idx_1], list0idx - list0idx_1, sizeof(H264_StorePic_t*), compare_pic_by_poc_asc);
1229 
1230         for (j = 0; j < list0idx_1; j++) {
1231             currSlice->listB[1][list0idx - list0idx_1 + j] = currSlice->listB[0][j];
1232         }
1233         for (j = list0idx_1; j < list0idx; j++) {
1234             currSlice->listB[1][j - list0idx_1] = currSlice->listB[0][j];
1235         }
1236         currSlice->listXsizeB[0] = currSlice->listXsizeB[1] = (RK_U8)list0idx;
1237         // long term handling
1238         for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
1239             if (p_Dpb->fs_ltref[i]->is_used == 3) {
1240                 if (p_Dpb->fs_ltref[i]->frame->is_long_term) {
1241                     currSlice->listB[0][list0idx] = p_Dpb->fs_ltref[i]->frame;
1242                     currSlice->listB[1][list0idx++] = p_Dpb->fs_ltref[i]->frame;
1243                 }
1244             }
1245         }
1246         qsort((void *)&currSlice->listB[0][(RK_S16)currSlice->listXsizeB[0]],
1247               list0idx - currSlice->listXsizeB[0], sizeof(H264_StorePic_t*), compare_pic_by_lt_pic_num_asc);
1248         qsort((void *)&currSlice->listB[1][(RK_S16)currSlice->listXsizeB[0]],
1249               list0idx - currSlice->listXsizeB[0], sizeof(H264_StorePic_t*), compare_pic_by_lt_pic_num_asc);
1250         currSlice->listXsizeB[0] = currSlice->listXsizeB[1] = (RK_U8)list0idx;
1251     } else {
1252         fs_list0  = mpp_calloc(H264_FrameStore_t*, p_Dpb->size);
1253         fs_list1  = mpp_calloc(H264_FrameStore_t*, p_Dpb->size);
1254         fs_listlt = mpp_calloc(H264_FrameStore_t*, p_Dpb->size);
1255         MEM_CHECK(ret, fs_list0 && fs_list1 && fs_listlt);
1256         currSlice->listXsizeB[0] = 0;
1257         currSlice->listXsizeB[1] = 1;
1258         for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
1259             if (p_Dpb->fs_ref[i]->is_used) {
1260                 if (currSlice->ThisPOC >= p_Dpb->fs_ref[i]->poc) {
1261                     fs_list0[list0idx++] = p_Dpb->fs_ref[i];
1262                 }
1263             }
1264         }
1265         qsort((void *)fs_list0, list0idx, sizeof(H264_FrameStore_t*), compare_fs_by_poc_desc);
1266         list0idx_1 = list0idx;
1267         for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
1268             if (p_Dpb->fs_ref[i]->is_used) {
1269                 if (currSlice->ThisPOC < p_Dpb->fs_ref[i]->poc) {
1270                     fs_list0[list0idx++] = p_Dpb->fs_ref[i];
1271                 }
1272             }
1273         }
1274         qsort((void *)&fs_list0[list0idx_1], list0idx - list0idx_1, sizeof(H264_FrameStore_t*), compare_fs_by_poc_asc);
1275 
1276         for (j = 0; j < list0idx_1; j++) {
1277             fs_list1[list0idx - list0idx_1 + j] = fs_list0[j];
1278         }
1279         for (j = list0idx_1; j < list0idx; j++) {
1280             fs_list1[j - list0idx_1] = fs_list0[j];
1281         }
1282         currSlice->listXsizeB[0] = 0;
1283         currSlice->listXsizeB[1] = 0;
1284         gen_pic_list_from_frame_list(currSlice->structure, fs_list0, list0idx, currSlice->listB[0], &currSlice->listXsizeB[0], 0);
1285         gen_pic_list_from_frame_list(currSlice->structure, fs_list1, list0idx, currSlice->listB[1], &currSlice->listXsizeB[1], 0);
1286 
1287         // long term handling
1288         for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
1289             fs_listlt[listltidx++] = p_Dpb->fs_ltref[i];
1290         }
1291         qsort((void *)fs_listlt, listltidx, sizeof(H264_FrameStore_t*), compare_fs_by_lt_pic_idx_asc);
1292 
1293         gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listB[0], &currSlice->listXsizeB[0], 1);
1294         gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listB[1], &currSlice->listXsizeB[1], 1);
1295 
1296         MPP_FREE(fs_list0);
1297         MPP_FREE(fs_list1);
1298         MPP_FREE(fs_listlt);
1299     }
1300     if ((currSlice->listXsizeB[0] == currSlice->listXsizeB[1]) && (currSlice->listXsizeB[0] > 1)) {
1301         // check if lists are identical, if yes swap first two elements of currSlice->listX[1]
1302         RK_S32 diff = 0;
1303         for (j = 0; j < currSlice->listXsizeB[0]; j++) {
1304             if (currSlice->listB[0][j] != currSlice->listB[1][j]) {
1305                 diff = 1;
1306                 break;
1307             }
1308         }
1309         if (!diff) {
1310             H264_StorePic_t *tmp_s = currSlice->listB[1][0];
1311             currSlice->listB[1][0] = currSlice->listB[1][1];
1312             currSlice->listB[1][1] = tmp_s;
1313         }
1314     }
1315     if (currSlice->mvcExt.valid && p_Vid->active_mvc_sps_flag && currSlice->svc_extension_flag == 0) {
1316         RK_S32 curr_layer_id = currSlice->layer_id;
1317         // B-Slice
1318         currSlice->fs_listinterview0 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size);
1319         currSlice->fs_listinterview1 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size);
1320         MEM_CHECK(ret, currSlice->fs_listinterview0 && currSlice->fs_listinterview1);
1321         list0idx = currSlice->listXsizeB[0];
1322         if (currSlice->structure == FRAME) {
1323             FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], currSlice->structure, 0,
1324                                                   currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_layer_id, anchor_pic_flag));
1325             FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], currSlice->structure, 1,
1326                                                   currSlice->fs_listinterview1, &currSlice->listinterviewidx1, currPOC, curr_layer_id, anchor_pic_flag));
1327 
1328             for (i = 0; i < (RK_U32)currSlice->listinterviewidx0; i++) {
1329                 currSlice->listB[0][list0idx++] = currSlice->fs_listinterview0[i]->frame;
1330             }
1331             currSlice->listXsizeB[0] = (RK_U8)list0idx;
1332             list0idx = currSlice->listXsizeB[1];
1333             for (i = 0; i < (RK_U32)currSlice->listinterviewidx1; i++) {
1334                 currSlice->listB[1][list0idx++] = currSlice->fs_listinterview1[i]->frame;
1335             }
1336             currSlice->listXsizeB[1] = (RK_U8)list0idx;
1337         } else {
1338             FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], currSlice->structure, 0,
1339                                                   currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_layer_id, anchor_pic_flag));
1340             gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview0,
1341                                                    currSlice->listinterviewidx0, currSlice->listB[0], &currSlice->listXsizeB[0]);
1342             FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], currSlice->structure, 1,
1343                                                   currSlice->fs_listinterview1, &currSlice->listinterviewidx1, currPOC, curr_layer_id, anchor_pic_flag));
1344             gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview1,
1345                                                    currSlice->listinterviewidx1, currSlice->listB[1], &currSlice->listXsizeB[1]);
1346         }
1347     }
1348     // set the unused list entries to NULL
1349     for (i = currSlice->listXsizeB[0]; i < (MAX_LIST_SIZE); i++) {
1350         currSlice->listB[0][i] = p_Vid->no_ref_pic;
1351     }
1352     for (i = currSlice->listXsizeB[1]; i < (MAX_LIST_SIZE); i++) {
1353         currSlice->listB[1][i] = p_Vid->no_ref_pic;
1354     }
1355     MPP_FREE(currSlice->fs_listinterview0);
1356     MPP_FREE(currSlice->fs_listinterview1);
1357 
1358     return ret = MPP_OK;
1359 __FAILED:
1360     MPP_FREE(fs_list0);
1361     MPP_FREE(fs_list1);
1362     MPP_FREE(fs_listlt);
1363     MPP_FREE(currSlice->fs_listinterview0);
1364     MPP_FREE(currSlice->fs_listinterview1);
1365 
1366     return ret;
1367 }
1368 
get_short_term_pic(H264_SLICE_t * currSlice,RK_S32 picNum,H264_StorePic_t ** find_pic)1369 static RK_U32 get_short_term_pic(H264_SLICE_t *currSlice, RK_S32 picNum, H264_StorePic_t **find_pic)
1370 {
1371     RK_S32 i = 0;
1372     H264_StorePic_t *ret_pic = NULL;
1373     H264_StorePic_t *near_pic = NULL;
1374     H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb;
1375 
1376     for (i = p_Dpb->ref_frames_in_buffer - 1; i >= 0; i--) {
1377         if (currSlice->structure == FRAME) {
1378             if ((p_Dpb->fs_ref[i]->is_reference == 3)
1379                 && (!p_Dpb->fs_ref[i]->frame->is_long_term)) {
1380                 if (p_Dpb->fs_ref[i]->frame->pic_num == picNum) {
1381                     ret_pic = p_Dpb->fs_ref[i]->frame;
1382                     break;
1383                 } else {
1384                     near_pic = p_Dpb->fs_ref[i]->frame;
1385                 }
1386             }
1387         } else {
1388             if ((p_Dpb->fs_ref[i]->is_reference & 1)
1389                 && (!p_Dpb->fs_ref[i]->top_field->is_long_term)) {
1390                 if (p_Dpb->fs_ref[i]->top_field->pic_num == picNum) {
1391                     ret_pic = p_Dpb->fs_ref[i]->top_field;
1392                     break;
1393                 } else {
1394                     near_pic = p_Dpb->fs_ref[i]->top_field;
1395                 }
1396             }
1397             if ((p_Dpb->fs_ref[i]->is_reference & 2)
1398                 && (!p_Dpb->fs_ref[i]->bottom_field->is_long_term)) {
1399                 if (p_Dpb->fs_ref[i]->bottom_field->pic_num == picNum) {
1400                     ret_pic = p_Dpb->fs_ref[i]->bottom_field;
1401                     break;
1402                 } else {
1403                     near_pic = p_Dpb->fs_ref[i]->bottom_field;
1404                 }
1405             }
1406         }
1407     }
1408     *find_pic = ret_pic ? ret_pic : near_pic;
1409     return (ret_pic ? 1 : 0);
1410 }
1411 
1412 
get_long_term_pic(H264_SLICE_t * currSlice,RK_S32 LongtermPicNum)1413 static H264_StorePic_t *get_long_term_pic(H264_SLICE_t *currSlice, RK_S32 LongtermPicNum)
1414 {
1415     RK_U32 i = 0;
1416     H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb;
1417 
1418     for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
1419         if (currSlice->structure == FRAME) {
1420             if (p_Dpb->fs_ltref[i]->is_reference == 3)
1421                 if ((p_Dpb->fs_ltref[i]->frame->is_long_term)
1422                     && (p_Dpb->fs_ltref[i]->frame->long_term_pic_num == LongtermPicNum))
1423                     return p_Dpb->fs_ltref[i]->frame;
1424         } else {
1425             if (p_Dpb->fs_ltref[i]->is_reference & 1)
1426                 if ((p_Dpb->fs_ltref[i]->top_field->is_long_term)
1427                     && (p_Dpb->fs_ltref[i]->top_field->long_term_pic_num == LongtermPicNum))
1428                     return p_Dpb->fs_ltref[i]->top_field;
1429             if (p_Dpb->fs_ltref[i]->is_reference & 2)
1430                 if ((p_Dpb->fs_ltref[i]->bottom_field->is_long_term)
1431                     && (p_Dpb->fs_ltref[i]->bottom_field->long_term_pic_num == LongtermPicNum))
1432                     return p_Dpb->fs_ltref[i]->bottom_field;
1433         }
1434     }
1435     return NULL;
1436 }
check_ref_pic_list(H264_SLICE_t * currSlice,RK_S32 cur_list)1437 static RK_U32 check_ref_pic_list(H264_SLICE_t *currSlice, RK_S32 cur_list)
1438 {
1439     RK_S32 i = 0;
1440     RK_U32 dpb_error_flag = 0;
1441     RK_S32 maxPicNum = 0, currPicNum = 0;
1442     RK_S32 picNumLXNoWrap = 0, picNumLXPred = 0, picNumLX = 0;
1443 
1444     RK_S32 *modification_of_pic_nums_idc = currSlice->modification_of_pic_nums_idc[cur_list];
1445     RK_S32 *abs_diff_pic_num_minus1 = currSlice->abs_diff_pic_num_minus1[cur_list];
1446     RK_S32 *long_term_pic_idx = currSlice->long_term_pic_idx[cur_list];
1447     H264dVideoCtx_t *p_Vid = currSlice->p_Vid;
1448 
1449     if (currSlice->structure == FRAME) {
1450         maxPicNum  = p_Vid->max_frame_num;
1451         currPicNum = currSlice->frame_num;
1452     } else {
1453         maxPicNum  = 2 * p_Vid->max_frame_num;
1454         currPicNum = 2 * currSlice->frame_num + 1;
1455     }
1456     picNumLXPred = currPicNum;
1457     for (i = 0; modification_of_pic_nums_idc[i] != 3 && i < MAX_REORDER_TIMES; i++) {
1458         H264_StorePic_t *tmp = NULL;
1459         RK_U32 error_flag = 0;
1460         if (modification_of_pic_nums_idc[i] > 3)
1461             continue;
1462         if (modification_of_pic_nums_idc[i] < 2) {
1463             if (modification_of_pic_nums_idc[i] == 0) {
1464                 if ( (picNumLXPred - (abs_diff_pic_num_minus1[i] + 1)) < 0)
1465                     picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1) + maxPicNum;
1466                 else
1467                     picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1);
1468             } else { //!< (modification_of_pic_nums_idc[i] == 1)
1469                 if (picNumLXPred + (abs_diff_pic_num_minus1[i] + 1) >= maxPicNum)
1470                     picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1) - maxPicNum;
1471                 else
1472                     picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1);
1473             }
1474             picNumLXPred = picNumLXNoWrap;
1475             picNumLX = (picNumLXNoWrap > currPicNum) ? (picNumLXNoWrap - maxPicNum) : picNumLXNoWrap;
1476             error_flag = 1;
1477             if (get_short_term_pic(currSlice, picNumLX, &tmp)) { //!< find short reference
1478                 MppFrame mframe = NULL;
1479                 H264D_DBG(H264D_DBG_DPB_REF_ERR, "find short reference, slot_idx=%d.\n", tmp->mem_mark->slot_idx);
1480                 if (tmp && tmp->mem_mark && tmp->mem_mark->slot_idx >= 0) {
1481                     mpp_buf_slot_get_prop(p_Vid->p_Dec->frame_slots, tmp->mem_mark->slot_idx, SLOT_FRAME_PTR, &mframe);
1482                     if (mframe && !mpp_frame_get_errinfo(mframe)) {
1483                         error_flag = 0;
1484                     }
1485                 }
1486             }
1487 
1488         } else { //!< (modification_of_pic_nums_idc[i] == 2)
1489             tmp = get_long_term_pic(currSlice, long_term_pic_idx[i]);
1490         }
1491         dpb_error_flag |= error_flag;
1492     }
1493 
1494     return dpb_error_flag;
1495 }
1496 
check_ref_dbp_err(H264_DecCtx_t * p_Dec,H264_RefPicInfo_t * pref,RK_U32 active_refs)1497 static RK_U32 check_ref_dbp_err(H264_DecCtx_t *p_Dec, H264_RefPicInfo_t *pref, RK_U32 active_refs)
1498 {
1499     RK_U32 i = 0;
1500     RK_U32 dpb_error_flag = 0;
1501 
1502     for (i = 0; i < MAX_REF_SIZE; i++) {
1503         if (pref[i].valid) {
1504             MppFrame mframe = NULL;
1505             RK_S32 slot_idx = p_Dec->dpb_info[pref[i].dpb_idx].slot_index;
1506             if (slot_idx < 0) {
1507                 dpb_error_flag |= 1;
1508                 break;
1509             }
1510             mpp_buf_slot_get_prop(p_Dec->frame_slots, slot_idx, SLOT_FRAME_PTR, &mframe);
1511             if (mframe) {
1512                 if (i < active_refs
1513                     && (!p_Dec->p_Vid->recovery.valid_flag
1514                         || p_Dec->dpb_info[pref[i].dpb_idx].frame_num < p_Dec->p_Vid->recovery.first_frm_valid
1515                         || p_Dec->dpb_info[pref[i].dpb_idx].frame_num >= p_Dec->p_Vid->recovery.recovery_pic_id)) {
1516                     dpb_error_flag |= mpp_frame_get_errinfo(mframe);
1517                 }
1518                 H264D_DBG(H264D_DBG_DPB_REF_ERR, "[DPB_REF_ERR] slot_idx=%d, dpb_err[%d]=%d", slot_idx, i, mpp_frame_get_errinfo(mframe));
1519             }
1520         }
1521     }
1522     return dpb_error_flag;
1523 }
1524 
check_refer_picture_lists(H264_SLICE_t * currSlice)1525 static void check_refer_picture_lists(H264_SLICE_t *currSlice)
1526 {
1527     H264_DecCtx_t *p_Dec = currSlice->p_Dec;
1528     H264dErrCtx_t *p_err = &p_Dec->errctx;
1529 
1530     if (H264_I_SLICE == currSlice->slice_type) {
1531         p_err->dpb_err_flag = 0;
1532         return;
1533     }
1534 #if 1
1535 
1536     if ((currSlice->slice_type % 5) != H264_I_SLICE
1537         && (currSlice->slice_type % 5) != H264_SI_SLICE) {
1538         if (currSlice->ref_pic_list_reordering_flag[LIST_0]) {
1539             p_err->cur_err_flag |= check_ref_pic_list(currSlice, 0) ? 1 : 0;
1540         } else {
1541             RK_S32 pps_refs = currSlice->active_pps->num_ref_idx_l0_default_active_minus1 + 1;
1542             RK_S32 over_flag = currSlice->num_ref_idx_override_flag;
1543             RK_S32 active_l0 = over_flag ? currSlice->num_ref_idx_active[LIST_0] : pps_refs;
1544             if (currSlice->slice_type % 5 == H264_B_SLICE)
1545                 p_err->cur_err_flag |= check_ref_dbp_err(p_Dec, p_Dec->refpic_info_b[0], active_l0) ? 1 : 0;
1546             else
1547                 p_err->cur_err_flag |= check_ref_dbp_err(p_Dec, p_Dec->refpic_info_p, active_l0) ? 1 : 0;
1548             H264D_DBG(H264D_DBG_DPB_REF_ERR, "list0 dpb: cur_err_flag=%d, pps_refs=%d, over_flag=%d, num_ref_l0=%d\n",
1549                       p_err->cur_err_flag, pps_refs, over_flag, active_l0);
1550         }
1551     }
1552     if (currSlice->slice_type % 5 == H264_B_SLICE) {
1553         if (currSlice->ref_pic_list_reordering_flag[LIST_1]) {
1554             p_err->cur_err_flag |= check_ref_pic_list(currSlice, 1) ? 1 : 0;
1555         } else {
1556             RK_S32 pps_refs = currSlice->active_pps->num_ref_idx_l1_default_active_minus1 + 1;
1557             RK_S32 over_flag = currSlice->num_ref_idx_override_flag;
1558             RK_S32 active_l1 = over_flag ? currSlice->num_ref_idx_active[LIST_1] : pps_refs;
1559             p_err->cur_err_flag |= check_ref_dbp_err(p_Dec, p_Dec->refpic_info_b[1], active_l1) ? 1 : 0;
1560             H264D_DBG(H264D_DBG_DPB_REF_ERR, "list1 dpb: cur_err_flag=%d, pps_refs=%d, over_flag=%d, num_ref_l1=%d\n",
1561                       p_err->cur_err_flag, pps_refs, over_flag, active_l1);
1562         }
1563     }
1564 
1565 #endif
1566 
1567 }
1568 
reset_dpb_info(H264_DpbInfo_t * p)1569 static void reset_dpb_info(H264_DpbInfo_t *p)
1570 {
1571     p->refpic = NULL;
1572     p->TOP_POC = 0;
1573     p->BOT_POC = 0;
1574     p->field_flag = 0;
1575     p->slot_index = -1;
1576     p->colmv_is_used = 0;
1577     p->frame_num = 0;
1578     p->is_long_term = 0;
1579     p->long_term_pic_num = 0;
1580     p->voidx = 0;
1581     p->view_id = 0;
1582     p->is_used = 0;
1583 }
1584 
prepare_init_dpb_info(H264_SLICE_t * currSlice)1585 static MPP_RET prepare_init_dpb_info(H264_SLICE_t *currSlice)
1586 {
1587     RK_U32 i = 0, j = 0;
1588     H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb;
1589     H264_DecCtx_t *p_Dec = currSlice->p_Dec;
1590 
1591     //!< reset parameters
1592     for (i = 0; i < MAX_DPB_SIZE; i++) {
1593         reset_dpb_info(&p_Dec->dpb_info[i]);
1594     }
1595     //!< reference
1596 #if 1
1597     for (i = 0, j = 0; j < p_Dpb->ref_frames_in_buffer; i++, j++) {
1598         if (p_Dpb->fs_ref[j]->is_used == 3) {
1599             p_Dec->dpb_info[i].refpic = p_Dpb->fs_ref[j]->frame;
1600             if (p_Dpb->fs_ref[j]->frame->iCodingType == FIELD_CODING) {
1601                 p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ref[j]->top_field->poc;
1602                 p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ref[j]->bottom_field->poc;
1603             } else {
1604                 if (p_Dpb->fs_ref[j]->frame->frame_poc != p_Dpb->fs_ref[j]->frame->poc) {
1605                     p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ref[j]->frame->top_poc - p_Dpb->fs_ref[j]->frame->frame_poc;
1606                     p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ref[j]->frame->bottom_poc - p_Dpb->fs_ref[j]->frame->frame_poc;
1607                 } else {
1608                     p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ref[j]->frame->top_poc;
1609                     p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ref[j]->frame->bottom_poc;
1610                 }
1611             }
1612             p_Dec->dpb_info[i].field_flag = p_Dpb->fs_ref[j]->frame->iCodingType == FIELD_CODING;
1613             p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ref[j]->frame->mem_mark->slot_idx;
1614             p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ref[j]->frame->colmv_no_used_flag ? 0 : 1);
1615         } else if (p_Dpb->fs_ref[j]->is_used) {
1616             if (p_Dpb->fs_ref[j]->is_used & 0x1) { // top
1617                 p_Dec->dpb_info[i].refpic = p_Dpb->fs_ref[j]->top_field;
1618 
1619                 p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ref[j]->top_field->poc;
1620                 p_Dec->dpb_info[i].BOT_POC = 0;
1621                 p_Dec->dpb_info[i].field_flag = 1;
1622                 p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ref[j]->top_field->mem_mark->slot_idx;
1623                 p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ref[j]->top_field->colmv_no_used_flag ? 0 : 1);
1624             } else { // if(p_Dpb->fs_ref[j]->is_used & 0x2) // bottom
1625                 p_Dec->dpb_info[i].refpic = p_Dpb->fs_ref[j]->bottom_field;
1626                 p_Dec->dpb_info[i].TOP_POC = 0;
1627                 p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ref[j]->bottom_field->poc;
1628                 p_Dec->dpb_info[i].field_flag = 1;
1629                 p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ref[j]->bottom_field->mem_mark->slot_idx;
1630                 p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ref[j]->bottom_field->colmv_no_used_flag ? 0 : 1);
1631             }
1632         }
1633         p_Dec->dpb_info[i].frame_num = p_Dpb->fs_ref[j]->frame_num;
1634         p_Dec->dpb_info[i].is_long_term = 0;
1635         p_Dec->dpb_info[i].long_term_pic_num = 0;
1636         p_Dec->dpb_info[i].long_term_frame_idx = 0;
1637         p_Dec->dpb_info[i].voidx = p_Dpb->fs_ref[j]->layer_id;
1638         p_Dec->dpb_info[i].view_id = p_Dpb->fs_ref[j]->view_id;
1639         p_Dec->dpb_info[i].is_used = p_Dpb->fs_ref[j]->is_used;
1640     }
1641 #endif
1642     //!<---- long term reference
1643 #if 1
1644     for (j = 0; j < p_Dpb->ltref_frames_in_buffer; i++, j++) {
1645         if (p_Dpb->fs_ltref[j]->is_used == 3) {
1646             p_Dec->dpb_info[i].refpic = p_Dpb->fs_ltref[j]->frame;
1647 
1648             if (p_Dpb->fs_ltref[j]->frame->iCodingType == FIELD_CODING) {
1649                 p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ltref[j]->top_field->poc;
1650                 p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ltref[j]->bottom_field->poc;
1651             } else {
1652                 if (p_Dpb->fs_ltref[j]->frame->frame_poc != p_Dpb->fs_ltref[j]->frame->poc) {
1653                     p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ltref[j]->frame->top_poc - p_Dpb->fs_ltref[j]->frame->frame_poc;
1654                     p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ltref[j]->frame->bottom_poc - p_Dpb->fs_ltref[j]->frame->frame_poc;
1655                 } else {
1656                     p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ltref[j]->frame->top_poc;
1657                     p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ltref[j]->frame->bottom_poc;
1658                 }
1659 
1660             }
1661             p_Dec->dpb_info[i].field_flag = p_Dpb->fs_ltref[j]->frame->iCodingType == FIELD_CODING;
1662             p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ltref[j]->frame->mem_mark->slot_idx;
1663             p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ltref[j]->frame->colmv_no_used_flag ? 0 : 1);
1664             p_Dec->dpb_info[i].long_term_pic_num = p_Dpb->fs_ltref[j]->frame->long_term_pic_num;
1665         } else if (p_Dpb->fs_ltref[j]->is_used) {
1666             if (p_Dpb->fs_ltref[j]->is_used & 0x1) {
1667                 p_Dec->dpb_info[i].refpic = p_Dpb->fs_ltref[j]->top_field;
1668                 p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ltref[j]->top_field->poc;
1669                 p_Dec->dpb_info[i].BOT_POC = 0;
1670                 p_Dec->dpb_info[i].field_flag = 1;
1671                 p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ltref[j]->top_field->mem_mark->slot_idx;
1672                 p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ltref[j]->top_field->colmv_no_used_flag ? 0 : 1);
1673                 p_Dec->dpb_info[i].long_term_pic_num = p_Dpb->fs_ltref[j]->top_field->long_term_pic_num;
1674             } else { // if(p_Dpb->fs_ref[j]->is_used & 0x2)
1675                 p_Dec->dpb_info[i].refpic = p_Dpb->fs_ltref[j]->bottom_field;
1676                 p_Dec->dpb_info[i].TOP_POC = 0;
1677                 p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ltref[j]->bottom_field->poc;
1678                 p_Dec->dpb_info[i].field_flag = 1;
1679                 p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ltref[j]->bottom_field->mem_mark->slot_idx;
1680                 p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ltref[j]->bottom_field->colmv_no_used_flag ? 0 : 1);
1681                 p_Dec->dpb_info[i].long_term_pic_num = p_Dpb->fs_ltref[j]->bottom_field->long_term_pic_num;
1682             }
1683         }
1684         p_Dec->dpb_info[i].frame_num = p_Dpb->fs_ltref[j]->long_term_frame_idx; //long term use long_term_frame_idx
1685         p_Dec->dpb_info[i].is_long_term = 1;
1686         p_Dec->dpb_info[i].long_term_frame_idx = p_Dpb->fs_ltref[j]->long_term_frame_idx;
1687         p_Dec->dpb_info[i].voidx = p_Dpb->fs_ltref[j]->layer_id;
1688         p_Dec->dpb_info[i].view_id = p_Dpb->fs_ltref[j]->view_id;
1689         p_Dec->dpb_info[i].is_used = p_Dpb->fs_ltref[j]->is_used;
1690     }
1691 #endif
1692     //!< inter-layer reference (for multi-layered codecs)
1693 #if 1
1694     for (j = 0; j < p_Dpb->used_size_il; i++, j++) {
1695         if (currSlice->structure == FRAME && p_Dpb->fs_ilref[j]->is_used == 3) {
1696             if (p_Dpb->fs_ilref[j]->inter_view_flag[0] == 0 && p_Dpb->fs_ilref[j]->inter_view_flag[1] == 0)
1697                 break;
1698             p_Dec->dpb_info[i].refpic = p_Dpb->fs_ilref[j]->frame;
1699 
1700             if (p_Dpb->fs_ilref[j]->frame->is_mmco_5) {
1701                 p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->frame->top_poc_mmco5;
1702                 p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->frame->bot_poc_mmco5;
1703             } else {
1704                 p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->frame->top_poc;
1705                 p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->frame->bottom_poc;
1706             }
1707             p_Dec->dpb_info[i].field_flag = p_Dpb->fs_ilref[j]->frame->iCodingType == FIELD_CODING;
1708             p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ilref[j]->frame->mem_mark->slot_idx;
1709             p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ilref[j]->frame->colmv_no_used_flag ? 0 : 1);
1710         } else if (currSlice->structure != FRAME && p_Dpb->fs_ilref[j]->is_used) {
1711             if (p_Dpb->fs_ilref[j]->is_used == 0x3) {
1712                 if (p_Dpb->fs_ilref[j]->inter_view_flag[currSlice->structure == BOTTOM_FIELD] == 0)
1713                     break;
1714                 p_Dec->dpb_info[i].refpic = p_Dpb->fs_ilref[j]->top_field;
1715 
1716                 if (p_Dpb->fs_ilref[j]->top_field->is_mmco_5) {
1717                     p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->top_field->top_poc_mmco5;
1718                 } else {
1719                     p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->top_field->top_poc;
1720                 }
1721                 if (p_Dpb->fs_ilref[j]->bottom_field->is_mmco_5) {
1722                     p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->bottom_field->bot_poc_mmco5;
1723                 } else {
1724                     p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->bottom_field->bottom_poc;
1725                 }
1726                 p_Dec->dpb_info[i].field_flag = p_Dpb->fs_ilref[j]->frame->iCodingType == FIELD_CODING;
1727                 p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ilref[j]->frame->mem_mark->slot_idx;
1728                 p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ilref[j]->frame->colmv_no_used_flag ? 0 : 1);
1729             }
1730             if (p_Dpb->fs_ilref[j]->is_used & 0x1) {
1731                 if (p_Dpb->fs_ilref[j]->inter_view_flag[0] == 0)
1732                     break;
1733                 p_Dec->dpb_info[i].refpic = p_Dpb->fs_ilref[j]->top_field;
1734 
1735                 if (p_Dpb->fs_ilref[j]->top_field->is_mmco_5) {
1736                     p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->top_field->top_poc_mmco5;
1737                 } else {
1738                     p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->top_field->top_poc;
1739                 }
1740                 p_Dec->dpb_info[i].BOT_POC = 0;
1741                 p_Dec->dpb_info[i].field_flag = 1;
1742                 p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ilref[j]->top_field->mem_mark->slot_idx;
1743                 p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ilref[j]->top_field->colmv_no_used_flag ? 0 : 1);
1744             } else { // if(p_Dpb->fs_ref[j]->is_used & 0x2)
1745                 if (p_Dpb->fs_ilref[j]->inter_view_flag[1] == 0)
1746                     break;
1747                 p_Dec->dpb_info[i].refpic = p_Dpb->fs_ilref[j]->bottom_field;
1748 
1749                 p_Dec->dpb_info[i].TOP_POC = 0;
1750                 if (p_Dpb->fs_ilref[j]->bottom_field->is_mmco_5) {
1751                     p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->bottom_field->bot_poc_mmco5;
1752                 } else {
1753                     p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->bottom_field->bottom_poc;
1754                 }
1755                 p_Dec->dpb_info[i].field_flag = 1;
1756                 p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ilref[j]->bottom_field->mem_mark->slot_idx;
1757                 p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ilref[j]->bottom_field->colmv_no_used_flag ? 0 : 1);
1758             }
1759         }
1760         p_Dec->dpb_info[i].frame_num = p_Dpb->fs_ilref[j]->frame_num;
1761         p_Dec->dpb_info[i].is_long_term = 0;//p_Dpb->fs_ilref[j]->is_long_term;
1762         p_Dec->dpb_info[i].is_ilt_flag = 1;
1763         p_Dec->dpb_info[i].long_term_pic_num = 0;
1764         p_Dec->dpb_info[i].long_term_frame_idx = 0;
1765         p_Dec->dpb_info[i].voidx = p_Dpb->fs_ilref[j]->layer_id;
1766         p_Dec->dpb_info[i].view_id = p_Dpb->fs_ilref[j]->view_id;
1767         p_Dec->dpb_info[i].is_used = p_Dpb->fs_ilref[j]->is_used;
1768     }
1769 #endif
1770 
1771     return MPP_OK;
1772 }
1773 
prepare_init_ref_info(H264_SLICE_t * currSlice)1774 static MPP_RET prepare_init_ref_info(H264_SLICE_t *currSlice)
1775 {
1776     void *refpic = NULL;
1777     RK_U32 i = 0, j = 0, k = 0;
1778     RK_S32 poc = 0, TOP_POC = 0, BOT_POC = 0;
1779     RK_S32 min_poc = 0, max_poc = 0;
1780     RK_S32 layer_id = 0, voidx = 0, is_used = 0, near_dpb_idx = 0;
1781     RK_U32 mmco5_flag = 0;
1782     H264_DecCtx_t *p_Dec = currSlice->p_Dec;
1783 
1784     memset(p_Dec->refpic_info_p,    0, MAX_REF_SIZE * sizeof(H264_RefPicInfo_t));
1785     memset(p_Dec->refpic_info_b[0], 0, MAX_REF_SIZE * sizeof(H264_RefPicInfo_t));
1786     memset(p_Dec->refpic_info_b[1], 0, MAX_REF_SIZE * sizeof(H264_RefPicInfo_t));
1787 
1788     if (currSlice->idr_flag && (currSlice->layer_id == 0)) { // idr_flag==1 && layer_id==0
1789         goto __RETURN;
1790     }
1791     //!<------ set listP -------
1792     near_dpb_idx = 0;
1793     for (j = 0; j < 32; j++) {
1794         if (j >= currSlice->listXsizeP[0])
1795             break;
1796         poc = 0;
1797         layer_id = currSlice->listP[0][j]->layer_id;
1798         mmco5_flag = (currSlice->listP[0][j]->is_mmco_5 && currSlice->layer_id && !currSlice->listP[0][j]->layer_id) ? 1 : 0;
1799         if (currSlice->listP[0][j]->structure == FRAME) {
1800             poc = mmco5_flag ? currSlice->listP[0][j]->poc_mmco5 : currSlice->listP[0][j]->poc;
1801         } else if (currSlice->listP[0][j]->structure == TOP_FIELD) {
1802             poc = mmco5_flag ? currSlice->listP[0][j]->top_poc_mmco5 : currSlice->listP[0][j]->top_poc;
1803         } else {
1804             poc = mmco5_flag ? currSlice->listP[0][j]->bot_poc_mmco5 : currSlice->listP[0][j]->bottom_poc;
1805         }
1806         for (i = 0; i < 16; i++) {
1807             refpic = p_Dec->dpb_info[i].refpic;
1808             TOP_POC = p_Dec->dpb_info[i].TOP_POC;
1809             BOT_POC = p_Dec->dpb_info[i].BOT_POC;
1810             voidx = p_Dec->dpb_info[i].voidx;
1811             is_used = p_Dec->dpb_info[i].is_used;
1812             if (currSlice->structure == FRAME && refpic) {
1813                 if (poc == MPP_MIN(TOP_POC, BOT_POC) && (layer_id == voidx))
1814                     break;
1815             } else {
1816                 if (is_used == 3) {
1817                     if ((poc == BOT_POC || poc == TOP_POC) && layer_id == voidx)
1818                         break;
1819                 } else if (is_used & 1) {
1820                     if (poc == TOP_POC && layer_id == voidx)
1821                         break;
1822                 } else if (is_used & 2) {
1823                     if (poc == BOT_POC && layer_id == voidx)
1824                         break;
1825                 }
1826             }
1827         }
1828         if (i < 16) {
1829             near_dpb_idx = i;
1830             p_Dec->refpic_info_p[j].dpb_idx = i;
1831         } else {
1832             ASSERT(near_dpb_idx >= 0);
1833             p_Dec->refpic_info_p[j].dpb_idx = near_dpb_idx;
1834             p_Dec->errctx.cur_err_flag |= 1;
1835         }
1836         if (currSlice->listP[0][j]->structure == BOTTOM_FIELD) {
1837             p_Dec->refpic_info_p[j].bottom_flag = 1;
1838         } else {
1839             p_Dec->refpic_info_p[j].bottom_flag = 0;
1840         }
1841         p_Dec->refpic_info_p[j].valid = 1;
1842     }
1843     //!<------  set listB -------
1844     for (k = 0; k < 2; k++) {
1845         RK_U32 tmp[16] = {0};
1846 
1847         min_poc =  0xFFFF;
1848         max_poc = -0xFFFF;
1849         near_dpb_idx = 0;
1850         for (j = 0; j < 32; j++) {
1851             if (j >= currSlice->listXsizeB[k])
1852                 break;
1853 
1854             poc = 0;
1855             layer_id = currSlice->listB[k][j]->layer_id;
1856             mmco5_flag = (currSlice->listB[k][j]->is_mmco_5 && currSlice->layer_id && !currSlice->listB[k][j]->layer_id) ? 1 : 0;
1857             if (currSlice->listB[k][j]->structure == FRAME) {
1858                 poc = mmco5_flag ? currSlice->listB[k][j]->poc_mmco5 : currSlice->listB[k][j]->poc;
1859             } else if (currSlice->listB[k][j]->structure == TOP_FIELD) {
1860                 poc = mmco5_flag ? currSlice->listB[k][j]->top_poc_mmco5 : currSlice->listB[k][j]->top_poc;
1861             } else {
1862                 poc = mmco5_flag ? currSlice->listB[k][j]->bot_poc_mmco5 : currSlice->listB[k][j]->bottom_poc;
1863             }
1864 
1865             min_poc = MPP_MIN(min_poc, poc);
1866             max_poc = MPP_MAX(max_poc, poc);
1867             for (i = 0; i < 16; i++) {
1868                 refpic = p_Dec->dpb_info[i].refpic;
1869                 TOP_POC = p_Dec->dpb_info[i].TOP_POC;
1870                 BOT_POC = p_Dec->dpb_info[i].BOT_POC;
1871                 voidx = p_Dec->dpb_info[i].voidx;
1872                 is_used = p_Dec->dpb_info[i].is_used;
1873                 if (currSlice->structure == FRAME && refpic) {
1874                     if (poc == MPP_MIN(TOP_POC, BOT_POC) && (layer_id == voidx) && !tmp[i]) {
1875                         tmp[i] = 1;
1876                         break;
1877                     }
1878                 } else {
1879                     if (is_used == 3) {
1880                         if ((poc == BOT_POC || poc == TOP_POC) && layer_id == voidx)
1881                             break;
1882                     } else if (is_used & 1) {
1883                         if (poc == TOP_POC && (layer_id == voidx || (layer_id != voidx && !currSlice->bottom_field_flag)))
1884                             break;
1885                     } else if (is_used & 2) {
1886                         if (poc == BOT_POC && (layer_id == voidx || (layer_id != voidx && currSlice->bottom_field_flag)))
1887                             break;
1888                     }
1889                 }
1890             }
1891             if (i < 16) {
1892                 near_dpb_idx = i;
1893                 p_Dec->refpic_info_b[k][j].dpb_idx = i;
1894             } else {
1895                 ASSERT(near_dpb_idx >= 0);
1896                 p_Dec->refpic_info_b[k][j].dpb_idx = near_dpb_idx;
1897                 p_Dec->errctx.cur_err_flag |= 1;
1898             }
1899             if (currSlice->listB[k][j]->structure == BOTTOM_FIELD) {
1900                 p_Dec->refpic_info_b[k][j].bottom_flag = 1;
1901             } else {
1902                 p_Dec->refpic_info_b[k][j].bottom_flag = 0;
1903             }
1904             p_Dec->refpic_info_b[k][j].valid = 1;
1905         }
1906 
1907     }
1908     //!< check dpb list poc
1909 #if 0
1910     {
1911         RK_S32 cur_poc = p_Dec->p_Vid->dec_pic->poc;
1912         if ((currSlice->slice_type % 5) != H264_I_SLICE
1913             && (currSlice->slice_type % 5) != H264_SI_SLICE) {
1914             if (cur_poc < min_poc) {
1915                 p_Dec->errctx.cur_err_flag |= 1;
1916                 H264D_DBG(H264D_DBG_DPB_REF_ERR, "[DPB_REF_ERR] min_poc=%d, dec_poc=%d", min_poc, cur_poc);
1917             }
1918         }
1919         if (currSlice->slice_type % 5 == H264_B_SLICE) {
1920             if (cur_poc > max_poc) {
1921                 p_Dec->errctx.cur_err_flag |= 1;
1922                 H264D_DBG(H264D_DBG_DPB_REF_ERR, "[DPB_REF_ERR] max_poc=%d, dec_poc=%d", max_poc, cur_poc);
1923             }
1924         }
1925     }
1926 #endif
1927 __RETURN:
1928     return MPP_OK;
1929 }
1930 
check_refer_dpb_buf_slots(H264_SLICE_t * currSlice)1931 static MPP_RET check_refer_dpb_buf_slots(H264_SLICE_t *currSlice)
1932 {
1933     RK_U32 i = 0;
1934     RK_S32 slot_idx = 0;
1935     RK_U32 dpb_used = 0;
1936     H264_DecCtx_t *p_Dec = NULL;
1937     H264_DpbMark_t *p_mark = NULL;
1938 
1939     p_Dec = currSlice->p_Dec;
1940     //!< set buf slot flag
1941     for (i = 0; i < MAX_DPB_SIZE; i++) {
1942         if ((NULL != p_Dec->dpb_info[i].refpic) && (p_Dec->dpb_info[i].slot_index >= 0)) {
1943             p_Dec->in_task->refer[i] = p_Dec->dpb_info[i].slot_index;
1944             mpp_buf_slot_set_flag(p_Dec->frame_slots, p_Dec->dpb_info[i].slot_index, SLOT_HAL_INPUT);
1945             mpp_buf_slot_set_flag(p_Dec->frame_slots, p_Dec->dpb_info[i].slot_index, SLOT_CODEC_USE);
1946         } else {
1947             p_Dec->in_task->refer[i] = -1;
1948         }
1949     }
1950     //!< dpb info
1951     if (h264d_debug & H264D_DBG_DPB_INFO) {
1952         H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_INFO] cur_slot_idx=%d", p_Dec->in_task->output);
1953         for (i = 0; i < MAX_DPB_SIZE; i++) {
1954             slot_idx = p_Dec->in_task->refer[i];
1955             if (slot_idx >= 0) {
1956                 H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_INFO] ref_slot_idx[%d]=%d", i, slot_idx);
1957             }
1958         }
1959     }
1960     //!< mark info
1961     for (i = 0; i < MAX_MARK_SIZE; i++) {
1962         p_mark = &p_Dec->dpb_mark[i];
1963         if (p_mark->out_flag && (p_mark->slot_idx >= 0)) {
1964             dpb_used++;
1965             if (h264d_debug & H264D_DBG_DPB_INFO) {
1966                 RK_S32 fd = 0;
1967                 MppFrame mframe = NULL;
1968                 MppBuffer mbuffer = NULL;
1969                 mpp_buf_slot_get_prop(p_Dec->frame_slots, p_mark->slot_idx, SLOT_FRAME_PTR, &mframe);
1970                 mbuffer = mframe ? mpp_frame_get_buffer(mframe) : NULL;
1971                 fd = mbuffer ? mpp_buffer_get_fd(mbuffer) : 0xFF;
1972                 H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_MARK_INFO] slot_idx=%d, top_used=%d, bot_used=%d, out_flag=%d, fd=0x%02x, poc=%d, view_id=%d",
1973                           p_mark->slot_idx, p_mark->top_used, p_mark->bot_used,
1974                           p_mark->out_flag, fd, p_mark->pic->poc, p_mark->pic->layer_id);
1975             }
1976         }
1977     }
1978     H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_MARK_INFO] ---------- cur_slot=%d --------------------", p_Dec->in_task->output);
1979 
1980     if (dpb_used > MPP_MIN(p_Dec->p_Vid->dpb_size[0] + p_Dec->p_Vid->dpb_size[1], 16) + 2)  {
1981         H264D_ERR("[h264d_reset_error]");
1982         h264d_reset((void *)p_Dec);
1983         return MPP_NOK;
1984     }
1985 
1986     return MPP_OK;
1987 }
1988 
1989 
1990 /*!
1991 ***********************************************************************
1992 * \brief
1993 *    flush dpb buffer slot
1994 ***********************************************************************
1995 */
1996 //extern "C"
flush_dpb_buf_slot(H264_DecCtx_t * p_Dec)1997 void flush_dpb_buf_slot(H264_DecCtx_t *p_Dec)
1998 {
1999     RK_U32 i = 0;
2000     H264_DpbMark_t *p_mark = NULL;
2001 
2002     for (i = 0; i < MAX_MARK_SIZE; i++) {
2003         p_mark = &p_Dec->dpb_mark[i];
2004         if (p_mark && p_mark->out_flag && (p_mark->slot_idx >= 0)) {
2005             MppFrame mframe = NULL;
2006             mpp_buf_slot_get_prop(p_Dec->frame_slots, p_mark->slot_idx, SLOT_FRAME_PTR, &mframe);
2007             if (mframe) {
2008                 H264D_DBG(H264D_DBG_SLOT_FLUSH, "[DPB_BUF_FLUSH] slot_idx=%d, top_used=%d, bot_used=%d",
2009                           p_mark->slot_idx, p_mark->top_used, p_mark->bot_used);
2010                 mpp_frame_set_discard(mframe, 1);
2011                 mpp_buf_slot_set_flag(p_Dec->frame_slots, p_mark->slot_idx, SLOT_QUEUE_USE);
2012                 mpp_buf_slot_enqueue(p_Dec->frame_slots, p_mark->slot_idx, QUEUE_DISPLAY);
2013                 mpp_buf_slot_clr_flag(p_Dec->frame_slots, p_mark->slot_idx, SLOT_CODEC_USE);
2014                 p_Dec->last_frame_slot_idx = p_mark->slot_idx;
2015             }
2016         }
2017         reset_dpb_mark(p_mark);
2018     }
2019 }
2020 
2021 /*!
2022 ***********************************************************************
2023 * \brief
2024 *    reset dpb mark
2025 ***********************************************************************
2026 */
2027 //extern "C"
reset_dpb_mark(H264_DpbMark_t * p_mark)2028 MPP_RET reset_dpb_mark(H264_DpbMark_t *p_mark)
2029 {
2030     if (p_mark) {
2031         p_mark->top_used = 0;
2032         p_mark->bot_used = 0;
2033         p_mark->out_flag = 0;
2034         p_mark->slot_idx = -1;
2035         p_mark->pic = NULL;
2036         p_mark->mframe = NULL;
2037     }
2038 
2039     return MPP_OK;
2040 }
2041 /*!
2042 ***********************************************************************
2043 * \brief
2044 *    init picture
2045 ***********************************************************************
2046 */
2047 //extern "C"
init_picture(H264_SLICE_t * currSlice)2048 MPP_RET init_picture(H264_SLICE_t *currSlice)
2049 {
2050     MPP_RET ret = MPP_ERR_UNKNOW;
2051     H264_DecCtx_t *p_Dec   = currSlice->p_Vid->p_Dec;
2052     H264dVideoCtx_t *p_Vid = currSlice->p_Vid;
2053     H264dErrCtx_t *p_err   = &p_Dec->errctx;
2054 
2055     //!< discard stream before I_SLICE
2056     if (!p_err->i_slice_no && p_Vid->recovery.valid_flag && p_Vid->recovery.first_frm_valid &&
2057         p_Vid->recovery.first_frm_id == currSlice->frame_num) {
2058         p_err->i_slice_no += (!currSlice->layer_id) ? 1 : 0;
2059     } else {
2060         p_err->i_slice_no += ((!currSlice->layer_id) && (H264_I_SLICE == currSlice->slice_type)) ? 1 : 0;
2061     }
2062 
2063     if (!p_err->i_slice_no) {
2064         H264D_WARNNING("[Discard] Discard slice before I Slice. \n");
2065         ret = MPP_NOK;
2066         goto __FAILED;
2067     }
2068     FUN_CHECK(ret = alloc_decpic(currSlice));
2069     if (((p_err->i_slice_no < 2) && (!currSlice->layer_id) && (H264_I_SLICE == currSlice->slice_type)) ||
2070         currSlice->idr_flag) {
2071         p_err->first_iframe_poc = p_Vid->dec_pic->poc; //!< recoder first i frame poc
2072         p_err->first_iframe_is_output = 0;
2073     }
2074     //!< idr_memory_management MVC_layer, idr_flag==1
2075     if (currSlice->layer_id && !currSlice->svc_extension_flag && !currSlice->mvcExt.non_idr_flag) {
2076         ASSERT(currSlice->layer_id == 1);
2077         FUN_CHECK(ret = idr_memory_management(p_Vid->p_Dpb_layer[currSlice->layer_id], p_Vid->dec_pic));
2078     }
2079 
2080     // if cur pic i frame poc & frame_num <= last pic, flush dpb.
2081     if (p_Vid->last_pic != NULL && p_Vid->dec_pic->poc != 0) {
2082         if (p_Vid->last_pic->frame_num >= p_Vid->dec_pic->frame_num
2083             && p_Vid->last_pic->poc >= p_Vid->dec_pic->poc
2084             && p_Vid->dec_pic->slice_type == H264_I_SLICE
2085             && p_Vid->dec_pic->structure == 3) {
2086             if (currSlice->layer_id == 0) {
2087                 FUN_CHECK(ret = flush_dpb(p_Vid->p_Dpb_layer[0], 1));
2088             } else {
2089                 FUN_CHECK(ret = flush_dpb(p_Vid->p_Dpb_layer[1], 2));
2090             }
2091         }
2092     }
2093     update_ref_list(p_Vid->p_Dpb_layer[currSlice->layer_id]);
2094     update_ltref_list(p_Vid->p_Dpb_layer[currSlice->layer_id]);
2095     update_pic_num(currSlice);
2096     //!< reorder
2097     if (!currSlice->idr_flag || currSlice->layer_id) {
2098         FUN_CHECK(ret = init_lists_p_slice_mvc(currSlice));
2099         FUN_CHECK(ret = init_lists_b_slice_mvc(currSlice));
2100     }
2101     prepare_init_dpb_info(currSlice);
2102     prepare_init_ref_info(currSlice);
2103 
2104     FUN_CHECK(ret = check_refer_dpb_buf_slots(currSlice));
2105     check_refer_picture_lists(currSlice);
2106     {
2107         H264dDxvaCtx_t *dxva_ctx = p_Dec->dxva_ctx;
2108 
2109         fill_picparams(currSlice->p_Vid, &dxva_ctx->pp);
2110         if (dxva_ctx->pp.scaleing_list_enable_flag) {
2111             prepare_init_scanlist(currSlice);
2112             fill_scanlist(currSlice->p_Vid, &dxva_ctx->qm);
2113         }
2114     }
2115 
2116     return ret = MPP_OK;
2117 __FAILED:
2118     return ret;
2119 }
2120 
2121 /*!
2122 ***********************************************************************
2123 * \brief
2124 *    update dpb
2125 ***********************************************************************
2126 */
2127 //extern "C"
update_dpb(H264_DecCtx_t * p_Dec)2128 MPP_RET update_dpb(H264_DecCtx_t *p_Dec)
2129 {
2130     MPP_RET ret = MPP_ERR_UNKNOW;
2131 
2132     p_Dec->p_Vid->exit_picture_flag = 1;
2133     p_Dec->p_Vid->have_outpicture_flag = 1;
2134     ret = exit_picture(p_Dec->p_Vid, &p_Dec->p_Vid->dec_pic);
2135 
2136     p_Dec->p_Vid->iNumOfSlicesDecoded = 0;
2137     p_Dec->p_Vid->exit_picture_flag = 0;
2138 
2139     return ret;
2140 }
2141 
2142