xref: /aosp_15_r20/external/libavc/decoder/mvc/imvcd_api_utils.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_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