1 /******************************************************************************
2 *
3 * Copyright (C) 2015 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 : ih264d_api.c */
24 /* */
25 /* Description : Has all API related functions */
26 /* */
27 /* */
28 /* List of Functions : api_check_struct_sanity */
29 /* ih264d_set_processor */
30 /* ih264d_create */
31 /* ih264d_delete */
32 /* ih264d_init */
33 /* ih264d_map_error */
34 /* ih264d_video_decode */
35 /* ih264d_get_version */
36 /* ih264d_get_display_frame */
37 /* ih264d_set_display_frame */
38 /* ih264d_set_flush_mode */
39 /* ih264d_get_status */
40 /* ih264d_get_buf_info */
41 /* ih264d_set_params */
42 /* ih264d_set_default_params */
43 /* ih264d_reset */
44 /* ih264d_ctl */
45 /* ih264d_rel_display_frame */
46 /* ih264d_set_degrade */
47 /* ih264d_get_frame_dimensions */
48 /* ih264d_set_num_cores */
49 /* ih264d_fill_output_struct_from_context */
50 /* ih264d_api_function */
51 /* */
52 /* Issues / Problems : None */
53 /* */
54 /* Revision History : */
55 /* */
56 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
57 /* 14 10 2008 100356(SKV) Draft */
58 /* */
59 /*****************************************************************************/
60 #include "ih264_typedefs.h"
61 #include "ih264_macros.h"
62 #include "ih264_platform_macros.h"
63 #include "ih264d_tables.h"
64 #include "iv.h"
65 #include "ivd.h"
66 #include "ih264d.h"
67 #include "ih264d_defs.h"
68
69 #include <string.h>
70 #include <limits.h>
71 #include <stddef.h>
72
73 #include "ih264d_inter_pred.h"
74
75 #include "ih264d_structs.h"
76 #include "ih264d_nal.h"
77 #include "ih264d_error_handler.h"
78
79 #include "ih264d_defs.h"
80
81 #include "ithread.h"
82 #include "ih264d_parse_slice.h"
83 #include "ih264d_function_selector.h"
84 #include "ih264_error.h"
85 #include "ih264_disp_mgr.h"
86 #include "ih264_buf_mgr.h"
87 #include "ih264d_deblocking.h"
88 #include "ih264d_parse_cavlc.h"
89 #include "ih264d_parse_cabac.h"
90 #include "ih264d_utils.h"
91 #include "ih264d_format_conv.h"
92 #include "ih264d_parse_headers.h"
93 #include "ih264d_thread_compute_bs.h"
94 #include <assert.h>
95
96
97 /*********************/
98 /* Codec Versioning */
99 /*********************/
100 //Move this to where it is used
101 #define CODEC_NAME "H264VDEC"
102 #define CODEC_RELEASE_TYPE "production"
103 #define CODEC_RELEASE_VER "05.00"
104 #define CODEC_VENDOR "ITTIAM"
105 #define MAXVERSION_STRLEN 511
106 #ifdef ANDROID
107 #define VERSION(version_string, codec_name, codec_release_type, codec_release_ver, codec_vendor) \
108 snprintf(version_string, MAXVERSION_STRLEN, \
109 "@(#)Id:%s_%s Ver:%s Released by %s", \
110 codec_name, codec_release_type, codec_release_ver, codec_vendor)
111 #else
112 #define VERSION(version_string, codec_name, codec_release_type, codec_release_ver, codec_vendor) \
113 snprintf(version_string, MAXVERSION_STRLEN, \
114 "@(#)Id:%s_%s Ver:%s Released by %s Build: %s @ %s", \
115 codec_name, codec_release_type, codec_release_ver, codec_vendor, __DATE__, __TIME__)
116 #endif
117
118
119 #define MIN_IN_BUFS 1
120 #define MIN_OUT_BUFS_420 3
121 #define MIN_OUT_BUFS_422ILE 1
122 #define MIN_OUT_BUFS_RGB565 1
123 #define MIN_OUT_BUFS_420SP 2
124
125 #define NUM_FRAMES_LIMIT_ENABLED 0
126
127 #if NUM_FRAMES_LIMIT_ENABLED
128 #define NUM_FRAMES_LIMIT 10000
129 #else
130 #define NUM_FRAMES_LIMIT 0x7FFFFFFF
131 #endif
132
133
134 UWORD32 ih264d_get_extra_mem_external(UWORD32 width, UWORD32 height);
135 WORD32 ih264d_get_frame_dimensions(iv_obj_t *dec_hdl,
136 void *pv_api_ip,
137 void *pv_api_op);
138 WORD32 ih264d_get_vui_params(iv_obj_t *dec_hdl,
139 void *pv_api_ip,
140 void *pv_api_op);
141
142 WORD32 ih264d_get_sei_mdcv_params(iv_obj_t *dec_hdl,
143 void *pv_api_ip,
144 void *pv_api_op);
145
146 WORD32 ih264d_get_sei_cll_params(iv_obj_t *dec_hdl,
147 void *pv_api_ip,
148 void *pv_api_op);
149
150 WORD32 ih264d_get_sei_ave_params(iv_obj_t *dec_hdl,
151 void *pv_api_ip,
152 void *pv_api_op);
153
154 WORD32 ih264d_get_sei_ccv_params(iv_obj_t *dec_hdl,
155 void *pv_api_ip,
156 void *pv_api_op);
157
158 WORD32 ih264d_get_sei_sii_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
159
160 WORD32 ih264d_get_sei_fgc_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
161
162 WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
163
164 WORD32 ih264d_deblock_display(dec_struct_t *ps_dec);
165
166 void ih264d_signal_decode_thread(dec_struct_t *ps_dec);
167
168 void ih264d_signal_bs_deblk_thread(dec_struct_t *ps_dec);
169 void ih264d_decode_picture_thread(dec_struct_t *ps_dec);
170
171 WORD32 ih264d_set_degrade(iv_obj_t *ps_codec_obj,
172 void *pv_api_ip,
173 void *pv_api_op);
174
175 void ih264d_fill_output_struct_from_context(dec_struct_t *ps_dec,
176 ivd_video_decode_op_t *ps_dec_op);
177
178 /*!
179 **************************************************************************
180 * \if Function name : ih264d_export_sei_params \endif
181 *
182 * \brief
183 * Exports sei params from decoder to application.
184 *
185 * \return
186 * 0 on Success and error code otherwise
187 **************************************************************************
188 */
189
ih264d_export_sei_params(ivd_sei_decode_op_t * ps_sei_decode_op,dec_struct_t * ps_dec)190 void ih264d_export_sei_params(ivd_sei_decode_op_t *ps_sei_decode_op, dec_struct_t *ps_dec)
191 {
192 WORD32 i4_status = IV_SUCCESS;
193 sei *ps_sei = (sei *)ps_dec->pv_disp_sei_params;
194
195 i4_status = ih264d_export_sei_mdcv_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export);
196 i4_status = ih264d_export_sei_cll_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export);
197 i4_status = ih264d_export_sei_ave_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export);
198 i4_status = ih264d_export_sei_ccv_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export);
199 i4_status = ih264d_export_sei_sii_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export);
200 i4_status = ih264d_export_sei_fgc_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export);
201
202 UNUSED(i4_status);
203 }
204
api_check_struct_sanity(iv_obj_t * ps_handle,void * pv_api_ip,void * pv_api_op)205 static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
206 void *pv_api_ip,
207 void *pv_api_op)
208 {
209 IVD_API_COMMAND_TYPE_T e_cmd;
210 UWORD32 *pu4_api_ip;
211 UWORD32 *pu4_api_op;
212 UWORD32 i, j;
213
214 if(NULL == pv_api_op)
215 return (IV_FAIL);
216
217 if(NULL == pv_api_ip)
218 return (IV_FAIL);
219
220 pu4_api_ip = (UWORD32 *)pv_api_ip;
221 pu4_api_op = (UWORD32 *)pv_api_op;
222 e_cmd = *(pu4_api_ip + 1);
223
224 /* error checks on handle */
225 switch((WORD32)e_cmd)
226 {
227 case IVD_CMD_CREATE:
228 break;
229
230 case IVD_CMD_REL_DISPLAY_FRAME:
231 case IVD_CMD_SET_DISPLAY_FRAME:
232 case IVD_CMD_GET_DISPLAY_FRAME:
233 case IVD_CMD_VIDEO_DECODE:
234 case IVD_CMD_DELETE:
235 case IVD_CMD_VIDEO_CTL:
236 if(ps_handle == NULL)
237 {
238 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
239 *(pu4_api_op + 1) |= IVD_HANDLE_NULL;
240 return IV_FAIL;
241 }
242
243 if(ps_handle->u4_size != sizeof(iv_obj_t))
244 {
245 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
246 *(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT;
247 return IV_FAIL;
248 }
249
250 if(ps_handle->pv_fxns != ih264d_api_function)
251 {
252 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
253 *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL;
254 return IV_FAIL;
255 }
256
257 if(ps_handle->pv_codec_handle == NULL)
258 {
259 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
260 *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL;
261 return IV_FAIL;
262 }
263 break;
264 default:
265 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
266 *(pu4_api_op + 1) |= IVD_INVALID_API_CMD;
267 return IV_FAIL;
268 }
269
270 switch((WORD32)e_cmd)
271 {
272 case IVD_CMD_CREATE:
273 {
274 ih264d_create_ip_t *ps_ip = (ih264d_create_ip_t *)pv_api_ip;
275 ih264d_create_op_t *ps_op = (ih264d_create_op_t *)pv_api_op;
276
277
278 ps_op->s_ivd_create_op_t.u4_error_code = 0;
279
280 if((ps_ip->s_ivd_create_ip_t.u4_size > sizeof(ih264d_create_ip_t))
281 || (ps_ip->s_ivd_create_ip_t.u4_size
282 < sizeof(ivd_create_ip_t)))
283 {
284 ps_op->s_ivd_create_op_t.u4_error_code |= 1
285 << IVD_UNSUPPORTEDPARAM;
286 ps_op->s_ivd_create_op_t.u4_error_code |=
287 IVD_IP_API_STRUCT_SIZE_INCORRECT;
288 H264_DEC_DEBUG_PRINT("\n");
289 return (IV_FAIL);
290 }
291
292 if((ps_op->s_ivd_create_op_t.u4_size != sizeof(ih264d_create_op_t))
293 && (ps_op->s_ivd_create_op_t.u4_size
294 != sizeof(ivd_create_op_t)))
295 {
296 ps_op->s_ivd_create_op_t.u4_error_code |= 1
297 << IVD_UNSUPPORTEDPARAM;
298 ps_op->s_ivd_create_op_t.u4_error_code |=
299 IVD_OP_API_STRUCT_SIZE_INCORRECT;
300 H264_DEC_DEBUG_PRINT("\n");
301 return (IV_FAIL);
302 }
303
304
305 if((ps_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420P)
306 && (ps_ip->s_ivd_create_ip_t.e_output_format
307 != IV_YUV_422ILE)
308 && (ps_ip->s_ivd_create_ip_t.e_output_format
309 != IV_RGB_565)
310 && (ps_ip->s_ivd_create_ip_t.e_output_format
311 != IV_YUV_420SP_UV)
312 && (ps_ip->s_ivd_create_ip_t.e_output_format
313 != IV_YUV_420SP_VU))
314 {
315 ps_op->s_ivd_create_op_t.u4_error_code |= 1
316 << IVD_UNSUPPORTEDPARAM;
317 ps_op->s_ivd_create_op_t.u4_error_code |=
318 IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED;
319 H264_DEC_DEBUG_PRINT("\n");
320 return (IV_FAIL);
321 }
322
323 }
324 break;
325
326 case IVD_CMD_GET_DISPLAY_FRAME:
327 {
328 ih264d_get_display_frame_ip_t *ps_ip =
329 (ih264d_get_display_frame_ip_t *)pv_api_ip;
330 ih264d_get_display_frame_op_t *ps_op =
331 (ih264d_get_display_frame_op_t *)pv_api_op;
332
333 ps_op->s_ivd_get_display_frame_op_t.u4_error_code = 0;
334
335 if((ps_ip->s_ivd_get_display_frame_ip_t.u4_size
336 != sizeof(ih264d_get_display_frame_ip_t))
337 && (ps_ip->s_ivd_get_display_frame_ip_t.u4_size
338 != sizeof(ivd_get_display_frame_ip_t)))
339 {
340 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
341 << IVD_UNSUPPORTEDPARAM;
342 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
343 IVD_IP_API_STRUCT_SIZE_INCORRECT;
344 return (IV_FAIL);
345 }
346
347 if((ps_op->s_ivd_get_display_frame_op_t.u4_size
348 != sizeof(ih264d_get_display_frame_op_t))
349 && (ps_op->s_ivd_get_display_frame_op_t.u4_size
350 != sizeof(ivd_get_display_frame_op_t)))
351 {
352 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
353 << IVD_UNSUPPORTEDPARAM;
354 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
355 IVD_OP_API_STRUCT_SIZE_INCORRECT;
356 return (IV_FAIL);
357 }
358 }
359 break;
360
361 case IVD_CMD_REL_DISPLAY_FRAME:
362 {
363 ih264d_rel_display_frame_ip_t *ps_ip =
364 (ih264d_rel_display_frame_ip_t *)pv_api_ip;
365 ih264d_rel_display_frame_op_t *ps_op =
366 (ih264d_rel_display_frame_op_t *)pv_api_op;
367
368 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code = 0;
369
370 if((ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
371 != sizeof(ih264d_rel_display_frame_ip_t))
372 && (ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
373 != sizeof(ivd_rel_display_frame_ip_t)))
374 {
375 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
376 << IVD_UNSUPPORTEDPARAM;
377 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
378 IVD_IP_API_STRUCT_SIZE_INCORRECT;
379 return (IV_FAIL);
380 }
381
382 if((ps_op->s_ivd_rel_display_frame_op_t.u4_size
383 != sizeof(ih264d_rel_display_frame_op_t))
384 && (ps_op->s_ivd_rel_display_frame_op_t.u4_size
385 != sizeof(ivd_rel_display_frame_op_t)))
386 {
387 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
388 << IVD_UNSUPPORTEDPARAM;
389 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
390 IVD_OP_API_STRUCT_SIZE_INCORRECT;
391 return (IV_FAIL);
392 }
393
394 }
395 break;
396
397 case IVD_CMD_SET_DISPLAY_FRAME:
398 {
399 ih264d_set_display_frame_ip_t *ps_ip =
400 (ih264d_set_display_frame_ip_t *)pv_api_ip;
401 ih264d_set_display_frame_op_t *ps_op =
402 (ih264d_set_display_frame_op_t *)pv_api_op;
403 UWORD32 j;
404
405 ps_op->s_ivd_set_display_frame_op_t.u4_error_code = 0;
406
407 if((ps_ip->s_ivd_set_display_frame_ip_t.u4_size
408 != sizeof(ih264d_set_display_frame_ip_t))
409 && (ps_ip->s_ivd_set_display_frame_ip_t.u4_size
410 != sizeof(ivd_set_display_frame_ip_t)))
411 {
412 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
413 << IVD_UNSUPPORTEDPARAM;
414 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
415 IVD_IP_API_STRUCT_SIZE_INCORRECT;
416 return (IV_FAIL);
417 }
418
419 if((ps_op->s_ivd_set_display_frame_op_t.u4_size
420 != sizeof(ih264d_set_display_frame_op_t))
421 && (ps_op->s_ivd_set_display_frame_op_t.u4_size
422 != sizeof(ivd_set_display_frame_op_t)))
423 {
424 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
425 << IVD_UNSUPPORTEDPARAM;
426 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
427 IVD_OP_API_STRUCT_SIZE_INCORRECT;
428 return (IV_FAIL);
429 }
430
431 if(ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs == 0)
432 {
433 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
434 << IVD_UNSUPPORTEDPARAM;
435 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
436 IVD_DISP_FRM_ZERO_OP_BUFS;
437 return IV_FAIL;
438 }
439
440 for(j = 0; j < ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs;
441 j++)
442 {
443 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs
444 == 0)
445 {
446 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
447 << IVD_UNSUPPORTEDPARAM;
448 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
449 IVD_DISP_FRM_ZERO_OP_BUFS;
450 return IV_FAIL;
451 }
452
453 for(i = 0;
454 i
455 < ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs;
456 i++)
457 {
458 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].pu1_bufs[i]
459 == NULL)
460 {
461 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
462 << IVD_UNSUPPORTEDPARAM;
463 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
464 IVD_DISP_FRM_OP_BUF_NULL;
465 return IV_FAIL;
466 }
467
468 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_min_out_buf_size[i]
469 == 0)
470 {
471 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
472 << IVD_UNSUPPORTEDPARAM;
473 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
474 IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
475 return IV_FAIL;
476 }
477 }
478 }
479 }
480 break;
481
482 case IVD_CMD_VIDEO_DECODE:
483 {
484 ih264d_video_decode_ip_t *ps_ip =
485 (ih264d_video_decode_ip_t *)pv_api_ip;
486 ih264d_video_decode_op_t *ps_op =
487 (ih264d_video_decode_op_t *)pv_api_op;
488
489 H264_DEC_DEBUG_PRINT("The input bytes is: %d",
490 ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes);
491 ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
492
493 if(ps_ip->s_ivd_video_decode_ip_t.u4_size != sizeof(ih264d_video_decode_ip_t) &&
494 ps_ip->s_ivd_video_decode_ip_t.u4_size != sizeof(ivd_video_decode_ip_t) &&
495 ps_ip->s_ivd_video_decode_ip_t.u4_size !=
496 offsetof(ivd_video_decode_ip_t, s_out_buffer))
497 {
498 ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
499 << IVD_UNSUPPORTEDPARAM;
500 ps_op->s_ivd_video_decode_op_t.u4_error_code |=
501 IVD_IP_API_STRUCT_SIZE_INCORRECT;
502 return (IV_FAIL);
503 }
504
505 if(ps_op->s_ivd_video_decode_op_t.u4_size != sizeof(ih264d_video_decode_op_t) &&
506 ps_op->s_ivd_video_decode_op_t.u4_size != sizeof(ivd_video_decode_op_t) &&
507 ps_op->s_ivd_video_decode_op_t.u4_size !=
508 offsetof(ivd_video_decode_op_t, u4_output_present))
509 {
510 ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
511 << IVD_UNSUPPORTEDPARAM;
512 ps_op->s_ivd_video_decode_op_t.u4_error_code |=
513 IVD_OP_API_STRUCT_SIZE_INCORRECT;
514 return (IV_FAIL);
515 }
516
517 {
518 dec_struct_t *ps_dec = (dec_struct_t *)(ps_handle->pv_codec_handle);
519 if(ps_dec->u1_enable_mb_info)
520 {
521 if(!ps_ip->pu1_8x8_blk_qp_map && !ps_ip->pu1_8x8_blk_type_map)
522 {
523 ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
524 << IVD_UNSUPPORTEDPARAM;
525 ps_op->s_ivd_video_decode_op_t.u4_error_code |=
526 IH264D_FRAME_INFO_OP_BUF_NULL;
527 return IV_FAIL;
528 }
529 }
530 }
531 }
532 break;
533
534 case IVD_CMD_DELETE:
535 {
536 ih264d_delete_ip_t *ps_ip =
537 (ih264d_delete_ip_t *)pv_api_ip;
538 ih264d_delete_op_t *ps_op =
539 (ih264d_delete_op_t *)pv_api_op;
540
541 ps_op->s_ivd_delete_op_t.u4_error_code = 0;
542
543 if(ps_ip->s_ivd_delete_ip_t.u4_size
544 != sizeof(ih264d_delete_ip_t))
545 {
546 ps_op->s_ivd_delete_op_t.u4_error_code |= 1
547 << IVD_UNSUPPORTEDPARAM;
548 ps_op->s_ivd_delete_op_t.u4_error_code |=
549 IVD_IP_API_STRUCT_SIZE_INCORRECT;
550 return (IV_FAIL);
551 }
552
553 if(ps_op->s_ivd_delete_op_t.u4_size
554 != sizeof(ih264d_delete_op_t))
555 {
556 ps_op->s_ivd_delete_op_t.u4_error_code |= 1
557 << IVD_UNSUPPORTEDPARAM;
558 ps_op->s_ivd_delete_op_t.u4_error_code |=
559 IVD_OP_API_STRUCT_SIZE_INCORRECT;
560 return (IV_FAIL);
561 }
562
563 }
564 break;
565
566 case IVD_CMD_VIDEO_CTL:
567 {
568 UWORD32 *pu4_ptr_cmd;
569 UWORD32 sub_command;
570
571 pu4_ptr_cmd = (UWORD32 *)pv_api_ip;
572 pu4_ptr_cmd += 2;
573 sub_command = *pu4_ptr_cmd;
574
575 switch(sub_command)
576 {
577 case IVD_CMD_CTL_SETPARAMS:
578 {
579 ih264d_ctl_set_config_ip_t *ps_ip;
580 ih264d_ctl_set_config_op_t *ps_op;
581 ps_ip = (ih264d_ctl_set_config_ip_t *)pv_api_ip;
582 ps_op = (ih264d_ctl_set_config_op_t *)pv_api_op;
583
584 if(ps_ip->s_ivd_ctl_set_config_ip_t.u4_size
585 != sizeof(ih264d_ctl_set_config_ip_t))
586 {
587 ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1
588 << IVD_UNSUPPORTEDPARAM;
589 ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
590 IVD_IP_API_STRUCT_SIZE_INCORRECT;
591 return IV_FAIL;
592 }
593 }
594 //no break; is needed here
595 case IVD_CMD_CTL_SETDEFAULT:
596 {
597 ih264d_ctl_set_config_op_t *ps_op;
598 ps_op = (ih264d_ctl_set_config_op_t *)pv_api_op;
599 if(ps_op->s_ivd_ctl_set_config_op_t.u4_size
600 != sizeof(ih264d_ctl_set_config_op_t))
601 {
602 ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1
603 << IVD_UNSUPPORTEDPARAM;
604 ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
605 IVD_OP_API_STRUCT_SIZE_INCORRECT;
606 return IV_FAIL;
607 }
608 }
609 break;
610
611 case IVD_CMD_CTL_GETPARAMS:
612 {
613 ih264d_ctl_getstatus_ip_t *ps_ip;
614 ih264d_ctl_getstatus_op_t *ps_op;
615
616 ps_ip = (ih264d_ctl_getstatus_ip_t *)pv_api_ip;
617 ps_op = (ih264d_ctl_getstatus_op_t *)pv_api_op;
618 if(ps_ip->s_ivd_ctl_getstatus_ip_t.u4_size
619 != sizeof(ih264d_ctl_getstatus_ip_t))
620 {
621 ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1
622 << IVD_UNSUPPORTEDPARAM;
623 ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
624 IVD_IP_API_STRUCT_SIZE_INCORRECT;
625 return IV_FAIL;
626 }
627 if(ps_op->s_ivd_ctl_getstatus_op_t.u4_size
628 != sizeof(ih264d_ctl_getstatus_op_t))
629 {
630 ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1
631 << IVD_UNSUPPORTEDPARAM;
632 ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
633 IVD_OP_API_STRUCT_SIZE_INCORRECT;
634 return IV_FAIL;
635 }
636 }
637 break;
638
639 case IVD_CMD_CTL_GETBUFINFO:
640 {
641 ih264d_ctl_getbufinfo_ip_t *ps_ip;
642 ih264d_ctl_getbufinfo_op_t *ps_op;
643 ps_ip = (ih264d_ctl_getbufinfo_ip_t *)pv_api_ip;
644 ps_op = (ih264d_ctl_getbufinfo_op_t *)pv_api_op;
645
646 if(ps_ip->s_ivd_ctl_getbufinfo_ip_t.u4_size
647 != sizeof(ih264d_ctl_getbufinfo_ip_t))
648 {
649 ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1
650 << IVD_UNSUPPORTEDPARAM;
651 ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
652 IVD_IP_API_STRUCT_SIZE_INCORRECT;
653 return IV_FAIL;
654 }
655 if(ps_op->s_ivd_ctl_getbufinfo_op_t.u4_size
656 != sizeof(ih264d_ctl_getbufinfo_op_t))
657 {
658 ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1
659 << IVD_UNSUPPORTEDPARAM;
660 ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
661 IVD_OP_API_STRUCT_SIZE_INCORRECT;
662 return IV_FAIL;
663 }
664 }
665 break;
666
667 case IVD_CMD_CTL_GETVERSION:
668 {
669 ih264d_ctl_getversioninfo_ip_t *ps_ip;
670 ih264d_ctl_getversioninfo_op_t *ps_op;
671 ps_ip = (ih264d_ctl_getversioninfo_ip_t *)pv_api_ip;
672 ps_op = (ih264d_ctl_getversioninfo_op_t *)pv_api_op;
673 if(ps_ip->s_ivd_ctl_getversioninfo_ip_t.u4_size
674 != sizeof(ih264d_ctl_getversioninfo_ip_t))
675 {
676 ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1
677 << IVD_UNSUPPORTEDPARAM;
678 ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
679 IVD_IP_API_STRUCT_SIZE_INCORRECT;
680 return IV_FAIL;
681 }
682 if(ps_op->s_ivd_ctl_getversioninfo_op_t.u4_size
683 != sizeof(ih264d_ctl_getversioninfo_op_t))
684 {
685 ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1
686 << IVD_UNSUPPORTEDPARAM;
687 ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
688 IVD_OP_API_STRUCT_SIZE_INCORRECT;
689 return IV_FAIL;
690 }
691 }
692 break;
693
694 case IVD_CMD_CTL_FLUSH:
695 {
696 ih264d_ctl_flush_ip_t *ps_ip;
697 ih264d_ctl_flush_op_t *ps_op;
698 ps_ip = (ih264d_ctl_flush_ip_t *)pv_api_ip;
699 ps_op = (ih264d_ctl_flush_op_t *)pv_api_op;
700 if(ps_ip->s_ivd_ctl_flush_ip_t.u4_size
701 != sizeof(ih264d_ctl_flush_ip_t))
702 {
703 ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1
704 << IVD_UNSUPPORTEDPARAM;
705 ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
706 IVD_IP_API_STRUCT_SIZE_INCORRECT;
707 return IV_FAIL;
708 }
709 if(ps_op->s_ivd_ctl_flush_op_t.u4_size
710 != sizeof(ih264d_ctl_flush_op_t))
711 {
712 ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1
713 << IVD_UNSUPPORTEDPARAM;
714 ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
715 IVD_OP_API_STRUCT_SIZE_INCORRECT;
716 return IV_FAIL;
717 }
718 }
719 break;
720
721 case IVD_CMD_CTL_RESET:
722 {
723 ih264d_ctl_reset_ip_t *ps_ip;
724 ih264d_ctl_reset_op_t *ps_op;
725 ps_ip = (ih264d_ctl_reset_ip_t *)pv_api_ip;
726 ps_op = (ih264d_ctl_reset_op_t *)pv_api_op;
727 if(ps_ip->s_ivd_ctl_reset_ip_t.u4_size
728 != sizeof(ih264d_ctl_reset_ip_t))
729 {
730 ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1
731 << IVD_UNSUPPORTEDPARAM;
732 ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
733 IVD_IP_API_STRUCT_SIZE_INCORRECT;
734 return IV_FAIL;
735 }
736 if(ps_op->s_ivd_ctl_reset_op_t.u4_size
737 != sizeof(ih264d_ctl_reset_op_t))
738 {
739 ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1
740 << IVD_UNSUPPORTEDPARAM;
741 ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
742 IVD_OP_API_STRUCT_SIZE_INCORRECT;
743 return IV_FAIL;
744 }
745 }
746 break;
747
748 case IH264D_CMD_CTL_DEGRADE:
749 {
750 ih264d_ctl_degrade_ip_t *ps_ip;
751 ih264d_ctl_degrade_op_t *ps_op;
752
753 ps_ip = (ih264d_ctl_degrade_ip_t *)pv_api_ip;
754 ps_op = (ih264d_ctl_degrade_op_t *)pv_api_op;
755
756 if(ps_ip->u4_size != sizeof(ih264d_ctl_degrade_ip_t))
757 {
758 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
759 ps_op->u4_error_code |=
760 IVD_IP_API_STRUCT_SIZE_INCORRECT;
761 return IV_FAIL;
762 }
763
764 if(ps_op->u4_size != sizeof(ih264d_ctl_degrade_op_t))
765 {
766 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
767 ps_op->u4_error_code |=
768 IVD_OP_API_STRUCT_SIZE_INCORRECT;
769 return IV_FAIL;
770 }
771
772 if((ps_ip->i4_degrade_pics < 0)
773 || (ps_ip->i4_degrade_pics > 4)
774 || (ps_ip->i4_nondegrade_interval < 0)
775 || (ps_ip->i4_degrade_type < 0)
776 || (ps_ip->i4_degrade_type > 15))
777 {
778 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
779 return IV_FAIL;
780 }
781
782 break;
783 }
784
785 case IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS:
786 {
787 ih264d_ctl_get_frame_dimensions_ip_t *ps_ip;
788 ih264d_ctl_get_frame_dimensions_op_t *ps_op;
789
790 ps_ip = (ih264d_ctl_get_frame_dimensions_ip_t *)pv_api_ip;
791 ps_op = (ih264d_ctl_get_frame_dimensions_op_t *)pv_api_op;
792
793 if(ps_ip->u4_size
794 != sizeof(ih264d_ctl_get_frame_dimensions_ip_t))
795 {
796 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
797 ps_op->u4_error_code |=
798 IVD_IP_API_STRUCT_SIZE_INCORRECT;
799 return IV_FAIL;
800 }
801
802 if(ps_op->u4_size
803 != sizeof(ih264d_ctl_get_frame_dimensions_op_t))
804 {
805 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
806 ps_op->u4_error_code |=
807 IVD_OP_API_STRUCT_SIZE_INCORRECT;
808 return IV_FAIL;
809 }
810
811 break;
812 }
813 case IH264D_CMD_CTL_GET_VUI_PARAMS:
814 {
815 ih264d_ctl_get_vui_params_ip_t *ps_ip;
816 ih264d_ctl_get_vui_params_op_t *ps_op;
817
818 ps_ip =
819 (ih264d_ctl_get_vui_params_ip_t *)pv_api_ip;
820 ps_op =
821 (ih264d_ctl_get_vui_params_op_t *)pv_api_op;
822
823 if(ps_ip->u4_size
824 != sizeof(ih264d_ctl_get_vui_params_ip_t))
825 {
826 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
827 ps_op->u4_error_code |=
828 IVD_IP_API_STRUCT_SIZE_INCORRECT;
829 return IV_FAIL;
830 }
831
832 if(ps_op->u4_size
833 != sizeof(ih264d_ctl_get_vui_params_op_t))
834 {
835 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
836 ps_op->u4_error_code |=
837 IVD_OP_API_STRUCT_SIZE_INCORRECT;
838 return IV_FAIL;
839 }
840
841 break;
842 }
843 case IH264D_CMD_CTL_GET_SEI_MDCV_PARAMS:
844 {
845 ih264d_ctl_get_sei_mdcv_params_ip_t *ps_ip;
846 ih264d_ctl_get_sei_mdcv_params_op_t *ps_op;
847
848 ps_ip = (ih264d_ctl_get_sei_mdcv_params_ip_t *)pv_api_ip;
849 ps_op = (ih264d_ctl_get_sei_mdcv_params_op_t *)pv_api_op;
850
851 if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_mdcv_params_ip_t))
852 {
853 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
854 ps_op->u4_error_code |=
855 IVD_IP_API_STRUCT_SIZE_INCORRECT;
856 return IV_FAIL;
857 }
858
859 if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_mdcv_params_op_t))
860 {
861 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
862 ps_op->u4_error_code |=
863 IVD_OP_API_STRUCT_SIZE_INCORRECT;
864 return IV_FAIL;
865 }
866
867 break;
868 }
869
870 case IH264D_CMD_CTL_GET_SEI_CLL_PARAMS:
871 {
872 ih264d_ctl_get_sei_cll_params_ip_t *ps_ip;
873 ih264d_ctl_get_sei_cll_params_op_t *ps_op;
874
875 ps_ip = (ih264d_ctl_get_sei_cll_params_ip_t *)pv_api_ip;
876 ps_op = (ih264d_ctl_get_sei_cll_params_op_t *)pv_api_op;
877
878 if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_cll_params_ip_t))
879 {
880 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
881 ps_op->u4_error_code |=
882 IVD_IP_API_STRUCT_SIZE_INCORRECT;
883 return IV_FAIL;
884 }
885
886 if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_cll_params_op_t))
887 {
888 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
889 ps_op->u4_error_code |=
890 IVD_OP_API_STRUCT_SIZE_INCORRECT;
891 return IV_FAIL;
892 }
893
894 break;
895 }
896
897 case IH264D_CMD_CTL_GET_SEI_AVE_PARAMS:
898 {
899 ih264d_ctl_get_sei_ave_params_ip_t *ps_ip;
900 ih264d_ctl_get_sei_ave_params_op_t *ps_op;
901
902 ps_ip = (ih264d_ctl_get_sei_ave_params_ip_t *)pv_api_ip;
903 ps_op = (ih264d_ctl_get_sei_ave_params_op_t *)pv_api_op;
904
905 if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_ave_params_ip_t))
906 {
907 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
908 ps_op->u4_error_code |=
909 IVD_IP_API_STRUCT_SIZE_INCORRECT;
910 return IV_FAIL;
911 }
912
913 if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_ave_params_op_t))
914 {
915 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
916 ps_op->u4_error_code |=
917 IVD_OP_API_STRUCT_SIZE_INCORRECT;
918 return IV_FAIL;
919 }
920
921 break;
922 }
923
924 case IH264D_CMD_CTL_GET_SEI_CCV_PARAMS:
925 {
926 ih264d_ctl_get_sei_ccv_params_ip_t *ps_ip;
927 ih264d_ctl_get_sei_ccv_params_op_t *ps_op;
928
929 ps_ip = (ih264d_ctl_get_sei_ccv_params_ip_t *)pv_api_ip;
930 ps_op = (ih264d_ctl_get_sei_ccv_params_op_t *)pv_api_op;
931
932 if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_ccv_params_ip_t))
933 {
934 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
935 ps_op->u4_error_code |=
936 IVD_IP_API_STRUCT_SIZE_INCORRECT;
937 return IV_FAIL;
938 }
939
940 if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_ccv_params_op_t))
941 {
942 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
943 ps_op->u4_error_code |=
944 IVD_OP_API_STRUCT_SIZE_INCORRECT;
945 return IV_FAIL;
946 }
947
948 break;
949 }
950
951 case IH264D_CMD_CTL_GET_SEI_SII_PARAMS:
952 {
953 ih264d_ctl_get_sei_sii_params_ip_t *ps_ip;
954 ih264d_ctl_get_sei_sii_params_op_t *ps_op;
955
956 ps_ip = (ih264d_ctl_get_sei_sii_params_ip_t *) pv_api_ip;
957 ps_op = (ih264d_ctl_get_sei_sii_params_op_t *) pv_api_op;
958
959 if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_sii_params_ip_t))
960 {
961 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
962 ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
963 return IV_FAIL;
964 }
965
966 if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_sii_params_op_t))
967 {
968 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
969 ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
970 return IV_FAIL;
971 }
972
973 break;
974 }
975
976 case IH264D_CMD_CTL_GET_SEI_FGC_PARAMS:
977 {
978 ih264d_ctl_get_sei_fgc_params_ip_t *ps_ip;
979 ih264d_ctl_get_sei_fgc_params_op_t *ps_op;
980
981 ps_ip = (ih264d_ctl_get_sei_fgc_params_ip_t *) pv_api_ip;
982 ps_op = (ih264d_ctl_get_sei_fgc_params_op_t *) pv_api_op;
983
984 if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_fgc_params_ip_t))
985 {
986 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
987 ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
988 return IV_FAIL;
989 }
990
991 if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_fgc_params_op_t))
992 {
993 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
994 ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
995 return IV_FAIL;
996 }
997
998 break;
999 }
1000
1001 case IH264D_CMD_CTL_SET_NUM_CORES:
1002 {
1003 ih264d_ctl_set_num_cores_ip_t *ps_ip;
1004 ih264d_ctl_set_num_cores_op_t *ps_op;
1005
1006 ps_ip = (ih264d_ctl_set_num_cores_ip_t *)pv_api_ip;
1007 ps_op = (ih264d_ctl_set_num_cores_op_t *)pv_api_op;
1008
1009 if(ps_ip->u4_size != sizeof(ih264d_ctl_set_num_cores_ip_t))
1010 {
1011 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1012 ps_op->u4_error_code |=
1013 IVD_IP_API_STRUCT_SIZE_INCORRECT;
1014 return IV_FAIL;
1015 }
1016
1017 if(ps_op->u4_size != sizeof(ih264d_ctl_set_num_cores_op_t))
1018 {
1019 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1020 ps_op->u4_error_code |=
1021 IVD_OP_API_STRUCT_SIZE_INCORRECT;
1022 return IV_FAIL;
1023 }
1024
1025 if((ps_ip->u4_num_cores != 1) && (ps_ip->u4_num_cores != 2)
1026 && (ps_ip->u4_num_cores != 3)
1027 && (ps_ip->u4_num_cores != 4))
1028 {
1029 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1030 return IV_FAIL;
1031 }
1032 break;
1033 }
1034 case IH264D_CMD_CTL_SET_PROCESSOR:
1035 {
1036 ih264d_ctl_set_processor_ip_t *ps_ip;
1037 ih264d_ctl_set_processor_op_t *ps_op;
1038
1039 ps_ip = (ih264d_ctl_set_processor_ip_t *)pv_api_ip;
1040 ps_op = (ih264d_ctl_set_processor_op_t *)pv_api_op;
1041
1042 if(ps_ip->u4_size != sizeof(ih264d_ctl_set_processor_ip_t))
1043 {
1044 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1045 ps_op->u4_error_code |=
1046 IVD_IP_API_STRUCT_SIZE_INCORRECT;
1047 return IV_FAIL;
1048 }
1049
1050 if(ps_op->u4_size != sizeof(ih264d_ctl_set_processor_op_t))
1051 {
1052 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1053 ps_op->u4_error_code |=
1054 IVD_OP_API_STRUCT_SIZE_INCORRECT;
1055 return IV_FAIL;
1056 }
1057
1058 break;
1059 }
1060 default:
1061 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
1062 *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD;
1063 return IV_FAIL;
1064 break;
1065 }
1066 }
1067 break;
1068 }
1069
1070 return IV_SUCCESS;
1071 }
1072
1073
1074 /**
1075 *******************************************************************************
1076 *
1077 * @brief
1078 * Sets Processor type
1079 *
1080 * @par Description:
1081 * Sets Processor type
1082 *
1083 * @param[in] ps_codec_obj
1084 * Pointer to codec object at API level
1085 *
1086 * @param[in] pv_api_ip
1087 * Pointer to input argument structure
1088 *
1089 * @param[out] pv_api_op
1090 * Pointer to output argument structure
1091 *
1092 * @returns Status
1093 *
1094 * @remarks
1095 *
1096 *
1097 *******************************************************************************
1098 */
1099
ih264d_set_processor(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)1100 WORD32 ih264d_set_processor(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
1101 {
1102 ih264d_ctl_set_processor_ip_t *ps_ip;
1103 ih264d_ctl_set_processor_op_t *ps_op;
1104 dec_struct_t *ps_codec = (dec_struct_t *)dec_hdl->pv_codec_handle;
1105
1106 ps_ip = (ih264d_ctl_set_processor_ip_t *)pv_api_ip;
1107 ps_op = (ih264d_ctl_set_processor_op_t *)pv_api_op;
1108
1109 ps_codec->e_processor_arch = (IVD_ARCH_T)ps_ip->u4_arch;
1110 ps_codec->e_processor_soc = (IVD_SOC_T)ps_ip->u4_soc;
1111
1112 ih264d_init_function_ptr(ps_codec);
1113
1114 ps_op->u4_error_code = 0;
1115 return IV_SUCCESS;
1116 }
1117
1118
1119 /**************************************************************************
1120 * \if Function name : ih264d_init_decoder \endif
1121 *
1122 *
1123 * \brief
1124 * Initializes the decoder
1125 *
1126 * \param apiVersion : Version of the api being used.
1127 * \param errorHandlingMechanism : Mechanism to be used for errror handling.
1128 * \param postFilteringType: Type of post filtering operation to be used.
1129 * \param uc_outputFormat: Format of the decoded picture [default 4:2:0].
1130 * \param uc_dispBufs: Number of Display Buffers.
1131 * \param p_NALBufAPI: Pointer to NAL Buffer API.
1132 * \param p_DispBufAPI: Pointer to Display Buffer API.
1133 * \param ih264d_dec_mem_manager :Pointer to the function that will be called by decoder
1134 * for memory allocation and freeing.
1135 *
1136 * \return
1137 * 0 on Success and -1 on error
1138 *
1139 **************************************************************************
1140 */
ih264d_init_decoder(void * ps_dec_params)1141 void ih264d_init_decoder(void * ps_dec_params)
1142 {
1143 dec_struct_t * ps_dec = (dec_struct_t *)ps_dec_params;
1144 dec_slice_params_t *ps_cur_slice;
1145 pocstruct_t *ps_prev_poc, *ps_cur_poc;
1146 WORD32 size;
1147
1148 size = sizeof(pred_info_t) * 2 * 32;
1149 memset(ps_dec->ps_pred, 0 , size);
1150
1151 size = sizeof(disp_mgr_t);
1152 memset(ps_dec->pv_disp_buf_mgr, 0 , size);
1153
1154 size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
1155 memset(ps_dec->pv_pic_buf_mgr, 0, size);
1156
1157 size = sizeof(dec_err_status_t);
1158 memset(ps_dec->ps_dec_err_status, 0, size);
1159
1160 size = sizeof(sei);
1161 memset(ps_dec->ps_sei, 0, size);
1162
1163 size = sizeof(sei);
1164 memset(ps_dec->ps_sei_parse, 0, size);
1165
1166 size = sizeof(dpb_commands_t);
1167 memset(ps_dec->ps_dpb_cmds, 0, size);
1168
1169 size = sizeof(dec_bit_stream_t);
1170 memset(ps_dec->ps_bitstrm, 0, size);
1171
1172 size = sizeof(dec_slice_params_t);
1173 memset(ps_dec->ps_cur_slice, 0, size);
1174
1175 size = MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t));
1176 memset(ps_dec->pv_scratch_sps_pps, 0, size);
1177
1178 size = sizeof(ctxt_inc_mb_info_t);
1179 memset(ps_dec->ps_left_mb_ctxt_info, 0, size);
1180
1181 size = (sizeof(neighbouradd_t) << 2);
1182 memset(ps_dec->ps_left_mvpred_addr, 0 ,size);
1183
1184 size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
1185 memset(ps_dec->pv_mv_buf_mgr, 0, size);
1186
1187 /* Free any dynamic buffers that are allocated */
1188 ih264d_free_dynamic_bufs(ps_dec);
1189
1190 {
1191 UWORD8 i;
1192 struct pic_buffer_t *ps_init_dpb;
1193 ps_init_dpb = ps_dec->ps_dpb_mgr->ps_init_dpb[0][0];
1194 for(i = 0; i < 2 * MAX_REF_BUFS; i++)
1195 {
1196 ps_init_dpb->pu1_buf1 = NULL;
1197 ps_init_dpb->u1_long_term_frm_idx = MAX_REF_BUFS + 1;
1198 ps_dec->ps_dpb_mgr->ps_init_dpb[0][i] = ps_init_dpb;
1199 ps_dec->ps_dpb_mgr->ps_mod_dpb[0][i] = ps_init_dpb;
1200 ps_init_dpb++;
1201 }
1202
1203 ps_init_dpb = ps_dec->ps_dpb_mgr->ps_init_dpb[1][0];
1204 for(i = 0; i < 2 * MAX_REF_BUFS; i++)
1205 {
1206 ps_init_dpb->pu1_buf1 = NULL;
1207 ps_init_dpb->u1_long_term_frm_idx = MAX_REF_BUFS + 1;
1208 ps_dec->ps_dpb_mgr->ps_init_dpb[1][i] = ps_init_dpb;
1209 ps_dec->ps_dpb_mgr->ps_mod_dpb[1][i] = ps_init_dpb;
1210 ps_init_dpb++;
1211 }
1212 }
1213
1214 ps_cur_slice = ps_dec->ps_cur_slice;
1215 ps_dec->init_done = 0;
1216
1217 ps_dec->u4_num_cores = 1;
1218
1219 ps_dec->u2_pic_ht = ps_dec->u2_pic_wd = 0;
1220
1221 ps_dec->u1_separate_parse = DEFAULT_SEPARATE_PARSE;
1222 ps_dec->u4_app_disable_deblk_frm = 0;
1223 ps_dec->i4_degrade_type = 0;
1224 ps_dec->i4_degrade_pics = 0;
1225
1226 memset(ps_dec->ps_pps, 0,
1227 ((sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS));
1228 memset(ps_dec->ps_sps, 0,
1229 ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS));
1230
1231 /* Initialization of function pointers ih264d_deblock_picture function*/
1232
1233 ps_dec->p_DeblockPicture[0] = ih264d_deblock_picture_non_mbaff;
1234 ps_dec->p_DeblockPicture[1] = ih264d_deblock_picture_mbaff;
1235
1236 ps_dec->s_cab_dec_env.pv_codec_handle = ps_dec;
1237
1238 ps_dec->u4_num_fld_in_frm = 0;
1239
1240 ps_dec->ps_dpb_mgr->pv_codec_handle = ps_dec;
1241
1242 /* Initialize the sei validity u4_flag with zero indiacting sei is not valid*/
1243 ps_dec->ps_sei->u1_is_valid = 0;
1244
1245 /* decParams Initializations */
1246 ps_dec->ps_cur_pps = NULL;
1247 ps_dec->ps_cur_sps = NULL;
1248 ps_dec->u1_init_dec_flag = 0;
1249 ps_dec->u1_first_slice_in_stream = 1;
1250 ps_dec->u1_last_pic_not_decoded = 0;
1251 ps_dec->u4_app_disp_width = 0;
1252 ps_dec->i4_header_decoded = 0;
1253 ps_dec->u4_total_frames_decoded = 0;
1254
1255 ps_dec->i4_error_code = 0;
1256 ps_dec->i4_content_type = IV_CONTENTTYPE_NA;
1257 ps_dec->ps_cur_slice->u1_mbaff_frame_flag = 0;
1258
1259 ps_dec->ps_dec_err_status->u1_err_flag = ACCEPT_ALL_PICS; //REJECT_PB_PICS;
1260 ps_dec->ps_dec_err_status->u1_cur_pic_type = PIC_TYPE_UNKNOWN;
1261 ps_dec->ps_dec_err_status->u4_frm_sei_sync = SYNC_FRM_DEFAULT;
1262 ps_dec->ps_dec_err_status->u4_cur_frm = INIT_FRAME;
1263 ps_dec->ps_dec_err_status->u1_pic_aud_i = PIC_TYPE_UNKNOWN;
1264
1265 ps_dec->u1_pr_sl_type = 0xFF;
1266 ps_dec->u2_mbx = 0xffff;
1267 ps_dec->u2_mby = 0;
1268 ps_dec->u2_total_mbs_coded = 0;
1269
1270 /* POC initializations */
1271 ps_prev_poc = &ps_dec->s_prev_pic_poc;
1272 ps_cur_poc = &ps_dec->s_cur_pic_poc;
1273 ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb = 0;
1274 ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb = 0;
1275 ps_prev_poc->i4_delta_pic_order_cnt_bottom =
1276 ps_cur_poc->i4_delta_pic_order_cnt_bottom = 0;
1277 ps_prev_poc->i4_delta_pic_order_cnt[0] =
1278 ps_cur_poc->i4_delta_pic_order_cnt[0] = 0;
1279 ps_prev_poc->i4_delta_pic_order_cnt[1] =
1280 ps_cur_poc->i4_delta_pic_order_cnt[1] = 0;
1281 ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
1282 ps_prev_poc->i4_top_field_order_count = ps_cur_poc->i4_top_field_order_count =
1283 0;
1284 ps_prev_poc->i4_bottom_field_order_count =
1285 ps_cur_poc->i4_bottom_field_order_count = 0;
1286 ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field = 0;
1287 ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
1288 ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst = 0;
1289 ps_cur_slice->u1_mmco_equalto5 = 0;
1290 ps_cur_slice->u2_frame_num = 0;
1291
1292 ps_dec->i4_max_poc = 0;
1293 ps_dec->i4_prev_max_display_seq = 0;
1294 ps_dec->u1_recon_mb_grp = 4;
1295 ps_dec->i4_reorder_depth = -1;
1296
1297 /* Field PIC initializations */
1298 ps_dec->u1_second_field = 0;
1299 ps_dec->s_prev_seq_params.u1_eoseq_pending = 0;
1300
1301 /* Set the cropping parameters as zero */
1302 ps_dec->u2_crop_offset_y = 0;
1303 ps_dec->u2_crop_offset_uv = 0;
1304
1305 /* The Initial Frame Rate Info is not Present */
1306 ps_dec->i4_vui_frame_rate = -1;
1307 ps_dec->i4_pic_type = NA_SLICE;
1308 ps_dec->i4_frametype = IV_NA_FRAME;
1309 ps_dec->i4_content_type = IV_CONTENTTYPE_NA;
1310
1311 ps_dec->u1_res_changed = 0;
1312
1313
1314 ps_dec->u1_frame_decoded_flag = 0;
1315
1316 /* Set the default frame seek mask mode */
1317 ps_dec->u4_skip_frm_mask = SKIP_NONE;
1318
1319 /********************************************************/
1320 /* Initialize CAVLC residual decoding function pointers */
1321 /********************************************************/
1322 ps_dec->pf_cavlc_4x4res_block[0] = ih264d_cavlc_4x4res_block_totalcoeff_1;
1323 ps_dec->pf_cavlc_4x4res_block[1] =
1324 ih264d_cavlc_4x4res_block_totalcoeff_2to10;
1325 ps_dec->pf_cavlc_4x4res_block[2] =
1326 ih264d_cavlc_4x4res_block_totalcoeff_11to16;
1327
1328 ps_dec->pf_cavlc_parse4x4coeff[0] = ih264d_cavlc_parse4x4coeff_n0to7;
1329 ps_dec->pf_cavlc_parse4x4coeff[1] = ih264d_cavlc_parse4x4coeff_n8;
1330
1331 ps_dec->pf_cavlc_parse_8x8block[0] =
1332 ih264d_cavlc_parse_8x8block_none_available;
1333 ps_dec->pf_cavlc_parse_8x8block[1] =
1334 ih264d_cavlc_parse_8x8block_left_available;
1335 ps_dec->pf_cavlc_parse_8x8block[2] =
1336 ih264d_cavlc_parse_8x8block_top_available;
1337 ps_dec->pf_cavlc_parse_8x8block[3] =
1338 ih264d_cavlc_parse_8x8block_both_available;
1339
1340 /***************************************************************************/
1341 /* Initialize Bs calculation function pointers for P and B, 16x16/non16x16 */
1342 /***************************************************************************/
1343 ps_dec->pf_fill_bs1[0][0] = ih264d_fill_bs1_16x16mb_pslice;
1344 ps_dec->pf_fill_bs1[0][1] = ih264d_fill_bs1_non16x16mb_pslice;
1345
1346 ps_dec->pf_fill_bs1[1][0] = ih264d_fill_bs1_16x16mb_bslice;
1347 ps_dec->pf_fill_bs1[1][1] = ih264d_fill_bs1_non16x16mb_bslice;
1348
1349 ps_dec->pf_fill_bs_xtra_left_edge[0] =
1350 ih264d_fill_bs_xtra_left_edge_cur_frm;
1351 ps_dec->pf_fill_bs_xtra_left_edge[1] =
1352 ih264d_fill_bs_xtra_left_edge_cur_fld;
1353
1354 /* Initialize Reference Pic Buffers */
1355 ih264d_init_ref_bufs(ps_dec->ps_dpb_mgr);
1356
1357 ps_dec->u2_prv_frame_num = 0;
1358 ps_dec->u1_top_bottom_decoded = 0;
1359 ps_dec->u1_dangling_field = 0;
1360
1361 ps_dec->s_cab_dec_env.cabac_table = gau4_ih264d_cabac_table;
1362
1363 ps_dec->pu1_left_mv_ctxt_inc = ps_dec->u1_left_mv_ctxt_inc_arr[0];
1364 ps_dec->pi1_left_ref_idx_ctxt_inc =
1365 &ps_dec->i1_left_ref_idx_ctx_inc_arr[0][0];
1366 ps_dec->pu1_left_yuv_dc_csbp = &ps_dec->u1_yuv_dc_csbp_topmb;
1367
1368 /* ! */
1369 /* Initializing flush frame u4_flag */
1370 ps_dec->u1_flushfrm = 0;
1371
1372 {
1373 ps_dec->s_cab_dec_env.pv_codec_handle = (void*)ps_dec;
1374 ps_dec->ps_bitstrm->pv_codec_handle = (void*)ps_dec;
1375 ps_dec->ps_cur_slice->pv_codec_handle = (void*)ps_dec;
1376 ps_dec->ps_dpb_mgr->pv_codec_handle = (void*)ps_dec;
1377 }
1378
1379 memset(ps_dec->disp_bufs, 0, (MAX_DISP_BUFS_NEW) * sizeof(disp_buf_t));
1380 memset(ps_dec->u4_disp_buf_mapping, 0,
1381 (MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
1382 memset(ps_dec->u4_disp_buf_to_be_freed, 0,
1383 (MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
1384 memset(ps_dec->ps_cur_slice, 0, sizeof(dec_slice_params_t));
1385
1386 ih264d_init_arch(ps_dec);
1387 ih264d_init_function_ptr(ps_dec);
1388 ps_dec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
1389 ps_dec->init_done = 1;
1390
1391 }
1392
ih264d_join_threads(dec_struct_t * ps_dec)1393 WORD32 ih264d_join_threads(dec_struct_t *ps_dec)
1394 {
1395 if(ps_dec->i4_threads_active)
1396 {
1397 /* Wait for threads */
1398 ps_dec->i4_break_threads = 1;
1399 if(ps_dec->u4_dec_thread_created)
1400 {
1401 ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]);
1402
1403 ps_dec->ai4_process_start[0] = PROC_START;
1404
1405 ithread_cond_signal(ps_dec->apv_proc_start_condition[0]);
1406
1407 ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]);
1408
1409 ithread_join(ps_dec->pv_dec_thread_handle, NULL);
1410
1411 ps_dec->u4_dec_thread_created = 0;
1412 }
1413
1414 if(ps_dec->u4_bs_deblk_thread_created)
1415 {
1416 ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]);
1417
1418 ps_dec->ai4_process_start[1] = PROC_START;
1419
1420 ithread_cond_signal(ps_dec->apv_proc_start_condition[1]);
1421
1422 ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]);
1423
1424 ithread_join(ps_dec->pv_bs_deblk_thread_handle, NULL);
1425
1426 ps_dec->u4_bs_deblk_thread_created = 0;
1427 }
1428 }
1429 return IV_SUCCESS;
1430 }
1431
ih264d_free_static_bufs(iv_obj_t * dec_hdl)1432 WORD32 ih264d_free_static_bufs(iv_obj_t *dec_hdl)
1433 {
1434 dec_struct_t *ps_dec;
1435
1436 void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
1437 void *pv_mem_ctxt;
1438
1439 ps_dec = (dec_struct_t *)dec_hdl->pv_codec_handle;
1440 pf_aligned_free = ps_dec->pf_aligned_free;
1441 pv_mem_ctxt = ps_dec->pv_mem_ctxt;
1442
1443 if(ps_dec->i4_threads_active)
1444 {
1445
1446 ih264d_join_threads(ps_dec);
1447
1448 // destroy mutex and condition variable for both the threads
1449 // 1. ih264d_decode_picture_thread
1450 // 2. ih264d_recon_deblk_thread
1451 {
1452 UWORD32 i;
1453 for(i = 0; i < 2; i++)
1454 {
1455 ithread_cond_destroy(ps_dec->apv_proc_start_condition[i]);
1456 ithread_cond_destroy(ps_dec->apv_proc_done_condition[i]);
1457
1458 ithread_mutex_destroy(ps_dec->apv_proc_start_mutex[i]);
1459 ithread_mutex_destroy(ps_dec->apv_proc_done_mutex[i]);
1460 }
1461 }
1462 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->apv_proc_start_mutex[0]);
1463 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->apv_proc_start_condition[0]);
1464 }
1465
1466 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sps);
1467 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pps);
1468 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_dec_thread_handle);
1469 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_bs_deblk_thread_handle);
1470 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dpb_mgr);
1471 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pred);
1472 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_disp_buf_mgr);
1473 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_pic_buf_mgr);
1474 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pic_buf_base);
1475 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dec_err_status);
1476 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sei);
1477 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sei_parse);
1478 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dpb_cmds);
1479 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_bitstrm);
1480 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_cur_slice);
1481 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_scratch_sps_pps);
1482 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_bits_buf_static);
1483 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ppv_map_ref_idx_to_poc_base);
1484 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->p_cabac_ctxt_table_t);
1485 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_left_mb_ctxt_info);
1486 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_ref_buff_base);
1487 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pi2_pred1);
1488 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_temp_mc_buffer);
1489 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_init_dpb_base);
1490 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu4_mbaff_wt_mat);
1491 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu4_wts_ofsts_mat);
1492 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_left_mvpred_addr);
1493 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_mv_buf_mgr);
1494 PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_col_mv_base);
1495 PS_DEC_ALIGNED_FREE(ps_dec, dec_hdl->pv_codec_handle);
1496
1497 if(dec_hdl)
1498 {
1499 pf_aligned_free(pv_mem_ctxt, dec_hdl);
1500 }
1501 return IV_SUCCESS;
1502 }
1503 /*****************************************************************************/
1504 /* */
1505 /* Function Name : ih264d_create */
1506 /* */
1507 /* Description : creates decoder */
1508 /* */
1509 /* Inputs :iv_obj_t decoder handle */
1510 /* :pv_api_ip pointer to input structure */
1511 /* :pv_api_op pointer to output structure */
1512 /* Outputs : */
1513 /* Returns : void */
1514 /* */
1515 /* Issues : none */
1516 /* */
1517 /* Revision History: */
1518 /* */
1519 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
1520 /* 22 10 2008 100356 Draft */
1521 /* */
1522 /*****************************************************************************/
ih264d_allocate_static_bufs(iv_obj_t ** dec_hdl,void * pv_api_ip,void * pv_api_op)1523 WORD32 ih264d_allocate_static_bufs(iv_obj_t **dec_hdl, void *pv_api_ip, void *pv_api_op)
1524 {
1525 ih264d_create_ip_t *ps_create_ip;
1526 ih264d_create_op_t *ps_create_op;
1527 void *pv_buf;
1528 UWORD8 *pu1_buf;
1529 dec_struct_t *ps_dec;
1530 void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
1531 void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
1532 void *pv_mem_ctxt;
1533 WORD32 size;
1534
1535 ps_create_ip = (ih264d_create_ip_t *)pv_api_ip;
1536 ps_create_op = (ih264d_create_op_t *)pv_api_op;
1537
1538 ps_create_op->s_ivd_create_op_t.u4_error_code = 0;
1539
1540 pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc;
1541 pf_aligned_free = ps_create_ip->s_ivd_create_ip_t.pf_aligned_free;
1542 pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
1543
1544 /* Initialize return handle to NULL */
1545 ps_create_op->s_ivd_create_op_t.pv_handle = NULL;
1546 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(iv_obj_t));
1547 RETURN_IF((NULL == pv_buf), IV_FAIL);
1548 memset(pv_buf, 0, sizeof(iv_obj_t));
1549 *dec_hdl = (iv_obj_t *)pv_buf;
1550 ps_create_op->s_ivd_create_op_t.pv_handle = *dec_hdl;
1551
1552 (*dec_hdl)->pv_codec_handle = NULL;
1553 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(dec_struct_t));
1554 RETURN_IF((NULL == pv_buf), IV_FAIL);
1555 (*dec_hdl)->pv_codec_handle = (dec_struct_t *)pv_buf;
1556 ps_dec = (dec_struct_t *)pv_buf;
1557
1558 memset(ps_dec, 0, sizeof(dec_struct_t));
1559
1560 #ifndef LOGO_EN
1561 ps_dec->u4_share_disp_buf = ps_create_ip->s_ivd_create_ip_t.u4_share_disp_buf;
1562 #else
1563 ps_dec->u4_share_disp_buf = 0;
1564 #endif
1565
1566 ps_dec->u1_chroma_format =
1567 (UWORD8)(ps_create_ip->s_ivd_create_ip_t.e_output_format);
1568
1569 if((ps_dec->u1_chroma_format != IV_YUV_420P)
1570 && (ps_dec->u1_chroma_format
1571 != IV_YUV_420SP_UV)
1572 && (ps_dec->u1_chroma_format
1573 != IV_YUV_420SP_VU))
1574 {
1575 ps_dec->u4_share_disp_buf = 0;
1576 }
1577
1578 ps_dec->u1_enable_mb_info = ps_create_ip->u4_enable_frame_info;
1579 ps_dec->pf_aligned_alloc = pf_aligned_alloc;
1580 ps_dec->pf_aligned_free = pf_aligned_free;
1581 ps_dec->pv_mem_ctxt = pv_mem_ctxt;
1582 ps_dec->i4_threads_active = ps_create_ip->u4_keep_threads_active;
1583
1584
1585 size = ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS);
1586 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1587 RETURN_IF((NULL == pv_buf), IV_FAIL);
1588 memset(pv_buf, 0, size);
1589 ps_dec->ps_sps = pv_buf;
1590
1591 size = (sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS;
1592 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1593 RETURN_IF((NULL == pv_buf), IV_FAIL);
1594 memset(pv_buf, 0, size);
1595 ps_dec->ps_pps = pv_buf;
1596
1597 size = ithread_get_handle_size();
1598 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1599 RETURN_IF((NULL == pv_buf), IV_FAIL);
1600 memset(pv_buf, 0, size);
1601 ps_dec->pv_dec_thread_handle = pv_buf;
1602
1603 size = ithread_get_handle_size();
1604 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1605 RETURN_IF((NULL == pv_buf), IV_FAIL);
1606 memset(pv_buf, 0, size);
1607 ps_dec->pv_bs_deblk_thread_handle = pv_buf;
1608
1609 if(ps_dec->i4_threads_active)
1610 {
1611 UWORD32 i;
1612 /* Request memory to hold mutex (start/done) for both threads */
1613 size = ithread_get_mutex_lock_size() << 2;
1614 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 8, size);
1615 RETURN_IF((NULL == pv_buf), IV_FAIL);
1616 memset(pv_buf, 0, size);
1617
1618 // init mutex variable for both the threads
1619 // 1. ih264d_decode_picture_thread
1620 // 2. ih264d_recon_deblk_thread
1621 for(i = 0; i < 2; i++)
1622 {
1623 WORD32 ret;
1624 WORD32 mutex_size = ithread_get_mutex_lock_size();
1625
1626 ps_dec->apv_proc_start_mutex[i] =
1627 (UWORD8 *)pv_buf + (2 * i * mutex_size);
1628 ps_dec->apv_proc_done_mutex[i] =
1629 (UWORD8 *)pv_buf + ((2 * i + 1) * mutex_size);
1630
1631 ret = ithread_mutex_init(ps_dec->apv_proc_start_mutex[i]);
1632 RETURN_IF((ret != IV_SUCCESS), ret);
1633
1634 ret = ithread_mutex_init(ps_dec->apv_proc_done_mutex[i]);
1635 RETURN_IF((ret != IV_SUCCESS), ret);
1636 }
1637
1638 size = ithread_get_cond_struct_size() << 2;
1639 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 8, size);
1640 RETURN_IF((NULL == pv_buf), IV_FAIL);
1641 memset(pv_buf, 0, size);
1642
1643 // init condition variable for both the threads
1644 for(i = 0; i < 2; i++)
1645 {
1646 WORD32 ret;
1647 WORD32 cond_size = ithread_get_cond_struct_size();
1648 ps_dec->apv_proc_start_condition[i] =
1649 (UWORD8 *)pv_buf + (2 * i * cond_size);
1650 ps_dec->apv_proc_done_condition[i] =
1651 (UWORD8 *)pv_buf + ((2 * i + 1) * cond_size);
1652
1653 ret = ithread_cond_init(ps_dec->apv_proc_start_condition[i]);
1654 RETURN_IF((ret != IV_SUCCESS), ret);
1655
1656 ret = ithread_cond_init(ps_dec->apv_proc_done_condition[i]);
1657 RETURN_IF((ret != IV_SUCCESS), ret);
1658 }
1659 }
1660
1661 size = sizeof(dpb_manager_t);
1662 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1663 RETURN_IF((NULL == pv_buf), IV_FAIL);
1664 memset(pv_buf, 0, size);
1665 ps_dec->ps_dpb_mgr = pv_buf;
1666
1667 size = sizeof(pred_info_t) * 2 * 32;
1668 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1669 RETURN_IF((NULL == pv_buf), IV_FAIL);
1670 memset(pv_buf, 0, size);
1671 ps_dec->ps_pred = pv_buf;
1672
1673 size = sizeof(disp_mgr_t);
1674 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1675 RETURN_IF((NULL == pv_buf), IV_FAIL);
1676 memset(pv_buf, 0, size);
1677 ps_dec->pv_disp_buf_mgr = pv_buf;
1678
1679 size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
1680 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1681 RETURN_IF((NULL == pv_buf), IV_FAIL);
1682 memset(pv_buf, 0, size);
1683 ps_dec->pv_pic_buf_mgr = pv_buf;
1684
1685 size = sizeof(struct pic_buffer_t) * (H264_MAX_REF_PICS * 2);
1686 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1687 RETURN_IF((NULL == pv_buf), IV_FAIL);
1688 memset(pv_buf, 0, size);
1689 ps_dec->ps_pic_buf_base = pv_buf;
1690
1691 size = sizeof(dec_err_status_t);
1692 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1693 RETURN_IF((NULL == pv_buf), IV_FAIL);
1694 memset(pv_buf, 0, size);
1695 ps_dec->ps_dec_err_status = (dec_err_status_t *)pv_buf;
1696
1697 size = sizeof(sei);
1698 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1699 RETURN_IF((NULL == pv_buf), IV_FAIL);
1700 memset(pv_buf, 0, size);
1701 ps_dec->ps_sei = (sei *)pv_buf;
1702
1703 size = sizeof(sei);
1704 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1705 RETURN_IF((NULL == pv_buf), IV_FAIL);
1706 memset(pv_buf, 0, size);
1707 ps_dec->ps_sei_parse = (sei *)pv_buf;
1708
1709 size = sizeof(dpb_commands_t);
1710 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1711 RETURN_IF((NULL == pv_buf), IV_FAIL);
1712 memset(pv_buf, 0, size);
1713 ps_dec->ps_dpb_cmds = (dpb_commands_t *)pv_buf;
1714
1715 size = sizeof(dec_bit_stream_t);
1716 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1717 RETURN_IF((NULL == pv_buf), IV_FAIL);
1718 memset(pv_buf, 0, size);
1719 ps_dec->ps_bitstrm = (dec_bit_stream_t *)pv_buf;
1720
1721 size = sizeof(dec_slice_params_t);
1722 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1723 RETURN_IF((NULL == pv_buf), IV_FAIL);
1724 memset(pv_buf, 0, size);
1725 ps_dec->ps_cur_slice = (dec_slice_params_t *)pv_buf;
1726
1727 size = MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t));
1728 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1729 RETURN_IF((NULL == pv_buf), IV_FAIL);
1730 memset(pv_buf, 0, size);
1731 ps_dec->pv_scratch_sps_pps = pv_buf;
1732
1733
1734 ps_dec->u4_static_bits_buf_size = 256000;
1735 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, ps_dec->u4_static_bits_buf_size);
1736 RETURN_IF((NULL == pv_buf), IV_FAIL);
1737 memset(pv_buf, 0, ps_dec->u4_static_bits_buf_size);
1738 ps_dec->pu1_bits_buf_static = pv_buf;
1739
1740
1741 size = ((TOTAL_LIST_ENTRIES + PAD_MAP_IDX_POC)
1742 * sizeof(void *));
1743 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1744 RETURN_IF((NULL == pv_buf), IV_FAIL);
1745 ps_dec->ppv_map_ref_idx_to_poc_base = pv_buf;
1746 memset(ps_dec->ppv_map_ref_idx_to_poc_base, 0, size);
1747
1748 ps_dec->ppv_map_ref_idx_to_poc = ps_dec->ppv_map_ref_idx_to_poc_base + OFFSET_MAP_IDX_POC;
1749
1750
1751 size = (sizeof(bin_ctxt_model_t) * NUM_CABAC_CTXTS);
1752 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1753 RETURN_IF((NULL == pv_buf), IV_FAIL);
1754 memset(pv_buf, 0, size);
1755 ps_dec->p_cabac_ctxt_table_t = pv_buf;
1756
1757
1758
1759 size = sizeof(ctxt_inc_mb_info_t);
1760 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1761 RETURN_IF((NULL == pv_buf), IV_FAIL);
1762 memset(pv_buf, 0, size);
1763 ps_dec->ps_left_mb_ctxt_info = pv_buf;
1764
1765
1766
1767 size = MAX_REF_BUF_SIZE * 2;
1768 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1769 RETURN_IF((NULL == pv_buf), IV_FAIL);
1770 memset(pv_buf, 0, size);
1771 ps_dec->pu1_ref_buff_base = pv_buf;
1772 ps_dec->pu1_ref_buff = ps_dec->pu1_ref_buff_base + MAX_REF_BUF_SIZE;
1773
1774
1775 size = ((sizeof(WORD16)) * PRED_BUFFER_WIDTH
1776 * PRED_BUFFER_HEIGHT * 2);
1777 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1778 RETURN_IF((NULL == pv_buf), IV_FAIL);
1779 memset(pv_buf, 0, size);
1780 ps_dec->pi2_pred1 = pv_buf;
1781
1782
1783 size = sizeof(UWORD8) * (MB_LUM_SIZE);
1784 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1785 RETURN_IF((NULL == pv_buf), IV_FAIL);
1786 memset(pv_buf, 0, size);
1787 ps_dec->pu1_temp_mc_buffer = pv_buf;
1788
1789
1790
1791
1792 size = 8 * MAX_REF_BUFS * sizeof(struct pic_buffer_t);
1793 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1794 RETURN_IF((NULL == pv_buf), IV_FAIL);
1795 memset(pv_buf, 0, size);
1796
1797 ps_dec->pu1_init_dpb_base = pv_buf;
1798 pu1_buf = pv_buf;
1799 ps_dec->ps_dpb_mgr->ps_init_dpb[0][0] = (struct pic_buffer_t *)pu1_buf;
1800
1801 pu1_buf += size / 2;
1802 ps_dec->ps_dpb_mgr->ps_init_dpb[1][0] = (struct pic_buffer_t *)pu1_buf;
1803
1804 size = (sizeof(UWORD32) * 2 * 3
1805 * ((MAX_FRAMES << 1) * (MAX_FRAMES << 1)) * 2);
1806 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1807 RETURN_IF((NULL == pv_buf), IV_FAIL);
1808 memset(pv_buf, 0, size);
1809 ps_dec->pu4_mbaff_wt_mat = pv_buf;
1810
1811 size = sizeof(UWORD32) * 2 * 3
1812 * ((MAX_FRAMES << 1) * (MAX_FRAMES << 1));
1813 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1814 RETURN_IF((NULL == pv_buf), IV_FAIL);
1815 memset(pv_buf, 0, size);
1816 ps_dec->pu4_wts_ofsts_mat = pv_buf;
1817
1818
1819 size = (sizeof(neighbouradd_t) << 2);
1820 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1821 RETURN_IF((NULL == pv_buf), IV_FAIL);
1822 memset(pv_buf, 0, size);
1823 ps_dec->ps_left_mvpred_addr = pv_buf;
1824
1825
1826 size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
1827 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1828 RETURN_IF((NULL == pv_buf), IV_FAIL);
1829 memset(pv_buf, 0, size);
1830 ps_dec->pv_mv_buf_mgr = pv_buf;
1831
1832
1833 size = sizeof(col_mv_buf_t) * (H264_MAX_REF_PICS * 2);
1834 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1835 RETURN_IF((NULL == pv_buf), IV_FAIL);
1836 ps_dec->ps_col_mv_base = pv_buf;
1837 memset(ps_dec->ps_col_mv_base, 0, size);
1838
1839 ih264d_init_decoder(ps_dec);
1840
1841 return IV_SUCCESS;
1842 }
1843
1844
1845 /*****************************************************************************/
1846 /* */
1847 /* Function Name : ih264d_create */
1848 /* */
1849 /* Description : creates decoder */
1850 /* */
1851 /* Inputs :iv_obj_t decoder handle */
1852 /* :pv_api_ip pointer to input structure */
1853 /* :pv_api_op pointer to output structure */
1854 /* Outputs : */
1855 /* Returns : void */
1856 /* */
1857 /* Issues : none */
1858 /* */
1859 /* Revision History: */
1860 /* */
1861 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
1862 /* 22 10 2008 100356 Draft */
1863 /* */
1864 /*****************************************************************************/
ih264d_create(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)1865 WORD32 ih264d_create(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
1866 {
1867 ih264d_create_ip_t *ps_create_ip;
1868 ih264d_create_op_t *ps_create_op;
1869
1870 WORD32 ret;
1871
1872 ps_create_ip = (ih264d_create_ip_t *)pv_api_ip;
1873 ps_create_op = (ih264d_create_op_t *)pv_api_op;
1874
1875 ps_create_op->s_ivd_create_op_t.u4_error_code = 0;
1876 dec_hdl = NULL;
1877 ret = ih264d_allocate_static_bufs(&dec_hdl, pv_api_ip, pv_api_op);
1878
1879 /* If allocation of some buffer fails, then free buffers allocated till then */
1880 if(IV_FAIL == ret)
1881 {
1882 if(dec_hdl)
1883 {
1884 if(dec_hdl->pv_codec_handle)
1885 {
1886 ih264d_free_static_bufs(dec_hdl);
1887 }
1888 else
1889 {
1890 void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
1891 void *pv_mem_ctxt;
1892
1893 pf_aligned_free = ps_create_ip->s_ivd_create_ip_t.pf_aligned_free;
1894 pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
1895 pf_aligned_free(pv_mem_ctxt, dec_hdl);
1896 }
1897 }
1898 ps_create_op->s_ivd_create_op_t.u4_error_code = IVD_MEM_ALLOC_FAILED;
1899 ps_create_op->s_ivd_create_op_t.u4_error_code |= 1 << IVD_FATALERROR;
1900
1901 return IV_FAIL;
1902 }
1903
1904 return IV_SUCCESS;
1905 }
1906
1907 /*****************************************************************************/
1908 /* */
1909 /* Function Name : ih264d_map_error */
1910 /* */
1911 /* Description : Maps error codes to IVD error groups */
1912 /* */
1913 /* Inputs : */
1914 /* Globals : <Does it use any global variables?> */
1915 /* Outputs : */
1916 /* Returns : void */
1917 /* */
1918 /* Issues : none */
1919 /* */
1920 /* Revision History: */
1921 /* */
1922 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
1923 /* 22 10 2008 100356 Draft */
1924 /* */
1925 /*****************************************************************************/
ih264d_map_error(UWORD32 i4_err_status)1926 UWORD32 ih264d_map_error(UWORD32 i4_err_status)
1927 {
1928 UWORD32 temp = 0;
1929
1930 switch(i4_err_status)
1931 {
1932 case ERROR_MEM_ALLOC_ISRAM_T:
1933 case ERROR_MEM_ALLOC_SDRAM_T:
1934 case ERROR_BUF_MGR:
1935 case ERROR_MB_GROUP_ASSGN_T:
1936 case ERROR_FRAME_LIMIT_OVER:
1937 case ERROR_ACTUAL_RESOLUTION_GREATER_THAN_INIT:
1938 case ERROR_PROFILE_NOT_SUPPORTED:
1939 case ERROR_INIT_NOT_DONE:
1940 case IVD_MEM_ALLOC_FAILED:
1941 case ERROR_FEATURE_UNAVAIL:
1942 case IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED:
1943 temp = 1 << IVD_FATALERROR;
1944 H264_DEC_DEBUG_PRINT("\nFatal Error\n");
1945 break;
1946
1947 case ERROR_DBP_MANAGER_T:
1948 case ERROR_GAPS_IN_FRM_NUM:
1949 case ERROR_UNKNOWN_NAL:
1950 case ERROR_INV_MB_SLC_GRP_T:
1951 case ERROR_MULTIPLE_SLC_GRP_T:
1952 case ERROR_UNKNOWN_LEVEL:
1953 case ERROR_UNAVAIL_PICBUF_T:
1954 case ERROR_UNAVAIL_MVBUF_T:
1955 case ERROR_UNAVAIL_DISPBUF_T:
1956 case ERROR_NUM_REF:
1957 case ERROR_REFIDX_ORDER_T:
1958 case ERROR_PIC0_NOT_FOUND_T:
1959 case ERROR_MB_TYPE:
1960 case ERROR_SUB_MB_TYPE:
1961 case ERROR_CBP:
1962 case ERROR_REF_IDX:
1963 case ERROR_NUM_MV:
1964 case ERROR_CHROMA_PRED_MODE:
1965 case ERROR_INTRAPRED:
1966 case ERROR_NEXT_MB_ADDRESS_T:
1967 case ERROR_MB_ADDRESS_T:
1968 case ERROR_PIC1_NOT_FOUND_T:
1969 case ERROR_CAVLC_NUM_COEFF_T:
1970 case ERROR_CAVLC_SCAN_POS_T:
1971 case ERROR_PRED_WEIGHT_TABLE_T:
1972 case ERROR_CORRUPTED_SLICE:
1973 temp = 1 << IVD_CORRUPTEDDATA;
1974 break;
1975
1976 case ERROR_NOT_SUPP_RESOLUTION:
1977 case ERROR_ACTUAL_LEVEL_GREATER_THAN_INIT:
1978 temp = 1 << IVD_UNSUPPORTEDINPUT;
1979 break;
1980
1981 case ERROR_INVALID_PIC_PARAM:
1982 case ERROR_INVALID_SEQ_PARAM:
1983 case ERROR_EGC_EXCEED_32_1_T:
1984 case ERROR_EGC_EXCEED_32_2_T:
1985 case ERROR_INV_RANGE_TEV_T:
1986 case ERROR_INV_SLC_TYPE_T:
1987 case ERROR_INV_POC_TYPE_T:
1988 case ERROR_INV_RANGE_QP_T:
1989 case ERROR_INV_SPS_PPS_T:
1990 case ERROR_INV_SLICE_HDR_T:
1991 case ERROR_INV_SEI_MDCV_PARAMS:
1992 case ERROR_INV_SEI_CLL_PARAMS:
1993 case ERROR_INV_SEI_AVE_PARAMS:
1994 case ERROR_INV_SEI_CCV_PARAMS:
1995 case ERROR_INV_SEI_SII_PARAMS:
1996
1997 temp = 1 << IVD_CORRUPTEDHEADER;
1998 break;
1999
2000 case ERROR_EOB_FLUSHBITS_T:
2001 case ERROR_EOB_GETBITS_T:
2002 case ERROR_EOB_GETBIT_T:
2003 case ERROR_EOB_BYPASS_T:
2004 case ERROR_EOB_DECISION_T:
2005 case ERROR_EOB_TERMINATE_T:
2006 case ERROR_EOB_READCOEFF4X4CAB_T:
2007 temp = 1 << IVD_INSUFFICIENTDATA;
2008 break;
2009 case ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED:
2010 case ERROR_DISP_WIDTH_RESET_TO_PIC_WIDTH:
2011 temp = 1 << IVD_UNSUPPORTEDPARAM | 1 << IVD_FATALERROR;
2012 break;
2013
2014 case ERROR_DANGLING_FIELD_IN_PIC:
2015 temp = 1 << IVD_APPLIEDCONCEALMENT;
2016 break;
2017
2018 }
2019
2020 return temp;
2021
2022 }
2023
ih264d_get_outbuf_size(WORD32 pic_wd,UWORD32 pic_ht,UWORD8 u1_chroma_format,UWORD32 * p_buf_size)2024 UWORD32 ih264d_get_outbuf_size(WORD32 pic_wd,
2025 UWORD32 pic_ht,
2026 UWORD8 u1_chroma_format,
2027 UWORD32 *p_buf_size)
2028 {
2029 UWORD32 u4_min_num_out_bufs = 0;
2030
2031 if(u1_chroma_format == IV_YUV_420P)
2032 u4_min_num_out_bufs = MIN_OUT_BUFS_420;
2033 else if(u1_chroma_format == IV_YUV_422ILE)
2034 u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
2035 else if(u1_chroma_format == IV_RGB_565)
2036 u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
2037 else if((u1_chroma_format == IV_YUV_420SP_UV)
2038 || (u1_chroma_format == IV_YUV_420SP_VU))
2039 u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
2040
2041 if(u1_chroma_format == IV_YUV_420P)
2042 {
2043 p_buf_size[0] = (pic_wd * pic_ht);
2044 p_buf_size[1] = (pic_wd * pic_ht) >> 2;
2045 p_buf_size[2] = (pic_wd * pic_ht) >> 2;
2046 }
2047 else if(u1_chroma_format == IV_YUV_422ILE)
2048 {
2049 p_buf_size[0] = (pic_wd * pic_ht) * 2;
2050 p_buf_size[1] = p_buf_size[2] = 0;
2051 }
2052 else if(u1_chroma_format == IV_RGB_565)
2053 {
2054 p_buf_size[0] = (pic_wd * pic_ht) * 2;
2055 p_buf_size[1] = p_buf_size[2] = 0;
2056 }
2057 else if((u1_chroma_format == IV_YUV_420SP_UV)
2058 || (u1_chroma_format == IV_YUV_420SP_VU))
2059 {
2060 p_buf_size[0] = (pic_wd * pic_ht);
2061 p_buf_size[1] = (pic_wd * pic_ht) >> 1;
2062 p_buf_size[2] = 0;
2063 }
2064
2065 return u4_min_num_out_bufs;
2066 }
2067
check_app_out_buf_size(dec_struct_t * ps_dec)2068 WORD32 check_app_out_buf_size(dec_struct_t *ps_dec)
2069 {
2070 UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS];
2071 UWORD32 u4_min_num_out_bufs, i;
2072 UWORD32 pic_wd, pic_ht;
2073
2074 if(0 == ps_dec->u4_share_disp_buf)
2075 {
2076 pic_wd = ps_dec->u2_disp_width;
2077 pic_ht = ps_dec->u2_disp_height;
2078
2079 }
2080 else
2081 {
2082 pic_wd = ps_dec->u2_frm_wd_y;
2083 pic_ht = ps_dec->u2_frm_ht_y;
2084 }
2085
2086 if(ps_dec->u4_app_disp_width > pic_wd)
2087 pic_wd = ps_dec->u4_app_disp_width;
2088
2089 u4_min_num_out_bufs = ih264d_get_outbuf_size(pic_wd, pic_ht,
2090 ps_dec->u1_chroma_format,
2091 &au4_min_out_buf_size[0]);
2092
2093
2094 if(0 == ps_dec->u4_share_disp_buf)
2095 {
2096 if(ps_dec->ps_out_buffer->u4_num_bufs < u4_min_num_out_bufs)
2097 return IV_FAIL;
2098
2099 for(i = 0; i < u4_min_num_out_bufs; i++)
2100 {
2101 if(ps_dec->ps_out_buffer->u4_min_out_buf_size[i]
2102 < au4_min_out_buf_size[i])
2103 return (IV_FAIL);
2104 }
2105 }
2106 else
2107 {
2108 if(ps_dec->disp_bufs[0].u4_num_bufs < u4_min_num_out_bufs)
2109 return IV_FAIL;
2110
2111 for(i = 0; i < u4_min_num_out_bufs; i++)
2112 {
2113 /* We need to check only with the disp_buffer[0], because we have
2114 * already ensured that all the buffers are of the same size in
2115 * ih264d_set_display_frame.
2116 */
2117 if(ps_dec->disp_bufs[0].u4_bufsize[i] < au4_min_out_buf_size[i])
2118 return (IV_FAIL);
2119 }
2120
2121 }
2122
2123 return (IV_SUCCESS);
2124 }
2125
2126
2127 /*****************************************************************************/
2128 /* */
2129 /* Function Name : ih264d_video_decode */
2130 /* */
2131 /* Description : handle video decode API command */
2132 /* */
2133 /* Inputs :iv_obj_t decoder handle */
2134 /* :pv_api_ip pointer to input structure */
2135 /* :pv_api_op pointer to output structure */
2136 /* Outputs : */
2137 /* Returns : void */
2138 /* */
2139 /* Issues : none */
2140 /* */
2141 /* Revision History: */
2142 /* */
2143 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
2144 /* 22 10 2008 100356 Draft */
2145 /* */
2146 /*****************************************************************************/
2147
ih264d_video_decode(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)2148 WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
2149 {
2150 /* ! */
2151
2152 dec_struct_t * ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
2153
2154 WORD32 i4_err_status = 0;
2155 UWORD8 *pu1_buf = NULL;
2156 WORD32 buflen;
2157 UWORD32 u4_max_ofst, u4_length_of_start_code = 0;
2158
2159 UWORD32 bytes_consumed = 0;
2160 UWORD32 cur_slice_is_nonref = 0;
2161 UWORD32 u4_next_is_aud;
2162 UWORD32 u4_first_start_code_found = 0;
2163 WORD32 ret = 0,api_ret_value = IV_SUCCESS;
2164 WORD32 header_data_left = 0,frame_data_left = 0;
2165 UWORD8 *pu1_bitstrm_buf;
2166 ih264d_video_decode_ip_t *ps_h264d_dec_ip;
2167 ih264d_video_decode_op_t *ps_h264d_dec_op;
2168 ivd_video_decode_ip_t *ps_dec_ip;
2169 ivd_video_decode_op_t *ps_dec_op;
2170
2171 ithread_set_name((void*)"Parse_thread");
2172
2173 ps_h264d_dec_ip = (ih264d_video_decode_ip_t *)pv_api_ip;
2174 ps_h264d_dec_op = (ih264d_video_decode_op_t *)pv_api_op;
2175 ps_dec_ip = &ps_h264d_dec_ip->s_ivd_video_decode_ip_t;
2176 ps_dec_op = &ps_h264d_dec_op->s_ivd_video_decode_op_t;
2177
2178 {
2179 UWORD32 u4_size;
2180 u4_size = ps_dec_op->u4_size;
2181 memset(ps_h264d_dec_op, 0, ps_dec_op->u4_size);
2182 ps_dec_op->u4_size = u4_size;
2183 }
2184
2185 ps_dec->pv_dec_out = ps_dec_op;
2186 if(ps_dec->init_done != 1)
2187 {
2188 return IV_FAIL;
2189 }
2190
2191 /*Data memory barries instruction,so that bitstream write by the application is complete*/
2192 DATA_SYNC();
2193
2194 if(0 == ps_dec->u1_flushfrm)
2195 {
2196 if(ps_dec_ip->pv_stream_buffer == NULL)
2197 {
2198 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
2199 ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL;
2200 return IV_FAIL;
2201 }
2202 if(ps_dec_ip->u4_num_Bytes <= 0)
2203 {
2204 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
2205 ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV;
2206 return IV_FAIL;
2207
2208 }
2209 }
2210 ps_dec->u1_pic_decode_done = 0;
2211
2212 if(ps_dec->i4_threads_active)
2213 {
2214 UWORD32 i;
2215 ps_dec->i4_break_threads = 0;
2216 for (i = 0; i < 2; i++)
2217 {
2218 ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[i]);
2219 RETURN_IF((ret != IV_SUCCESS), ret);
2220
2221 ps_dec->ai4_process_start[i] = PROC_INIT;
2222
2223 ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[i]);
2224 RETURN_IF((ret != IV_SUCCESS), ret);
2225 }
2226 }
2227 else {
2228 ps_dec->u4_dec_thread_created = 0;
2229 ps_dec->u4_bs_deblk_thread_created = 0;
2230 }
2231
2232 ps_dec_op->u4_num_bytes_consumed = 0;
2233 ps_dec_op->i4_reorder_depth = -1;
2234 ps_dec_op->i4_display_index = DEFAULT_POC;
2235 ps_dec->ps_out_buffer = NULL;
2236
2237 if(ps_dec_ip->u4_size
2238 >= offsetof(ivd_video_decode_ip_t, s_out_buffer))
2239 ps_dec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
2240
2241 ps_dec->u4_fmt_conv_cur_row = 0;
2242
2243 ps_dec->u4_output_present = 0;
2244 ps_dec->s_disp_op.u4_error_code = 1;
2245 ps_dec->u4_fmt_conv_num_rows = FMT_CONV_NUM_ROWS;
2246 if(0 == ps_dec->u4_share_disp_buf
2247 && ps_dec->i4_decode_header == 0)
2248 {
2249 UWORD32 i;
2250 if((ps_dec->ps_out_buffer->u4_num_bufs == 0) ||
2251 (ps_dec->ps_out_buffer->u4_num_bufs > IVD_VIDDEC_MAX_IO_BUFFERS))
2252 {
2253 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
2254 ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
2255 return IV_FAIL;
2256 }
2257
2258 for(i = 0; i < ps_dec->ps_out_buffer->u4_num_bufs; i++)
2259 {
2260 if(ps_dec->ps_out_buffer->pu1_bufs[i] == NULL)
2261 {
2262 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
2263 ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL;
2264 return IV_FAIL;
2265 }
2266
2267 if(ps_dec->ps_out_buffer->u4_min_out_buf_size[i] == 0)
2268 {
2269 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
2270 ps_dec_op->u4_error_code |=
2271 IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
2272 return IV_FAIL;
2273 }
2274 }
2275 }
2276
2277 if(ps_dec->u4_total_frames_decoded >= NUM_FRAMES_LIMIT)
2278 {
2279 ps_dec_op->u4_error_code = ERROR_FRAME_LIMIT_OVER;
2280 return IV_FAIL;
2281 }
2282
2283 /* ! */
2284 ps_dec->u4_ts = ps_dec_ip->u4_ts;
2285
2286 ps_dec_op->u4_error_code = 0;
2287 ps_dec_op->e_pic_type = IV_NA_FRAME;
2288 ps_dec_op->u4_output_present = 0;
2289 ps_dec_op->u4_frame_decoded_flag = 0;
2290
2291 ps_dec->i4_frametype = IV_NA_FRAME;
2292 ps_dec->i4_content_type = IV_CONTENTTYPE_NA;
2293
2294 ps_dec->u4_slice_start_code_found = 0;
2295
2296 /* In case the decoder is not in flush mode(in shared mode),
2297 then decoder has to pick up a buffer to write current frame.
2298 Check if a frame is available in such cases */
2299
2300 if(ps_dec->u1_init_dec_flag == 1 && ps_dec->u4_share_disp_buf == 1
2301 && ps_dec->u1_flushfrm == 0)
2302 {
2303 UWORD32 i;
2304
2305 WORD32 disp_avail = 0, free_id;
2306
2307 /* Check if at least one buffer is available with the codec */
2308 /* If not then return to application with error */
2309 for(i = 0; i < ps_dec->u1_pic_bufs; i++)
2310 {
2311 if(0 == ps_dec->u4_disp_buf_mapping[i]
2312 || 1 == ps_dec->u4_disp_buf_to_be_freed[i])
2313 {
2314 disp_avail = 1;
2315 break;
2316 }
2317
2318 }
2319
2320 if(0 == disp_avail)
2321 {
2322 /* If something is queued for display wait for that buffer to be returned */
2323
2324 ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
2325 ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
2326 return (IV_FAIL);
2327 }
2328
2329 while(1)
2330 {
2331 pic_buffer_t *ps_pic_buf;
2332 ps_pic_buf = (pic_buffer_t *)ih264_buf_mgr_get_next_free(
2333 (buf_mgr_t *)ps_dec->pv_pic_buf_mgr, &free_id);
2334
2335 if(ps_pic_buf == NULL)
2336 {
2337 UWORD32 display_queued = 0;
2338
2339 /* check if any buffer was given for display which is not returned yet */
2340 for(i = 0; i < (MAX_DISP_BUFS_NEW); i++)
2341 {
2342 if(0 != ps_dec->u4_disp_buf_mapping[i])
2343 {
2344 display_queued = 1;
2345 break;
2346 }
2347 }
2348 /* If some buffer is queued for display, then codec has to singal an error and wait
2349 for that buffer to be returned.
2350 If nothing is queued for display then codec has ownership of all display buffers
2351 and it can reuse any of the existing buffers and continue decoding */
2352
2353 if(1 == display_queued)
2354 {
2355 /* If something is queued for display wait for that buffer to be returned */
2356 ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
2357 ps_dec_op->u4_error_code |= (1
2358 << IVD_UNSUPPORTEDPARAM);
2359 return (IV_FAIL);
2360 }
2361 }
2362 else
2363 {
2364 /* If the buffer is with display, then mark it as in use and then look for a buffer again */
2365 if(1 == ps_dec->u4_disp_buf_mapping[free_id])
2366 {
2367 ih264_buf_mgr_set_status(
2368 (buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
2369 free_id,
2370 BUF_MGR_IO);
2371 }
2372 else
2373 {
2374 /**
2375 * Found a free buffer for present call. Release it now.
2376 * Will be again obtained later.
2377 */
2378 ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
2379 free_id,
2380 BUF_MGR_IO);
2381 break;
2382 }
2383 }
2384 }
2385
2386 }
2387
2388 if(ps_dec->u1_enable_mb_info && (ps_dec->i4_header_decoded & DECODED_SPS_MASK))
2389 {
2390 UWORD32 blk_qp_map_size = ps_h264d_dec_ip->u4_8x8_blk_qp_map_size;
2391 UWORD32 blk_type_map_size = ps_h264d_dec_ip->u4_8x8_blk_type_map_size;
2392 UWORD32 blk_8x8_map_size = ps_dec->u4_total_mbs << 2;
2393 if ((ps_h264d_dec_ip->pu1_8x8_blk_qp_map && blk_qp_map_size < blk_8x8_map_size) ||
2394 (ps_h264d_dec_ip->pu1_8x8_blk_type_map && blk_type_map_size < blk_8x8_map_size))
2395 {
2396 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
2397 ps_dec_op->u4_error_code |= IH264D_INSUFFICIENT_METADATA_BUFFER;
2398 return IV_FAIL;
2399 }
2400 }
2401
2402 if(ps_dec->u1_flushfrm)
2403 {
2404 if(ps_dec->u1_init_dec_flag == 0)
2405 {
2406 /*Come out of flush mode and return*/
2407 ps_dec->u1_flushfrm = 0;
2408 return (IV_FAIL);
2409 }
2410
2411
2412
2413 ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer,
2414 &(ps_dec->s_disp_op));
2415 if(0 == ps_dec->s_disp_op.u4_error_code)
2416 {
2417 /* check output buffer size given by the application */
2418 if(check_app_out_buf_size(ps_dec) != IV_SUCCESS)
2419 {
2420 ps_dec_op->u4_error_code= IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
2421 return (IV_FAIL);
2422 }
2423
2424 ps_dec->u4_fmt_conv_cur_row = 0;
2425 ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht;
2426 ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op),
2427 ps_dec->u4_fmt_conv_cur_row,
2428 ps_dec->u4_fmt_conv_num_rows);
2429 ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
2430 ps_dec->u4_output_present = 1;
2431
2432 if(ps_dec->u1_enable_mb_info)
2433 {
2434 UWORD32 disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
2435 if(ps_h264d_dec_ip->pu1_8x8_blk_qp_map)
2436 {
2437 ps_h264d_dec_op->pu1_8x8_blk_qp_map = ps_h264d_dec_ip->pu1_8x8_blk_qp_map;
2438 ps_h264d_dec_op->u4_8x8_blk_qp_map_size = ps_dec->u4_total_mbs << 2;
2439 ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_qp_map,
2440 ps_dec->as_buf_id_info_map[disp_buf_id].pu1_qp_map,
2441 ps_dec->u4_total_mbs << 2);
2442 }
2443 if(ps_h264d_dec_ip->pu1_8x8_blk_type_map)
2444 {
2445 ps_h264d_dec_op->pu1_8x8_blk_type_map = ps_h264d_dec_ip->pu1_8x8_blk_type_map;
2446 ps_h264d_dec_op->u4_8x8_blk_type_map_size = ps_dec->u4_total_mbs << 2;
2447 ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_type_map,
2448 ps_dec->as_buf_id_info_map[disp_buf_id].pu1_mb_type_map,
2449 ps_dec->u4_total_mbs << 2);
2450 }
2451 }
2452 }
2453 ih264d_export_sei_params(&ps_dec_op->s_sei_decode_op, ps_dec);
2454
2455 ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op));
2456
2457 ps_dec_op->u4_pic_wd = (UWORD32)ps_dec->u2_disp_width;
2458 ps_dec_op->u4_pic_ht = (UWORD32)ps_dec->u2_disp_height;
2459 ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth;
2460 ps_dec_op->i4_display_index = ps_dec->i4_display_index;
2461
2462 ps_dec_op->u4_new_seq = 0;
2463
2464 ps_dec_op->u4_output_present = ps_dec->u4_output_present;
2465 ps_dec_op->u4_progressive_frame_flag =
2466 ps_dec->s_disp_op.u4_progressive_frame_flag;
2467 ps_dec_op->e_output_format =
2468 ps_dec->s_disp_op.e_output_format;
2469 ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf;
2470 ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type;
2471 ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts;
2472 ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
2473
2474 /*In the case of flush ,since no frame is decoded set pic type as invalid*/
2475 ps_dec_op->u4_is_ref_flag = -1;
2476 ps_dec_op->e_pic_type = IV_NA_FRAME;
2477 ps_dec_op->u4_frame_decoded_flag = 0;
2478
2479 if(0 == ps_dec->s_disp_op.u4_error_code)
2480 {
2481 return (IV_SUCCESS);
2482 }
2483 else
2484 return (IV_FAIL);
2485
2486 }
2487 if(ps_dec->u1_res_changed == 1)
2488 {
2489 /*if resolution has changed and all buffers have been flushed, reset decoder*/
2490 ih264d_init_decoder(ps_dec);
2491 }
2492
2493 ps_dec->u2_cur_mb_addr = 0;
2494 ps_dec->u2_total_mbs_coded = 0;
2495 ps_dec->u2_cur_slice_num = 0;
2496 ps_dec->cur_dec_mb_num = 0;
2497 ps_dec->cur_recon_mb_num = 0;
2498 ps_dec->u4_first_slice_in_pic = 1;
2499 ps_dec->u1_slice_header_done = 0;
2500 ps_dec->u1_dangling_field = 0;
2501 ps_dec->u4_cur_bs_mb_num = 0;
2502 ps_dec->u4_start_recon_deblk = 0;
2503 ps_dec->u4_sps_cnt_in_process = 0;
2504
2505 DEBUG_THREADS_PRINTF(" Starting process call\n");
2506
2507
2508 ps_dec->u4_pic_buf_got = 0;
2509
2510 do
2511 {
2512 WORD32 buf_size;
2513
2514 pu1_buf = (UWORD8*)ps_dec_ip->pv_stream_buffer
2515 + ps_dec_op->u4_num_bytes_consumed;
2516
2517 u4_max_ofst = ps_dec_ip->u4_num_Bytes
2518 - ps_dec_op->u4_num_bytes_consumed;
2519
2520 /* If dynamic bitstream buffer is not allocated and
2521 * header decode is done, then allocate dynamic bitstream buffer
2522 */
2523 if((NULL == ps_dec->pu1_bits_buf_dynamic) &&
2524 (ps_dec->i4_header_decoded & 1))
2525 {
2526 WORD32 size;
2527
2528 void *pv_buf;
2529 void *pv_mem_ctxt = ps_dec->pv_mem_ctxt;
2530 size = MAX(256000, ps_dec->u2_pic_wd * ps_dec->u2_pic_ht * 3 / 2);
2531 pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128,
2532 size + EXTRA_BS_OFFSET);
2533 RETURN_IF((NULL == pv_buf), IV_FAIL);
2534 memset(pv_buf, 0, size + EXTRA_BS_OFFSET);
2535 ps_dec->pu1_bits_buf_dynamic = pv_buf;
2536 ps_dec->u4_dynamic_bits_buf_size = size;
2537 }
2538
2539 if(ps_dec->pu1_bits_buf_dynamic)
2540 {
2541 pu1_bitstrm_buf = ps_dec->pu1_bits_buf_dynamic;
2542 buf_size = ps_dec->u4_dynamic_bits_buf_size;
2543 }
2544 else
2545 {
2546 pu1_bitstrm_buf = ps_dec->pu1_bits_buf_static;
2547 buf_size = ps_dec->u4_static_bits_buf_size;
2548 }
2549
2550 u4_next_is_aud = 0;
2551
2552 buflen = ih264d_find_start_code(pu1_buf, 0, u4_max_ofst,
2553 &u4_length_of_start_code,
2554 &u4_next_is_aud);
2555
2556 if(buflen == -1)
2557 buflen = 0;
2558 /* Ignore bytes beyond the allocated size of intermediate buffer */
2559 /* Since 8 bytes are read ahead, ensure 8 bytes are free at the
2560 end of the buffer, which will be memset to 0 after emulation prevention */
2561 buflen = MIN(buflen, buf_size - 8);
2562
2563 bytes_consumed = buflen + u4_length_of_start_code;
2564 ps_dec_op->u4_num_bytes_consumed += bytes_consumed;
2565
2566 if(buflen)
2567 {
2568 memcpy(pu1_bitstrm_buf, pu1_buf + u4_length_of_start_code,
2569 buflen);
2570 /* Decoder may read extra 8 bytes near end of the frame */
2571 if((buflen + 8) < buf_size)
2572 {
2573 memset(pu1_bitstrm_buf + buflen, 0, 8);
2574 }
2575 u4_first_start_code_found = 1;
2576
2577 }
2578 else
2579 {
2580 /*start code not found*/
2581
2582 if(u4_first_start_code_found == 0)
2583 {
2584 /*no start codes found in current process call*/
2585
2586 ps_dec->i4_error_code = ERROR_START_CODE_NOT_FOUND;
2587 ps_dec_op->u4_error_code |= 1 << IVD_INSUFFICIENTDATA;
2588
2589 if(ps_dec->u4_pic_buf_got == 0)
2590 {
2591
2592 ih264d_fill_output_struct_from_context(ps_dec,
2593 ps_dec_op);
2594
2595 ps_dec_op->u4_error_code = ps_dec->i4_error_code;
2596 ps_dec_op->u4_frame_decoded_flag = 0;
2597
2598 return (IV_FAIL);
2599 }
2600 else
2601 {
2602 ps_dec->u1_pic_decode_done = 1;
2603 continue;
2604 }
2605 }
2606 else
2607 {
2608 /* a start code has already been found earlier in the same process call*/
2609 frame_data_left = 0;
2610 header_data_left = 0;
2611 continue;
2612 }
2613
2614 }
2615
2616 ret = ih264d_parse_nal_unit(dec_hdl, ps_dec_op,
2617 pu1_bitstrm_buf, buflen);
2618 if(ret != OK)
2619 {
2620 UWORD32 error = ih264d_map_error(ret);
2621 ps_dec_op->u4_error_code = error | ret;
2622 api_ret_value = IV_FAIL;
2623
2624 if((ret == IVD_RES_CHANGED)
2625 || (ret == IVD_MEM_ALLOC_FAILED)
2626 || (ret == ERROR_UNAVAIL_PICBUF_T)
2627 || (ret == ERROR_UNAVAIL_MVBUF_T)
2628 || (ret == ERROR_INV_SPS_PPS_T)
2629 || (ret == ERROR_FEATURE_UNAVAIL)
2630 || (ret == IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED)
2631 || (ret == IVD_DISP_FRM_ZERO_OP_BUF_SIZE))
2632 {
2633 ps_dec->u4_slice_start_code_found = 0;
2634 break;
2635 }
2636
2637 if((ret == ERROR_INCOMPLETE_FRAME) || (ret == ERROR_DANGLING_FIELD_IN_PIC))
2638 {
2639 ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
2640 api_ret_value = IV_FAIL;
2641 break;
2642 }
2643
2644 if(ret == ERROR_IN_LAST_SLICE_OF_PIC)
2645 {
2646 api_ret_value = IV_FAIL;
2647 break;
2648 }
2649
2650 }
2651
2652 header_data_left = ((ps_dec->i4_decode_header == 1)
2653 && (ps_dec->i4_header_decoded != 3)
2654 && (ps_dec_op->u4_num_bytes_consumed
2655 < ps_dec_ip->u4_num_Bytes));
2656 frame_data_left = (((ps_dec->i4_decode_header == 0)
2657 && ((ps_dec->u1_pic_decode_done == 0)
2658 || (u4_next_is_aud == 1)))
2659 && (ps_dec_op->u4_num_bytes_consumed
2660 < ps_dec_ip->u4_num_Bytes));
2661 }
2662 while(( header_data_left == 1)||(frame_data_left == 1));
2663
2664 if((ps_dec->u4_pic_buf_got == 1)
2665 && (ret != IVD_MEM_ALLOC_FAILED)
2666 && ps_dec->u2_total_mbs_coded < ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
2667 {
2668 // last slice - missing/corruption
2669 WORD32 num_mb_skipped;
2670 WORD32 prev_slice_err;
2671 pocstruct_t temp_poc;
2672 WORD32 ret1;
2673 WORD32 ht_in_mbs;
2674 ht_in_mbs = ps_dec->u2_pic_ht >> (4 + ps_dec->ps_cur_slice->u1_field_pic_flag);
2675 num_mb_skipped = (ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
2676 - ps_dec->u2_total_mbs_coded;
2677
2678 if(ps_dec->u4_first_slice_in_pic && (ps_dec->u4_pic_buf_got == 0))
2679 prev_slice_err = 1;
2680 else
2681 prev_slice_err = 2;
2682
2683 if(ps_dec->u4_first_slice_in_pic && (ps_dec->u2_total_mbs_coded == 0))
2684 prev_slice_err = 1;
2685
2686 ret1 = ih264d_mark_err_slice_skip(ps_dec, num_mb_skipped, ps_dec->u1_nal_unit_type == IDR_SLICE_NAL, ps_dec->ps_cur_slice->u2_frame_num,
2687 &temp_poc, prev_slice_err);
2688
2689 if((ret1 == ERROR_UNAVAIL_PICBUF_T) || (ret1 == ERROR_UNAVAIL_MVBUF_T) ||
2690 (ret1 == ERROR_INV_SPS_PPS_T))
2691 {
2692 ret = ret1;
2693 }
2694 }
2695
2696 if((ret == IVD_RES_CHANGED)
2697 || (ret == IVD_MEM_ALLOC_FAILED)
2698 || (ret == ERROR_UNAVAIL_PICBUF_T)
2699 || (ret == ERROR_UNAVAIL_MVBUF_T)
2700 || (ret == ERROR_INV_SPS_PPS_T))
2701 {
2702
2703 /* signal the decode thread */
2704 ih264d_signal_decode_thread(ps_dec);
2705 /* close deblock thread if it is not closed yet */
2706 if(ps_dec->u4_num_cores == 3)
2707 {
2708 ih264d_signal_bs_deblk_thread(ps_dec);
2709 }
2710 /* dont consume bitstream for change in resolution case */
2711 if(ret == IVD_RES_CHANGED)
2712 {
2713 ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
2714 }
2715 return IV_FAIL;
2716 }
2717
2718
2719 if(ps_dec->u1_separate_parse)
2720 {
2721 /* If Format conversion is not complete,
2722 complete it here */
2723 if(ps_dec->u4_num_cores == 2)
2724 {
2725
2726 /*do deblocking of all mbs*/
2727 if((ps_dec->u4_nmb_deblk == 0) &&(ps_dec->u4_start_recon_deblk == 1) && (ps_dec->ps_cur_sps->u1_mb_aff_flag == 0))
2728 {
2729 UWORD32 u4_num_mbs,u4_max_addr;
2730 tfr_ctxt_t s_tfr_ctxt;
2731 tfr_ctxt_t *ps_tfr_cxt = &s_tfr_ctxt;
2732 pad_mgr_t *ps_pad_mgr = &ps_dec->s_pad_mgr;
2733
2734 /*BS is done for all mbs while parsing*/
2735 u4_max_addr = (ps_dec->u2_frm_wd_in_mbs * ps_dec->u2_frm_ht_in_mbs) - 1;
2736 ps_dec->u4_cur_bs_mb_num = u4_max_addr + 1;
2737
2738
2739 ih264d_init_deblk_tfr_ctxt(ps_dec, ps_pad_mgr, ps_tfr_cxt,
2740 ps_dec->u2_frm_wd_in_mbs, 0);
2741
2742
2743 u4_num_mbs = u4_max_addr
2744 - ps_dec->u4_cur_deblk_mb_num + 1;
2745
2746 DEBUG_PERF_PRINTF("mbs left for deblocking= %d \n",u4_num_mbs);
2747
2748 if(u4_num_mbs != 0)
2749 ih264d_check_mb_map_deblk(ps_dec, u4_num_mbs,
2750 ps_tfr_cxt,1);
2751
2752 ps_dec->u4_start_recon_deblk = 0;
2753
2754 }
2755
2756 }
2757
2758 /*signal the decode thread*/
2759 ih264d_signal_decode_thread(ps_dec);
2760 /* close deblock thread if it is not closed yet*/
2761 if(ps_dec->u4_num_cores == 3)
2762 {
2763 ih264d_signal_bs_deblk_thread(ps_dec);
2764 }
2765 }
2766
2767
2768 DATA_SYNC();
2769
2770
2771 if((ps_dec_op->u4_error_code & 0xff)
2772 != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED)
2773 {
2774 ps_dec_op->u4_pic_wd = (UWORD32)ps_dec->u2_disp_width;
2775 ps_dec_op->u4_pic_ht = (UWORD32)ps_dec->u2_disp_height;
2776 ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth;
2777 }
2778
2779 //Report if header (sps and pps) has not been decoded yet
2780 if(ps_dec->i4_decode_header == 1 && ps_dec->i4_header_decoded != 3)
2781 {
2782 ps_dec_op->u4_error_code |= (1 << IVD_INSUFFICIENTDATA);
2783 api_ret_value = IV_FAIL;
2784 }
2785
2786 if((ps_dec->u4_pic_buf_got == 1)
2787 && (ERROR_DANGLING_FIELD_IN_PIC != i4_err_status))
2788 {
2789 /*
2790 * For field pictures, set the bottom and top picture decoded u4_flag correctly.
2791 */
2792
2793 if(ps_dec->ps_cur_slice->u1_field_pic_flag)
2794 {
2795 if(1 == ps_dec->ps_cur_slice->u1_bottom_field_flag)
2796 {
2797 ps_dec->u1_top_bottom_decoded |= BOT_FIELD_ONLY;
2798 }
2799 else
2800 {
2801 ps_dec->u1_top_bottom_decoded |= TOP_FIELD_ONLY;
2802 }
2803 }
2804 else
2805 {
2806 ps_dec->u1_top_bottom_decoded = TOP_FIELD_ONLY | BOT_FIELD_ONLY;
2807 }
2808
2809 /* if new frame in not found (if we are still getting slices from previous frame)
2810 * ih264d_deblock_display is not called. Such frames will not be added to reference /display
2811 */
2812 if ((ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC) == 0)
2813 {
2814 /* Calling Function to deblock Picture and Display */
2815 ret = ih264d_deblock_display(ps_dec);
2816 }
2817
2818
2819 /*set to complete ,as we dont support partial frame decode*/
2820 if(ps_dec->i4_header_decoded == 3)
2821 {
2822 ps_dec->u2_total_mbs_coded = ps_dec->ps_cur_sps->u2_max_mb_addr + 1;
2823 }
2824
2825 /*Update the i4_frametype at the end of picture*/
2826 if(ps_dec->ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL)
2827 {
2828 ps_dec->i4_frametype = IV_IDR_FRAME;
2829 }
2830 else if(ps_dec->i4_pic_type == B_SLICE)
2831 {
2832 ps_dec->i4_frametype = IV_B_FRAME;
2833 }
2834 else if(ps_dec->i4_pic_type == P_SLICE)
2835 {
2836 ps_dec->i4_frametype = IV_P_FRAME;
2837 }
2838 else if(ps_dec->i4_pic_type == I_SLICE)
2839 {
2840 ps_dec->i4_frametype = IV_I_FRAME;
2841 }
2842 else
2843 {
2844 H264_DEC_DEBUG_PRINT("Shouldn't come here\n");
2845 }
2846
2847 //Update the content type
2848 ps_dec->i4_content_type = ps_dec->ps_cur_slice->u1_field_pic_flag;
2849
2850 ps_dec->u4_total_frames_decoded = ps_dec->u4_total_frames_decoded + 2;
2851 ps_dec->u4_total_frames_decoded = ps_dec->u4_total_frames_decoded
2852 - ps_dec->ps_cur_slice->u1_field_pic_flag;
2853
2854 }
2855
2856 /* close deblock thread if it is not closed yet*/
2857 if(!ps_dec->i4_threads_active)
2858 {
2859 if(ps_dec->u4_num_cores == 3)
2860 {
2861 ih264d_signal_bs_deblk_thread(ps_dec);
2862 }
2863 }
2864
2865
2866 {
2867 /* In case the decoder is configured to run in low delay mode,
2868 * then get display buffer and then format convert.
2869 * Note in this mode, format conversion does not run paralelly in a thread and adds to the codec cycles
2870 */
2871
2872 if((IVD_DECODE_FRAME_OUT == ps_dec->e_frm_out_mode)
2873 && ps_dec->u1_init_dec_flag)
2874 {
2875
2876 ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer,
2877 &(ps_dec->s_disp_op));
2878 if(0 == ps_dec->s_disp_op.u4_error_code)
2879 {
2880 ps_dec->u4_fmt_conv_cur_row = 0;
2881 ps_dec->u4_output_present = 1;
2882 }
2883 }
2884
2885 ih264d_fill_output_struct_from_context(ps_dec, ps_dec_op);
2886
2887 /* If Format conversion is not complete,
2888 complete it here */
2889 if(ps_dec->u4_output_present &&
2890 (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
2891 {
2892 ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht
2893 - ps_dec->u4_fmt_conv_cur_row;
2894 ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op),
2895 ps_dec->u4_fmt_conv_cur_row,
2896 ps_dec->u4_fmt_conv_num_rows);
2897 ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
2898 }
2899
2900 ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op));
2901 }
2902
2903 if(ps_dec->i4_decode_header == 1 && (ps_dec->i4_header_decoded & 1) == 1)
2904 {
2905 ps_dec_op->u4_progressive_frame_flag = 1;
2906 if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
2907 {
2908 if((0 == ps_dec->ps_sps->u1_frame_mbs_only_flag)
2909 && (0 == ps_dec->ps_sps->u1_mb_aff_flag))
2910 ps_dec_op->u4_progressive_frame_flag = 0;
2911
2912 }
2913 }
2914
2915 if((TOP_FIELD_ONLY | BOT_FIELD_ONLY) == ps_dec->u1_top_bottom_decoded)
2916 {
2917 ps_dec->u1_top_bottom_decoded = 0;
2918 }
2919 /*--------------------------------------------------------------------*/
2920 /* Do End of Pic processing. */
2921 /* Should be called only if frame was decoded in previous process call*/
2922 /*--------------------------------------------------------------------*/
2923 if(ps_dec->u4_pic_buf_got == 1)
2924 {
2925 if(1 == ps_dec->u1_last_pic_not_decoded)
2926 {
2927 ret = ih264d_end_of_pic_dispbuf_mgr(ps_dec);
2928
2929 if(ret != OK)
2930 return ret;
2931
2932 ret = ih264d_end_of_pic(ps_dec);
2933 if(ret != OK)
2934 return ret;
2935 }
2936 else
2937 {
2938 ret = ih264d_end_of_pic(ps_dec);
2939 if(ret != OK)
2940 return ret;
2941 }
2942
2943 }
2944
2945 if(ps_dec->u1_enable_mb_info && ps_dec->u4_output_present)
2946 {
2947 UWORD32 disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
2948 if(ps_h264d_dec_ip->pu1_8x8_blk_qp_map)
2949 {
2950 ps_h264d_dec_op->pu1_8x8_blk_qp_map = ps_h264d_dec_ip->pu1_8x8_blk_qp_map;
2951 ps_h264d_dec_op->u4_8x8_blk_qp_map_size = ps_dec->u4_total_mbs << 2;
2952 ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_qp_map,
2953 ps_dec->as_buf_id_info_map[disp_buf_id].pu1_qp_map,
2954 ps_dec->u4_total_mbs << 2);
2955 }
2956 if(ps_h264d_dec_ip->pu1_8x8_blk_type_map)
2957 {
2958 ps_h264d_dec_op->pu1_8x8_blk_type_map = ps_h264d_dec_ip->pu1_8x8_blk_type_map;
2959 ps_h264d_dec_op->u4_8x8_blk_type_map_size = ps_dec->u4_total_mbs << 2;
2960 ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_type_map,
2961 ps_dec->as_buf_id_info_map[disp_buf_id].pu1_mb_type_map,
2962 ps_dec->u4_total_mbs << 2);
2963 }
2964 }
2965
2966 /*Data memory barrier instruction,so that yuv write by the library is complete*/
2967 DATA_SYNC();
2968
2969 H264_DEC_DEBUG_PRINT("The num bytes consumed: %d\n",
2970 ps_dec_op->u4_num_bytes_consumed);
2971 return api_ret_value;
2972 }
2973
ih264d_get_version(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)2974 WORD32 ih264d_get_version(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
2975 {
2976 char version_string[MAXVERSION_STRLEN + 1];
2977 UWORD32 version_string_len;
2978
2979 ivd_ctl_getversioninfo_ip_t *ps_ip;
2980 ivd_ctl_getversioninfo_op_t *ps_op;
2981
2982 ps_ip = (ivd_ctl_getversioninfo_ip_t *)pv_api_ip;
2983 ps_op = (ivd_ctl_getversioninfo_op_t *)pv_api_op;
2984 UNUSED(dec_hdl);
2985 ps_op->u4_error_code = IV_SUCCESS;
2986
2987 VERSION(version_string, CODEC_NAME, CODEC_RELEASE_TYPE, CODEC_RELEASE_VER,
2988 CODEC_VENDOR);
2989
2990 if((WORD32)ps_ip->u4_version_buffer_size <= 0)
2991 {
2992 ps_op->u4_error_code = IH264D_VERS_BUF_INSUFFICIENT;
2993 return (IV_FAIL);
2994 }
2995
2996 version_string_len = strnlen(version_string, MAXVERSION_STRLEN) + 1;
2997
2998 if(ps_ip->u4_version_buffer_size >= version_string_len) //(WORD32)sizeof(sizeof(version_string)))
2999 {
3000 memcpy(ps_ip->pv_version_buffer, version_string, version_string_len);
3001 ps_op->u4_error_code = IV_SUCCESS;
3002 }
3003 else
3004 {
3005 ps_op->u4_error_code = IH264D_VERS_BUF_INSUFFICIENT;
3006 return IV_FAIL;
3007 }
3008 return (IV_SUCCESS);
3009 }
3010
3011 /*****************************************************************************/
3012 /* */
3013 /* Function Name : ih264d_get_display_frame */
3014 /* */
3015 /* Description : */
3016 /* Inputs :iv_obj_t decoder handle */
3017 /* :pv_api_ip pointer to input structure */
3018 /* :pv_api_op pointer to output structure */
3019 /* Outputs : */
3020 /* Returns : void */
3021 /* */
3022 /* Issues : none */
3023 /* */
3024 /* Revision History: */
3025 /* */
3026 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
3027 /* 22 10 2008 100356 Draft */
3028 /* */
3029 /*****************************************************************************/
ih264d_get_display_frame(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3030 WORD32 ih264d_get_display_frame(iv_obj_t *dec_hdl,
3031 void *pv_api_ip,
3032 void *pv_api_op)
3033 {
3034
3035 UNUSED(dec_hdl);
3036 UNUSED(pv_api_ip);
3037 UNUSED(pv_api_op);
3038 // This function is no longer needed, output is returned in the process()
3039 return IV_FAIL;
3040 }
3041
3042 /*****************************************************************************/
3043 /* */
3044 /* Function Name : ih264d_set_display_frame */
3045 /* */
3046 /* Description : */
3047 /* */
3048 /* Inputs :iv_obj_t decoder handle */
3049 /* :pv_api_ip pointer to input structure */
3050 /* :pv_api_op pointer to output structure */
3051 /* Outputs : */
3052 /* Returns : void */
3053 /* */
3054 /* Issues : none */
3055 /* */
3056 /* Revision History: */
3057 /* */
3058 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
3059 /* 22 10 2008 100356 Draft */
3060 /* */
3061 /*****************************************************************************/
ih264d_set_display_frame(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3062 WORD32 ih264d_set_display_frame(iv_obj_t *dec_hdl,
3063 void *pv_api_ip,
3064 void *pv_api_op)
3065 {
3066
3067 UWORD32 u4_disp_buf_size[3], u4_num_disp_bufs;
3068 ivd_set_display_frame_ip_t *dec_disp_ip;
3069 ivd_set_display_frame_op_t *dec_disp_op;
3070
3071 UWORD32 i;
3072 dec_struct_t * ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
3073
3074 dec_disp_ip = (ivd_set_display_frame_ip_t *)pv_api_ip;
3075 dec_disp_op = (ivd_set_display_frame_op_t *)pv_api_op;
3076 dec_disp_op->u4_error_code = 0;
3077
3078
3079 ps_dec->u4_num_disp_bufs = 0;
3080 if(ps_dec->u4_share_disp_buf)
3081 {
3082 UWORD32 u4_num_bufs = dec_disp_ip->num_disp_bufs;
3083
3084 u4_num_bufs = MIN(u4_num_bufs, MAX_DISP_BUFS_NEW);
3085
3086 ps_dec->u4_num_disp_bufs = u4_num_bufs;
3087
3088 /* Get the number and sizes of the first buffer. Compare this with the
3089 * rest to make sure all the buffers are of the same size.
3090 */
3091 u4_num_disp_bufs = dec_disp_ip->s_disp_buffer[0].u4_num_bufs;
3092
3093 u4_disp_buf_size[0] =
3094 dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[0];
3095 u4_disp_buf_size[1] =
3096 dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[1];
3097 u4_disp_buf_size[2] =
3098 dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[2];
3099
3100 for(i = 0; i < u4_num_bufs; i++)
3101 {
3102 if(dec_disp_ip->s_disp_buffer[i].u4_num_bufs != u4_num_disp_bufs)
3103 {
3104 return IV_FAIL;
3105 }
3106
3107 if((dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[0]
3108 != u4_disp_buf_size[0])
3109 || (dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[1]
3110 != u4_disp_buf_size[1])
3111 || (dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[2]
3112 != u4_disp_buf_size[2]))
3113 {
3114 return IV_FAIL;
3115 }
3116
3117 ps_dec->disp_bufs[i].u4_num_bufs =
3118 dec_disp_ip->s_disp_buffer[i].u4_num_bufs;
3119
3120 ps_dec->disp_bufs[i].buf[0] =
3121 dec_disp_ip->s_disp_buffer[i].pu1_bufs[0];
3122 ps_dec->disp_bufs[i].buf[1] =
3123 dec_disp_ip->s_disp_buffer[i].pu1_bufs[1];
3124 ps_dec->disp_bufs[i].buf[2] =
3125 dec_disp_ip->s_disp_buffer[i].pu1_bufs[2];
3126
3127 ps_dec->disp_bufs[i].u4_bufsize[0] =
3128 dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[0];
3129 ps_dec->disp_bufs[i].u4_bufsize[1] =
3130 dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[1];
3131 ps_dec->disp_bufs[i].u4_bufsize[2] =
3132 dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[2];
3133
3134 }
3135 }
3136 return IV_SUCCESS;
3137
3138 }
3139
3140 /*****************************************************************************/
3141 /* */
3142 /* Function Name : ih264d_set_flush_mode */
3143 /* */
3144 /* Description : */
3145 /* */
3146 /* Inputs :iv_obj_t decoder handle */
3147 /* :pv_api_ip pointer to input structure */
3148 /* :pv_api_op pointer to output structure */
3149 /* Globals : <Does it use any global variables?> */
3150 /* Outputs : */
3151 /* Returns : void */
3152 /* */
3153 /* Issues : none */
3154 /* */
3155 /* Revision History: */
3156 /* */
3157 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
3158 /* 22 10 2008 100356 Draft */
3159 /* */
3160 /*****************************************************************************/
ih264d_set_flush_mode(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3161 WORD32 ih264d_set_flush_mode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
3162 {
3163 dec_struct_t * ps_dec;
3164 ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t*)pv_api_op;
3165 ps_ctl_op->u4_error_code = 0;
3166
3167 ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
3168 ih264d_join_threads(ps_dec);
3169 UNUSED(pv_api_ip);
3170 /* ! */
3171 /* Signal flush frame control call */
3172 ps_dec->u1_flushfrm = 1;
3173
3174 if(ps_dec->u1_init_dec_flag == 1)
3175 {
3176 ih264d_release_pics_in_dpb((void *)ps_dec, ps_dec->u1_pic_bufs);
3177 ih264d_release_display_bufs(ps_dec);
3178 }
3179
3180 ps_ctl_op->u4_error_code = 0;
3181
3182 /* Ignore dangling fields during flush */
3183 ps_dec->u1_top_bottom_decoded = 0;
3184
3185 return IV_SUCCESS;
3186 }
3187
3188 /*****************************************************************************/
3189 /* */
3190 /* Function Name : ih264d_get_status */
3191 /* */
3192 /* Description : */
3193 /* */
3194 /* Inputs :iv_obj_t decoder handle */
3195 /* :pv_api_ip pointer to input structure */
3196 /* :pv_api_op pointer to output structure */
3197 /* Globals : <Does it use any global variables?> */
3198 /* Outputs : */
3199 /* Returns : void */
3200 /* */
3201 /* Issues : none */
3202 /* */
3203 /* Revision History: */
3204 /* */
3205 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
3206 /* 22 10 2008 100356 Draft */
3207 /* */
3208 /*****************************************************************************/
3209
ih264d_get_status(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3210 WORD32 ih264d_get_status(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
3211 {
3212
3213 UWORD32 i;
3214 dec_struct_t * ps_dec;
3215 UWORD32 pic_wd, pic_ht;
3216 ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t*)pv_api_op;
3217 UNUSED(pv_api_ip);
3218 ps_ctl_op->u4_error_code = 0;
3219
3220 ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
3221
3222
3223 if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
3224 {
3225 ps_ctl_op->u4_pic_ht = ps_dec->u2_disp_height;
3226 ps_ctl_op->u4_pic_wd = ps_dec->u2_disp_width;
3227
3228 if(0 == ps_dec->u4_share_disp_buf)
3229 {
3230 pic_wd = ps_dec->u2_disp_width;
3231 pic_ht = ps_dec->u2_disp_height;
3232
3233 }
3234 else
3235 {
3236 pic_wd = ps_dec->u2_frm_wd_y;
3237 pic_ht = ps_dec->u2_frm_ht_y;
3238 }
3239 }
3240 else
3241 {
3242 pic_wd = 0;
3243 pic_ht = 0;
3244
3245 ps_ctl_op->u4_pic_ht = pic_wd;
3246 ps_ctl_op->u4_pic_wd = pic_ht;
3247
3248 if(1 == ps_dec->u4_share_disp_buf)
3249 {
3250 pic_wd += (PAD_LEN_Y_H << 1);
3251 pic_ht += (PAD_LEN_Y_V << 2);
3252
3253 }
3254
3255 }
3256
3257 if(ps_dec->u4_app_disp_width > pic_wd)
3258 pic_wd = ps_dec->u4_app_disp_width;
3259 if(0 == ps_dec->u4_share_disp_buf)
3260 ps_ctl_op->u4_num_disp_bufs = 1;
3261 else
3262 {
3263 if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
3264 {
3265 if((ps_dec->ps_cur_sps->u1_vui_parameters_present_flag == 1) &&
3266 (1 == ps_dec->ps_cur_sps->s_vui.u1_bitstream_restriction_flag))
3267 {
3268 ps_ctl_op->u4_num_disp_bufs =
3269 ps_dec->ps_cur_sps->s_vui.u4_num_reorder_frames + 1;
3270 }
3271 else
3272 {
3273 /*if VUI is not present assume maximum possible refrence frames for the level,
3274 * as max reorder frames*/
3275 ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size(ps_dec->ps_cur_sps);
3276 }
3277
3278 ps_ctl_op->u4_num_disp_bufs +=
3279 ps_dec->ps_cur_sps->u1_num_ref_frames + 1;
3280 }
3281 else
3282 {
3283 ps_ctl_op->u4_num_disp_bufs = 32;
3284 }
3285 ps_ctl_op->u4_num_disp_bufs = MAX(
3286 ps_ctl_op->u4_num_disp_bufs, 6);
3287 ps_ctl_op->u4_num_disp_bufs = MIN(
3288 ps_ctl_op->u4_num_disp_bufs, 32);
3289 }
3290
3291 ps_ctl_op->u4_error_code = ps_dec->i4_error_code;
3292
3293 ps_ctl_op->u4_frame_rate = 0; //make it proper
3294 ps_ctl_op->u4_bit_rate = 0; //make it proper
3295 ps_ctl_op->e_content_type = ps_dec->i4_content_type;
3296 ps_ctl_op->e_output_chroma_format = ps_dec->u1_chroma_format;
3297 ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
3298
3299 if(ps_dec->u1_chroma_format == IV_YUV_420P)
3300 {
3301 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
3302 }
3303 else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
3304 {
3305 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
3306 }
3307 else if(ps_dec->u1_chroma_format == IV_RGB_565)
3308 {
3309 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
3310 }
3311 else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV)
3312 || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
3313 {
3314 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
3315 }
3316
3317 else
3318 {
3319 //Invalid chroma format; Error code may be updated, verify in testing if needed
3320 ps_ctl_op->u4_error_code = ERROR_FEATURE_UNAVAIL;
3321 return IV_FAIL;
3322 }
3323
3324 for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
3325 {
3326 ps_ctl_op->u4_min_in_buf_size[i] = MAX(256000, pic_wd * pic_ht * 3 / 2);
3327 }
3328
3329 /*!*/
3330 if(ps_dec->u1_chroma_format == IV_YUV_420P)
3331 {
3332 ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
3333 ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht)
3334 >> 2;
3335 ps_ctl_op->u4_min_out_buf_size[2] = (pic_wd * pic_ht)
3336 >> 2;
3337 }
3338 else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
3339 {
3340 ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht)
3341 * 2;
3342 ps_ctl_op->u4_min_out_buf_size[1] =
3343 ps_ctl_op->u4_min_out_buf_size[2] = 0;
3344 }
3345 else if(ps_dec->u1_chroma_format == IV_RGB_565)
3346 {
3347 ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht)
3348 * 2;
3349 ps_ctl_op->u4_min_out_buf_size[1] =
3350 ps_ctl_op->u4_min_out_buf_size[2] = 0;
3351 }
3352 else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV)
3353 || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
3354 {
3355 ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
3356 ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht)
3357 >> 1;
3358 ps_ctl_op->u4_min_out_buf_size[2] = 0;
3359 }
3360
3361 ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs;
3362 return IV_SUCCESS;
3363 }
3364
3365 /*****************************************************************************/
3366 /* */
3367 /* Function Name : ih264d_get_buf_info */
3368 /* */
3369 /* Description : */
3370 /* */
3371 /* Inputs :iv_obj_t decoder handle */
3372 /* :pv_api_ip pointer to input structure */
3373 /* :pv_api_op pointer to output structure */
3374 /* Globals : <Does it use any global variables?> */
3375 /* Outputs : */
3376 /* Returns : void */
3377 /* */
3378 /* Issues : none */
3379 /* */
3380 /* Revision History: */
3381 /* */
3382 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
3383 /* 22 10 2008 100356 Draft */
3384 /* */
3385 /*****************************************************************************/
ih264d_get_buf_info(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3386 WORD32 ih264d_get_buf_info(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
3387 {
3388
3389 dec_struct_t * ps_dec;
3390 UWORD8 i = 0; // Default for 420P format
3391 UWORD16 pic_wd, pic_ht;
3392 ivd_ctl_getbufinfo_op_t *ps_ctl_op =
3393 (ivd_ctl_getbufinfo_op_t*)pv_api_op;
3394 UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS];
3395 UNUSED(pv_api_ip);
3396
3397 ps_ctl_op->u4_error_code = 0;
3398
3399 ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
3400
3401 ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
3402
3403
3404 ps_ctl_op->u4_num_disp_bufs = 1;
3405
3406
3407 pic_wd = 0;
3408 pic_ht = 0;
3409
3410 if(ps_dec->i4_header_decoded == 3)
3411 {
3412
3413 if(0 == ps_dec->u4_share_disp_buf)
3414 {
3415 pic_wd = ps_dec->u2_disp_width;
3416 pic_ht = ps_dec->u2_disp_height;
3417
3418 }
3419 else
3420 {
3421 pic_wd = ps_dec->u2_frm_wd_y;
3422 pic_ht = ps_dec->u2_frm_ht_y;
3423 }
3424
3425 }
3426
3427 for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
3428 {
3429 ps_ctl_op->u4_min_in_buf_size[i] = MAX(256000, pic_wd * pic_ht * 3 / 2);
3430 }
3431 if((WORD32)ps_dec->u4_app_disp_width > pic_wd)
3432 pic_wd = ps_dec->u4_app_disp_width;
3433
3434 if(0 == ps_dec->u4_share_disp_buf)
3435 ps_ctl_op->u4_num_disp_bufs = 1;
3436 else
3437 {
3438 if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
3439 {
3440 if((ps_dec->ps_cur_sps->u1_vui_parameters_present_flag == 1) &&
3441 (1 == ps_dec->ps_cur_sps->s_vui.u1_bitstream_restriction_flag))
3442 {
3443 ps_ctl_op->u4_num_disp_bufs =
3444 ps_dec->ps_cur_sps->s_vui.u4_num_reorder_frames + 1;
3445 }
3446 else
3447 {
3448 /*if VUI is not present assume maximum possible refrence frames for the level,
3449 * as max reorder frames*/
3450 ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size(ps_dec->ps_cur_sps);
3451 }
3452
3453 ps_ctl_op->u4_num_disp_bufs +=
3454 ps_dec->ps_cur_sps->u1_num_ref_frames + 1;
3455
3456 }
3457 else
3458 {
3459 ps_ctl_op->u4_num_disp_bufs = 32;
3460
3461 }
3462
3463 ps_ctl_op->u4_num_disp_bufs = MAX(
3464 ps_ctl_op->u4_num_disp_bufs, 6);
3465 ps_ctl_op->u4_num_disp_bufs = MIN(
3466 ps_ctl_op->u4_num_disp_bufs, 32);
3467 }
3468
3469 ps_ctl_op->u4_min_num_out_bufs = ih264d_get_outbuf_size(
3470 pic_wd, pic_ht, ps_dec->u1_chroma_format,
3471 &au4_min_out_buf_size[0]);
3472
3473 for(i = 0; i < ps_ctl_op->u4_min_num_out_bufs; i++)
3474 {
3475 ps_ctl_op->u4_min_out_buf_size[i] = au4_min_out_buf_size[i];
3476 }
3477
3478 ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs;
3479
3480 return IV_SUCCESS;
3481 }
3482
3483 /*****************************************************************************/
3484 /* */
3485 /* Function Name : ih264d_set_params */
3486 /* */
3487 /* Description : */
3488 /* */
3489 /* Inputs :iv_obj_t decoder handle */
3490 /* :pv_api_ip pointer to input structure */
3491 /* :pv_api_op pointer to output structure */
3492 /* Outputs : */
3493 /* Returns : void */
3494 /* */
3495 /* Issues : none */
3496 /* */
3497 /* Revision History: */
3498 /* */
3499 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
3500 /* 22 10 2008 100356 Draft */
3501 /* */
3502 /*****************************************************************************/
ih264d_set_params(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3503 WORD32 ih264d_set_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
3504 {
3505
3506 dec_struct_t * ps_dec;
3507 WORD32 ret = IV_SUCCESS;
3508
3509 ih264d_ctl_set_config_ip_t *ps_h264d_ctl_ip =
3510 (ih264d_ctl_set_config_ip_t *)pv_api_ip;
3511 ih264d_ctl_set_config_op_t *ps_h264d_ctl_op =
3512 (ih264d_ctl_set_config_op_t *)pv_api_op;
3513 ivd_ctl_set_config_ip_t *ps_ctl_ip =
3514 &ps_h264d_ctl_ip->s_ivd_ctl_set_config_ip_t;
3515 ivd_ctl_set_config_op_t *ps_ctl_op =
3516 &ps_h264d_ctl_op->s_ivd_ctl_set_config_op_t;
3517
3518 ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
3519
3520 ps_dec->u4_skip_frm_mask = 0;
3521
3522 ps_ctl_op->u4_error_code = 0;
3523
3524 if(ps_ctl_ip->e_frm_skip_mode != IVD_SKIP_NONE)
3525 {
3526 ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
3527 ret = IV_FAIL;
3528 }
3529
3530 if(ps_ctl_ip->u4_disp_wd >= ps_dec->u2_disp_width)
3531 {
3532 ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd;
3533 }
3534 else if(0 == ps_dec->i4_header_decoded)
3535 {
3536 ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd;
3537 }
3538 else if(ps_ctl_ip->u4_disp_wd == 0)
3539 {
3540 ps_dec->u4_app_disp_width = 0;
3541 }
3542 else
3543 {
3544 /*
3545 * Set the display width to zero. This will ensure that the wrong value we had stored (0xFFFFFFFF)
3546 * does not propogate.
3547 */
3548 ps_dec->u4_app_disp_width = 0;
3549 ps_ctl_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
3550 ps_ctl_op->u4_error_code |= ERROR_DISP_WIDTH_INVALID;
3551 ret = IV_FAIL;
3552 }
3553
3554 if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_FRAME)
3555 ps_dec->i4_decode_header = 0;
3556 else if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_HEADER)
3557 ps_dec->i4_decode_header = 1;
3558 else
3559 {
3560 ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
3561 ps_dec->i4_decode_header = 1;
3562 ret = IV_FAIL;
3563 }
3564 ps_dec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
3565
3566 if((ps_ctl_ip->e_frm_out_mode != IVD_DECODE_FRAME_OUT) &&
3567 (ps_ctl_ip->e_frm_out_mode != IVD_DISPLAY_FRAME_OUT))
3568 {
3569 ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
3570 ret = IV_FAIL;
3571 }
3572 ps_dec->e_frm_out_mode = ps_ctl_ip->e_frm_out_mode;
3573 return ret;
3574
3575 }
3576
3577 /*****************************************************************************/
3578 /* */
3579 /* Function Name : ih264d_set_default_params */
3580 /* */
3581 /* Description : */
3582 /* */
3583 /* Inputs :iv_obj_t decoder handle */
3584 /* :pv_api_ip pointer to input structure */
3585 /* :pv_api_op pointer to output structure */
3586 /* Outputs : */
3587 /* Returns : void */
3588 /* */
3589 /* Issues : none */
3590 /* */
3591 /* Revision History: */
3592 /* */
3593 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
3594 /* 08 08 2011 100421 Copied from set_params */
3595 /* */
3596 /*****************************************************************************/
ih264d_set_default_params(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3597 WORD32 ih264d_set_default_params(iv_obj_t *dec_hdl,
3598 void *pv_api_ip,
3599 void *pv_api_op)
3600 {
3601
3602 dec_struct_t * ps_dec;
3603 WORD32 ret = IV_SUCCESS;
3604
3605 ivd_ctl_set_config_op_t *ps_ctl_op =
3606 (ivd_ctl_set_config_op_t *)pv_api_op;
3607 ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
3608 UNUSED(pv_api_ip);
3609
3610
3611 {
3612 ps_dec->u4_app_disp_width = 0;
3613 ps_dec->u4_skip_frm_mask = 0;
3614 ps_dec->i4_decode_header = 1;
3615
3616 ps_ctl_op->u4_error_code = 0;
3617 }
3618
3619
3620 return ret;
3621 }
3622 /*****************************************************************************/
3623 /* */
3624 /* Function Name : ih264d_reset */
3625 /* */
3626 /* Description : */
3627 /* */
3628 /* Inputs :iv_obj_t decoder handle */
3629 /* :pv_api_ip pointer to input structure */
3630 /* :pv_api_op pointer to output structure */
3631 /* Globals : <Does it use any global variables?> */
3632 /* Outputs : */
3633 /* Returns : void */
3634 /* */
3635 /* Issues : none */
3636 /* */
3637 /* Revision History: */
3638 /* */
3639 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
3640 /* 22 10 2008 100356 Draft */
3641 /* */
3642 /*****************************************************************************/
ih264d_delete(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3643 WORD32 ih264d_delete(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
3644 {
3645 dec_struct_t *ps_dec;
3646 ih264d_delete_ip_t *ps_ip = (ih264d_delete_ip_t *)pv_api_ip;
3647 ih264d_delete_op_t *ps_op = (ih264d_delete_op_t *)pv_api_op;
3648
3649 ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
3650 UNUSED(ps_ip);
3651 ps_op->s_ivd_delete_op_t.u4_error_code = 0;
3652 ih264d_free_dynamic_bufs(ps_dec);
3653 ih264d_free_static_bufs(dec_hdl);
3654 return IV_SUCCESS;
3655 }
3656 /*****************************************************************************/
3657 /* */
3658 /* Function Name : ih264d_reset */
3659 /* */
3660 /* Description : */
3661 /* */
3662 /* Inputs :iv_obj_t decoder handle */
3663 /* :pv_api_ip pointer to input structure */
3664 /* :pv_api_op pointer to output structure */
3665 /* Globals : <Does it use any global variables?> */
3666 /* Outputs : */
3667 /* Returns : void */
3668 /* */
3669 /* Issues : none */
3670 /* */
3671 /* Revision History: */
3672 /* */
3673 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
3674 /* 22 10 2008 100356 Draft */
3675 /* */
3676 /*****************************************************************************/
ih264d_reset(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3677 WORD32 ih264d_reset(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
3678 {
3679 dec_struct_t * ps_dec;
3680 ivd_ctl_reset_op_t *ps_ctl_op = (ivd_ctl_reset_op_t *)pv_api_op;
3681 UNUSED(pv_api_ip);
3682 ps_ctl_op->u4_error_code = 0;
3683
3684 ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
3685
3686 if(ps_dec != NULL)
3687 {
3688 ih264d_join_threads(ps_dec);
3689 ih264d_init_decoder(ps_dec);
3690 }
3691 else
3692 {
3693 H264_DEC_DEBUG_PRINT(
3694 "\nReset called without Initializing the decoder\n");
3695 ps_ctl_op->u4_error_code = ERROR_INIT_NOT_DONE;
3696 }
3697
3698 return IV_SUCCESS;
3699 }
3700
3701 /*****************************************************************************/
3702 /* */
3703 /* Function Name : ih264d_ctl */
3704 /* */
3705 /* Description : */
3706 /* */
3707 /* Inputs :iv_obj_t decoder handle */
3708 /* :pv_api_ip pointer to input structure */
3709 /* :pv_api_op pointer to output structure */
3710 /* Outputs : */
3711 /* Returns : void */
3712 /* */
3713 /* Issues : none */
3714 /* */
3715 /* Revision History: */
3716 /* */
3717 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
3718 /* 22 10 2008 100356 Draft */
3719 /* */
3720 /*****************************************************************************/
ih264d_ctl(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3721 WORD32 ih264d_ctl(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
3722 {
3723 ivd_ctl_set_config_ip_t *ps_ctl_ip;
3724 ivd_ctl_set_config_op_t *ps_ctl_op;
3725 WORD32 ret = IV_SUCCESS;
3726 UWORD32 subcommand;
3727 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
3728
3729 if(ps_dec->init_done != 1)
3730 {
3731 //Return proper Error Code
3732 return IV_FAIL;
3733 }
3734 ps_ctl_ip = (ivd_ctl_set_config_ip_t*)pv_api_ip;
3735 ps_ctl_op = (ivd_ctl_set_config_op_t*)pv_api_op;
3736 ps_ctl_op->u4_error_code = 0;
3737 subcommand = ps_ctl_ip->e_sub_cmd;
3738
3739 switch(subcommand)
3740 {
3741 case IVD_CMD_CTL_GETPARAMS:
3742 ret = ih264d_get_status(dec_hdl, (void *)pv_api_ip,
3743 (void *)pv_api_op);
3744 break;
3745 case IVD_CMD_CTL_SETPARAMS:
3746 ret = ih264d_set_params(dec_hdl, (void *)pv_api_ip,
3747 (void *)pv_api_op);
3748 break;
3749 case IVD_CMD_CTL_RESET:
3750 ret = ih264d_reset(dec_hdl, (void *)pv_api_ip, (void *)pv_api_op);
3751 break;
3752 case IVD_CMD_CTL_SETDEFAULT:
3753 ret = ih264d_set_default_params(dec_hdl, (void *)pv_api_ip,
3754 (void *)pv_api_op);
3755 break;
3756 case IVD_CMD_CTL_FLUSH:
3757 ret = ih264d_set_flush_mode(dec_hdl, (void *)pv_api_ip,
3758 (void *)pv_api_op);
3759 break;
3760 case IVD_CMD_CTL_GETBUFINFO:
3761 ret = ih264d_get_buf_info(dec_hdl, (void *)pv_api_ip,
3762 (void *)pv_api_op);
3763 break;
3764 case IVD_CMD_CTL_GETVERSION:
3765 ret = ih264d_get_version(dec_hdl, (void *)pv_api_ip,
3766 (void *)pv_api_op);
3767 break;
3768 case IH264D_CMD_CTL_DEGRADE:
3769 ret = ih264d_set_degrade(dec_hdl, (void *)pv_api_ip,
3770 (void *)pv_api_op);
3771 break;
3772
3773 case IH264D_CMD_CTL_SET_NUM_CORES:
3774 ret = ih264d_set_num_cores(dec_hdl, (void *)pv_api_ip,
3775 (void *)pv_api_op);
3776 break;
3777 case IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS:
3778 ret = ih264d_get_frame_dimensions(dec_hdl, (void *)pv_api_ip,
3779 (void *)pv_api_op);
3780 break;
3781 case IH264D_CMD_CTL_GET_VUI_PARAMS:
3782 ret = ih264d_get_vui_params(dec_hdl, (void *)pv_api_ip,
3783 (void *)pv_api_op);
3784 break;
3785 case IH264D_CMD_CTL_GET_SEI_MDCV_PARAMS:
3786 ret = ih264d_get_sei_mdcv_params(dec_hdl, (void *)pv_api_ip,
3787 (void *)pv_api_op);
3788 break;
3789 case IH264D_CMD_CTL_GET_SEI_CLL_PARAMS:
3790 ret = ih264d_get_sei_cll_params(dec_hdl, (void *)pv_api_ip,
3791 (void *)pv_api_op);
3792 break;
3793 case IH264D_CMD_CTL_GET_SEI_AVE_PARAMS:
3794 ret = ih264d_get_sei_ave_params(dec_hdl, (void *)pv_api_ip,
3795 (void *)pv_api_op);
3796 break;
3797 case IH264D_CMD_CTL_GET_SEI_CCV_PARAMS:
3798 ret = ih264d_get_sei_ccv_params(dec_hdl, (void *)pv_api_ip,
3799 (void *)pv_api_op);
3800 break;
3801 case IH264D_CMD_CTL_GET_SEI_SII_PARAMS:
3802 ret = ih264d_get_sei_sii_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
3803 break;
3804
3805 case IH264D_CMD_CTL_GET_SEI_FGC_PARAMS:
3806 ret = ih264d_get_sei_fgc_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
3807 break;
3808
3809 case IH264D_CMD_CTL_SET_PROCESSOR:
3810 ret = ih264d_set_processor(dec_hdl, (void *)pv_api_ip,
3811 (void *)pv_api_op);
3812 break;
3813 default:
3814 H264_DEC_DEBUG_PRINT("\ndo nothing\n")
3815 ;
3816 break;
3817 }
3818
3819 return ret;
3820 }
3821 /*****************************************************************************/
3822 /* */
3823 /* Function Name : ih264d_rel_display_frame */
3824 /* */
3825 /* Description : */
3826 /* */
3827 /* Inputs :iv_obj_t decoder handle */
3828 /* :pv_api_ip pointer to input structure */
3829 /* :pv_api_op pointer to output structure */
3830 /* Outputs : */
3831 /* Returns : void */
3832 /* */
3833 /* Issues : none */
3834 /* */
3835 /* Revision History: */
3836 /* */
3837 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
3838 /* 22 10 2008 100356 Draft */
3839 /* */
3840 /*****************************************************************************/
ih264d_rel_display_frame(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3841 WORD32 ih264d_rel_display_frame(iv_obj_t *dec_hdl,
3842 void *pv_api_ip,
3843 void *pv_api_op)
3844 {
3845
3846 ivd_rel_display_frame_ip_t *ps_rel_ip;
3847 ivd_rel_display_frame_op_t *ps_rel_op;
3848 UWORD32 buf_released = 0;
3849
3850 UWORD32 u4_ts = 0;
3851 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
3852
3853 ps_rel_ip = (ivd_rel_display_frame_ip_t *)pv_api_ip;
3854 ps_rel_op = (ivd_rel_display_frame_op_t *)pv_api_op;
3855 ps_rel_op->u4_error_code = 0;
3856 u4_ts = ps_rel_ip->u4_disp_buf_id;
3857
3858 if(0 == ps_dec->u4_share_disp_buf)
3859 {
3860 ps_dec->u4_disp_buf_mapping[u4_ts] = 0;
3861 ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 0;
3862 return IV_SUCCESS;
3863 }
3864
3865 if(ps_dec->pv_pic_buf_mgr != NULL)
3866 {
3867 if(1 == ps_dec->u4_disp_buf_mapping[u4_ts])
3868 {
3869 ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
3870 ps_rel_ip->u4_disp_buf_id,
3871 BUF_MGR_IO);
3872 ps_dec->u4_disp_buf_mapping[u4_ts] = 0;
3873 buf_released = 1;
3874 }
3875 }
3876
3877 if((1 == ps_dec->u4_share_disp_buf) && (0 == buf_released))
3878 ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 1;
3879
3880 return IV_SUCCESS;
3881 }
3882
3883 /**
3884 *******************************************************************************
3885 *
3886 * @brief
3887 * Sets degrade params
3888 *
3889 * @par Description:
3890 * Sets degrade params.
3891 * Refer to ih264d_ctl_degrade_ip_t definition for details
3892 *
3893 * @param[in] ps_codec_obj
3894 * Pointer to codec object at API level
3895 *
3896 * @param[in] pv_api_ip
3897 * Pointer to input argument structure
3898 *
3899 * @param[out] pv_api_op
3900 * Pointer to output argument structure
3901 *
3902 * @returns Status
3903 *
3904 * @remarks
3905 *
3906 *
3907 *******************************************************************************
3908 */
3909
ih264d_set_degrade(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3910 WORD32 ih264d_set_degrade(iv_obj_t *ps_codec_obj,
3911 void *pv_api_ip,
3912 void *pv_api_op)
3913 {
3914 ih264d_ctl_degrade_ip_t *ps_ip;
3915 ih264d_ctl_degrade_op_t *ps_op;
3916 dec_struct_t *ps_codec = (dec_struct_t *)ps_codec_obj->pv_codec_handle;
3917
3918 ps_ip = (ih264d_ctl_degrade_ip_t *)pv_api_ip;
3919 ps_op = (ih264d_ctl_degrade_op_t *)pv_api_op;
3920
3921 ps_codec->i4_degrade_type = ps_ip->i4_degrade_type;
3922 ps_codec->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval;
3923 ps_codec->i4_degrade_pics = ps_ip->i4_degrade_pics;
3924
3925 ps_op->u4_error_code = 0;
3926 ps_codec->i4_degrade_pic_cnt = 0;
3927
3928 return IV_SUCCESS;
3929 }
3930
ih264d_get_frame_dimensions(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3931 WORD32 ih264d_get_frame_dimensions(iv_obj_t *dec_hdl,
3932 void *pv_api_ip,
3933 void *pv_api_op)
3934 {
3935 ih264d_ctl_get_frame_dimensions_ip_t *ps_ip;
3936 ih264d_ctl_get_frame_dimensions_op_t *ps_op;
3937 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
3938 UWORD32 disp_wd, disp_ht, buffer_wd, buffer_ht, x_offset, y_offset;
3939
3940 ps_ip = (ih264d_ctl_get_frame_dimensions_ip_t *)pv_api_ip;
3941
3942 ps_op = (ih264d_ctl_get_frame_dimensions_op_t *)pv_api_op;
3943 UNUSED(ps_ip);
3944 if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
3945 {
3946 disp_wd = ps_dec->u2_disp_width;
3947 disp_ht = ps_dec->u2_disp_height;
3948
3949 if(0 == ps_dec->u4_share_disp_buf)
3950 {
3951 buffer_wd = disp_wd;
3952 buffer_ht = disp_ht;
3953 }
3954 else
3955 {
3956 buffer_wd = ps_dec->u2_frm_wd_y;
3957 buffer_ht = ps_dec->u2_frm_ht_y;
3958 }
3959 }
3960 else
3961 {
3962 disp_wd = 0;
3963 disp_ht = 0;
3964
3965 if(0 == ps_dec->u4_share_disp_buf)
3966 {
3967 buffer_wd = disp_wd;
3968 buffer_ht = disp_ht;
3969 }
3970 else
3971 {
3972 buffer_wd = ALIGN16(disp_wd) + (PAD_LEN_Y_H << 1);
3973 buffer_ht = ALIGN16(disp_ht) + (PAD_LEN_Y_V << 2);
3974 }
3975 }
3976 if(ps_dec->u4_app_disp_width > buffer_wd)
3977 buffer_wd = ps_dec->u4_app_disp_width;
3978
3979 if(0 == ps_dec->u4_share_disp_buf)
3980 {
3981 x_offset = 0;
3982 y_offset = 0;
3983 }
3984 else
3985 {
3986 y_offset = (PAD_LEN_Y_V << 1);
3987 x_offset = PAD_LEN_Y_H;
3988
3989 if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid))
3990 && (0 != ps_dec->u2_crop_offset_y))
3991 {
3992 y_offset += ps_dec->u2_crop_offset_y / ps_dec->u2_frm_wd_y;
3993 x_offset += ps_dec->u2_crop_offset_y % ps_dec->u2_frm_wd_y;
3994 }
3995 }
3996
3997 ps_op->u4_disp_wd[0] = disp_wd;
3998 ps_op->u4_disp_ht[0] = disp_ht;
3999 ps_op->u4_buffer_wd[0] = buffer_wd;
4000 ps_op->u4_buffer_ht[0] = buffer_ht;
4001 ps_op->u4_x_offset[0] = x_offset;
4002 ps_op->u4_y_offset[0] = y_offset;
4003
4004 ps_op->u4_disp_wd[1] = ps_op->u4_disp_wd[2] = ((ps_op->u4_disp_wd[0] + 1)
4005 >> 1);
4006 ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1)
4007 >> 1);
4008 ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0]
4009 >> 1);
4010 ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0]
4011 >> 1);
4012 ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] =
4013 (ps_op->u4_x_offset[0] >> 1);
4014 ps_op->u4_y_offset[1] = ps_op->u4_y_offset[2] =
4015 (ps_op->u4_y_offset[0] >> 1);
4016
4017 if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV)
4018 || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
4019 {
4020 ps_op->u4_disp_wd[2] = 0;
4021 ps_op->u4_disp_ht[2] = 0;
4022 ps_op->u4_buffer_wd[2] = 0;
4023 ps_op->u4_buffer_ht[2] = 0;
4024 ps_op->u4_x_offset[2] = 0;
4025 ps_op->u4_y_offset[2] = 0;
4026
4027 ps_op->u4_disp_wd[1] <<= 1;
4028 ps_op->u4_buffer_wd[1] <<= 1;
4029 ps_op->u4_x_offset[1] <<= 1;
4030 }
4031
4032 return IV_SUCCESS;
4033
4034 }
4035
ih264d_get_vui_params(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)4036 WORD32 ih264d_get_vui_params(iv_obj_t *dec_hdl,
4037 void *pv_api_ip,
4038 void *pv_api_op)
4039 {
4040 ih264d_ctl_get_vui_params_ip_t *ps_ip;
4041 ih264d_ctl_get_vui_params_op_t *ps_op;
4042 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
4043 dec_seq_params_t *ps_sps;
4044 vui_t *ps_vui;
4045 WORD32 i;
4046 UWORD32 u4_size;
4047
4048 ps_ip = (ih264d_ctl_get_vui_params_ip_t *)pv_api_ip;
4049 ps_op = (ih264d_ctl_get_vui_params_op_t *)pv_api_op;
4050 UNUSED(ps_ip);
4051
4052 u4_size = ps_op->u4_size;
4053 memset(ps_op, 0, sizeof(ih264d_ctl_get_vui_params_op_t));
4054 ps_op->u4_size = u4_size;
4055
4056 if(NULL == ps_dec->ps_cur_sps)
4057 {
4058 ps_op->u4_error_code = ERROR_VUI_PARAMS_NOT_FOUND;
4059 return IV_FAIL;
4060 }
4061
4062 ps_sps = ps_dec->ps_cur_sps;
4063 if((0 == ps_sps->u1_is_valid)
4064 || (0 == ps_sps->u1_vui_parameters_present_flag))
4065 {
4066 ps_op->u4_error_code = ERROR_VUI_PARAMS_NOT_FOUND;
4067 return IV_FAIL;
4068 }
4069
4070 ps_vui = &ps_sps->s_vui;
4071
4072 ps_op->u1_aspect_ratio_idc = ps_vui->u1_aspect_ratio_idc;
4073 ps_op->u2_sar_width = ps_vui->u2_sar_width;
4074 ps_op->u2_sar_height = ps_vui->u2_sar_height;
4075 ps_op->u1_overscan_appropriate_flag = ps_vui->u1_overscan_appropriate_flag;
4076 ps_op->u1_video_format = ps_vui->u1_video_format;
4077 ps_op->u1_video_full_range_flag = ps_vui->u1_video_full_range_flag;
4078 ps_op->u1_colour_primaries = ps_vui->u1_colour_primaries;
4079 ps_op->u1_tfr_chars = ps_vui->u1_tfr_chars;
4080 ps_op->u1_matrix_coeffs = ps_vui->u1_matrix_coeffs;
4081 ps_op->u1_cr_top_field = ps_vui->u1_cr_top_field;
4082 ps_op->u1_cr_bottom_field = ps_vui->u1_cr_bottom_field;
4083 ps_op->u4_num_units_in_tick = ps_vui->u4_num_units_in_tick;
4084 ps_op->u4_time_scale = ps_vui->u4_time_scale;
4085 ps_op->u1_fixed_frame_rate_flag = ps_vui->u1_fixed_frame_rate_flag;
4086 ps_op->u1_nal_hrd_params_present = ps_vui->u1_nal_hrd_params_present;
4087 ps_op->u1_vcl_hrd_params_present = ps_vui->u1_vcl_hrd_params_present;
4088 ps_op->u1_low_delay_hrd_flag = ps_vui->u1_low_delay_hrd_flag;
4089 ps_op->u1_pic_struct_present_flag = ps_vui->u1_pic_struct_present_flag;
4090 ps_op->u1_bitstream_restriction_flag = ps_vui->u1_bitstream_restriction_flag;
4091 ps_op->u1_mv_over_pic_boundaries_flag = ps_vui->u1_mv_over_pic_boundaries_flag;
4092 ps_op->u4_max_bytes_per_pic_denom = ps_vui->u4_max_bytes_per_pic_denom;
4093 ps_op->u4_max_bits_per_mb_denom = ps_vui->u4_max_bits_per_mb_denom;
4094 ps_op->u4_log2_max_mv_length_horz = ps_vui->u4_log2_max_mv_length_horz;
4095 ps_op->u4_log2_max_mv_length_vert = ps_vui->u4_log2_max_mv_length_vert;
4096 ps_op->u4_num_reorder_frames = ps_vui->u4_num_reorder_frames;
4097 ps_op->u4_max_dec_frame_buffering = ps_vui->u4_max_dec_frame_buffering;
4098
4099 return IV_SUCCESS;
4100 }
4101 /*****************************************************************************/
4102 /* */
4103 /* Function Name : ih264d_get_sei_mdcv_params */
4104 /* */
4105 /* Description : This function populates SEI mdcv message in */
4106 /* output structure */
4107 /* Inputs : iv_obj_t decoder handle */
4108 /* : pv_api_ip pointer to input structure */
4109 /* : pv_api_op pointer to output structure */
4110 /* Outputs : */
4111 /* Returns : returns 0; 1 with error code when MDCV is not present */
4112 /* */
4113 /* Issues : none */
4114 /* */
4115 /* Revision History: */
4116 /* */
4117 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
4118 /* */
4119 /* */
4120 /*****************************************************************************/
ih264d_get_sei_mdcv_params(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)4121 WORD32 ih264d_get_sei_mdcv_params(iv_obj_t *dec_hdl,
4122 void *pv_api_ip,
4123 void *pv_api_op)
4124 {
4125 ih264d_ctl_get_sei_mdcv_params_ip_t *ps_ip;
4126 ih264d_ctl_get_sei_mdcv_params_op_t *ps_op;
4127 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
4128 sei_mdcv_params_t *ps_sei_mdcv;
4129 WORD32 i4_count;
4130
4131 ps_ip = (ih264d_ctl_get_sei_mdcv_params_ip_t *)pv_api_ip;
4132 ps_op = (ih264d_ctl_get_sei_mdcv_params_op_t *)pv_api_op;
4133 UNUSED(ps_ip);
4134
4135 if(0 == ps_dec->s_sei_export.u1_sei_mdcv_params_present_flag)
4136 {
4137 ps_op->u4_error_code = ERROR_SEI_MDCV_PARAMS_NOT_FOUND;
4138 return IV_FAIL;
4139 }
4140
4141 ps_sei_mdcv = &ps_dec->s_sei_export.s_sei_mdcv_params;
4142
4143 for(i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; i4_count++)
4144 {
4145 ps_op->au2_display_primaries_x[i4_count] = ps_sei_mdcv->au2_display_primaries_x[i4_count];
4146 ps_op->au2_display_primaries_y[i4_count] = ps_sei_mdcv->au2_display_primaries_y[i4_count];
4147 }
4148
4149 ps_op->u2_white_point_x = ps_sei_mdcv->u2_white_point_x;
4150 ps_op->u2_white_point_y = ps_sei_mdcv->u2_white_point_y;
4151 ps_op->u4_max_display_mastering_luminance = ps_sei_mdcv->u4_max_display_mastering_luminance;
4152 ps_op->u4_min_display_mastering_luminance = ps_sei_mdcv->u4_min_display_mastering_luminance;
4153
4154 return IV_SUCCESS;
4155 }
4156
4157 /*****************************************************************************/
4158 /* */
4159 /* Function Name : ih264d_get_sei_cll_params */
4160 /* */
4161 /* Description : This function populates SEI cll message in */
4162 /* output structure */
4163 /* Inputs : iv_obj_t decoder handle */
4164 /* : pv_api_ip pointer to input structure */
4165 /* : pv_api_op pointer to output structure */
4166 /* Outputs : */
4167 /* Returns : returns 0; 1 with error code when CLL is not present */
4168 /* */
4169 /* Issues : none */
4170 /* */
4171 /* Revision History: */
4172 /* */
4173 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
4174 /* */
4175 /* */
4176 /*****************************************************************************/
ih264d_get_sei_cll_params(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)4177 WORD32 ih264d_get_sei_cll_params(iv_obj_t *dec_hdl,
4178 void *pv_api_ip,
4179 void *pv_api_op)
4180 {
4181 ih264d_ctl_get_sei_cll_params_ip_t *ps_ip;
4182 ih264d_ctl_get_sei_cll_params_op_t *ps_op;
4183 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
4184 sei_cll_params_t *ps_sei_cll;
4185
4186 ps_ip = (ih264d_ctl_get_sei_cll_params_ip_t *)pv_api_ip;
4187 ps_op = (ih264d_ctl_get_sei_cll_params_op_t *)pv_api_op;
4188 UNUSED(ps_ip);
4189
4190 if(0 == ps_dec->s_sei_export.u1_sei_cll_params_present_flag)
4191 {
4192 ps_op->u4_error_code = ERROR_SEI_CLL_PARAMS_NOT_FOUND;
4193 return IV_FAIL;
4194 }
4195
4196 ps_sei_cll = &ps_dec->s_sei_export.s_sei_cll_params;
4197
4198 ps_op->u2_max_content_light_level = ps_sei_cll->u2_max_content_light_level;
4199 ps_op->u2_max_pic_average_light_level = ps_sei_cll->u2_max_pic_average_light_level;
4200
4201 return IV_SUCCESS;
4202 }
4203
4204 /*****************************************************************************/
4205 /* */
4206 /* Function Name : ih264d_get_sei_ave_params */
4207 /* */
4208 /* Description : This function populates SEI ave message in */
4209 /* output structure */
4210 /* Inputs : iv_obj_t decoder handle */
4211 /* : pv_api_ip pointer to input structure */
4212 /* : pv_api_op pointer to output structure */
4213 /* Outputs : */
4214 /* Returns : returns 0; 1 with error code when AVE is not present */
4215 /* */
4216 /* Issues : none */
4217 /* */
4218 /* Revision History: */
4219 /* */
4220 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
4221 /* */
4222 /* */
4223 /*****************************************************************************/
ih264d_get_sei_ave_params(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)4224 WORD32 ih264d_get_sei_ave_params(iv_obj_t *dec_hdl,
4225 void *pv_api_ip,
4226 void *pv_api_op)
4227 {
4228 ih264d_ctl_get_sei_ave_params_ip_t *ps_ip;
4229 ih264d_ctl_get_sei_ave_params_op_t *ps_op;
4230 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
4231 sei_ave_params_t *ps_sei_ave;
4232
4233 ps_ip = (ih264d_ctl_get_sei_ave_params_ip_t *)pv_api_ip;
4234 ps_op = (ih264d_ctl_get_sei_ave_params_op_t *)pv_api_op;
4235 UNUSED(ps_ip);
4236
4237 if(0 == ps_dec->s_sei_export.u1_sei_ave_params_present_flag)
4238 {
4239 ps_op->u4_error_code = ERROR_SEI_AVE_PARAMS_NOT_FOUND;
4240 return IV_FAIL;
4241 }
4242
4243 ps_sei_ave = &ps_dec->s_sei_export.s_sei_ave_params;
4244
4245 ps_op->u4_ambient_illuminance = ps_sei_ave->u4_ambient_illuminance;
4246 ps_op->u2_ambient_light_x = ps_sei_ave->u2_ambient_light_x;
4247 ps_op->u2_ambient_light_y = ps_sei_ave->u2_ambient_light_y;
4248
4249 return IV_SUCCESS;
4250 }
4251
4252 /*****************************************************************************/
4253 /* */
4254 /* Function Name : ih264d_get_sei_ccv_params */
4255 /* */
4256 /* Description : This function populates SEI mdcv message in */
4257 /* output structure */
4258 /* Inputs : iv_obj_t decoder handle */
4259 /* : pv_api_ip pointer to input structure */
4260 /* : pv_api_op pointer to output structure */
4261 /* Outputs : */
4262 /* Returns : returns 0; 1 with error code when CCV is not present */
4263 /* */
4264 /* Issues : none */
4265 /* */
4266 /* Revision History: */
4267 /* */
4268 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
4269 /* */
4270 /* */
4271 /*****************************************************************************/
ih264d_get_sei_ccv_params(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)4272 WORD32 ih264d_get_sei_ccv_params(iv_obj_t *dec_hdl,
4273 void *pv_api_ip,
4274 void *pv_api_op)
4275 {
4276 ih264d_ctl_get_sei_ccv_params_ip_t *ps_ip;
4277 ih264d_ctl_get_sei_ccv_params_op_t *ps_op;
4278 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
4279 sei_ccv_params_t *ps_sei_ccv;
4280 WORD32 i4_count;
4281
4282 ps_ip = (ih264d_ctl_get_sei_ccv_params_ip_t *)pv_api_ip;
4283 ps_op = (ih264d_ctl_get_sei_ccv_params_op_t *)pv_api_op;
4284 UNUSED(ps_ip);
4285
4286 if(0 == ps_dec->s_sei_export.u1_sei_ccv_params_present_flag)
4287 {
4288 ps_op->u4_error_code = ERROR_SEI_CCV_PARAMS_NOT_FOUND;
4289 return IV_FAIL;
4290 }
4291
4292 ps_sei_ccv = &ps_dec->s_sei_export.s_sei_ccv_params;
4293
4294 ps_op->u1_ccv_cancel_flag = ps_sei_ccv->u1_ccv_cancel_flag;
4295
4296 if(0 == ps_op->u1_ccv_cancel_flag)
4297 {
4298 ps_op->u1_ccv_persistence_flag = ps_sei_ccv->u1_ccv_persistence_flag;
4299 ps_op->u1_ccv_primaries_present_flag = ps_sei_ccv->u1_ccv_primaries_present_flag;
4300 ps_op->u1_ccv_min_luminance_value_present_flag =
4301 ps_sei_ccv->u1_ccv_min_luminance_value_present_flag;
4302 ps_op->u1_ccv_max_luminance_value_present_flag =
4303 ps_sei_ccv->u1_ccv_max_luminance_value_present_flag;
4304 ps_op->u1_ccv_avg_luminance_value_present_flag =
4305 ps_sei_ccv->u1_ccv_avg_luminance_value_present_flag;
4306 ps_op->u1_ccv_reserved_zero_2bits = ps_sei_ccv->u1_ccv_reserved_zero_2bits;
4307
4308 if(1 == ps_sei_ccv->u1_ccv_primaries_present_flag)
4309 {
4310 for(i4_count = 0; i4_count < NUM_SEI_CCV_PRIMARIES; i4_count++)
4311 {
4312 ps_op->ai4_ccv_primaries_x[i4_count] = ps_sei_ccv->ai4_ccv_primaries_x[i4_count];
4313 ps_op->ai4_ccv_primaries_y[i4_count] = ps_sei_ccv->ai4_ccv_primaries_y[i4_count];
4314 }
4315 }
4316
4317 if(1 == ps_sei_ccv->u1_ccv_min_luminance_value_present_flag)
4318 {
4319 ps_op->u4_ccv_min_luminance_value = ps_sei_ccv->u4_ccv_min_luminance_value;
4320 }
4321 if(1 == ps_sei_ccv->u1_ccv_max_luminance_value_present_flag)
4322 {
4323 ps_op->u4_ccv_max_luminance_value = ps_sei_ccv->u4_ccv_max_luminance_value;
4324 }
4325 if(1 == ps_sei_ccv->u1_ccv_avg_luminance_value_present_flag)
4326 {
4327 ps_op->u4_ccv_avg_luminance_value = ps_sei_ccv->u4_ccv_avg_luminance_value;
4328 }
4329 }
4330
4331 return IV_SUCCESS;
4332 }
4333
4334 /*****************************************************************************/
4335 /* */
4336 /* Function Name : ih264d_get_sei_sii_params */
4337 /* */
4338 /* Description : This function populates SEI sii message in */
4339 /* output structure */
4340 /* Inputs : iv_obj_t decoder handle */
4341 /* : pv_api_ip pointer to input structure */
4342 /* : pv_api_op pointer to output structure */
4343 /* Outputs : */
4344 /* Returns : returns 0; 1 with error code when SII is not present */
4345 /* */
4346 /* Issues : none */
4347 /* */
4348 /* Revision History: */
4349 /* */
4350 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
4351 /* */
4352 /* */
4353 /*****************************************************************************/
ih264d_get_sei_sii_params(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)4354 WORD32 ih264d_get_sei_sii_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
4355 {
4356 ih264d_ctl_get_sei_sii_params_ip_t *ps_ip;
4357 ih264d_ctl_get_sei_sii_params_op_t *ps_op;
4358 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
4359 sei_sii_params_t *ps_sei_sii;
4360 int i;
4361
4362 ps_ip = (ih264d_ctl_get_sei_sii_params_ip_t *) pv_api_ip;
4363 ps_op = (ih264d_ctl_get_sei_sii_params_op_t *) pv_api_op;
4364 UNUSED(ps_ip);
4365
4366 if(0 == ps_dec->s_sei_export.u1_sei_sii_params_present_flag)
4367 {
4368 ps_op->u4_error_code = ERROR_SEI_SII_PARAMS_NOT_FOUND;
4369 return IV_FAIL;
4370 }
4371
4372 ps_sei_sii = &ps_dec->s_sei_export.s_sei_sii_params;
4373
4374 if((ps_sei_sii->u4_sii_sub_layer_idx > 0) &&
4375 (ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag == 1))
4376 {
4377 ps_op->u4_error_code = ERROR_INV_SEI_SII_PARAMS;
4378 return IV_FAIL;
4379 }
4380
4381 if((ps_sei_sii->u4_sii_sub_layer_idx > ps_sei_sii->u1_sii_max_sub_layers_minus1) &&
4382 (ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag == 0))
4383 {
4384 ps_op->u4_error_code = ERROR_INV_SEI_SII_PARAMS;
4385 return IV_FAIL;
4386 }
4387
4388 ps_op->u4_sii_sub_layer_idx = ps_sei_sii->u4_sii_sub_layer_idx;
4389
4390 if(0 == ps_op->u4_sii_sub_layer_idx)
4391 {
4392 ps_op->u1_shutter_interval_info_present_flag =
4393 ps_sei_sii->u1_shutter_interval_info_present_flag;
4394
4395 if(1 == ps_sei_sii->u1_shutter_interval_info_present_flag)
4396 {
4397 ps_op->u4_sii_time_scale = ps_sei_sii->u4_sii_time_scale;
4398 ps_op->u1_fixed_shutter_interval_within_cvs_flag =
4399 ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag;
4400
4401 if(1 == ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag)
4402 {
4403 ps_op->u4_sii_num_units_in_shutter_interval =
4404 ps_sei_sii->u4_sii_num_units_in_shutter_interval;
4405 }
4406 else
4407 {
4408 ps_op->u1_sii_max_sub_layers_minus1 = ps_sei_sii->u1_sii_max_sub_layers_minus1;
4409 for(i = 0; i <= ps_sei_sii->u1_sii_max_sub_layers_minus1; i++)
4410 {
4411 ps_op->au4_sub_layer_num_units_in_shutter_interval[i] =
4412 ps_sei_sii->au4_sub_layer_num_units_in_shutter_interval[i];
4413 }
4414 }
4415 }
4416 }
4417
4418 return IV_SUCCESS;
4419 }
4420
4421 /*****************************************************************************/
4422 /* */
4423 /* Function Name : ih264d_get_sei_fgc_params */
4424 /* */
4425 /* Description : This function populates SEI FGC message in */
4426 /* output structure */
4427 /* Inputs : iv_obj_t decoder handle */
4428 /* : pv_api_ip pointer to input structure */
4429 /* : pv_api_op pointer to output structure */
4430 /* Outputs : */
4431 /* Returns : returns 0; 1 with error code when FGC is not present */
4432 /* */
4433 /* Issues : none */
4434 /* */
4435 /* Revision History: */
4436 /* */
4437 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
4438 /* */
4439 /* */
4440 /*****************************************************************************/
ih264d_get_sei_fgc_params(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)4441 WORD32 ih264d_get_sei_fgc_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
4442 {
4443 ih264d_ctl_get_sei_fgc_params_ip_t *ps_ip;
4444 ih264d_ctl_get_sei_fgc_params_op_t *ps_op;
4445 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
4446 sei_fgc_params_t *ps_sei_fgc;
4447 WORD32 i4_count;
4448 UWORD32 c, i, j;
4449
4450 ps_ip = (ih264d_ctl_get_sei_fgc_params_ip_t *) pv_api_ip;
4451 ps_op = (ih264d_ctl_get_sei_fgc_params_op_t *) pv_api_op;
4452 UNUSED(ps_ip);
4453
4454 if(0 == ps_dec->s_sei_export.u1_sei_fgc_params_present_flag)
4455 {
4456 ps_op->u4_error_code = ERROR_SEI_FGC_PARAMS_NOT_FOUND;
4457 return IV_FAIL;
4458 }
4459
4460 ps_sei_fgc = &ps_dec->s_sei_export.s_sei_fgc_params;
4461
4462 ps_op->u1_film_grain_characteristics_cancel_flag =
4463 ps_sei_fgc->u1_film_grain_characteristics_cancel_flag;
4464
4465 if(0 == ps_op->u1_film_grain_characteristics_cancel_flag)
4466 {
4467 ps_op->i4_poc = ps_sei_fgc->i4_poc;
4468 ps_op->u4_idr_pic_id = ps_sei_fgc->u4_idr_pic_id;
4469 ps_op->u1_film_grain_model_id = ps_sei_fgc->u1_film_grain_model_id;
4470 ps_op->u1_separate_colour_description_present_flag =
4471 ps_sei_fgc->u1_separate_colour_description_present_flag;
4472
4473 if(ps_op->u1_separate_colour_description_present_flag)
4474 {
4475 ps_op->u1_film_grain_bit_depth_luma_minus8 =
4476 ps_sei_fgc->u1_film_grain_bit_depth_luma_minus8;
4477 ps_op->u1_film_grain_bit_depth_chroma_minus8 =
4478 ps_sei_fgc->u1_film_grain_bit_depth_chroma_minus8;
4479 ps_op->u1_film_grain_full_range_flag = ps_sei_fgc->u1_film_grain_full_range_flag;
4480 ps_op->u1_film_grain_colour_primaries = ps_sei_fgc->u1_film_grain_colour_primaries;
4481 ps_op->u1_film_grain_transfer_characteristics =
4482 ps_sei_fgc->u1_film_grain_transfer_characteristics;
4483 ps_op->u1_film_grain_matrix_coefficients =
4484 ps_sei_fgc->u1_film_grain_matrix_coefficients;
4485 }
4486 ps_op->u1_blending_mode_id = ps_sei_fgc->u1_blending_mode_id;
4487 ps_op->u1_log2_scale_factor = ps_sei_fgc->u1_log2_scale_factor;
4488
4489 for(c = 0; c < SEI_FGC_NUM_COLOUR_COMPONENTS; c++)
4490 {
4491 ps_op->au1_comp_model_present_flag[c] = ps_sei_fgc->au1_comp_model_present_flag[c];
4492 }
4493
4494 for(c = 0; c < SEI_FGC_NUM_COLOUR_COMPONENTS; c++)
4495 {
4496 if(ps_op->au1_comp_model_present_flag[c])
4497 {
4498 ps_op->au1_num_intensity_intervals_minus1[c] =
4499 ps_sei_fgc->au1_num_intensity_intervals_minus1[c];
4500
4501 ps_op->au1_num_model_values_minus1[c] = ps_sei_fgc->au1_num_model_values_minus1[c];
4502
4503 for(i = 0; i <= ps_op->au1_num_intensity_intervals_minus1[c]; i++)
4504 {
4505 ps_op->au1_intensity_interval_lower_bound[c][i] =
4506 ps_sei_fgc->au1_intensity_interval_lower_bound[c][i];
4507 ps_op->au1_intensity_interval_upper_bound[c][i] =
4508 ps_sei_fgc->au1_intensity_interval_upper_bound[c][i];
4509
4510 for(j = 0; j <= ps_op->au1_num_model_values_minus1[c]; j++)
4511 {
4512 ps_op->ai4_comp_model_value[c][i][j] =
4513 ps_sei_fgc->ai4_comp_model_value[c][i][j];
4514 }
4515 }
4516 }
4517 }
4518 ps_op->u4_film_grain_characteristics_repetition_period =
4519 ps_sei_fgc->u4_film_grain_characteristics_repetition_period;
4520 }
4521 return IV_SUCCESS;
4522 }
4523
ih264d_set_num_cores(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)4524 WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
4525 {
4526 ih264d_ctl_set_num_cores_ip_t *ps_ip;
4527 ih264d_ctl_set_num_cores_op_t *ps_op;
4528 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
4529
4530 ps_ip = (ih264d_ctl_set_num_cores_ip_t *)pv_api_ip;
4531 ps_op = (ih264d_ctl_set_num_cores_op_t *)pv_api_op;
4532 ps_op->u4_error_code = 0;
4533 ps_dec->u4_num_cores = ps_ip->u4_num_cores;
4534 if(ps_dec->u4_num_cores == 1)
4535 {
4536 ps_dec->u1_separate_parse = 0;
4537 }
4538 else
4539 {
4540 ps_dec->u1_separate_parse = 1;
4541 }
4542
4543 /*using only upto three threads currently*/
4544 if(ps_dec->u4_num_cores > 3)
4545 ps_dec->u4_num_cores = 3;
4546
4547 return IV_SUCCESS;
4548 }
4549
ih264d_fill_output_struct_from_context(dec_struct_t * ps_dec,ivd_video_decode_op_t * ps_dec_op)4550 void ih264d_fill_output_struct_from_context(dec_struct_t *ps_dec,
4551 ivd_video_decode_op_t *ps_dec_op)
4552 {
4553 if((ps_dec_op->u4_error_code & 0xff)
4554 != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED)
4555 {
4556 ps_dec_op->u4_pic_wd = (UWORD32)ps_dec->u2_disp_width;
4557 ps_dec_op->u4_pic_ht = (UWORD32)ps_dec->u2_disp_height;
4558 }
4559 ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth;
4560 ps_dec_op->i4_display_index = ps_dec->i4_display_index;
4561 ps_dec_op->e_pic_type = ps_dec->i4_frametype;
4562
4563 ps_dec_op->u4_new_seq = 0;
4564 ps_dec_op->u4_output_present = ps_dec->u4_output_present;
4565 ps_dec_op->u4_progressive_frame_flag =
4566 ps_dec->s_disp_op.u4_progressive_frame_flag;
4567
4568 ps_dec_op->u4_is_ref_flag = 1;
4569 if(ps_dec_op->u4_frame_decoded_flag)
4570 {
4571 if(ps_dec->ps_cur_slice->u1_nal_ref_idc == 0)
4572 ps_dec_op->u4_is_ref_flag = 0;
4573 }
4574
4575 ps_dec_op->e_output_format = ps_dec->s_disp_op.e_output_format;
4576 ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf;
4577 ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type;
4578 ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts;
4579 ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
4580
4581 ih264d_export_sei_params(&ps_dec_op->s_sei_decode_op, ps_dec);
4582 }
4583
4584 /*****************************************************************************/
4585 /* */
4586 /* Function Name : ih264d_api_function */
4587 /* */
4588 /* Description : */
4589 /* */
4590 /* Inputs :iv_obj_t decoder handle */
4591 /* :pv_api_ip pointer to input structure */
4592 /* :pv_api_op pointer to output structure */
4593 /* Outputs : */
4594 /* Returns : void */
4595 /* */
4596 /* Issues : none */
4597 /* */
4598 /* Revision History: */
4599 /* */
4600 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
4601 /* 22 10 2008 100356 Draft */
4602 /* */
4603 /*****************************************************************************/
ih264d_api_function(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)4604 IV_API_CALL_STATUS_T ih264d_api_function(iv_obj_t *dec_hdl,
4605 void *pv_api_ip,
4606 void *pv_api_op)
4607 {
4608 UWORD32 command;
4609 UWORD32 *pu2_ptr_cmd;
4610 UWORD32 u4_api_ret;
4611 IV_API_CALL_STATUS_T e_status;
4612 e_status = api_check_struct_sanity(dec_hdl, pv_api_ip, pv_api_op);
4613
4614 if(e_status != IV_SUCCESS)
4615 {
4616 UWORD32 *ptr_err;
4617
4618 ptr_err = (UWORD32 *)pv_api_op;
4619 UNUSED(ptr_err);
4620 H264_DEC_DEBUG_PRINT("error code = %d\n", *(ptr_err + 1));
4621 return IV_FAIL;
4622 }
4623
4624 pu2_ptr_cmd = (UWORD32 *)pv_api_ip;
4625 pu2_ptr_cmd++;
4626
4627 command = *pu2_ptr_cmd;
4628 // H264_DEC_DEBUG_PRINT("inside lib = %d\n",command);
4629 switch(command)
4630 {
4631
4632 case IVD_CMD_CREATE:
4633 u4_api_ret = ih264d_create(dec_hdl, (void *)pv_api_ip,
4634 (void *)pv_api_op);
4635 break;
4636 case IVD_CMD_DELETE:
4637 u4_api_ret = ih264d_delete(dec_hdl, (void *)pv_api_ip,
4638 (void *)pv_api_op);
4639 break;
4640
4641 case IVD_CMD_VIDEO_DECODE:
4642 u4_api_ret = ih264d_video_decode(dec_hdl, (void *)pv_api_ip,
4643 (void *)pv_api_op);
4644 break;
4645
4646 case IVD_CMD_GET_DISPLAY_FRAME:
4647 u4_api_ret = ih264d_get_display_frame(dec_hdl, (void *)pv_api_ip,
4648 (void *)pv_api_op);
4649
4650 break;
4651
4652 case IVD_CMD_SET_DISPLAY_FRAME:
4653 u4_api_ret = ih264d_set_display_frame(dec_hdl, (void *)pv_api_ip,
4654 (void *)pv_api_op);
4655
4656 break;
4657
4658 case IVD_CMD_REL_DISPLAY_FRAME:
4659 u4_api_ret = ih264d_rel_display_frame(dec_hdl, (void *)pv_api_ip,
4660 (void *)pv_api_op);
4661 break;
4662
4663 case IVD_CMD_VIDEO_CTL:
4664 u4_api_ret = ih264d_ctl(dec_hdl, (void *)pv_api_ip,
4665 (void *)pv_api_op);
4666 break;
4667 default:
4668 u4_api_ret = IV_FAIL;
4669 break;
4670 }
4671
4672 return u4_api_ret;
4673 }
4674