xref: /aosp_15_r20/external/libavc/decoder/svc/isvcd_utils.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1 /******************************************************************************
2  *
3  * Copyright (C) 2022 The Android Open Source Project
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  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 /**
21  *******************************************************************************
22  * @file
23  *  isvcd_utils.c
24  *
25  * @brief
26  *  Contains routines that handle of start and end of pic processing
27  *
28  * @author
29  *  Kishore
30  *
31  * @remarks
32  *  None
33  *
34  *******************************************************************************
35  */
36 
37 #include <string.h>
38 #include "ih264_typedefs.h"
39 #include "ithread.h"
40 #include "ih264d_deblocking.h"
41 #include "ih264d_parse_slice.h"
42 #include "ih264d_parse_cavlc.h"
43 #include "ih264d_dpb_manager.h"
44 #include "ih264d_defs.h"
45 #include "isvcd_structs.h"
46 #include "ih264d_mem_request.h"
47 #include "ih264_typedefs.h"
48 #include "ih264_macros.h"
49 #include "ih264_platform_macros.h"
50 #include "ih264d_tables.h"
51 #include "ih264d_debug.h"
52 #include "ih264d_mb_utils.h"
53 #include "ih264d_error_handler.h"
54 #include "ih264d_dpb_manager.h"
55 #include "ih264d_utils.h"
56 #include "ih264d_defs.h"
57 #include "ih264d_tables.h"
58 #include "ih264d_inter_pred.h"
59 #include "ih264d_dpb_manager.h"
60 #include "iv.h"
61 #include "ivd.h"
62 #include "ih264d_format_conv.h"
63 #include "ih264_error.h"
64 #include "ih264_disp_mgr.h"
65 #include "ih264_buf_mgr.h"
66 #include "ih264d_utils.h"
67 
68 WORD32 ih264d_init_dec_mb_grp(dec_struct_t *ps_dec);
69 /*!
70 **************************************************************************
71 * \if Function name : isvcd_free_dynamic_bufs \endif
72 *
73 * \brief
74 *    This function frees dynamic memory allocated by Decoder.
75 *
76 * \param ps_dec: Pointer to dec_struct_t.
77 *
78 * \return
79 *    Returns i4_status as returned by MemManager.
80 *
81 **************************************************************************
82 */
isvcd_free_dynamic_bufs(svc_dec_lyr_struct_t * ps_svc_lyr_dec)83 WORD16 isvcd_free_dynamic_bufs(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
84 {
85     dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
86     /* Free any avc dynamic buffers that are allocated */
87     ih264d_free_dynamic_bufs(ps_dec);
88     PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->pu1_crop_wnd_flag);
89     PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->ps_inter_lyr_mb_prms_base);
90     PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->ps_il_pred_mv_bank_buf_base);
91     PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->pi2_il_residual_resample_luma_base);
92     PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->pi2_il_residual_resample_chroma_base);
93     PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->ps_svc_frm_mb_info);
94     PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->pu2_frm_res_luma_csbp);
95     PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->pu1_svc_base_mode_flag);
96     return 0;
97 }
98 
99 /*!
100 **************************************************************************
101 * \if Function name : isvcd_allocate_dynamic_bufs \endif
102 *
103 * \brief
104 *    This function allocates memory required by Decoder.
105 *
106 * \param ps_dec: Pointer to dec_struct_t.
107 *
108 * \return
109 *    Returns i4_status as returned by MemManager.
110 *
111 **************************************************************************
112 */
113 
isvcd_allocate_dynamic_bufs(svc_dec_lyr_struct_t * ps_svc_lyr_dec)114 WORD16 isvcd_allocate_dynamic_bufs(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
115 {
116     dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
117     WORD16 i16_status = 0;
118     UWORD8 uc_frmOrFld = (1 - ps_dec->ps_cur_sps->u1_frame_mbs_only_flag);
119     dec_seq_params_t *ps_sps = ps_dec->ps_cur_sps;
120     UWORD32 u4_total_mbs = ps_sps->u2_total_num_of_mbs << uc_frmOrFld;
121     WORD32 size;
122     void *pv_buf;
123     void *pv_mem_ctxt = ps_dec->pv_mem_ctxt;
124     size = u4_total_mbs;
125 
126     i16_status = ih264d_allocate_dynamic_bufs(ps_dec);
127 
128     if(i16_status != OK)
129     {
130         /* Free any dynamic buffers that are allocated */
131         ih264d_free_dynamic_bufs(ps_dec);
132         ps_dec->i4_error_code = IVD_MEM_ALLOC_FAILED;
133         return IVD_MEM_ALLOC_FAILED;
134     }
135     if(u4_total_mbs == 0)
136     {
137         return IVD_MEM_ALLOC_FAILED;
138     }
139 
140     /* Allocate frame level mb info */
141     size = sizeof(dec_svc_mb_info_t) * u4_total_mbs;
142     pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
143     RETURN_IF((NULL == pv_buf), IV_FAIL);
144     ps_svc_lyr_dec->ps_svc_frm_mb_info = pv_buf;
145     memset(ps_svc_lyr_dec->ps_svc_frm_mb_info, 0, size);
146 
147     /* Allocate frame level residual luma csbp info */
148     size = sizeof(UWORD16) * u4_total_mbs;
149     pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
150     RETURN_IF((NULL == pv_buf), IV_FAIL);
151     ps_svc_lyr_dec->pu2_frm_res_luma_csbp = pv_buf;
152     memset(ps_svc_lyr_dec->pu2_frm_res_luma_csbp, 0, size);
153     ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride = ps_dec->u2_frm_wd_in_mbs;
154 
155     /* Allocate frame level residual luma csbp info */
156     size = sizeof(UWORD8) * u4_total_mbs;
157     pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
158     RETURN_IF((NULL == pv_buf), IV_FAIL);
159     ps_svc_lyr_dec->pu1_svc_base_mode_flag = pv_buf;
160     memset(ps_svc_lyr_dec->pu1_svc_base_mode_flag, 0, size);
161     ps_svc_lyr_dec->i4_frm_svc_base_mode_cabac_stride = ps_dec->u2_frm_wd_in_mbs;
162     ps_svc_lyr_dec->i4_frm_svc_base_mode_cabac_size = u4_total_mbs;
163 
164     /* Allocate frame level crop windows flags */
165     size = sizeof(UWORD8) * u4_total_mbs;
166     pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
167     RETURN_IF((NULL == pv_buf), IV_FAIL);
168     ps_svc_lyr_dec->pu1_crop_wnd_flag = pv_buf;
169     memset(ps_svc_lyr_dec->pu1_crop_wnd_flag, 0, size);
170 
171     /**********************************/
172     /*Creation of Inter layer buffers */
173     /**********************************/
174 
175     /* MB type buffer : one element per MB */
176     size = (ps_dec->u2_frm_wd_in_mbs + 2) * (ps_dec->u2_frm_ht_in_mbs + 2) *
177            sizeof(inter_lyr_mb_prms_t);
178     pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
179     RETURN_IF((NULL == pv_buf), IV_FAIL);
180     memset(pv_buf, -1, size);
181     ps_svc_lyr_dec->ps_inter_lyr_mb_prms_base = pv_buf;
182     ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride = ps_dec->u2_frm_wd_in_mbs + 2;
183     ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start =
184         ps_svc_lyr_dec->ps_inter_lyr_mb_prms_base + 1 + ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride;
185 
186     ps_svc_lyr_dec->u4_inter_lyr_mb_prms_size = (ps_dec->u2_frm_wd_in_mbs + 2) *
187                                                 (ps_dec->u2_frm_ht_in_mbs + 2) *
188                                                 sizeof(inter_lyr_mb_prms_t);
189 
190     /* Luma Residual data at each layer : dafault 0*/
191     size = ((ps_dec->u2_pic_wd + 4) * (ps_dec->u2_pic_ht + 4)) * sizeof(WORD16);
192     pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
193     RETURN_IF((NULL == pv_buf), IV_FAIL);
194     memset(pv_buf, 0, size);
195     ps_svc_lyr_dec->pi2_il_residual_resample_luma_base = pv_buf;
196     ps_svc_lyr_dec->u2_residual_resample_luma_stride = (ps_dec->u2_pic_wd + 4);
197     ps_svc_lyr_dec->pi2_il_residual_resample_mb_luma_frm_start =
198         ps_svc_lyr_dec->pi2_il_residual_resample_luma_base + 2 +
199         (2 * ps_svc_lyr_dec->u2_residual_resample_luma_stride);
200     ps_svc_lyr_dec->u4_residual_resample_luma_size =
201         ((ps_dec->u2_pic_wd + 4) * (ps_dec->u2_pic_ht + 4)) * sizeof(WORD16);
202 
203     /* Chroma Residual data at each layer : dafault 0*/
204     size = (((4 + ps_dec->u2_pic_wd) * ((4 + ps_dec->u2_pic_ht) >> 1)) * sizeof(WORD16));
205     pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
206     RETURN_IF((NULL == pv_buf), IV_FAIL);
207     memset(pv_buf, 0, size);
208     ps_svc_lyr_dec->pi2_il_residual_resample_chroma_base = pv_buf;
209     ps_svc_lyr_dec->u2_residual_resample_chroma_stride = (ps_dec->u2_pic_wd + 4);
210     ps_svc_lyr_dec->pi2_il_residual_resample_mb_chroma_frm_start =
211         ps_svc_lyr_dec->pi2_il_residual_resample_chroma_base + 2 +
212         ps_svc_lyr_dec->u2_residual_resample_chroma_stride;
213     ps_svc_lyr_dec->u4_residual_resample_chroma_size =
214         (((4 + ps_dec->u2_pic_wd) * ((4 + ps_dec->u2_pic_ht) >> 1)) * sizeof(WORD16));
215 
216     /* mv bank buffer : 16 elements per MB: each at 4x4 block level */
217     size = ((ps_dec->u2_pic_wd) * (ps_dec->u2_pic_ht >> 4)) * sizeof(mv_pred_t);
218     pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
219     RETURN_IF((NULL == pv_buf), IV_FAIL);
220     memset(pv_buf, 0, size);
221     ps_svc_lyr_dec->ps_il_pred_mv_bank_buf_base = pv_buf;
222 
223     /*syntax for SVC related bin ctxt tables*/
224     {
225         bin_ctxt_model_t *const p_cabac_ctxt_table_t = ps_dec->p_cabac_ctxt_table_t;
226 
227         ps_svc_lyr_dec->ps_base_mode_flag = p_cabac_ctxt_table_t + CABAC_BASE_MODE_FLAG;
228         ps_svc_lyr_dec->ps_motion_prediction_flag_l0 = p_cabac_ctxt_table_t + CABAC_MOT_PRED_FLAG0;
229         ps_svc_lyr_dec->ps_motion_prediction_flag_l1 = p_cabac_ctxt_table_t + CABAC_MOT_PRED_FLAG1;
230         ps_svc_lyr_dec->ps_residual_prediction_flag = p_cabac_ctxt_table_t + CABAC_RES_PRED_FLAG;
231     }
232     return (i16_status);
233 }
234 
235 /*!
236 **************************************************************************
237 * \if Function name : isvcd_decode_pic_order_cnt \endif
238 *
239 * \brief
240 *    Calculates picture order count of picture.
241 *
242 * \return
243 *    Returns the pic order count of the picture to which current
244 *    Slice belongs.
245 *
246 **************************************************************************
247 */
isvcd_decode_pic_order_cnt(UWORD8 u1_is_idr_slice,UWORD32 u2_frame_num,pocstruct_t * ps_prev_poc,pocstruct_t * ps_cur_poc,dec_slice_params_t * ps_cur_slice,dec_pic_params_t * ps_pps,UWORD8 u1_nal_ref_idc,UWORD8 u1_bottom_field_flag,UWORD8 u1_field_pic_flag,WORD32 * pi4_poc,dec_struct_t * ps_dec)248 WORD32 isvcd_decode_pic_order_cnt(
249     UWORD8 u1_is_idr_slice, UWORD32 u2_frame_num, pocstruct_t *ps_prev_poc, pocstruct_t *ps_cur_poc,
250     dec_slice_params_t *ps_cur_slice, /*!< Pointer to current slice Params*/
251     dec_pic_params_t *ps_pps, UWORD8 u1_nal_ref_idc, UWORD8 u1_bottom_field_flag,
252     UWORD8 u1_field_pic_flag, WORD32 *pi4_poc, dec_struct_t *ps_dec)
253 {
254     WORD64 i8_pic_msb;
255     WORD32 i4_top_field_order_cnt = 0, i4_bottom_field_order_cnt = 0;
256     dec_seq_params_t *ps_seq = ps_dec->ps_cur_sps;
257     WORD32 i4_prev_frame_num_ofst;
258 
259     switch(ps_seq->u1_pic_order_cnt_type)
260     {
261         case 0:
262             /* POC TYPE 0 */
263             if(u1_is_idr_slice)
264             {
265                 ps_prev_poc->i4_pic_order_cnt_msb = 0;
266                 ps_prev_poc->i4_pic_order_cnt_lsb = 0;
267             }
268             if(ps_prev_poc->u1_mmco_equalto5)
269             {
270                 if(ps_prev_poc->u1_bot_field != 1)
271                 {
272                     ps_prev_poc->i4_pic_order_cnt_msb = 0;
273                     ps_prev_poc->i4_pic_order_cnt_lsb = ps_prev_poc->i4_top_field_order_count;
274                 }
275                 else
276                 {
277                     ps_prev_poc->i4_pic_order_cnt_msb = 0;
278                     ps_prev_poc->i4_pic_order_cnt_lsb = 0;
279                 }
280             }
281 
282             if((ps_cur_poc->i4_pic_order_cnt_lsb < ps_prev_poc->i4_pic_order_cnt_lsb) &&
283                ((ps_prev_poc->i4_pic_order_cnt_lsb - ps_cur_poc->i4_pic_order_cnt_lsb) >=
284                 (ps_seq->i4_max_pic_order_cntLsb >> 1)))
285             {
286                 i8_pic_msb =
287                     (WORD64) ps_prev_poc->i4_pic_order_cnt_msb + ps_seq->i4_max_pic_order_cntLsb;
288             }
289             else if((ps_cur_poc->i4_pic_order_cnt_lsb > ps_prev_poc->i4_pic_order_cnt_lsb) &&
290                     ((ps_cur_poc->i4_pic_order_cnt_lsb - ps_prev_poc->i4_pic_order_cnt_lsb) >=
291                      (ps_seq->i4_max_pic_order_cntLsb >> 1)))
292             {
293                 i8_pic_msb =
294                     (WORD64) ps_prev_poc->i4_pic_order_cnt_msb - ps_seq->i4_max_pic_order_cntLsb;
295             }
296             else
297             {
298                 i8_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb;
299             }
300 
301             if(!u1_field_pic_flag || !u1_bottom_field_flag)
302             {
303                 WORD64 i8_result = i8_pic_msb + ps_cur_poc->i4_pic_order_cnt_lsb;
304                 if(IS_OUT_OF_RANGE_S32(i8_result))
305                 {
306                     return ERROR_INV_POC;
307                 }
308                 i4_top_field_order_cnt = (WORD32) i8_result;
309             }
310 
311             if(!u1_field_pic_flag)
312             {
313                 WORD64 i8_result =
314                     (WORD64) i4_top_field_order_cnt + ps_cur_poc->i4_delta_pic_order_cnt_bottom;
315                 if(IS_OUT_OF_RANGE_S32(i8_result))
316                 {
317                     return ERROR_INV_POC;
318                 }
319                 i4_bottom_field_order_cnt = (WORD32) i8_result;
320             }
321             else if(u1_bottom_field_flag)
322             {
323                 WORD64 i8_result = i8_pic_msb + ps_cur_poc->i4_pic_order_cnt_lsb;
324                 if(IS_OUT_OF_RANGE_S32(i8_result))
325                 {
326                     return ERROR_INV_POC;
327                 }
328                 i4_bottom_field_order_cnt = (WORD32) i8_result;
329             }
330 
331             if(IS_OUT_OF_RANGE_S32(i8_pic_msb))
332             {
333                 return ERROR_INV_POC;
334             }
335             ps_cur_poc->i4_pic_order_cnt_msb = (WORD32) i8_pic_msb;
336             break;
337 
338         case 1:
339         {
340             /* POC TYPE 1 */
341             UWORD8 i;
342             WORD32 prev_frame_num;
343             WORD32 frame_num_ofst;
344             WORD32 abs_frm_num;
345             WORD32 poc_cycle_cnt, frame_num_in_poc_cycle;
346             WORD64 i8_expected_delta_poc_cycle;
347             WORD32 expected_poc;
348             WORD64 i8_result;
349 
350             prev_frame_num = (WORD32) ps_cur_slice->u2_frame_num;
351             if(!u1_is_idr_slice)
352             {
353                 if(ps_cur_slice->u1_mmco_equalto5)
354                 {
355                     prev_frame_num = 0;
356                     i4_prev_frame_num_ofst = 0;
357                 }
358                 else
359                 {
360                     i4_prev_frame_num_ofst = ps_prev_poc->i4_prev_frame_num_ofst;
361                 }
362             }
363             else
364                 i4_prev_frame_num_ofst = 0;
365 
366             /* 1. Derivation for FrameNumOffset */
367             if(u1_is_idr_slice)
368             {
369                 frame_num_ofst = 0;
370                 ps_cur_poc->i4_delta_pic_order_cnt[0] = 0;
371                 ps_cur_poc->i4_delta_pic_order_cnt[1] = 0;
372             }
373             else if(prev_frame_num > ((WORD32) u2_frame_num))
374             {
375                 WORD64 i8_result =
376                     i4_prev_frame_num_ofst + (WORD64) ps_seq->u2_u4_max_pic_num_minus1 + 1;
377                 if(IS_OUT_OF_RANGE_S32(i8_result))
378                 {
379                     return ERROR_INV_FRAME_NUM;
380                 }
381                 frame_num_ofst = (WORD32) i8_result;
382             }
383             else
384                 frame_num_ofst = i4_prev_frame_num_ofst;
385 
386             /* 2. Derivation for absFrameNum */
387             if(0 != ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle)
388             {
389                 WORD64 i8_result = frame_num_ofst + (WORD64) u2_frame_num;
390                 if(IS_OUT_OF_RANGE_S32(i8_result))
391                 {
392                     return ERROR_INV_FRAME_NUM;
393                 }
394                 abs_frm_num = (WORD32) i8_result;
395             }
396             else
397                 abs_frm_num = 0;
398             if((u1_nal_ref_idc == 0) && (abs_frm_num > 0)) abs_frm_num = abs_frm_num - 1;
399 
400             /* 4. expectedDeltaPerPicOrderCntCycle is derived as */
401             i8_expected_delta_poc_cycle = 0;
402             for(i = 0; i < ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle; i++)
403             {
404                 i8_expected_delta_poc_cycle += ps_seq->i4_ofst_for_ref_frame[i];
405             }
406 
407             /* 3. When absFrameNum > 0, picOrderCntCycleCnt and
408             frame_num_in_poc_cycle are derived as : */
409             /* 5. expectedPicOrderCnt is derived as : */
410             if(abs_frm_num > 0)
411             {
412                 poc_cycle_cnt =
413                     DIV((abs_frm_num - 1), ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle);
414                 frame_num_in_poc_cycle =
415                     MOD((abs_frm_num - 1), ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle);
416 
417                 i8_result = poc_cycle_cnt * i8_expected_delta_poc_cycle;
418 
419                 for(i = 0; i <= frame_num_in_poc_cycle; i++)
420                 {
421                     i8_result = i8_result + ps_seq->i4_ofst_for_ref_frame[i];
422                 }
423 
424                 if(IS_OUT_OF_RANGE_S32(i8_result)) return ERROR_INV_POC;
425 
426                 expected_poc = (WORD32) i8_result;
427             }
428             else
429                 expected_poc = 0;
430 
431             if(u1_nal_ref_idc == 0)
432             {
433                 i8_result = (WORD64) expected_poc + ps_seq->i4_ofst_for_non_ref_pic;
434 
435                 if(IS_OUT_OF_RANGE_S32(i8_result)) return ERROR_INV_POC;
436 
437                 expected_poc = (WORD32) i8_result;
438             }
439 
440             /* 6. TopFieldOrderCnt or BottomFieldOrderCnt are derived as */
441             if(!u1_field_pic_flag)
442             {
443                 i8_result = (WORD64) expected_poc + ps_cur_poc->i4_delta_pic_order_cnt[0];
444 
445                 if(IS_OUT_OF_RANGE_S32(i8_result)) return ERROR_INV_POC;
446                 i4_top_field_order_cnt = (WORD32) i8_result;
447 
448                 i8_result = (WORD64) i4_top_field_order_cnt +
449                             ps_seq->i4_ofst_for_top_to_bottom_field +
450                             ps_cur_poc->i4_delta_pic_order_cnt[1];
451 
452                 if(IS_OUT_OF_RANGE_S32(i8_result)) return ERROR_INV_POC;
453                 i4_bottom_field_order_cnt = (WORD32) i8_result;
454             }
455             else if(!u1_bottom_field_flag)
456             {
457                 i8_result = (WORD64) expected_poc + ps_cur_poc->i4_delta_pic_order_cnt[0];
458 
459                 if(IS_OUT_OF_RANGE_S32(i8_result)) return ERROR_INV_POC;
460                 i4_top_field_order_cnt = (WORD32) i8_result;
461             }
462             else
463             {
464                 i8_result = (WORD64) expected_poc + ps_seq->i4_ofst_for_top_to_bottom_field +
465                             ps_cur_poc->i4_delta_pic_order_cnt[0];
466 
467                 if(IS_OUT_OF_RANGE_S32(i8_result)) return ERROR_INV_POC;
468                 i4_bottom_field_order_cnt = (WORD32) i8_result;
469             }
470             /* Copy the current POC info into Previous POC structure */
471             ps_cur_poc->i4_prev_frame_num_ofst = frame_num_ofst;
472         }
473 
474         break;
475         case 2:
476         {
477             /* POC TYPE 2 */
478             WORD32 prev_frame_num;
479             WORD32 frame_num_ofst;
480             WORD32 tmp_poc;
481 
482             prev_frame_num = (WORD32) ps_cur_slice->u2_frame_num;
483             if(!u1_is_idr_slice)
484             {
485                 if(ps_cur_slice->u1_mmco_equalto5)
486                 {
487                     prev_frame_num = 0;
488                     i4_prev_frame_num_ofst = 0;
489                 }
490                 else
491                     i4_prev_frame_num_ofst = ps_prev_poc->i4_prev_frame_num_ofst;
492             }
493             else
494                 i4_prev_frame_num_ofst = 0;
495 
496             /* 1. Derivation for FrameNumOffset */
497             if(u1_is_idr_slice)
498             {
499                 frame_num_ofst = 0;
500                 ps_cur_poc->i4_delta_pic_order_cnt[0] = 0;
501                 ps_cur_poc->i4_delta_pic_order_cnt[1] = 0;
502             }
503             else if(prev_frame_num > ((WORD32) u2_frame_num))
504             {
505                 WORD64 i8_result =
506                     i4_prev_frame_num_ofst + (WORD64) ps_seq->u2_u4_max_pic_num_minus1 + 1;
507                 if(IS_OUT_OF_RANGE_S32(i8_result))
508                 {
509                     return ERROR_INV_FRAME_NUM;
510                 }
511                 frame_num_ofst = (WORD32) i8_result;
512             }
513             else
514                 frame_num_ofst = i4_prev_frame_num_ofst;
515 
516             /* 2. Derivation for tempPicOrderCnt */
517             if(u1_is_idr_slice)
518                 tmp_poc = 0;
519             else if(u1_nal_ref_idc == 0)
520             {
521                 WORD64 i8_result = ((frame_num_ofst + (WORD64) u2_frame_num) << 1) - 1;
522                 if(IS_OUT_OF_RANGE_S32(i8_result))
523                 {
524                     return ERROR_INV_POC;
525                 }
526                 tmp_poc = (WORD32) i8_result;
527             }
528             else
529             {
530                 WORD64 i8_result = (frame_num_ofst + (WORD64) u2_frame_num) << 1;
531                 if(IS_OUT_OF_RANGE_S32(i8_result))
532                 {
533                     return ERROR_INV_POC;
534                 }
535                 tmp_poc = (WORD32) i8_result;
536             }
537 
538             /* 6. TopFieldOrderCnt or BottomFieldOrderCnt are derived as */
539             if(!u1_field_pic_flag)
540             {
541                 i4_top_field_order_cnt = tmp_poc;
542                 i4_bottom_field_order_cnt = tmp_poc;
543             }
544             else if(!u1_bottom_field_flag)
545                 i4_top_field_order_cnt = tmp_poc;
546             else
547                 i4_bottom_field_order_cnt = tmp_poc;
548 
549             /* Copy the current POC info into Previous POC structure */
550             ps_prev_poc->i4_prev_frame_num_ofst = frame_num_ofst;
551             ps_cur_poc->i4_prev_frame_num_ofst = frame_num_ofst;
552         }
553         break;
554         default:
555             return ERROR_INV_POC_TYPE_T;
556             break;
557     }
558 
559     if(!u1_field_pic_flag)  // or a complementary field pair
560     {
561         *pi4_poc = MIN(i4_top_field_order_cnt, i4_bottom_field_order_cnt);
562         ps_pps->i4_top_field_order_cnt = i4_top_field_order_cnt;
563         ps_pps->i4_bottom_field_order_cnt = i4_bottom_field_order_cnt;
564     }
565     else if(!u1_bottom_field_flag)
566     {
567         *pi4_poc = i4_top_field_order_cnt;
568         ps_pps->i4_top_field_order_cnt = i4_top_field_order_cnt;
569     }
570     else
571     {
572         *pi4_poc = i4_bottom_field_order_cnt;
573         ps_pps->i4_bottom_field_order_cnt = i4_bottom_field_order_cnt;
574     }
575 
576     ps_pps->i4_avg_poc = *pi4_poc;
577 
578     return OK;
579 }
580 
581 /*****************************************************************************/
582 /*                                                                           */
583 /*  Function Name : isvcd_decode_gaps_in_frame_num */
584 /*                                                                           */
585 /*  Description   : This function decodes gaps in frame number               */
586 /*                                                                           */
587 /*  Inputs        : ps_dec          Decoder parameters                       */
588 /*                  u2_frame_num   current frame number                     */
589 /*                                                                           */
590 /*  Globals       : None                                                     */
591 /*  Processing    : This functionality needs to be implemented               */
592 /*  Outputs       : None                                                     */
593 /*  Returns       : None                                                     */
594 /*                                                                           */
595 /*  Issues        : Not implemented                                          */
596 /*                                                                           */
597 /*  Revision History:                                                        */
598 /*                                                                           */
599 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
600 /*         06 05 2002   NS              Draft                                */
601 /*                                                                           */
602 /*****************************************************************************/
isvcd_decode_gaps_in_frame_num(dec_struct_t * ps_dec,UWORD16 u2_frame_num)603 WORD32 isvcd_decode_gaps_in_frame_num(dec_struct_t *ps_dec, UWORD16 u2_frame_num)
604 {
605     UWORD32 u4_next_frm_num, u4_start_frm_num;
606     UWORD32 u4_max_frm_num;
607     pocstruct_t s_tmp_poc;
608     WORD32 i4_poc;
609     dec_slice_params_t *ps_cur_slice;
610 
611     dec_pic_params_t *ps_pic_params;
612     WORD8 i1_gap_idx;
613     WORD32 *i4_gaps_start_frm_num;
614     dpb_manager_t *ps_dpb_mgr;
615     WORD8 *pi1_gaps_per_seq;
616     WORD32 ret;
617 
618     ps_cur_slice = ps_dec->ps_cur_slice;
619     if(ps_cur_slice->u1_field_pic_flag)
620     {
621         if(ps_dec->u2_prev_ref_frame_num == u2_frame_num) return 0;
622     }
623 
624     u4_next_frm_num = ps_dec->u2_prev_ref_frame_num + 1;
625     u4_max_frm_num = ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1;
626 
627     if(u4_next_frm_num >= u4_max_frm_num)
628     {
629         u4_next_frm_num -= u4_max_frm_num;
630     }
631 
632     if(u4_next_frm_num == u2_frame_num)
633     {
634         return (0);
635     }
636 
637     if((ps_dec->u1_nal_unit_type == IDR_SLICE_NAL) && (u4_next_frm_num >= u2_frame_num))
638     {
639         return (0);
640     }
641     u4_start_frm_num = u4_next_frm_num;
642 
643     s_tmp_poc.i4_pic_order_cnt_lsb = 0;
644     s_tmp_poc.i4_delta_pic_order_cnt_bottom = 0;
645     s_tmp_poc.i4_pic_order_cnt_lsb = 0;
646     s_tmp_poc.i4_delta_pic_order_cnt_bottom = 0;
647     s_tmp_poc.i4_delta_pic_order_cnt[0] = 0;
648     s_tmp_poc.i4_delta_pic_order_cnt[1] = 0;
649 
650     ps_cur_slice = ps_dec->ps_cur_slice;
651     ps_pic_params = ps_dec->ps_cur_pps;
652 
653     ps_dpb_mgr = ps_dec->ps_dpb_mgr;
654 
655     /* Find a empty slot to store gap seqn info */
656     i4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num;
657     for(i1_gap_idx = 0; i1_gap_idx < MAX_FRAMES; i1_gap_idx++)
658     {
659         if(INVALID_FRAME_NUM == i4_gaps_start_frm_num[i1_gap_idx]) break;
660     }
661     if(MAX_FRAMES == i1_gap_idx)
662     {
663         UWORD32 i4_error_code;
664         i4_error_code = ERROR_DBP_MANAGER_T;
665         return i4_error_code;
666     }
667 
668     i4_poc = 0;
669     i4_gaps_start_frm_num[i1_gap_idx] = u4_start_frm_num;
670     ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = u2_frame_num - 1;
671     pi1_gaps_per_seq = ps_dpb_mgr->ai1_gaps_per_seq;
672     pi1_gaps_per_seq[i1_gap_idx] = 0;
673     while(u4_next_frm_num != u2_frame_num)
674     {
675         ih264d_delete_nonref_nondisplay_pics(ps_dpb_mgr);
676         if(ps_pic_params->ps_sps->u1_pic_order_cnt_type)
677         {
678             /* allocate a picture buffer and insert it as ST node */
679             ret =
680                 isvcd_decode_pic_order_cnt(0, u4_next_frm_num, &ps_dec->s_prev_pic_poc, &s_tmp_poc,
681                                            ps_cur_slice, ps_pic_params, 1, 0, 0, &i4_poc, ps_dec);
682             if(ret != OK) return ret;
683 
684             /* Display seq no calculations */
685             if(i4_poc >= ps_dec->i4_max_poc) ps_dec->i4_max_poc = i4_poc;
686             /* IDR Picture or POC wrap around */
687             if(i4_poc == 0)
688             {
689                 WORD64 i8_temp;
690                 i8_temp = (WORD64) ps_dec->i4_prev_max_display_seq + ps_dec->i4_max_poc +
691                           ps_dec->u1_max_dec_frame_buffering + 1;
692                 /*If i4_prev_max_display_seq overflows integer range, reset it */
693                 ps_dec->i4_prev_max_display_seq =
694                     IS_OUT_OF_RANGE_S32(i8_temp) ? 0 : (WORD32) i8_temp;
695                 ps_dec->i4_max_poc = 0;
696             }
697 
698             ps_cur_slice->u1_mmco_equalto5 = 0;
699             ps_cur_slice->u2_frame_num = u4_next_frm_num;
700         }
701 
702         if(ps_dpb_mgr->i1_poc_buf_id_entries >= ps_dec->u1_max_dec_frame_buffering)
703         {
704             ret = ih264d_assign_display_seq(ps_dec);
705             if(ret != OK) return ret;
706         }
707 
708         {
709             WORD64 i8_display_poc;
710             i8_display_poc = (WORD64) ps_dec->i4_prev_max_display_seq + i4_poc;
711             if(IS_OUT_OF_RANGE_S32(i8_display_poc))
712             {
713                 ps_dec->i4_prev_max_display_seq = 0;
714             }
715         }
716         ret = ih264d_insert_pic_in_display_list(ps_dec->ps_dpb_mgr, (WORD8) DO_NOT_DISP,
717                                                 (WORD32) (ps_dec->i4_prev_max_display_seq + i4_poc),
718                                                 u4_next_frm_num);
719         if(ret != OK) return ret;
720 
721         pi1_gaps_per_seq[i1_gap_idx]++;
722         ret = ih264d_do_mmco_for_gaps(ps_dpb_mgr, ps_dec->ps_cur_sps->u1_num_ref_frames);
723         if(ret != OK) return ret;
724 
725         ih264d_delete_nonref_nondisplay_pics(ps_dpb_mgr);
726 
727         u4_next_frm_num++;
728         if(u4_next_frm_num >= u4_max_frm_num)
729         {
730             u4_next_frm_num -= u4_max_frm_num;
731         }
732     }
733 
734     return OK;
735 }
736 
737 /*!
738 **************************************************************************
739 * \if Function name : isvcd_init_pic \endif
740 *
741 * \brief
742 *    Initializes the picture.
743 *
744 * \return
745 *    0 on Success and Error code otherwise
746 *
747 * \note
748 *    This function is called when first slice of the
749 *    NON -IDR picture is encountered.
750 **************************************************************************
751 */
isvcd_init_pic(svc_dec_lyr_struct_t * ps_svc_lyr_dec,UWORD16 u2_frame_num,WORD32 i4_poc,dec_pic_params_t * ps_pps)752 WORD32 isvcd_init_pic(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_frame_num, WORD32 i4_poc,
753                       dec_pic_params_t *ps_pps)
754 {
755     dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
756     dec_seq_params_t *ps_seq = ps_dec->ps_cur_sps;
757     prev_seq_params_t *ps_prev_seq_params = &ps_dec->s_prev_seq_params;
758     WORD32 ret;
759 
760     ps_dec->ps_cur_slice->u2_frame_num = u2_frame_num;
761     ps_dec->ps_cur_slice->i4_poc = i4_poc;
762     ps_dec->ps_cur_pps = ps_pps;
763     ps_dec->ps_cur_pps->pv_codec_handle = ps_dec;
764 
765     ps_dec->ps_dpb_mgr->i4_max_frm_num = ps_seq->u2_u4_max_pic_num_minus1 + 1;
766 
767     ps_dec->ps_dpb_mgr->u2_pic_ht = ps_dec->u2_pic_ht;
768     ps_dec->ps_dpb_mgr->u2_pic_wd = ps_dec->u2_pic_wd;
769     ps_dec->i4_pic_type = NA_SLICE;
770     ps_dec->i4_frametype = IV_NA_FRAME;
771     ps_dec->i4_content_type = IV_CONTENTTYPE_NA;
772 
773     /*--------------------------------------------------------------------*/
774     /* Get the value of MaxMbAddress and frmheight in Mbs                 */
775     /*--------------------------------------------------------------------*/
776     ps_seq->u2_max_mb_addr =
777         (ps_seq->u2_frm_wd_in_mbs *
778          (ps_dec->u2_pic_ht >> (4 + ps_dec->ps_cur_slice->u1_field_pic_flag))) -
779         1;
780     ps_dec->u2_frm_ht_in_mbs = (ps_dec->u2_pic_ht >> (4 + ps_dec->ps_cur_slice->u1_field_pic_flag));
781 
782     /***************************************************************************/
783     /* If change in Level or the required PicBuffers i4_size is more than the  */
784     /* current one FREE the current PicBuffers and allocate affresh            */
785     /***************************************************************************/
786     if(!ps_dec->u1_init_dec_flag)
787     {
788         ps_dec->u1_max_dec_frame_buffering = ih264d_get_dpb_size(ps_seq);
789 
790         ps_dec->i4_display_delay = ps_dec->u1_max_dec_frame_buffering;
791         if((1 == ps_seq->u1_vui_parameters_present_flag) &&
792            (1 == ps_seq->s_vui.u1_bitstream_restriction_flag))
793         {
794             if(ps_seq->u1_frame_mbs_only_flag == 1)
795                 ps_dec->i4_display_delay = ps_seq->s_vui.u4_num_reorder_frames + 1;
796             else
797                 ps_dec->i4_display_delay = ps_seq->s_vui.u4_num_reorder_frames * 2 + 2;
798         }
799 
800         if(IVD_DECODE_FRAME_OUT == ps_dec->e_frm_out_mode) ps_dec->i4_display_delay = 0;
801 
802         if(ps_dec->u4_share_disp_buf == 0)
803         {
804             if(ps_seq->u1_frame_mbs_only_flag == 1)
805                 ps_dec->u1_pic_bufs = ps_dec->i4_display_delay + ps_seq->u1_num_ref_frames + 1;
806             else
807                 ps_dec->u1_pic_bufs = ps_dec->i4_display_delay + ps_seq->u1_num_ref_frames * 2 + 2;
808         }
809         else
810         {
811             ps_dec->u1_pic_bufs = (WORD32) ps_dec->u4_num_disp_bufs;
812         }
813 
814         /* Ensure at least two buffers are allocated */
815         ps_dec->u1_pic_bufs = MAX(ps_dec->u1_pic_bufs, 2);
816 
817         if(ps_dec->u4_share_disp_buf == 0)
818             ps_dec->u1_pic_bufs = MIN(ps_dec->u1_pic_bufs, (H264_MAX_REF_PICS * 2));
819 
820         ps_dec->u1_max_dec_frame_buffering =
821             MIN(ps_dec->u1_max_dec_frame_buffering, ps_dec->u1_pic_bufs);
822 
823         /* Temporary hack to run Tractor Cav/Cab/MbAff Profiler streams  also for
824          * CAFI1_SVA_C.264 in conformance*/
825         if(ps_dec->u1_init_dec_flag)
826         {
827             ih264d_release_pics_in_dpb((void *) ps_dec, ps_dec->u1_pic_bufs);
828             ih264d_release_display_bufs(ps_dec);
829             ih264d_reset_ref_bufs(ps_dec->ps_dpb_mgr);
830         }
831 
832         /*********************************************************************/
833         /* Configuring decoder parameters based on level and then            */
834         /* fresh pointer initialisation in decoder scratch and state buffers */
835         /*********************************************************************/
836         if(!ps_dec->u1_init_dec_flag || ((ps_seq->u1_level_idc < H264_LEVEL_3_0) ^
837                                          (ps_prev_seq_params->u1_level_idc < H264_LEVEL_3_0)))
838         {
839             ret = ih264d_init_dec_mb_grp(ps_dec);
840             if(ret != OK) return ret;
841         }
842 
843         ret = isvcd_allocate_dynamic_bufs(ps_svc_lyr_dec);
844 
845         if(ret != OK)
846         {
847             /* Free any dynamic buffers that are allocated */
848             isvcd_free_dynamic_bufs(ps_svc_lyr_dec);
849             ps_dec->i4_error_code = IVD_MEM_ALLOC_FAILED;
850             return IVD_MEM_ALLOC_FAILED;
851         }
852 
853         ret = ih264d_create_pic_buffers(ps_dec->u1_pic_bufs, ps_dec);
854         if(ret != OK) return ret;
855 
856         ret = ih264d_create_mv_bank(ps_dec, ps_dec->u2_pic_wd, ps_dec->u2_pic_ht);
857         if(ret != OK) return ret;
858 
859         /* In shared mode, set all of them as used by display */
860         if(ps_dec->u4_share_disp_buf == 1)
861         {
862             WORD32 i;
863 
864             for(i = 0; i < ps_dec->u1_pic_bufs; i++)
865             {
866                 ih264_buf_mgr_set_status((buf_mgr_t *) ps_dec->pv_pic_buf_mgr, i, BUF_MGR_IO);
867             }
868         }
869 
870         ps_dec->u1_init_dec_flag = 1;
871         ps_prev_seq_params->u2_frm_wd_in_mbs = ps_seq->u2_frm_wd_in_mbs;
872         ps_prev_seq_params->u1_level_idc = ps_seq->u1_level_idc;
873         ps_prev_seq_params->u1_profile_idc = ps_seq->u1_profile_idc;
874         ps_prev_seq_params->u2_frm_ht_in_mbs = ps_seq->u2_frm_ht_in_mbs;
875         ps_prev_seq_params->u1_frame_mbs_only_flag = ps_seq->u1_frame_mbs_only_flag;
876         ps_prev_seq_params->u1_direct_8x8_inference_flag = ps_seq->u1_direct_8x8_inference_flag;
877 
878         ps_dec->i4_cur_display_seq = 0;
879         ps_dec->i4_prev_max_display_seq = 0;
880         ps_dec->i4_max_poc = 0;
881 
882         {
883             /* 0th entry of CtxtIncMbMap will be always be containing default values
884             for CABAC context representing MB not available */
885             ctxt_inc_mb_info_t *p_DefCtxt = ps_dec->p_ctxt_inc_mb_map - 1;
886             UWORD8 *pu1_temp;
887             WORD8 i;
888             p_DefCtxt->u1_mb_type = CAB_SKIP;
889 
890             p_DefCtxt->u1_cbp = 0x0f;
891             p_DefCtxt->u1_intra_chroma_pred_mode = 0;
892 
893             p_DefCtxt->u1_yuv_dc_csbp = 0x7;
894 
895             p_DefCtxt->u1_transform8x8_ctxt = 0;
896 
897             pu1_temp = (UWORD8 *) p_DefCtxt->i1_ref_idx;
898             for(i = 0; i < 4; i++, pu1_temp++) (*pu1_temp) = 0;
899             pu1_temp = (UWORD8 *) p_DefCtxt->u1_mv;
900             for(i = 0; i < 16; i++, pu1_temp++) (*pu1_temp) = 0;
901             ps_dec->ps_def_ctxt_mb_info = p_DefCtxt;
902         }
903     }
904     /* reset DBP commands read u4_flag */
905     ps_dec->ps_dpb_cmds->u1_dpb_commands_read = 0;
906 
907     return OK;
908 }
909