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_utils.c */
24 /* */
25 /* Description : Utility functions used by 'imvcd_api.c' */
26 /* */
27 /*****************************************************************************/
28 #include <string.h>
29
30 #include "ih264_typedefs.h"
31 #include "iv.h"
32 #include "imvcd.h"
33 #include "ih264_disp_mgr.h"
34 #include "ih264d_structs.h"
35 #include "ih264d_tables.h"
36 #include "ih264d_utils.h"
37 #include "imvcd_structs.h"
38 #include "imvcd_utils.h"
39
imvcd_check_dec_handle(iv_obj_t * ps_handle)40 IV_API_CALL_STATUS_T imvcd_check_dec_handle(iv_obj_t *ps_handle)
41 {
42 if(ps_handle == NULL)
43 {
44 return IV_FAIL;
45 }
46
47 if(ps_handle->pv_codec_handle == NULL)
48 {
49 return IV_FAIL;
50 }
51
52 return IV_SUCCESS;
53 }
54
imvcd_check_create_structs(imvcd_create_ip_t * ps_ip,imvcd_create_op_t * ps_op)55 IV_API_CALL_STATUS_T imvcd_check_create_structs(imvcd_create_ip_t *ps_ip, imvcd_create_op_t *ps_op)
56 {
57 if(NULL == ps_ip)
58 {
59 return IV_FAIL;
60 }
61
62 if(NULL == ps_op)
63 {
64 return IV_FAIL;
65 }
66
67 if(ps_ip->s_ivd_ip.e_output_format != IV_YUV_420P)
68 {
69 return IV_FAIL;
70 }
71
72 if(NULL == ps_ip->s_ivd_ip.pf_aligned_alloc)
73 {
74 return IV_FAIL;
75 }
76
77 if(NULL == ps_ip->s_ivd_ip.pf_aligned_free)
78 {
79 return IV_FAIL;
80 }
81
82 if(0 != ps_ip->s_ivd_ip.u4_share_disp_buf)
83 {
84 return IV_FAIL;
85 }
86
87 return IV_SUCCESS;
88 }
89
imvcd_check_ctl_structs(void * pv_ip,void * pv_op)90 IV_API_CALL_STATUS_T imvcd_check_ctl_structs(void *pv_ip, void *pv_op)
91 {
92 ivd_ctl_set_config_ip_t *ps_ip = (ivd_ctl_set_config_ip_t *) pv_ip;
93 ivd_ctl_set_config_op_t *ps_op = (ivd_ctl_set_config_op_t *) pv_op;
94
95 WORD32 i4_sub_cmd = ps_ip->e_sub_cmd;
96
97 if(NULL == ps_ip)
98 {
99 return IV_FAIL;
100 }
101
102 if(NULL == ps_op)
103 {
104 return IV_FAIL;
105 }
106
107 switch(i4_sub_cmd)
108 {
109 case IVD_CMD_CTL_SETPARAMS:
110 {
111 if((ps_ip->u4_size != sizeof(ivd_ctl_set_config_ip_t)) ||
112 (ps_op->u4_size != sizeof(ivd_ctl_set_config_op_t)))
113 {
114 return IV_FAIL;
115 }
116 else
117 {
118 return IV_SUCCESS;
119 }
120 }
121 case IMVCD_CTL_SET_NUM_CORES:
122 {
123 if((ps_ip->u4_size != sizeof(imvcd_set_num_cores_ip_t)) ||
124 (ps_op->u4_size != sizeof(imvcd_set_num_cores_op_t)))
125 {
126 return IV_FAIL;
127 }
128 else
129 {
130 return IV_SUCCESS;
131 }
132 }
133 case IMVCD_CTL_SET_PROCESSOR:
134 {
135 if((ps_ip->u4_size != sizeof(imvcd_set_arch_ip_t)) ||
136 (ps_op->u4_size != sizeof(imvcd_set_arch_op_t)))
137 {
138 return IV_FAIL;
139 }
140 else
141 {
142 return IV_SUCCESS;
143 }
144 }
145 case IMVCD_CTL_DEGRADE:
146 {
147 if((ps_ip->u4_size != sizeof(imvcd_set_degrade_mode_ip_t)) ||
148 (ps_op->u4_size != sizeof(imvcd_set_degrade_mode_op_t)))
149 {
150 return IV_FAIL;
151 }
152 else
153 {
154 return IV_SUCCESS;
155 }
156 }
157 case IVD_CMD_CTL_FLUSH:
158 {
159 if((ps_ip->u4_size != sizeof(ivd_ctl_flush_ip_t)) ||
160 (ps_op->u4_size != sizeof(ivd_ctl_flush_op_t)))
161 {
162 return IV_FAIL;
163 }
164 else
165 {
166 return IV_SUCCESS;
167 }
168 }
169 case IVD_CMD_CTL_GETBUFINFO:
170 {
171 if((ps_ip->u4_size != sizeof(ivd_ctl_getbufinfo_ip_t)) ||
172 (ps_op->u4_size != sizeof(ivd_ctl_getbufinfo_op_t)))
173 {
174 return IV_FAIL;
175 }
176 else
177 {
178 return IV_SUCCESS;
179 }
180 }
181 case IMVCD_CTL_GET_VUI_PARAMS:
182 {
183 if((ps_ip->u4_size != sizeof(imvcd_get_vui_ip_t)) ||
184 (ps_op->u4_size != sizeof(imvcd_get_vui_op_t)))
185 {
186 return IV_FAIL;
187 }
188 else
189 {
190 return IV_SUCCESS;
191 }
192 }
193 default:
194 {
195 return IV_FAIL;
196 }
197 }
198 }
199
imvcd_check_decode_structs(iv_obj_t * ps_dec_hdl,imvcd_video_decode_ip_t * ps_ip,imvcd_video_decode_op_t * ps_op)200 IV_API_CALL_STATUS_T imvcd_check_decode_structs(iv_obj_t *ps_dec_hdl,
201 imvcd_video_decode_ip_t *ps_ip,
202 imvcd_video_decode_op_t *ps_op)
203 {
204 WORD32 i, j;
205
206 mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
207
208 UWORD16 u2_num_views = 1;
209
210 if(NULL == ps_ip)
211 {
212 return IV_FAIL;
213 }
214
215 if(NULL == ps_op)
216 {
217 return IV_FAIL;
218 }
219
220 if(!ps_mvcd_ctxt->b_flush_enabled && !ps_mvcd_ctxt->b_header_only_decode)
221 {
222 if(NULL == ps_ip->s_ivd_ip.pv_stream_buffer)
223 {
224 return IV_FAIL;
225 }
226
227 for(i = 0; i < u2_num_views; i++)
228 {
229 for(j = 0; j < NUM_COMPONENTS; j++)
230 {
231 if(NULL == ps_ip->s_ivd_ip.s_out_buffer.pu1_bufs[i * NUM_COMPONENTS + j])
232 {
233 return IV_FAIL;
234 }
235 }
236 }
237
238 if(0 == ps_ip->s_ivd_ip.u4_num_Bytes)
239 {
240 return IV_FAIL;
241 }
242 }
243
244 return IV_SUCCESS;
245 }
246
imvcd_convert_app_out_buf(mvc_dec_ctxt_t * ps_mvcd_ctxt,ivd_out_bufdesc_t * ps_app_buffer)247 static void imvcd_convert_app_out_buf(mvc_dec_ctxt_t *ps_mvcd_ctxt,
248 ivd_out_bufdesc_t *ps_app_buffer)
249 {
250 if(!ps_mvcd_ctxt->b_header_only_decode)
251 {
252 WORD32 i, j;
253
254 subset_sps_t *ps_subset_sps = imvcd_get_valid_subset_sps(ps_mvcd_ctxt);
255 dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
256
257 UWORD16 u2_num_views =
258 (NULL == ps_subset_sps) ? 1 : ps_subset_sps->s_sps_mvc_ext.u2_num_views;
259
260 for(i = 0; i < u2_num_views; i++)
261 {
262 yuv_buf_props_t *ps_view_buf = &ps_mvcd_ctxt->s_out_buffer.as_view_buf_props[i];
263
264 ps_view_buf->u1_bit_depth = 8;
265 ps_view_buf->u2_height = ps_view_ctxt->u2_disp_height;
266 ps_view_buf->u2_width = ps_view_ctxt->u2_disp_width;
267
268 for(j = 0; j < NUM_COMPONENTS; j++)
269 {
270 buffer_container_t *ps_component_buf = &ps_view_buf->as_component_bufs[j];
271 bool b_is_chroma = (((COMPONENT_TYPES_T) j) != Y);
272
273 ps_component_buf->pv_data = ps_app_buffer->pu1_bufs[i * NUM_COMPONENTS + j];
274 ps_component_buf->i4_data_stride = ps_view_buf->u2_width >> b_is_chroma;
275 }
276 }
277 }
278 }
279
imvcd_convert_to_app_disp_buf(mvc_dec_ctxt_t * ps_mvcd_ctxt,iv_yuv_buf_t * ps_view_disp_bufs)280 void imvcd_convert_to_app_disp_buf(mvc_dec_ctxt_t *ps_mvcd_ctxt, iv_yuv_buf_t *ps_view_disp_bufs)
281 {
282 WORD32 i;
283
284 UWORD16 u2_num_views = ps_mvcd_ctxt->u2_num_views;
285
286 for(i = 0; i < u2_num_views; i++)
287 {
288 yuv_buf_props_t *ps_view_buf = &ps_mvcd_ctxt->s_out_buffer.as_view_buf_props[i];
289
290 ps_view_disp_bufs[i].u4_size = sizeof(ps_view_disp_bufs[i]);
291
292 ps_view_disp_bufs[i].pv_y_buf = ps_view_buf->as_component_bufs[Y].pv_data;
293 ps_view_disp_bufs[i].u4_y_strd = ps_view_buf->as_component_bufs[Y].i4_data_stride;
294 ps_view_disp_bufs[i].u4_y_wd = ps_view_buf->u2_width;
295 ps_view_disp_bufs[i].u4_y_ht = ps_view_buf->u2_height;
296
297 ps_view_disp_bufs[i].pv_u_buf = ps_view_buf->as_component_bufs[U].pv_data;
298 ps_view_disp_bufs[i].u4_u_strd = ps_view_buf->as_component_bufs[U].i4_data_stride;
299 ps_view_disp_bufs[i].u4_u_wd = ps_view_buf->u2_width / 2;
300 ps_view_disp_bufs[i].u4_u_ht = ps_view_buf->u2_height / 2;
301
302 ps_view_disp_bufs[i].pv_v_buf = ps_view_buf->as_component_bufs[V].pv_data;
303 ps_view_disp_bufs[i].u4_v_strd = ps_view_buf->as_component_bufs[V].i4_data_stride;
304 ps_view_disp_bufs[i].u4_v_wd = ps_view_buf->u2_width / 2;
305 ps_view_disp_bufs[i].u4_v_ht = ps_view_buf->u2_height / 2;
306 }
307 }
308
imvcd_au_init(iv_obj_t * ps_dec_hdl,imvcd_video_decode_ip_t * ps_ip,imvcd_video_decode_op_t * ps_op)309 void imvcd_au_init(iv_obj_t *ps_dec_hdl, imvcd_video_decode_ip_t *ps_ip,
310 imvcd_video_decode_op_t *ps_op)
311 {
312 subset_sps_t *ps_subset_sps;
313
314 mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
315 dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
316
317 ps_mvcd_ctxt->u2_num_views_decoded = 0;
318 ps_subset_sps = imvcd_get_valid_subset_sps(ps_mvcd_ctxt);
319 ps_mvcd_ctxt->u2_num_views =
320 (NULL == ps_subset_sps) ? 1 : ps_subset_sps->s_sps_mvc_ext.u2_num_views;
321 imvcd_convert_app_out_buf(ps_mvcd_ctxt, &ps_ip->s_ivd_ip.s_out_buffer);
322
323 ps_op->s_ivd_op.u4_num_bytes_consumed = 0;
324 ps_op->s_ivd_op.u4_output_present = 0;
325 ps_op->s_ivd_op.u4_error_code = 0;
326 ps_op->s_ivd_op.e_pic_type = IV_FRAMETYPE_DEFAULT;
327 ps_op->s_ivd_op.u4_frame_decoded_flag = 0;
328 ps_op->s_ivd_op.u4_new_seq = 0;
329 ps_op->s_ivd_op.u4_progressive_frame_flag = 1;
330 ps_op->s_ivd_op.u4_is_ref_flag = 1;
331 ps_op->s_ivd_op.e4_fld_type = IV_NA_FLD;
332
333 ps_view_ctxt->u4_fmt_conv_cur_row = 0;
334 ps_view_ctxt->u4_output_present = 0;
335 ps_view_ctxt->u4_fmt_conv_num_rows = FMT_CONV_NUM_ROWS;
336 ps_view_ctxt->u4_ts = ps_ip->s_ivd_ip.u4_ts;
337 ps_view_ctxt->i4_frametype = IV_NA_FRAME;
338 ps_view_ctxt->i4_content_type = IV_CONTENTTYPE_NA;
339
340 /* Mimicking the hack in lines '2005' in 'ih264d_api.c' and '1323' in
341 * 'ih264d_parse_headers.c */
342 ps_view_ctxt->u4_sps_cnt_in_process = 0;
343
344 memset(ps_mvcd_ctxt->as_nalu_mvc_ext, 0, sizeof(ps_mvcd_ctxt->as_nalu_mvc_ext));
345 }
346
imvcd_view_init(mvc_dec_ctxt_t * ps_mvcd_ctxt)347 void imvcd_view_init(mvc_dec_ctxt_t *ps_mvcd_ctxt)
348 {
349 dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
350
351 ps_view_ctxt->u4_num_fld_in_frm = 0;
352 ps_view_ctxt->u4_slice_start_code_found = 0;
353 ps_view_ctxt->u2_cur_mb_addr = 0;
354 ps_view_ctxt->u2_total_mbs_coded = 0;
355 ps_view_ctxt->u2_cur_slice_num = 0;
356 ps_view_ctxt->cur_dec_mb_num = 0;
357 ps_view_ctxt->cur_recon_mb_num = 0;
358 ps_view_ctxt->u4_first_slice_in_pic = 1;
359 ps_view_ctxt->u1_slice_header_done = 0;
360 ps_view_ctxt->u1_dangling_field = 0;
361 ps_view_ctxt->u4_dec_thread_created = 0;
362 ps_view_ctxt->u4_bs_deblk_thread_created = 0;
363 ps_view_ctxt->u4_cur_bs_mb_num = 0;
364 ps_view_ctxt->u4_start_recon_deblk = 0;
365 ps_view_ctxt->u4_pic_buf_got = 0;
366 ps_view_ctxt->pu1_inv_scan = (UWORD8 *) gau1_ih264d_inv_scan;
367 ps_view_ctxt->u1_pic_decode_done = 0;
368
369 ps_view_ctxt->pu1_init_dpb_base = NULL;
370 ps_view_ctxt->ps_dpb_mgr = NULL;
371 }
372
imvcd_bitstream_buf_alloc(dec_struct_t * ps_view_ctxt,UWORD16 u2_num_views)373 IV_API_CALL_STATUS_T imvcd_bitstream_buf_alloc(dec_struct_t *ps_view_ctxt, UWORD16 u2_num_views)
374 {
375 UWORD32 u4_size;
376
377 u4_size = MAX(MIN_BITSTREAMS_BUF_SIZE,
378 ((ps_view_ctxt->u2_pic_wd * ps_view_ctxt->u2_pic_ht * 3 / 2) + EXTRA_BS_OFFSET) *
379 u2_num_views * sizeof(ps_view_ctxt->pu1_bits_buf_dynamic[0]));
380 ps_view_ctxt->pu1_bits_buf_dynamic =
381 ps_view_ctxt->pf_aligned_alloc(ps_view_ctxt->pv_mem_ctxt, 128, u4_size);
382 RETURN_IF((NULL == ps_view_ctxt->pu1_bits_buf_dynamic), IV_FAIL);
383
384 memset(ps_view_ctxt->pu1_bits_buf_dynamic, 0, u4_size);
385 ps_view_ctxt->u4_dynamic_bits_buf_size = u4_size;
386
387 return IV_SUCCESS;
388 }
389
imvcd_bitsteam_buf_free(dec_struct_t * ps_view_ctxt)390 void imvcd_bitsteam_buf_free(dec_struct_t *ps_view_ctxt)
391 {
392 PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_bits_buf_dynamic);
393 }
394
imvcd_bitstream_buf_realloc(dec_struct_t * ps_view_ctxt,UWORD32 u4_size)395 IV_API_CALL_STATUS_T imvcd_bitstream_buf_realloc(dec_struct_t *ps_view_ctxt, UWORD32 u4_size)
396 {
397 imvcd_bitsteam_buf_free(ps_view_ctxt);
398
399 u4_size = MAX(MIN_BITSTREAMS_BUF_SIZE, u4_size);
400
401 ps_view_ctxt->pu1_bits_buf_dynamic =
402 ps_view_ctxt->pf_aligned_alloc(ps_view_ctxt->pv_mem_ctxt, 128, u4_size);
403 RETURN_IF((NULL == ps_view_ctxt->pu1_bits_buf_dynamic), IV_FAIL);
404
405 memset(ps_view_ctxt->pu1_bits_buf_dynamic, 0, u4_size);
406 ps_view_ctxt->u4_dynamic_bits_buf_size = u4_size;
407
408 return IV_SUCCESS;
409 }
410