xref: /aosp_15_r20/external/libavc/decoder/mvc/imvcd_api.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1 /******************************************************************************
2  *
3  * Copyright (C) 2021 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 /*                                                                           */
23 /*  File Name         : imvcd_api.c                                          */
24 /*                                                                           */
25 /*  Description       : Has all MVC API functions                            */
26 /*                                                                           */
27 /*                                                                           */
28 /*  List of Functions :                                                      */
29 /*                                                                           */
30 /*****************************************************************************/
31 #include <string.h>
32 
33 #include "ih264_typedefs.h"
34 #include "iv.h"
35 #include "ivd.h"
36 #include "imvcd.h"
37 #include "ih264_debug.h"
38 #include "ih264_disp_mgr.h"
39 #include "ih264_error.h"
40 #include "ih264_buf_mgr.h"
41 #include "ih264_platform_macros.h"
42 #include "ih264d_inter_pred.h"
43 #include "ih264d_structs.h"
44 #include "ih264d_deblocking.h"
45 #include "ih264d_error_handler.h"
46 #include "ih264d_function_selector.h"
47 #include "ih264d_nal.h"
48 #include "ih264d_parse_cavlc.h"
49 #include "ih264d_parse_headers.h"
50 #include "ih264d_tables.h"
51 #include "ih264d_thread_compute_bs.h"
52 #include "ih264d_utils.h"
53 #include "ih264d_api_utils.h"
54 #include "ithread.h"
55 #include "imvcd_api_utils.h"
56 #include "imvcd_dpb_manager.h"
57 #include "imvcd_error_handler.h"
58 #include "imvcd_nalu_parser.h"
59 #include "imvcd_structs.h"
60 #include "imvcd_utils.h"
61 
imvcd_free_static_bufs(iv_obj_t * ps_dec_hdl)62 static void imvcd_free_static_bufs(iv_obj_t *ps_dec_hdl)
63 {
64     mvc_dec_ctxt_t *ps_mvcd_ctxt;
65     dec_struct_t *ps_view_ctxt;
66 
67     FT_ALIGNED_FREE *pf_aligned_free;
68 
69     void *pv_mem_ctxt;
70 
71     if(!ps_dec_hdl)
72     {
73         return;
74     }
75 
76     ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
77 
78     if(!ps_mvcd_ctxt)
79     {
80         return;
81     }
82 
83     ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
84     pf_aligned_free = ps_view_ctxt->pf_aligned_free;
85     pv_mem_ctxt = ps_view_ctxt->pv_mem_ctxt;
86 
87     imvcd_free_dynamic_bufs(ps_mvcd_ctxt);
88 
89     imvcd_bitsteam_buf_free(ps_view_ctxt);
90 
91     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_left_mvpred_addr);
92 
93     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu4_wts_ofsts_mat);
94 
95     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu4_mbaff_wt_mat);
96 
97     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_init_dpb_base);
98 
99     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_temp_mc_buffer);
100 
101     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pi2_pred1);
102 
103     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_ref_buff_base);
104 
105     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_left_mb_ctxt_info);
106 
107     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->p_cabac_ctxt_table_t);
108 
109     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ppv_map_ref_idx_to_poc_base);
110 
111     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_bits_buf_static);
112 
113     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pv_scratch_sps_pps);
114 
115     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_bitstrm);
116 
117     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_dpb_cmds);
118 
119     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_sei_parse);
120 
121     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_sei);
122 
123     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_dec_err_status);
124 
125     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_pred);
126 
127     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pv_bs_deblk_thread_handle);
128 
129     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pv_dec_thread_handle);
130 
131     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_pps);
132 
133     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_sps);
134 
135     ih264_buf_mgr_free(ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.pv_mem);
136 
137     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.pv_mem);
138 
139     ih264_buf_mgr_free(ps_mvcd_ctxt->s_mvc_au_buf_mgr.pv_mem);
140 
141     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_mvcd_ctxt->s_mvc_au_buf_mgr.pv_mem);
142 
143     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_mvcd_ctxt->ps_dpb_mgr);
144 
145     PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_mvcd_ctxt);
146 
147     if(ps_dec_hdl)
148     {
149         pf_aligned_free(pv_mem_ctxt, ps_dec_hdl);
150     }
151 }
152 
imvcd_view_ctxt_init(imvcd_create_ip_t * ps_ip,dec_struct_t * ps_view_ctxt)153 static IV_API_CALL_STATUS_T imvcd_view_ctxt_init(imvcd_create_ip_t *ps_ip,
154                                                  dec_struct_t *ps_view_ctxt)
155 {
156     pocstruct_t *ps_prev_poc, *ps_cur_poc;
157 
158     WORD32 i4_mem_size;
159     void *pv_buf;
160 
161     FT_ALIGNED_ALLOC *pf_aligned_alloc = ps_ip->s_ivd_ip.pf_aligned_alloc;
162 
163     void *pv_mem_ctxt = ps_ip->s_ivd_ip.pv_mem_ctxt;
164     const WORD32 i4_default_alignment = 128;
165 
166     ps_view_ctxt->u4_share_disp_buf = 0;
167     ps_view_ctxt->u1_chroma_format = ps_ip->s_ivd_ip.e_output_format;
168 
169     ps_view_ctxt->pf_aligned_alloc = pf_aligned_alloc;
170     ps_view_ctxt->pf_aligned_free = ps_ip->s_ivd_ip.pf_aligned_free;
171     ps_view_ctxt->pv_mem_ctxt = ps_ip->s_ivd_ip.pv_mem_ctxt;
172 
173     i4_mem_size = ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS);
174     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
175     RETURN_IF((NULL == pv_buf), IV_FAIL);
176     memset(pv_buf, 0, i4_mem_size);
177     ps_view_ctxt->ps_sps = pv_buf;
178 
179     i4_mem_size = (sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS;
180     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
181     RETURN_IF((NULL == pv_buf), IV_FAIL);
182     memset(pv_buf, 0, i4_mem_size);
183     ps_view_ctxt->ps_pps = pv_buf;
184 
185     i4_mem_size = ithread_get_handle_size();
186     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
187     RETURN_IF((NULL == pv_buf), IV_FAIL);
188     memset(pv_buf, 0, i4_mem_size);
189     ps_view_ctxt->pv_dec_thread_handle = pv_buf;
190 
191     i4_mem_size = ithread_get_handle_size();
192     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
193     RETURN_IF((NULL == pv_buf), IV_FAIL);
194     memset(pv_buf, 0, i4_mem_size);
195     ps_view_ctxt->pv_bs_deblk_thread_handle = pv_buf;
196 
197     i4_mem_size = sizeof(pred_info_t) * 2 * 32;
198     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
199     RETURN_IF((NULL == pv_buf), IV_FAIL);
200     memset(pv_buf, 0, i4_mem_size);
201     ps_view_ctxt->ps_pred = pv_buf;
202 
203     ps_view_ctxt->pv_disp_buf_mgr = NULL;
204 
205     ps_view_ctxt->pv_pic_buf_mgr = NULL;
206 
207     ps_view_ctxt->ps_pic_buf_base = NULL;
208 
209     i4_mem_size = sizeof(dec_err_status_t);
210     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
211     RETURN_IF((NULL == pv_buf), IV_FAIL);
212     memset(pv_buf, 0, i4_mem_size);
213     ps_view_ctxt->ps_dec_err_status = (dec_err_status_t *) pv_buf;
214 
215     i4_mem_size = sizeof(sei);
216     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
217     RETURN_IF((NULL == pv_buf), IV_FAIL);
218     memset(pv_buf, 0, i4_mem_size);
219     ps_view_ctxt->ps_sei = (sei *) pv_buf;
220 
221     i4_mem_size = sizeof(sei);
222     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
223     RETURN_IF((NULL == pv_buf), IV_FAIL);
224     memset(pv_buf, 0, i4_mem_size);
225     ps_view_ctxt->ps_sei_parse = (sei *) pv_buf;
226 
227     i4_mem_size = sizeof(dpb_commands_t);
228     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
229     RETURN_IF((NULL == pv_buf), IV_FAIL);
230     memset(pv_buf, 0, i4_mem_size);
231     ps_view_ctxt->ps_dpb_cmds = (dpb_commands_t *) pv_buf;
232 
233     i4_mem_size = sizeof(dec_bit_stream_t);
234     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
235     RETURN_IF((NULL == pv_buf), IV_FAIL);
236     memset(pv_buf, 0, i4_mem_size);
237     ps_view_ctxt->ps_bitstrm = (dec_bit_stream_t *) pv_buf;
238 
239     i4_mem_size = MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t));
240     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
241     RETURN_IF((NULL == pv_buf), IV_FAIL);
242     memset(pv_buf, 0, i4_mem_size);
243     ps_view_ctxt->pv_scratch_sps_pps = pv_buf;
244 
245     ps_view_ctxt->u4_static_bits_buf_size = MIN_BITSTREAMS_BUF_SIZE;
246     pv_buf =
247         pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, ps_view_ctxt->u4_static_bits_buf_size);
248     RETURN_IF((NULL == pv_buf), IV_FAIL);
249     memset(pv_buf, 0, ps_view_ctxt->u4_static_bits_buf_size);
250     ps_view_ctxt->pu1_bits_buf_static = pv_buf;
251 
252     i4_mem_size = (TOTAL_LIST_ENTRIES + PAD_MAP_IDX_POC) * sizeof(void *);
253     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
254     RETURN_IF((NULL == pv_buf), IV_FAIL);
255     ps_view_ctxt->ppv_map_ref_idx_to_poc_base = pv_buf;
256     ps_view_ctxt->ppv_map_ref_idx_to_poc =
257         ps_view_ctxt->ppv_map_ref_idx_to_poc_base + OFFSET_MAP_IDX_POC;
258     memset(ps_view_ctxt->ppv_map_ref_idx_to_poc_base, 0, i4_mem_size);
259 
260     i4_mem_size = (sizeof(bin_ctxt_model_t) * NUM_CABAC_CTXTS);
261     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
262     RETURN_IF((NULL == pv_buf), IV_FAIL);
263     memset(pv_buf, 0, i4_mem_size);
264     ps_view_ctxt->p_cabac_ctxt_table_t = pv_buf;
265 
266     i4_mem_size = sizeof(ctxt_inc_mb_info_t);
267     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
268     RETURN_IF((NULL == pv_buf), IV_FAIL);
269     memset(pv_buf, 0, i4_mem_size);
270     ps_view_ctxt->ps_left_mb_ctxt_info = pv_buf;
271 
272     i4_mem_size = MAX_REF_BUF_SIZE * 2;
273     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
274     RETURN_IF((NULL == pv_buf), IV_FAIL);
275     memset(pv_buf, 0, i4_mem_size);
276     ps_view_ctxt->pu1_ref_buff_base = pv_buf;
277     ps_view_ctxt->pu1_ref_buff = ps_view_ctxt->pu1_ref_buff_base + MAX_REF_BUF_SIZE;
278 
279     i4_mem_size = sizeof(WORD16) * PRED_BUFFER_WIDTH * PRED_BUFFER_HEIGHT * 2;
280     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
281     RETURN_IF((NULL == pv_buf), IV_FAIL);
282     memset(pv_buf, 0, i4_mem_size);
283     ps_view_ctxt->pi2_pred1 = pv_buf;
284 
285     i4_mem_size = sizeof(UWORD8) * (MB_LUM_SIZE);
286     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
287     RETURN_IF((NULL == pv_buf), IV_FAIL);
288     memset(pv_buf, 0, i4_mem_size);
289     ps_view_ctxt->pu1_temp_mc_buffer = pv_buf;
290 
291     i4_mem_size = (sizeof(UWORD32) * 2 * 3 * ((MAX_FRAMES << 1) * (MAX_FRAMES << 1)) * 2);
292     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
293     RETURN_IF((NULL == pv_buf), IV_FAIL);
294     memset(pv_buf, 0, i4_mem_size);
295     ps_view_ctxt->pu4_mbaff_wt_mat = pv_buf;
296 
297     i4_mem_size = sizeof(UWORD32) * 2 * 3 * ((MAX_FRAMES << 1) * (MAX_FRAMES << 1));
298     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
299     RETURN_IF((NULL == pv_buf), IV_FAIL);
300     memset(pv_buf, 0, i4_mem_size);
301     ps_view_ctxt->pu4_wts_ofsts_mat = pv_buf;
302 
303     i4_mem_size = (sizeof(neighbouradd_t) << 2);
304     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
305     RETURN_IF((NULL == pv_buf), IV_FAIL);
306     memset(pv_buf, 0, i4_mem_size);
307     ps_view_ctxt->ps_left_mvpred_addr = pv_buf;
308 
309     ps_view_ctxt->pv_mv_buf_mgr = NULL;
310 
311     ps_view_ctxt->ps_col_mv_base = NULL;
312 
313     ps_view_ctxt->init_done = 0;
314     ps_view_ctxt->u4_num_cores = 1;
315     ps_view_ctxt->u2_pic_ht = ps_view_ctxt->u2_pic_wd = 0;
316     ps_view_ctxt->u1_separate_parse = DEFAULT_SEPARATE_PARSE;
317     ps_view_ctxt->u4_app_disable_deblk_frm = 0;
318     ps_view_ctxt->i4_degrade_type = 0;
319     ps_view_ctxt->i4_degrade_pics = 0;
320 
321     memset(ps_view_ctxt->ps_pps, 0, ((sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS));
322     memset(ps_view_ctxt->ps_sps, 0, ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS));
323 
324     ps_view_ctxt->p_DeblockPicture[0] = ih264d_deblock_picture_non_mbaff;
325     ps_view_ctxt->p_DeblockPicture[1] = ih264d_deblock_picture_mbaff;
326     ps_view_ctxt->s_cab_dec_env.pv_codec_handle = ps_view_ctxt;
327     ps_view_ctxt->u4_num_fld_in_frm = 0;
328     ps_view_ctxt->ps_sei->u1_is_valid = 0;
329     ps_view_ctxt->ps_cur_pps = NULL;
330     ps_view_ctxt->ps_cur_sps = NULL;
331     ps_view_ctxt->ps_cur_slice = NULL;
332     ps_view_ctxt->u1_init_dec_flag = 0;
333     ps_view_ctxt->u1_first_slice_in_stream = 1;
334     ps_view_ctxt->u1_last_pic_not_decoded = 0;
335     ps_view_ctxt->u4_app_disp_width = 0;
336     ps_view_ctxt->i4_header_decoded = 0;
337     ps_view_ctxt->u4_total_frames_decoded = 0;
338     ps_view_ctxt->i4_error_code = 0;
339     ps_view_ctxt->i4_content_type = IV_CONTENTTYPE_NA;
340     ps_view_ctxt->ps_dec_err_status->u1_err_flag = ACCEPT_ALL_PICS;
341     ps_view_ctxt->ps_dec_err_status->u1_cur_pic_type = PIC_TYPE_UNKNOWN;
342     ps_view_ctxt->ps_dec_err_status->u4_frm_sei_sync = SYNC_FRM_DEFAULT;
343     ps_view_ctxt->ps_dec_err_status->u4_cur_frm = INIT_FRAME;
344     ps_view_ctxt->ps_dec_err_status->u1_pic_aud_i = PIC_TYPE_UNKNOWN;
345     ps_view_ctxt->u1_pr_sl_type = 0xFF;
346     ps_view_ctxt->u2_mbx = 0xffff;
347     ps_view_ctxt->u2_mby = 0;
348     ps_view_ctxt->u2_total_mbs_coded = 0;
349 
350     ps_prev_poc = &ps_view_ctxt->s_prev_pic_poc;
351     ps_cur_poc = &ps_view_ctxt->s_cur_pic_poc;
352     ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb = 0;
353     ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb = 0;
354     ps_prev_poc->i4_delta_pic_order_cnt_bottom = ps_cur_poc->i4_delta_pic_order_cnt_bottom = 0;
355     ps_prev_poc->i4_delta_pic_order_cnt[0] = ps_cur_poc->i4_delta_pic_order_cnt[0] = 0;
356     ps_prev_poc->i4_delta_pic_order_cnt[1] = ps_cur_poc->i4_delta_pic_order_cnt[1] = 0;
357     ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
358     ps_prev_poc->i4_top_field_order_count = ps_cur_poc->i4_top_field_order_count = 0;
359     ps_prev_poc->i4_bottom_field_order_count = ps_cur_poc->i4_bottom_field_order_count = 0;
360     ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field = 0;
361     ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
362     ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst = 0;
363 
364     ps_view_ctxt->i4_max_poc = 0;
365     ps_view_ctxt->i4_prev_max_display_seq = 0;
366     ps_view_ctxt->u1_recon_mb_grp = 4;
367     ps_view_ctxt->i4_reorder_depth = -1;
368     ps_view_ctxt->u1_second_field = 0;
369     ps_view_ctxt->s_prev_seq_params.u1_eoseq_pending = 0;
370     ps_view_ctxt->u2_crop_offset_y = 0;
371     ps_view_ctxt->u2_crop_offset_uv = 0;
372     ps_view_ctxt->i4_vui_frame_rate = -1;
373     ps_view_ctxt->i4_pic_type = NA_SLICE;
374     ps_view_ctxt->i4_frametype = IV_NA_FRAME;
375     ps_view_ctxt->i4_content_type = IV_CONTENTTYPE_NA;
376     ps_view_ctxt->u1_res_changed = 0;
377     ps_view_ctxt->u1_frame_decoded_flag = 0;
378     ps_view_ctxt->u4_skip_frm_mask = SKIP_NONE;
379 
380     ps_view_ctxt->pf_cavlc_4x4res_block[0] = ih264d_cavlc_4x4res_block_totalcoeff_1;
381     ps_view_ctxt->pf_cavlc_4x4res_block[1] = ih264d_cavlc_4x4res_block_totalcoeff_2to10;
382     ps_view_ctxt->pf_cavlc_4x4res_block[2] = ih264d_cavlc_4x4res_block_totalcoeff_11to16;
383     ps_view_ctxt->pf_cavlc_parse4x4coeff[0] = ih264d_cavlc_parse4x4coeff_n0to7;
384     ps_view_ctxt->pf_cavlc_parse4x4coeff[1] = ih264d_cavlc_parse4x4coeff_n8;
385     ps_view_ctxt->pf_cavlc_parse_8x8block[0] = ih264d_cavlc_parse_8x8block_none_available;
386     ps_view_ctxt->pf_cavlc_parse_8x8block[1] = ih264d_cavlc_parse_8x8block_left_available;
387     ps_view_ctxt->pf_cavlc_parse_8x8block[2] = ih264d_cavlc_parse_8x8block_top_available;
388     ps_view_ctxt->pf_cavlc_parse_8x8block[3] = ih264d_cavlc_parse_8x8block_both_available;
389 
390     ps_view_ctxt->pf_fill_bs1[0][0] = ih264d_fill_bs1_16x16mb_pslice;
391     ps_view_ctxt->pf_fill_bs1[0][1] = ih264d_fill_bs1_non16x16mb_pslice;
392     ps_view_ctxt->pf_fill_bs1[1][0] = ih264d_fill_bs1_16x16mb_bslice;
393     ps_view_ctxt->pf_fill_bs1[1][1] = ih264d_fill_bs1_non16x16mb_bslice;
394     ps_view_ctxt->pf_fill_bs_xtra_left_edge[0] = ih264d_fill_bs_xtra_left_edge_cur_frm;
395     ps_view_ctxt->pf_fill_bs_xtra_left_edge[1] = ih264d_fill_bs_xtra_left_edge_cur_fld;
396 
397     ps_view_ctxt->u2_prv_frame_num = 0;
398     ps_view_ctxt->u1_top_bottom_decoded = 0;
399     ps_view_ctxt->u1_dangling_field = 0;
400     ps_view_ctxt->s_cab_dec_env.cabac_table = gau4_ih264d_cabac_table;
401     ps_view_ctxt->pu1_left_mv_ctxt_inc = ps_view_ctxt->u1_left_mv_ctxt_inc_arr[0];
402     ps_view_ctxt->pi1_left_ref_idx_ctxt_inc = &ps_view_ctxt->i1_left_ref_idx_ctx_inc_arr[0][0];
403     ps_view_ctxt->pu1_left_yuv_dc_csbp = &ps_view_ctxt->u1_yuv_dc_csbp_topmb;
404     ps_view_ctxt->u1_flushfrm = 0;
405     ps_view_ctxt->s_cab_dec_env.pv_codec_handle = ps_view_ctxt;
406     ps_view_ctxt->ps_bitstrm->pv_codec_handle = ps_view_ctxt;
407 
408     memset(ps_view_ctxt->disp_bufs, 0, (MAX_DISP_BUFS_NEW) * sizeof(disp_buf_t));
409     memset(ps_view_ctxt->u4_disp_buf_mapping, 0, (MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
410     memset(ps_view_ctxt->u4_disp_buf_to_be_freed, 0, (MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
411 
412     ih264d_init_arch(ps_view_ctxt);
413     ih264d_init_function_ptr(ps_view_ctxt);
414     ps_view_ctxt->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
415     ps_view_ctxt->init_done = 1;
416 
417     return IV_SUCCESS;
418 }
419 
imvcd_ctxt_init(imvcd_create_ip_t * ps_ip,mvc_dec_ctxt_t * ps_mvcd_ctxt)420 static IV_API_CALL_STATUS_T imvcd_ctxt_init(imvcd_create_ip_t *ps_ip, mvc_dec_ctxt_t *ps_mvcd_ctxt)
421 {
422     WORD32 i4_mem_size;
423     void *pv_buf;
424 
425     FT_ALIGNED_ALLOC *pf_aligned_alloc = ps_ip->s_ivd_ip.pf_aligned_alloc;
426 
427     void *pv_mem_ctxt = ps_ip->s_ivd_ip.pv_mem_ctxt;
428     const WORD32 i4_default_alignment = 128;
429 
430     memset(ps_mvcd_ctxt, 0, sizeof(ps_mvcd_ctxt[0]));
431 
432     i4_mem_size = sizeof(mvc_dpb_manager_t);
433     ps_mvcd_ctxt->ps_dpb_mgr = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
434     RETURN_IF((NULL == ps_mvcd_ctxt->ps_dpb_mgr), IV_FAIL);
435     memset(ps_mvcd_ctxt->ps_dpb_mgr, 0, i4_mem_size);
436 
437     imvcd_init_dpb_mgr(ps_mvcd_ctxt->ps_dpb_mgr, &ps_mvcd_ctxt->s_mvc_au_buf_mgr,
438                        &ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr, &ps_mvcd_ctxt->s_mvc_disp_buf_mgr);
439 
440     ih264_disp_mgr_init(&ps_mvcd_ctxt->s_mvc_disp_buf_mgr);
441 
442     i4_mem_size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
443     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
444     RETURN_IF((NULL == pv_buf), IV_FAIL);
445     memset(pv_buf, 0, i4_mem_size);
446     ps_mvcd_ctxt->s_mvc_au_buf_mgr.pv_mem = pv_buf;
447     ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt = pv_buf;
448 
449     ih264_buf_mgr_init(ps_mvcd_ctxt->s_mvc_au_buf_mgr.pv_mem);
450 
451     i4_mem_size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
452     pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
453     RETURN_IF((NULL == pv_buf), IV_FAIL);
454     memset(pv_buf, 0, i4_mem_size);
455     ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.pv_mem = pv_buf;
456     ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.ps_buf_mgr_ctxt = pv_buf;
457 
458     ih264_buf_mgr_init(ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.pv_mem);
459 
460     if(IV_SUCCESS != imvcd_view_ctxt_init(ps_ip, &ps_mvcd_ctxt->s_view_dec_ctxt))
461     {
462         return IV_FAIL;
463     }
464 
465     ps_mvcd_ctxt->u2_num_views = 0;
466     ps_mvcd_ctxt->u2_num_views_decoded = 0;
467 
468     return IV_SUCCESS;
469 }
470 
imvcd_allocate_static_bufs(imvcd_create_ip_t * ps_ip,imvcd_create_op_t * ps_op)471 static IV_API_CALL_STATUS_T imvcd_allocate_static_bufs(imvcd_create_ip_t *ps_ip,
472                                                        imvcd_create_op_t *ps_op)
473 {
474     iv_obj_t *ps_dec_hdl;
475     mvc_dec_ctxt_t *ps_mvcd_ctxt;
476 
477     WORD32 i4_mem_size;
478 
479     FT_ALIGNED_ALLOC *pf_aligned_alloc = ps_ip->s_ivd_ip.pf_aligned_alloc;
480 
481     void *pv_mem_ctxt = ps_ip->s_ivd_ip.pv_mem_ctxt;
482     const WORD32 i4_default_alignment = 128;
483 
484     i4_mem_size = sizeof(ps_dec_hdl[0]);
485     ps_op->s_ivd_op.pv_handle = ps_dec_hdl =
486         (iv_obj_t *) pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
487 
488     if(NULL == ps_dec_hdl)
489     {
490         return IV_FAIL;
491     }
492 
493     i4_mem_size = sizeof(ps_mvcd_ctxt[0]);
494     ps_dec_hdl->pv_codec_handle = ps_mvcd_ctxt =
495         (mvc_dec_ctxt_t *) pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
496 
497     if(NULL == ps_mvcd_ctxt)
498     {
499         return IV_FAIL;
500     }
501 
502     if(IV_SUCCESS != imvcd_ctxt_init(ps_ip, ps_mvcd_ctxt))
503     {
504         return IV_FAIL;
505     }
506 
507     return IV_SUCCESS;
508 }
509 
510 /* Description - 'Create' API for MVC Decoder */
imvcd_create(imvcd_create_ip_t * ps_ip,imvcd_create_op_t * ps_op)511 static IV_API_CALL_STATUS_T imvcd_create(imvcd_create_ip_t *ps_ip, imvcd_create_op_t *ps_op)
512 {
513     if(IV_SUCCESS != imvcd_check_create_structs(ps_ip, ps_op))
514     {
515         return IV_FAIL;
516     }
517 
518     if(IV_SUCCESS != imvcd_allocate_static_bufs(ps_ip, ps_op))
519     {
520         imvcd_free_static_bufs((iv_obj_t *) ps_op->s_ivd_op.pv_handle);
521 
522         return IV_FAIL;
523     }
524 
525     return IV_SUCCESS;
526 }
527 
528 /* Description - 'Delete' API for MVC Decoder */
imvcd_delete(iv_obj_t * ps_dec_hdl)529 static IV_API_CALL_STATUS_T imvcd_delete(iv_obj_t *ps_dec_hdl)
530 {
531     if(IV_SUCCESS != imvcd_check_dec_handle(ps_dec_hdl))
532     {
533         return IV_FAIL;
534     }
535 
536     imvcd_free_static_bufs(ps_dec_hdl);
537 
538     return IV_SUCCESS;
539 }
540 
imvcd_flush_mode_decode(mvc_dec_ctxt_t * ps_mvcd_ctxt,imvcd_video_decode_op_t * ps_op)541 static IV_API_CALL_STATUS_T imvcd_flush_mode_decode(mvc_dec_ctxt_t *ps_mvcd_ctxt,
542                                                     imvcd_video_decode_op_t *ps_op)
543 {
544     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
545 
546     if(!ps_view_ctxt->u1_init_dec_flag)
547     {
548         ps_view_ctxt->u1_flushfrm = 0;
549         ps_mvcd_ctxt->b_flush_enabled = false;
550         ps_op->s_ivd_op.u4_output_present = 0;
551 
552         return IV_FAIL;
553     }
554 
555     if(IV_SUCCESS != imvcd_get_next_display_au_buf(ps_mvcd_ctxt))
556     {
557         ps_view_ctxt->u1_flushfrm = 0;
558         ps_mvcd_ctxt->b_flush_enabled = false;
559         ps_op->s_ivd_op.u4_output_present = false;
560 
561         return IV_SUCCESS;
562     }
563 
564     ih264d_export_sei_params(&ps_op->s_ivd_op.s_sei_decode_op, ps_view_ctxt);
565 
566     ps_op->s_ivd_op.u4_pic_wd = ps_view_ctxt->u2_disp_width;
567     ps_op->s_ivd_op.u4_pic_ht = ps_view_ctxt->u2_disp_height;
568     ps_op->s_ivd_op.u4_ts = ps_view_ctxt->s_disp_op.u4_ts;
569     ps_op->s_ivd_op.u4_output_present = 1;
570     ps_op->s_ivd_op.e_output_format = IV_YUV_420P;
571 
572     imvcd_convert_to_app_disp_buf(ps_mvcd_ctxt, ps_op->ps_view_disp_bufs);
573 
574     return IV_SUCCESS;
575 }
576 
imvcd_fill_output_struct_from_context(mvc_dec_ctxt_t * ps_mvcd_ctxt,imvcd_video_decode_op_t * ps_op)577 static void imvcd_fill_output_struct_from_context(mvc_dec_ctxt_t *ps_mvcd_ctxt,
578                                                   imvcd_video_decode_op_t *ps_op)
579 {
580     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
581 
582     if((ps_op->s_ivd_op.u4_error_code & 0xff) != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED)
583     {
584         ps_op->s_ivd_op.u4_pic_wd = ps_view_ctxt->u2_disp_width;
585         ps_op->s_ivd_op.u4_pic_ht = ps_view_ctxt->u2_disp_height;
586     }
587 
588     ps_op->s_ivd_op.u4_output_present = ps_view_ctxt->u4_output_present;
589 
590     ps_op->s_ivd_op.e_output_format = IV_YUV_420P;
591 
592     imvcd_convert_to_app_disp_buf(ps_mvcd_ctxt, ps_op->ps_view_disp_bufs);
593 
594     ih264d_export_sei_params(&ps_op->s_ivd_op.s_sei_decode_op, ps_view_ctxt);
595 }
596 
imvcd_video_decode_clean_return(mvc_dec_ctxt_t * ps_mvcd_ctxt,imvcd_video_decode_ip_t * ps_ip,imvcd_video_decode_op_t * ps_op)597 static void imvcd_video_decode_clean_return(mvc_dec_ctxt_t *ps_mvcd_ctxt,
598                                             imvcd_video_decode_ip_t *ps_ip,
599                                             imvcd_video_decode_op_t *ps_op)
600 {
601     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
602 
603     ih264d_signal_decode_thread(ps_view_ctxt);
604     ih264d_signal_bs_deblk_thread(ps_view_ctxt);
605 
606     imvcd_fill_output_struct_from_context(ps_mvcd_ctxt, ps_op);
607 
608     ps_op->s_ivd_op.u4_frame_decoded_flag = 0;
609     ps_op->s_ivd_op.u4_num_bytes_consumed = ps_ip->s_ivd_ip.u4_num_Bytes;
610 }
611 
imvcd_update_num_pps(mvc_dec_ctxt_t * ps_mvcd_ctxt)612 static FORCEINLINE void imvcd_update_num_pps(mvc_dec_ctxt_t *ps_mvcd_ctxt)
613 {
614     WORD32 i;
615 
616     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
617 
618     ps_mvcd_ctxt->u1_num_pps = 0;
619 
620     for(i = 0; i < MAX_NUM_PIC_PARAMS; i++)
621     {
622         if(ps_view_ctxt->ps_pps[i].u1_is_valid)
623         {
624             UWORD8 u1_sps_id = ps_view_ctxt->ps_pps[i].ps_sps->u1_seq_parameter_set_id;
625 
626             if(ps_mvcd_ctxt->as_subset_sps[u1_sps_id].s_sps_data.u1_is_valid)
627             {
628                 ps_mvcd_ctxt->aps_pps_id_to_subset_sps_map[i] =
629                     &ps_mvcd_ctxt->as_subset_sps[u1_sps_id];
630             }
631 
632             ps_mvcd_ctxt->u1_num_pps++;
633         }
634     }
635 }
636 
imvcd_update_num_sps(mvc_dec_ctxt_t * ps_mvcd_ctxt)637 static FORCEINLINE void imvcd_update_num_sps(mvc_dec_ctxt_t *ps_mvcd_ctxt)
638 {
639     WORD32 i;
640 
641     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
642 
643     ps_mvcd_ctxt->u1_num_sps = 0;
644 
645     for(i = 0; i < MAX_NUM_SEQ_PARAMS; i++)
646     {
647         if(ps_view_ctxt->ps_sps[i].u1_is_valid)
648         {
649             ps_mvcd_ctxt->u1_num_sps++;
650         }
651     }
652 }
653 
imvcd_update_num_subset_sps(mvc_dec_ctxt_t * ps_mvcd_ctxt)654 static FORCEINLINE void imvcd_update_num_subset_sps(mvc_dec_ctxt_t *ps_mvcd_ctxt)
655 {
656     WORD32 i;
657 
658     ps_mvcd_ctxt->u1_num_subset_sps = 0;
659 
660     for(i = 0; i < MAX_NUM_SEQ_PARAMS; i++)
661     {
662         if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_is_valid)
663         {
664             ps_mvcd_ctxt->u1_num_subset_sps++;
665         }
666     }
667 }
668 
imvcd_view_decode(iv_obj_t * ps_dec_hdl,imvcd_video_decode_ip_t * ps_ip,imvcd_video_decode_op_t * ps_op)669 static IV_API_CALL_STATUS_T imvcd_view_decode(iv_obj_t *ps_dec_hdl, imvcd_video_decode_ip_t *ps_ip,
670                                               imvcd_video_decode_op_t *ps_op)
671 {
672     UWORD8 *pu1_input_buffer;
673     UWORD8 *pu1_bitstream_buf;
674     UWORD32 u4_bitstream_buf_size;
675     WORD32 i4_nalu_length;
676     UWORD32 u4_length_of_start_code;
677     WORD32 i4_error_code;
678 
679     mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
680     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
681 
682     UWORD32 u4_num_bytes_consumed = 0;
683     UWORD32 u4_num_bytes_remaining = ps_ip->s_ivd_ip.u4_num_Bytes;
684     bool b_first_start_code_found = false;
685     bool b_frame_data_left = true;
686     bool b_header_data_left = true;
687     UWORD32 u4_next_is_aud = 0;
688 
689     ASSERT(u4_num_bytes_remaining > 0);
690 
691     imvcd_view_init(ps_mvcd_ctxt);
692 
693     do
694     {
695         pu1_input_buffer = ((UWORD8 *) ps_ip->s_ivd_ip.pv_stream_buffer) + u4_num_bytes_consumed;
696 
697         if(!ps_view_ctxt->pu1_bits_buf_dynamic &&
698            is_header_decoded(ps_view_ctxt->i4_header_decoded, PPS))
699         {
700             if(IV_SUCCESS !=
701                imvcd_bitstream_buf_alloc(
702                    ps_view_ctxt, is_header_decoded(ps_view_ctxt->i4_header_decoded, SUBSET_SPS)
703                                      ? ps_mvcd_ctxt->u2_num_views
704                                      : 1))
705             {
706                 return IV_FAIL;
707             }
708         }
709 
710         if(ps_view_ctxt->pu1_bits_buf_dynamic)
711         {
712             pu1_bitstream_buf = ps_view_ctxt->pu1_bits_buf_dynamic;
713             u4_bitstream_buf_size = ps_view_ctxt->u4_dynamic_bits_buf_size;
714         }
715         else
716         {
717             pu1_bitstream_buf = ps_view_ctxt->pu1_bits_buf_static;
718             u4_bitstream_buf_size = ps_view_ctxt->u4_static_bits_buf_size;
719         }
720 
721         i4_nalu_length = ih264d_find_start_code(pu1_input_buffer, 0, u4_num_bytes_remaining,
722                                                 &u4_length_of_start_code, &u4_next_is_aud);
723 
724         if(i4_nalu_length == -1)
725         {
726             i4_nalu_length = 0;
727         }
728 
729         if((0 != u4_next_is_aud) && (1 != u4_next_is_aud))
730         {
731             return IV_FAIL;
732         }
733 
734         if(i4_nalu_length)
735         {
736             /* In some erroneous fuzzer bistreams, the slice data requires more
737               parsing than what was implied by the distance between successive
738               start codes.The primary culprit is the NEXTBITS macro which requires
739               reading 4 additional bytes of the bitstream buffer.To alleviate
740               this, 4 bytes per 4x4 TU have been additionally allocated to the
741               bitstream buffer. */
742             UWORD32 u4_nalu_buf_size = ((UWORD32) i4_nalu_length) + 8 + 4 * 16;
743 
744             if(u4_nalu_buf_size > u4_bitstream_buf_size)
745             {
746                 /* 64 extra bytes to account for OOB accesses during SEI parsing in */
747                 /* some fuzzer bitstreams */
748                 if(IV_SUCCESS != imvcd_bitstream_buf_realloc(ps_view_ctxt, u4_nalu_buf_size + 64))
749                 {
750                     return IV_FAIL;
751                 }
752 
753                 pu1_bitstream_buf = ps_view_ctxt->pu1_bits_buf_dynamic;
754                 u4_bitstream_buf_size = ps_view_ctxt->u4_dynamic_bits_buf_size;
755             }
756 
757             memcpy(pu1_bitstream_buf, pu1_input_buffer + u4_length_of_start_code, i4_nalu_length);
758 
759             /* Decoder may read extra 8 bytes near end of the frame */
760             if(u4_nalu_buf_size < u4_bitstream_buf_size)
761             {
762                 memset(pu1_bitstream_buf + i4_nalu_length, 0, 8 * sizeof(pu1_bitstream_buf[0]));
763             }
764 
765             b_first_start_code_found = true;
766         }
767         else
768         {
769             if(!b_first_start_code_found)
770             {
771                 ps_view_ctxt->i4_error_code = ERROR_START_CODE_NOT_FOUND;
772                 ps_op->s_ivd_op.u4_error_code |= 1 << IVD_INSUFFICIENTDATA;
773 
774                 if(ps_view_ctxt->u4_pic_buf_got == 0)
775                 {
776                     imvcd_fill_output_struct_from_context(ps_mvcd_ctxt, ps_op);
777 
778                     ps_op->s_ivd_op.u4_error_code = ps_view_ctxt->i4_error_code;
779 
780                     imvcd_video_decode_clean_return(ps_mvcd_ctxt, ps_ip, ps_op);
781 
782                     return IV_FAIL;
783                 }
784                 else
785                 {
786                     ps_view_ctxt->u1_pic_decode_done = 1;
787 
788                     continue;
789                 }
790             }
791             else
792             {
793                 /* a start code has already been found earlier in the same process
794                  * call*/
795                 b_frame_data_left = false;
796                 b_header_data_left = false;
797 
798                 if(!ps_view_ctxt->i4_decode_header && !ps_view_ctxt->u4_pic_buf_got)
799                 {
800                     ps_op->s_ivd_op.u4_error_code = ih264d_map_error(ERROR_UNKNOWN_NAL);
801 
802                     imvcd_video_decode_clean_return(ps_mvcd_ctxt, ps_ip, ps_op);
803 
804                     return IV_FAIL;
805                 }
806 
807                 continue;
808             }
809         }
810 
811         ps_mvcd_ctxt->ae_nalu_id[ps_mvcd_ctxt->u2_num_views_decoded] =
812             NAL_UNIT_TYPE(pu1_bitstream_buf[0]);
813         ps_mvcd_ctxt->au1_nal_ref_idc[ps_mvcd_ctxt->u2_num_views_decoded] =
814             NAL_REF_IDC(pu1_bitstream_buf[0]);
815 
816         if(ps_view_ctxt->u4_dec_thread_created &&
817            !is_slice_nalu_type(ps_mvcd_ctxt->ae_nalu_id[ps_mvcd_ctxt->u2_num_views_decoded]))
818         {
819             ps_op->s_ivd_op.u4_error_code = ERROR_FEATURE_UNAVAIL;
820 
821             imvcd_video_decode_clean_return(ps_mvcd_ctxt, ps_ip, ps_op);
822 
823             return IV_FAIL;
824         }
825 
826         if(!is_mvc_nalu(ps_mvcd_ctxt->ae_nalu_id[ps_mvcd_ctxt->u2_num_views_decoded]))
827         {
828             ivd_video_decode_op_t s_avc_op;
829 
830             i4_error_code =
831                 ih264d_parse_nal_unit(ps_dec_hdl, &s_avc_op, pu1_bitstream_buf, i4_nalu_length);
832         }
833         else
834         {
835             i4_error_code = imvcd_nalu_parser(ps_mvcd_ctxt, pu1_bitstream_buf, i4_nalu_length);
836         }
837 
838         if(OK != i4_error_code)
839         {
840             ps_op->s_ivd_op.u4_error_code = i4_error_code;
841 
842             imvcd_video_decode_clean_return(ps_mvcd_ctxt, ps_ip, ps_op);
843 
844             return IV_FAIL;
845         }
846         else if(PPS == ps_mvcd_ctxt->ae_nalu_id[ps_mvcd_ctxt->u2_num_views_decoded])
847         {
848             imvcd_update_num_pps(ps_mvcd_ctxt);
849         }
850         else if(SPS == ps_mvcd_ctxt->ae_nalu_id[ps_mvcd_ctxt->u2_num_views_decoded])
851         {
852             imvcd_update_num_sps(ps_mvcd_ctxt);
853         }
854         else if(SUBSET_SPS == ps_mvcd_ctxt->ae_nalu_id[ps_mvcd_ctxt->u2_num_views_decoded])
855         {
856             imvcd_update_num_subset_sps(ps_mvcd_ctxt);
857         }
858 
859         b_header_data_left = ps_view_ctxt->i4_decode_header &&
860                              (!is_header_decoded(ps_view_ctxt->i4_header_decoded, SPS) ||
861                               !is_header_decoded(ps_view_ctxt->i4_header_decoded, PPS)) &&
862                              (u4_num_bytes_consumed < ps_ip->s_ivd_ip.u4_num_Bytes);
863         b_frame_data_left = (!ps_view_ctxt->i4_decode_header &&
864                              (!ps_view_ctxt->u1_pic_decode_done || u4_next_is_aud)) &&
865                             (u4_num_bytes_consumed < ps_ip->s_ivd_ip.u4_num_Bytes);
866 
867         u4_num_bytes_consumed += i4_nalu_length + u4_length_of_start_code;
868         u4_num_bytes_remaining -= i4_nalu_length + u4_length_of_start_code;
869 
870     } while(b_header_data_left || b_frame_data_left);
871 
872     if((i4_error_code == IVD_RES_CHANGED) || (i4_error_code == IVD_MEM_ALLOC_FAILED) ||
873        (i4_error_code == ERROR_UNAVAIL_PICBUF_T) || (i4_error_code == ERROR_UNAVAIL_MVBUF_T) ||
874        (i4_error_code == ERROR_INV_SPS_PPS_T))
875     {
876         ih264d_signal_decode_thread(ps_view_ctxt);
877 
878         if(ps_view_ctxt->u4_num_cores == 3)
879         {
880             ih264d_signal_bs_deblk_thread(ps_view_ctxt);
881         }
882 
883         /* dont consume bitstream for change in resolution case */
884         if(i4_error_code == IVD_RES_CHANGED)
885         {
886             ps_op->s_ivd_op.u4_num_bytes_consumed -= u4_num_bytes_consumed;
887         }
888 
889         imvcd_video_decode_clean_return(ps_mvcd_ctxt, ps_ip, ps_op);
890 
891         return IV_FAIL;
892     }
893 
894     if(ps_view_ctxt->u1_separate_parse)
895     {
896         if(ps_view_ctxt->u4_num_cores == 2)
897         {
898             if((ps_view_ctxt->u4_nmb_deblk == 0) && (ps_view_ctxt->u4_start_recon_deblk == 1))
899             {
900                 tfr_ctxt_t s_tfr_ctxt;
901 
902                 UWORD32 u4_num_mbs, u4_max_addr;
903 
904                 tfr_ctxt_t *ps_tfr_cxt = &s_tfr_ctxt;
905                 pad_mgr_t *ps_pad_mgr = &ps_view_ctxt->s_pad_mgr;
906                 nalu_mvc_ext_t *ps_cur_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt);
907 
908                 /*BS is done for all mbs while parsing*/
909                 u4_max_addr = (ps_view_ctxt->u2_frm_wd_in_mbs * ps_view_ctxt->u2_frm_ht_in_mbs) - 1;
910                 ps_view_ctxt->u4_cur_bs_mb_num = u4_max_addr + 1;
911 
912                 ps_view_ctxt->ps_cur_pic = &ps_view_ctxt->s_cur_pic;
913                 imvcd_convert_au_buf_to_view_buf(ps_mvcd_ctxt->ps_cur_au, &ps_view_ctxt->s_cur_pic,
914                                                  ps_mvcd_ctxt->u2_num_views_decoded,
915                                                  ps_cur_nalu_mvc_ext->u2_view_id);
916 
917                 ih264d_init_deblk_tfr_ctxt(ps_view_ctxt, ps_pad_mgr, ps_tfr_cxt,
918                                            ps_view_ctxt->u2_frm_wd_in_mbs, 0);
919 
920                 u4_num_mbs = u4_max_addr - ps_view_ctxt->u4_cur_deblk_mb_num + 1;
921 
922                 if(u4_num_mbs != 0)
923                 {
924                     ih264d_check_mb_map_deblk(ps_view_ctxt, u4_num_mbs, ps_tfr_cxt, 1);
925                 }
926 
927                 ps_view_ctxt->u4_start_recon_deblk = 0;
928             }
929         }
930 
931         ih264d_signal_decode_thread(ps_view_ctxt);
932 
933         if(ps_view_ctxt->u4_num_cores == 3)
934         {
935             ih264d_signal_bs_deblk_thread(ps_view_ctxt);
936         }
937     }
938 
939     DATA_SYNC();
940 
941     // Report if header (sps and pps) has not been decoded yet
942     if(ps_view_ctxt->i4_decode_header &&
943        (!is_header_decoded(ps_view_ctxt->i4_header_decoded, SPS) &&
944         !is_header_decoded(ps_view_ctxt->i4_header_decoded, PPS)))
945     {
946         ps_op->s_ivd_op.u4_error_code |= (1 << IVD_INSUFFICIENTDATA);
947 
948         imvcd_video_decode_clean_return(ps_mvcd_ctxt, ps_ip, ps_op);
949 
950         return IV_FAIL;
951     }
952 
953     if(ps_view_ctxt->u4_pic_buf_got)
954     {
955         ps_view_ctxt->u1_top_bottom_decoded = TOP_FIELD_ONLY | BOT_FIELD_ONLY;
956 
957         if(((ps_view_ctxt->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC) == 0) &&
958            ps_view_ctxt->u1_pic_decode_done)
959         {
960             nalu_mvc_ext_t *ps_cur_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt);
961 
962             if(!ps_mvcd_ctxt->au1_nal_ref_idc[ps_mvcd_ctxt->u2_num_views_decoded] &&
963                ps_cur_nalu_mvc_ext->u1_inter_view_flag)
964             {
965                 ps_view_ctxt->ps_cur_slice->u1_nal_ref_idc = 1;
966             }
967 
968             /* Padding only. Deblk has happened already. */
969             ih264d_deblock_picture_progressive(ps_view_ctxt);
970 
971             if(!ps_mvcd_ctxt->au1_nal_ref_idc[ps_mvcd_ctxt->u2_num_views_decoded] &&
972                ps_cur_nalu_mvc_ext->u1_inter_view_flag)
973             {
974                 ps_view_ctxt->ps_cur_slice->u1_nal_ref_idc = 0;
975             }
976         }
977 
978         /*Update the i4_frametype at the end of picture*/
979         if(imvcd_is_idr_au(ps_mvcd_ctxt))
980         {
981             ps_view_ctxt->i4_frametype = IV_IDR_FRAME;
982         }
983         else if(ps_view_ctxt->i4_pic_type == B_SLICE)
984         {
985             ps_view_ctxt->i4_frametype = IV_B_FRAME;
986         }
987         else if(ps_view_ctxt->i4_pic_type == P_SLICE)
988         {
989             ps_view_ctxt->i4_frametype = IV_P_FRAME;
990         }
991         else if(ps_view_ctxt->i4_pic_type == I_SLICE)
992         {
993             ps_view_ctxt->i4_frametype = IV_I_FRAME;
994         }
995 
996         ps_view_ctxt->i4_content_type = ps_view_ctxt->ps_cur_slice->u1_field_pic_flag;
997     }
998 
999     /* close deblock thread if it is not closed yet*/
1000     if(ps_view_ctxt->u4_num_cores == 3)
1001     {
1002         ih264d_signal_bs_deblk_thread(ps_view_ctxt);
1003     }
1004 
1005     if(ps_view_ctxt->u4_dec_thread_created)
1006     {
1007         ih264d_signal_decode_thread(ps_view_ctxt);
1008     }
1009 
1010     if(ps_view_ctxt->u4_bs_deblk_thread_created)
1011     {
1012         ih264d_signal_bs_deblk_thread(ps_view_ctxt);
1013     }
1014 
1015     ps_op->s_ivd_op.u4_num_bytes_consumed = u4_num_bytes_consumed;
1016 
1017     DATA_SYNC();
1018 
1019     return IV_SUCCESS;
1020 }
1021 
imvcd_finish_au_decode(mvc_dec_ctxt_t * ps_mvcd_ctxt,imvcd_video_decode_op_t * ps_op)1022 static IV_API_CALL_STATUS_T imvcd_finish_au_decode(mvc_dec_ctxt_t *ps_mvcd_ctxt,
1023                                                    imvcd_video_decode_op_t *ps_op)
1024 {
1025     WORD32 i4_error_code;
1026 
1027     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
1028     dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice;
1029     mvc_au_buffer_t *ps_cur_au = ps_mvcd_ctxt->ps_cur_au;
1030     mvc_dpb_manager_t *ps_dpb_mgr = ps_mvcd_ctxt->ps_dpb_mgr;
1031 
1032     bool b_is_idr = imvcd_is_idr_au(ps_mvcd_ctxt);
1033     bool b_is_ref_au = !!ps_mvcd_ctxt->au1_nal_ref_idc[ps_mvcd_ctxt->u2_num_views - 1];
1034     WORD64 i8_display_poc =
1035         ((WORD64) ps_view_ctxt->i4_prev_max_display_seq) + ((WORD64) ps_cur_au->i4_poc);
1036 
1037     imvcd_dpb_delete_nonref_nondisplay_pics(ps_dpb_mgr);
1038 
1039     if(ps_cur_slice->u1_mmco_equalto5 || b_is_idr)
1040     {
1041         ps_cur_au->i4_poc = 0;
1042         ps_cur_au->i4_avg_poc = 0;
1043 
1044         if(ps_view_ctxt->u2_total_mbs_coded == (ps_view_ctxt->ps_cur_sps->u2_max_mb_addr + 1))
1045         {
1046             imvcd_reset_dpb(ps_dpb_mgr);
1047         }
1048 
1049         imvcd_dpb_release_display_bufs(ps_dpb_mgr);
1050     }
1051 
1052     if(IVD_DECODE_FRAME_OUT != ps_view_ctxt->e_frm_out_mode)
1053     {
1054         i4_error_code = imvcd_dpb_assign_display_seq(ps_dpb_mgr);
1055 
1056         if(OK != i4_error_code)
1057         {
1058             return IV_FAIL;
1059         }
1060     }
1061 
1062     if(b_is_ref_au)
1063     {
1064         ih264_buf_mgr_set_status(ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt,
1065                                  ps_cur_au->i4_pic_buf_id, BUF_MGR_REF);
1066 
1067         ih264_buf_mgr_set_status(ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.ps_buf_mgr_ctxt,
1068                                  ps_cur_au->i4_mv_buf_id, BUF_MGR_REF);
1069 
1070         ps_view_ctxt->au1_pic_buf_ref_flag[ps_cur_au->i4_pic_buf_id] = 1;
1071     }
1072     else
1073     {
1074         ih264_buf_mgr_release(ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt,
1075                               ps_cur_au->i4_pic_buf_id, BUF_MGR_REF);
1076 
1077         ih264_buf_mgr_release(ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.ps_buf_mgr_ctxt,
1078                               ps_cur_au->i4_mv_buf_id, BUF_MGR_REF | BUF_MGR_IO);
1079 
1080         ps_view_ctxt->au1_pic_buf_ref_flag[ps_cur_au->i4_pic_buf_id] = 0;
1081     }
1082 
1083     if((!ps_view_ctxt->u1_last_pic_not_decoded &&
1084         (0 == (ps_view_ctxt->ps_cur_pic->u4_pack_slc_typ & ps_view_ctxt->u4_skip_frm_mask))) ||
1085        b_is_idr)
1086     {
1087         ih264_buf_mgr_set_status(ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt,
1088                                  ps_cur_au->i4_pic_buf_id, BUF_MGR_IO);
1089     }
1090 
1091     if(IS_OUT_OF_RANGE_S32(i8_display_poc))
1092     {
1093         ps_view_ctxt->i4_prev_max_display_seq = 0;
1094     }
1095 
1096     i4_error_code = imvcd_dpb_insert_pic_in_display_list(
1097         ps_dpb_mgr, i8_display_poc, ps_cur_au->i4_frame_num, ps_cur_au->i4_pic_buf_id);
1098 
1099     if(i4_error_code != OK)
1100     {
1101         return IV_FAIL;
1102     }
1103 
1104     if(IVD_DECODE_FRAME_OUT == ps_view_ctxt->e_frm_out_mode)
1105     {
1106         i4_error_code = imvcd_dpb_assign_display_seq(ps_dpb_mgr);
1107 
1108         if(i4_error_code != OK)
1109         {
1110             return IV_FAIL;
1111         }
1112     }
1113 
1114     ps_view_ctxt->u4_total_frames_decoded++;
1115 
1116     /* In case the decoder is configured to run in low delay mode,
1117      * then get display buffer and then format convert.
1118      * Note in this mode, format conversion does not run paralelly in a thread
1119      * and adds to the codec cycles
1120      */
1121     if((IVD_DECODE_FRAME_OUT == ps_view_ctxt->e_frm_out_mode) && ps_view_ctxt->u1_init_dec_flag)
1122     {
1123         i4_error_code = imvcd_get_next_display_au_buf(ps_mvcd_ctxt);
1124 
1125         if(i4_error_code != OK)
1126         {
1127             return IV_FAIL;
1128         }
1129 
1130         ps_op->s_ivd_op.u4_output_present = 1;
1131     }
1132 
1133     ps_cur_au->u1_pic_type |= TOP_REF | BOT_REF;
1134 
1135     if(ps_view_ctxt->u4_pic_buf_got)
1136     {
1137         if(ps_view_ctxt->u1_last_pic_not_decoded)
1138         {
1139             return IV_FAIL;
1140         }
1141         else if(b_is_ref_au)
1142         {
1143             if(b_is_idr)
1144             {
1145                 ps_dpb_mgr->u1_mmco_error_in_seq = 0;
1146 
1147                 if(!ps_view_ctxt->ps_dpb_cmds->u1_long_term_reference_flag)
1148                 {
1149                     imvcd_reset_dpb(ps_dpb_mgr);
1150 
1151                     i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);
1152 
1153                     if(i4_error_code != OK)
1154                     {
1155                         return IV_FAIL;
1156                     }
1157 
1158                     ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES;
1159                 }
1160                 else
1161                 {
1162                     i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);
1163 
1164                     if(i4_error_code != OK)
1165                     {
1166                         return IV_FAIL;
1167                     }
1168 
1169                     imvcd_dpb_delete_st_node_or_make_lt(ps_dpb_mgr, ps_cur_au->i4_pic_num, 0);
1170 
1171                     ps_dpb_mgr->u1_max_lt_frame_idx = 0;
1172                 }
1173             }
1174             else if(!ps_dpb_mgr->u1_mmco_error_in_seq)
1175             {
1176                 i4_error_code = imvcd_dpb_do_mmco(ps_view_ctxt->ps_dpb_cmds, ps_dpb_mgr, ps_cur_au,
1177                                                   ps_view_ctxt->ps_cur_sps->u1_num_ref_frames,
1178                                                   ps_view_ctxt->e_dec_status);
1179 
1180                 ps_dpb_mgr->u1_mmco_error_in_seq = i4_error_code != OK;
1181             }
1182 
1183             i4_error_code = imvcd_dpb_update_default_index_list(ps_dpb_mgr);
1184 
1185             if(i4_error_code != OK)
1186             {
1187                 return IV_FAIL;
1188             }
1189         }
1190     }
1191 
1192     ps_op->s_ivd_op.u4_frame_decoded_flag = 1;
1193 
1194     return IV_SUCCESS;
1195 }
1196 
1197 /* Description - 'AU Decode' API for MVC Decoder */
imvcd_decode(iv_obj_t * ps_dec_hdl,imvcd_video_decode_ip_t * ps_ip,imvcd_video_decode_op_t * ps_op)1198 static IV_API_CALL_STATUS_T imvcd_decode(iv_obj_t *ps_dec_hdl, imvcd_video_decode_ip_t *ps_ip,
1199                                          imvcd_video_decode_op_t *ps_op)
1200 {
1201     IV_API_CALL_STATUS_T e_retval;
1202 
1203     mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
1204     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
1205     imvcd_video_decode_ip_t s_view_ip = ps_ip[0];
1206     imvcd_video_decode_op_t s_view_op = ps_op[0];
1207 
1208     UWORD16 u2_num_views_decoded = 0;
1209     UWORD16 u2_num_views = (ps_mvcd_ctxt->b_flush_enabled || ps_mvcd_ctxt->b_header_only_decode)
1210                                ? 1
1211                                : ps_mvcd_ctxt->u2_num_views;
1212 
1213     ps_mvcd_ctxt->u2_num_views_decoded = 0;
1214 
1215     if(IV_SUCCESS != imvcd_check_dec_handle(ps_dec_hdl))
1216     {
1217         return IV_FAIL;
1218     }
1219 
1220     if(IV_SUCCESS != imvcd_check_decode_structs(ps_dec_hdl, ps_ip, ps_op))
1221     {
1222         return IV_FAIL;
1223     }
1224 
1225     if(!ps_mvcd_ctxt->b_header_only_decode)
1226     {
1227         if(IV_SUCCESS != imvcd_au_error_checks(ps_mvcd_ctxt, ps_ip))
1228         {
1229             return IV_FAIL;
1230         }
1231     }
1232 
1233     /*Data memory barries instruction,so that bitstream write by the application
1234      * is complete*/
1235     DATA_SYNC();
1236 
1237     imvcd_au_init(ps_dec_hdl, ps_ip, ps_op);
1238 
1239     if(ps_mvcd_ctxt->b_flush_enabled)
1240     {
1241         return imvcd_flush_mode_decode(ps_mvcd_ctxt, ps_op);
1242     }
1243 
1244     while(u2_num_views_decoded < u2_num_views)
1245     {
1246         e_retval = imvcd_view_decode(ps_dec_hdl, &s_view_ip, &s_view_op);
1247 
1248         if(IV_SUCCESS != e_retval)
1249         {
1250             ps_op->s_ivd_op.u4_error_code = s_view_op.s_ivd_op.u4_error_code;
1251 
1252             return IV_FAIL;
1253         }
1254 
1255         s_view_ip.s_ivd_ip.pv_stream_buffer = ((UWORD8 *) s_view_ip.s_ivd_ip.pv_stream_buffer) +
1256                                               s_view_op.s_ivd_op.u4_num_bytes_consumed;
1257         s_view_ip.s_ivd_ip.u4_num_Bytes -= s_view_op.s_ivd_op.u4_num_bytes_consumed;
1258         ps_op->s_ivd_op.u4_num_bytes_consumed += s_view_op.s_ivd_op.u4_num_bytes_consumed;
1259 
1260         u2_num_views_decoded++;
1261         ps_mvcd_ctxt->u2_num_views_decoded++;
1262     }
1263 
1264     if(!ps_mvcd_ctxt->b_header_only_decode)
1265     {
1266         e_retval = imvcd_finish_au_decode(ps_mvcd_ctxt, ps_op);
1267 
1268         if(IV_SUCCESS != e_retval)
1269         {
1270             return IV_FAIL;
1271         }
1272     }
1273 
1274     ps_op->s_ivd_op.u4_pic_wd = ps_view_ctxt->u2_disp_width;
1275     ps_op->s_ivd_op.u4_pic_ht = ps_view_ctxt->u2_disp_height;
1276     ps_op->s_ivd_op.u4_output_present = ps_view_ctxt->u4_output_present;
1277     ps_op->s_ivd_op.u4_ts = ps_view_ctxt->s_disp_op.u4_ts;
1278     ps_op->s_ivd_op.i4_reorder_depth = ps_view_ctxt->i4_reorder_depth;
1279     ps_op->s_ivd_op.e_output_format = IV_YUV_420P;
1280 
1281     if(ps_op->s_ivd_op.u4_output_present)
1282     {
1283         imvcd_convert_to_app_disp_buf(ps_mvcd_ctxt, ps_op->ps_view_disp_bufs);
1284     }
1285 
1286     return e_retval;
1287 }
1288 
imvcd_ctl_set_dec_mode(iv_obj_t * ps_dec_hdl,imvcd_set_config_ip_t * ps_ip,imvcd_set_config_op_t * ps_op)1289 static IV_API_CALL_STATUS_T imvcd_ctl_set_dec_mode(iv_obj_t *ps_dec_hdl,
1290                                                    imvcd_set_config_ip_t *ps_ip,
1291                                                    imvcd_set_config_op_t *ps_op)
1292 {
1293     mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
1294     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
1295 
1296     ps_view_ctxt->u4_skip_frm_mask = SKIP_NONE;
1297 
1298     ps_op->s_ivd_op.u4_error_code = 0;
1299 
1300     ps_view_ctxt->u4_app_disp_width = 0;
1301 
1302     if(ps_ip->s_ivd_ip.e_frm_skip_mode != IVD_SKIP_NONE)
1303     {
1304         ps_op->s_ivd_op.u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
1305 
1306         return IV_FAIL;
1307     }
1308 
1309     if(ps_ip->s_ivd_ip.e_vid_dec_mode == IVD_DECODE_FRAME)
1310     {
1311         ps_view_ctxt->i4_decode_header = 0;
1312         ps_mvcd_ctxt->b_header_only_decode = false;
1313     }
1314     else if(ps_ip->s_ivd_ip.e_vid_dec_mode == IVD_DECODE_HEADER)
1315     {
1316         ps_view_ctxt->i4_decode_header = 1;
1317         ps_mvcd_ctxt->b_header_only_decode = true;
1318     }
1319     else
1320     {
1321         ps_op->s_ivd_op.u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
1322 
1323         return IV_FAIL;
1324     }
1325 
1326     if((ps_ip->s_ivd_ip.e_frm_out_mode != IVD_DECODE_FRAME_OUT) &&
1327        (ps_ip->s_ivd_ip.e_frm_out_mode != IVD_DISPLAY_FRAME_OUT))
1328     {
1329         ps_op->s_ivd_op.u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
1330 
1331         return IV_FAIL;
1332     }
1333 
1334     ps_mvcd_ctxt->b_flush_enabled = false;
1335     ps_view_ctxt->e_frm_out_mode = ps_ip->s_ivd_ip.e_frm_out_mode;
1336 
1337     return IV_SUCCESS;
1338 }
1339 
imvcd_ctl_set_num_cores(iv_obj_t * ps_dec_hdl,imvcd_set_num_cores_ip_t * ps_ip,imvcd_set_num_cores_op_t * ps_op)1340 static IV_API_CALL_STATUS_T imvcd_ctl_set_num_cores(iv_obj_t *ps_dec_hdl,
1341                                                     imvcd_set_num_cores_ip_t *ps_ip,
1342                                                     imvcd_set_num_cores_op_t *ps_op)
1343 {
1344     mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
1345     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
1346 
1347     ps_view_ctxt->u4_num_cores = ps_ip->u4_num_cores;
1348 
1349     ps_op->u4_error_code = 0;
1350 
1351     if(ps_view_ctxt->u4_num_cores == 1)
1352     {
1353         ps_view_ctxt->u1_separate_parse = 0;
1354     }
1355     else
1356     {
1357         ps_view_ctxt->u1_separate_parse = 1;
1358     }
1359 
1360     /*using only upto three threads currently*/
1361     if(ps_view_ctxt->u4_num_cores > 3)
1362     {
1363         ps_view_ctxt->u4_num_cores = 3;
1364     }
1365 
1366     return IV_SUCCESS;
1367 }
1368 
imvcd_ctl_set_arch(iv_obj_t * ps_dec_hdl,imvcd_set_arch_ip_t * ps_ip,imvcd_set_arch_op_t * ps_op)1369 static IV_API_CALL_STATUS_T imvcd_ctl_set_arch(iv_obj_t *ps_dec_hdl, imvcd_set_arch_ip_t *ps_ip,
1370                                                imvcd_set_arch_op_t *ps_op)
1371 {
1372     mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
1373     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
1374 
1375     ps_view_ctxt->e_processor_arch = ps_ip->e_arch;
1376     ps_view_ctxt->e_processor_soc = ps_ip->e_soc;
1377 
1378     ps_op->u4_error_code = 0;
1379 
1380     return IV_SUCCESS;
1381 }
1382 
imvcd_ctl_set_degrade_mode(iv_obj_t * ps_dec_hdl,imvcd_set_degrade_mode_ip_t * ps_ip,imvcd_set_degrade_mode_op_t * ps_op)1383 static IV_API_CALL_STATUS_T imvcd_ctl_set_degrade_mode(iv_obj_t *ps_dec_hdl,
1384                                                        imvcd_set_degrade_mode_ip_t *ps_ip,
1385                                                        imvcd_set_degrade_mode_op_t *ps_op)
1386 {
1387     mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
1388     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
1389 
1390     ps_view_ctxt->i4_degrade_type = ps_ip->i4_degrade_type;
1391     ps_view_ctxt->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval;
1392     ps_view_ctxt->i4_degrade_pics = ps_ip->i4_degrade_pics;
1393     ps_view_ctxt->i4_degrade_pic_cnt = 0;
1394 
1395     ps_op->u4_error_code = 0;
1396 
1397     return IV_SUCCESS;
1398 }
1399 
imvcd_ctl_flush_dec(iv_obj_t * ps_dec_hdl,imvcd_flush_dec_ip_t * ps_ip,imvcd_flush_dec_op_t * ps_op)1400 static IV_API_CALL_STATUS_T imvcd_ctl_flush_dec(iv_obj_t *ps_dec_hdl, imvcd_flush_dec_ip_t *ps_ip,
1401                                                 imvcd_flush_dec_op_t *ps_op)
1402 {
1403     mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
1404     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
1405 
1406     UNUSED(ps_ip);
1407 
1408     ps_op->s_ivd_op.u4_error_code = 0;
1409 
1410     ps_mvcd_ctxt->b_flush_enabled = true;
1411     ps_view_ctxt->u1_flushfrm = 1;
1412 
1413     if(ps_view_ctxt->u1_init_dec_flag)
1414     {
1415         imvcd_release_all_ref_bufs(ps_mvcd_ctxt, ps_view_ctxt->u1_pic_bufs);
1416         imvcd_dpb_release_display_bufs(ps_mvcd_ctxt->ps_dpb_mgr);
1417     }
1418 
1419     /* Ignore dangling fields during flush */
1420     ps_view_ctxt->u1_top_bottom_decoded = 0;
1421 
1422     return IV_SUCCESS;
1423 }
1424 
imvcd_ctl_get_buf_info(iv_obj_t * ps_dec_hdl,imvcd_get_buf_info_ip_t * ps_ip,imvcd_get_buf_info_op_t * ps_op)1425 static IV_API_CALL_STATUS_T imvcd_ctl_get_buf_info(iv_obj_t *ps_dec_hdl,
1426                                                    imvcd_get_buf_info_ip_t *ps_ip,
1427                                                    imvcd_get_buf_info_op_t *ps_op)
1428 {
1429     UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS];
1430     UWORD32 u4_pic_wd, u4_pic_ht;
1431     UWORD32 i;
1432 
1433     mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
1434     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
1435 
1436     UNUSED(ps_ip);
1437 
1438     ps_op->s_ivd_op.u4_error_code = 0;
1439 
1440     ps_op->s_ivd_op.u4_num_disp_bufs = 0;
1441     ps_op->s_ivd_op.u4_min_num_in_bufs = MIN_IN_BUFS;
1442 
1443     u4_pic_wd = 0;
1444     u4_pic_ht = 0;
1445 
1446     if(is_header_decoded(ps_view_ctxt->i4_header_decoded, SPS))
1447     {
1448         u4_pic_wd = ps_view_ctxt->u2_disp_width;
1449         u4_pic_ht = ps_view_ctxt->u2_disp_height;
1450     }
1451 
1452     ps_op->s_mvc_buf_info.u2_num_views = ps_mvcd_ctxt->u2_num_views;
1453 
1454     for(i = 0; i < ps_op->s_ivd_op.u4_min_num_in_bufs; i++)
1455     {
1456         ps_op->s_ivd_op.u4_min_in_buf_size[i] =
1457             MAX(256000, u4_pic_wd * u4_pic_ht * ps_mvcd_ctxt->u2_num_views * 3 / 2);
1458     }
1459 
1460     ps_op->s_ivd_op.u4_min_num_out_bufs = ih264d_get_outbuf_size(
1461         u4_pic_wd, u4_pic_ht, ps_view_ctxt->u1_chroma_format, &au4_min_out_buf_size[0]);
1462     ps_op->s_ivd_op.u4_min_num_out_bufs *= ps_mvcd_ctxt->u2_num_views;
1463 
1464     for(i = 0; i < ps_op->s_ivd_op.u4_min_num_out_bufs; i++)
1465     {
1466         ps_op->s_ivd_op.u4_min_out_buf_size[i] = au4_min_out_buf_size[i % NUM_COMPONENTS];
1467     }
1468 
1469     return IV_SUCCESS;
1470 }
1471 
imvcd_ctl_get_vui(iv_obj_t * ps_dec_hdl,imvcd_get_vui_ip_t * ps_ip,imvcd_get_vui_op_t * ps_op)1472 static IV_API_CALL_STATUS_T imvcd_ctl_get_vui(iv_obj_t *ps_dec_hdl, imvcd_get_vui_ip_t *ps_ip,
1473                                               imvcd_get_vui_op_t *ps_op)
1474 {
1475     mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
1476     dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
1477 
1478     UNUSED(ps_ip);
1479 
1480     ps_op->u4_error_code = 0;
1481     ps_op->b_is_vui_available = false;
1482 
1483     if((ps_mvcd_ctxt->u1_num_sps > 0) && ps_view_ctxt->ps_cur_sps)
1484     {
1485         ps_op->b_is_vui_available = ps_view_ctxt->ps_cur_sps->u1_vui_parameters_present_flag;
1486 
1487         if(ps_op->b_is_vui_available)
1488         {
1489             ps_op->u1_aspect_ratio_idc = ps_view_ctxt->ps_cur_sps->s_vui.u1_aspect_ratio_idc;
1490             ps_op->u2_sar_width = ps_view_ctxt->ps_cur_sps->s_vui.u2_sar_width;
1491             ps_op->u2_sar_height = ps_view_ctxt->ps_cur_sps->s_vui.u2_sar_height;
1492             ps_op->u1_overscan_appropriate_flag =
1493                 ps_view_ctxt->ps_cur_sps->s_vui.u1_overscan_appropriate_flag;
1494             ps_op->u1_video_format = ps_view_ctxt->ps_cur_sps->s_vui.u1_video_format;
1495             ps_op->u1_video_full_range_flag =
1496                 ps_view_ctxt->ps_cur_sps->s_vui.u1_video_full_range_flag;
1497             ps_op->u1_colour_primaries = ps_view_ctxt->ps_cur_sps->s_vui.u1_colour_primaries;
1498             ps_op->u1_tfr_chars = ps_view_ctxt->ps_cur_sps->s_vui.u1_tfr_chars;
1499             ps_op->u1_matrix_coeffs = ps_view_ctxt->ps_cur_sps->s_vui.u1_matrix_coeffs;
1500             ps_op->u1_cr_top_field = ps_view_ctxt->ps_cur_sps->s_vui.u1_cr_top_field;
1501             ps_op->u1_cr_bottom_field = ps_view_ctxt->ps_cur_sps->s_vui.u1_cr_bottom_field;
1502             ps_op->u4_num_units_in_tick = ps_view_ctxt->ps_cur_sps->s_vui.u4_num_units_in_tick;
1503             ps_op->u4_time_scale = ps_view_ctxt->ps_cur_sps->s_vui.u4_time_scale;
1504             ps_op->u1_fixed_frame_rate_flag =
1505                 ps_view_ctxt->ps_cur_sps->s_vui.u1_fixed_frame_rate_flag;
1506             ps_op->u1_nal_hrd_params_present =
1507                 ps_view_ctxt->ps_cur_sps->s_vui.u1_nal_hrd_params_present;
1508             ps_op->u1_vcl_hrd_params_present =
1509                 ps_view_ctxt->ps_cur_sps->s_vui.u1_vcl_hrd_params_present;
1510             ps_op->u1_low_delay_hrd_flag = ps_view_ctxt->ps_cur_sps->s_vui.u1_low_delay_hrd_flag;
1511             ps_op->u1_pic_struct_present_flag =
1512                 ps_view_ctxt->ps_cur_sps->s_vui.u1_pic_struct_present_flag;
1513             ps_op->u1_bitstream_restriction_flag =
1514                 ps_view_ctxt->ps_cur_sps->s_vui.u1_bitstream_restriction_flag;
1515             ps_op->u1_mv_over_pic_boundaries_flag =
1516                 ps_view_ctxt->ps_cur_sps->s_vui.u1_mv_over_pic_boundaries_flag;
1517             ps_op->u4_max_bytes_per_pic_denom =
1518                 ps_view_ctxt->ps_cur_sps->s_vui.u4_max_bytes_per_pic_denom;
1519             ps_op->u4_max_bits_per_mb_denom =
1520                 ps_view_ctxt->ps_cur_sps->s_vui.u4_max_bits_per_mb_denom;
1521             ps_op->u4_log2_max_mv_length_horz =
1522                 ps_view_ctxt->ps_cur_sps->s_vui.u4_log2_max_mv_length_horz;
1523             ps_op->u4_log2_max_mv_length_vert =
1524                 ps_view_ctxt->ps_cur_sps->s_vui.u4_log2_max_mv_length_vert;
1525             ps_op->u4_num_reorder_frames = ps_view_ctxt->ps_cur_sps->s_vui.u4_num_reorder_frames;
1526             ps_op->u4_max_dec_frame_buffering =
1527                 ps_view_ctxt->ps_cur_sps->s_vui.u4_max_dec_frame_buffering;
1528         }
1529     }
1530 
1531     return IV_SUCCESS;
1532 }
1533 
1534 /* Description - 'Control Cmd' API for MVC Decoder */
imvcd_ctl_cmd_handler(iv_obj_t * ps_dec_hdl,void * pv_ip,void * pv_op)1535 static IV_API_CALL_STATUS_T imvcd_ctl_cmd_handler(iv_obj_t *ps_dec_hdl, void *pv_ip, void *pv_op)
1536 {
1537     ivd_ctl_set_config_ip_t *ps_ip = (ivd_ctl_set_config_ip_t *) pv_ip;
1538 
1539     WORD32 i4_sub_cmd = ps_ip->e_sub_cmd;
1540 
1541     if(IV_SUCCESS != imvcd_check_dec_handle(ps_dec_hdl))
1542     {
1543         return IV_FAIL;
1544     }
1545 
1546     if(IV_SUCCESS != imvcd_check_ctl_structs(pv_ip, pv_op))
1547     {
1548         return IV_FAIL;
1549     }
1550 
1551     switch(i4_sub_cmd)
1552     {
1553         case IVD_CMD_CTL_SETPARAMS:
1554         {
1555             return imvcd_ctl_set_dec_mode(ps_dec_hdl, pv_ip, pv_op);
1556         }
1557         case IMVCD_CTL_SET_NUM_CORES:
1558         {
1559             return imvcd_ctl_set_num_cores(ps_dec_hdl, pv_ip, pv_op);
1560         }
1561         case IMVCD_CTL_SET_PROCESSOR:
1562         {
1563             return imvcd_ctl_set_arch(ps_dec_hdl, pv_ip, pv_op);
1564         }
1565         case IMVCD_CTL_DEGRADE:
1566         {
1567             return imvcd_ctl_set_degrade_mode(ps_dec_hdl, pv_ip, pv_op);
1568         }
1569         case IVD_CMD_CTL_FLUSH:
1570         {
1571             return imvcd_ctl_flush_dec(ps_dec_hdl, pv_ip, pv_op);
1572         }
1573         case IVD_CMD_CTL_GETBUFINFO:
1574         {
1575             return imvcd_ctl_get_buf_info(ps_dec_hdl, pv_ip, pv_op);
1576         }
1577         case IMVCD_CTL_GET_VUI_PARAMS:
1578         {
1579             return imvcd_ctl_get_vui(ps_dec_hdl, pv_ip, pv_op);
1580         }
1581         default:
1582         {
1583             return IV_FAIL;
1584         }
1585     }
1586 }
1587 
imvcd_api_function(iv_obj_t * ps_dec_hdl,void * pv_ip,void * pv_op)1588 IV_API_CALL_STATUS_T imvcd_api_function(iv_obj_t *ps_dec_hdl, void *pv_ip, void *pv_op)
1589 {
1590     IVD_API_COMMAND_TYPE_T e_cmd = ((WORD32 *) pv_ip)[1];
1591 
1592     switch(e_cmd)
1593     {
1594         case IVD_CMD_CREATE:
1595         {
1596             return imvcd_create(pv_ip, pv_op);
1597         }
1598         case IVD_CMD_DELETE:
1599         {
1600             return imvcd_delete(ps_dec_hdl);
1601         }
1602         case IVD_CMD_VIDEO_CTL:
1603         {
1604             return imvcd_ctl_cmd_handler(ps_dec_hdl, pv_ip, pv_op);
1605         }
1606         case IVD_CMD_VIDEO_DECODE:
1607         {
1608             return imvcd_decode(ps_dec_hdl, pv_ip, pv_op);
1609         }
1610         default:
1611         {
1612             return IV_FAIL;
1613         }
1614     }
1615 }
1616