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