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_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
139 
140 WORD32 ih264d_deblock_display(dec_struct_t *ps_dec);
141 
142 void ih264d_signal_decode_thread(dec_struct_t *ps_dec);
143 
144 void ih264d_signal_bs_deblk_thread(dec_struct_t *ps_dec);
145 void ih264d_decode_picture_thread(dec_struct_t *ps_dec);
146 
147 WORD32 ih264d_set_degrade(iv_obj_t *ps_codec_obj,
148                           void *pv_api_ip,
149                           void *pv_api_op);
150 
151 void ih264d_fill_output_struct_from_context(dec_struct_t *ps_dec,
152                                             ivd_video_decode_op_t *ps_dec_op);
153 
api_check_struct_sanity(iv_obj_t * ps_handle,void * pv_api_ip,void * pv_api_op)154 static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
155                                                     void *pv_api_ip,
156                                                     void *pv_api_op)
157 {
158     IVD_API_COMMAND_TYPE_T e_cmd;
159     UWORD32 *pu4_api_ip;
160     UWORD32 *pu4_api_op;
161     UWORD32 i, j;
162 
163     if(NULL == pv_api_op)
164         return (IV_FAIL);
165 
166     if(NULL == pv_api_ip)
167         return (IV_FAIL);
168 
169     pu4_api_ip = (UWORD32 *)pv_api_ip;
170     pu4_api_op = (UWORD32 *)pv_api_op;
171     e_cmd = *(pu4_api_ip + 1);
172 
173     /* error checks on handle */
174     switch((WORD32)e_cmd)
175     {
176         case IVD_CMD_CREATE:
177             break;
178 
179         case IVD_CMD_REL_DISPLAY_FRAME:
180         case IVD_CMD_SET_DISPLAY_FRAME:
181         case IVD_CMD_GET_DISPLAY_FRAME:
182         case IVD_CMD_VIDEO_DECODE:
183         case IVD_CMD_DELETE:
184         case IVD_CMD_VIDEO_CTL:
185             if(ps_handle == NULL)
186             {
187                 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
188                 *(pu4_api_op + 1) |= IVD_HANDLE_NULL;
189                 return IV_FAIL;
190             }
191 
192             if(ps_handle->u4_size != sizeof(iv_obj_t))
193             {
194                 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
195                 *(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT;
196                 return IV_FAIL;
197             }
198 
199             if(ps_handle->pv_fxns != ih264d_api_function)
200             {
201                 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
202                 *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL;
203                 return IV_FAIL;
204             }
205 
206             if(ps_handle->pv_codec_handle == NULL)
207             {
208                 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
209                 *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL;
210                 return IV_FAIL;
211             }
212             break;
213         default:
214             *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
215             *(pu4_api_op + 1) |= IVD_INVALID_API_CMD;
216             return IV_FAIL;
217     }
218 
219     switch((WORD32)e_cmd)
220     {
221         case IVD_CMD_CREATE:
222         {
223             ih264d_create_ip_t *ps_ip = (ih264d_create_ip_t *)pv_api_ip;
224             ih264d_create_op_t *ps_op = (ih264d_create_op_t *)pv_api_op;
225 
226 
227             ps_op->s_ivd_create_op_t.u4_error_code = 0;
228 
229             if((ps_ip->s_ivd_create_ip_t.u4_size > sizeof(ih264d_create_ip_t))
230                             || (ps_ip->s_ivd_create_ip_t.u4_size
231                                             < sizeof(ivd_create_ip_t)))
232             {
233                 ps_op->s_ivd_create_op_t.u4_error_code |= 1
234                                 << IVD_UNSUPPORTEDPARAM;
235                 ps_op->s_ivd_create_op_t.u4_error_code |=
236                                 IVD_IP_API_STRUCT_SIZE_INCORRECT;
237                 H264_DEC_DEBUG_PRINT("\n");
238                 return (IV_FAIL);
239             }
240 
241             if((ps_op->s_ivd_create_op_t.u4_size != sizeof(ih264d_create_op_t))
242                             && (ps_op->s_ivd_create_op_t.u4_size
243                                             != sizeof(ivd_create_op_t)))
244             {
245                 ps_op->s_ivd_create_op_t.u4_error_code |= 1
246                                 << IVD_UNSUPPORTEDPARAM;
247                 ps_op->s_ivd_create_op_t.u4_error_code |=
248                                 IVD_OP_API_STRUCT_SIZE_INCORRECT;
249                 H264_DEC_DEBUG_PRINT("\n");
250                 return (IV_FAIL);
251             }
252 
253 
254             if((ps_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420P)
255                             && (ps_ip->s_ivd_create_ip_t.e_output_format
256                                             != IV_YUV_422ILE)
257                             && (ps_ip->s_ivd_create_ip_t.e_output_format
258                                             != IV_RGB_565)
259                             && (ps_ip->s_ivd_create_ip_t.e_output_format
260                                             != IV_YUV_420SP_UV)
261                             && (ps_ip->s_ivd_create_ip_t.e_output_format
262                                             != IV_YUV_420SP_VU))
263             {
264                 ps_op->s_ivd_create_op_t.u4_error_code |= 1
265                                 << IVD_UNSUPPORTEDPARAM;
266                 ps_op->s_ivd_create_op_t.u4_error_code |=
267                                 IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED;
268                 H264_DEC_DEBUG_PRINT("\n");
269                 return (IV_FAIL);
270             }
271 
272         }
273             break;
274 
275         case IVD_CMD_GET_DISPLAY_FRAME:
276         {
277             ih264d_get_display_frame_ip_t *ps_ip =
278                             (ih264d_get_display_frame_ip_t *)pv_api_ip;
279             ih264d_get_display_frame_op_t *ps_op =
280                             (ih264d_get_display_frame_op_t *)pv_api_op;
281 
282             ps_op->s_ivd_get_display_frame_op_t.u4_error_code = 0;
283 
284             if((ps_ip->s_ivd_get_display_frame_ip_t.u4_size
285                             != sizeof(ih264d_get_display_frame_ip_t))
286                             && (ps_ip->s_ivd_get_display_frame_ip_t.u4_size
287                                             != sizeof(ivd_get_display_frame_ip_t)))
288             {
289                 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
290                                 << IVD_UNSUPPORTEDPARAM;
291                 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
292                                 IVD_IP_API_STRUCT_SIZE_INCORRECT;
293                 return (IV_FAIL);
294             }
295 
296             if((ps_op->s_ivd_get_display_frame_op_t.u4_size
297                             != sizeof(ih264d_get_display_frame_op_t))
298                             && (ps_op->s_ivd_get_display_frame_op_t.u4_size
299                                             != sizeof(ivd_get_display_frame_op_t)))
300             {
301                 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
302                                 << IVD_UNSUPPORTEDPARAM;
303                 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
304                                 IVD_OP_API_STRUCT_SIZE_INCORRECT;
305                 return (IV_FAIL);
306             }
307         }
308             break;
309 
310         case IVD_CMD_REL_DISPLAY_FRAME:
311         {
312             ih264d_rel_display_frame_ip_t *ps_ip =
313                             (ih264d_rel_display_frame_ip_t *)pv_api_ip;
314             ih264d_rel_display_frame_op_t *ps_op =
315                             (ih264d_rel_display_frame_op_t *)pv_api_op;
316 
317             ps_op->s_ivd_rel_display_frame_op_t.u4_error_code = 0;
318 
319             if((ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
320                             != sizeof(ih264d_rel_display_frame_ip_t))
321                             && (ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
322                                             != sizeof(ivd_rel_display_frame_ip_t)))
323             {
324                 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
325                                 << IVD_UNSUPPORTEDPARAM;
326                 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
327                                 IVD_IP_API_STRUCT_SIZE_INCORRECT;
328                 return (IV_FAIL);
329             }
330 
331             if((ps_op->s_ivd_rel_display_frame_op_t.u4_size
332                             != sizeof(ih264d_rel_display_frame_op_t))
333                             && (ps_op->s_ivd_rel_display_frame_op_t.u4_size
334                                             != sizeof(ivd_rel_display_frame_op_t)))
335             {
336                 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
337                                 << IVD_UNSUPPORTEDPARAM;
338                 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
339                                 IVD_OP_API_STRUCT_SIZE_INCORRECT;
340                 return (IV_FAIL);
341             }
342 
343         }
344             break;
345 
346         case IVD_CMD_SET_DISPLAY_FRAME:
347         {
348             ih264d_set_display_frame_ip_t *ps_ip =
349                             (ih264d_set_display_frame_ip_t *)pv_api_ip;
350             ih264d_set_display_frame_op_t *ps_op =
351                             (ih264d_set_display_frame_op_t *)pv_api_op;
352             UWORD32 j;
353 
354             ps_op->s_ivd_set_display_frame_op_t.u4_error_code = 0;
355 
356             if((ps_ip->s_ivd_set_display_frame_ip_t.u4_size
357                             != sizeof(ih264d_set_display_frame_ip_t))
358                             && (ps_ip->s_ivd_set_display_frame_ip_t.u4_size
359                                             != sizeof(ivd_set_display_frame_ip_t)))
360             {
361                 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
362                                 << IVD_UNSUPPORTEDPARAM;
363                 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
364                                 IVD_IP_API_STRUCT_SIZE_INCORRECT;
365                 return (IV_FAIL);
366             }
367 
368             if((ps_op->s_ivd_set_display_frame_op_t.u4_size
369                             != sizeof(ih264d_set_display_frame_op_t))
370                             && (ps_op->s_ivd_set_display_frame_op_t.u4_size
371                                             != sizeof(ivd_set_display_frame_op_t)))
372             {
373                 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
374                                 << IVD_UNSUPPORTEDPARAM;
375                 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
376                                 IVD_OP_API_STRUCT_SIZE_INCORRECT;
377                 return (IV_FAIL);
378             }
379 
380             if(ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs == 0)
381             {
382                 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
383                                 << IVD_UNSUPPORTEDPARAM;
384                 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
385                                 IVD_DISP_FRM_ZERO_OP_BUFS;
386                 return IV_FAIL;
387             }
388 
389             for(j = 0; j < ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs;
390                             j++)
391             {
392                 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs
393                                 == 0)
394                 {
395                     ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
396                                     << IVD_UNSUPPORTEDPARAM;
397                     ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
398                                     IVD_DISP_FRM_ZERO_OP_BUFS;
399                     return IV_FAIL;
400                 }
401 
402                 for(i = 0;
403                                 i
404                                                 < ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs;
405                                 i++)
406                 {
407                     if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].pu1_bufs[i]
408                                     == NULL)
409                     {
410                         ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
411                                         << IVD_UNSUPPORTEDPARAM;
412                         ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
413                                         IVD_DISP_FRM_OP_BUF_NULL;
414                         return IV_FAIL;
415                     }
416 
417                     if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_min_out_buf_size[i]
418                                     == 0)
419                     {
420                         ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
421                                         << IVD_UNSUPPORTEDPARAM;
422                         ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
423                                         IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
424                         return IV_FAIL;
425                     }
426                 }
427             }
428         }
429             break;
430 
431         case IVD_CMD_VIDEO_DECODE:
432         {
433             ih264d_video_decode_ip_t *ps_ip =
434                             (ih264d_video_decode_ip_t *)pv_api_ip;
435             ih264d_video_decode_op_t *ps_op =
436                             (ih264d_video_decode_op_t *)pv_api_op;
437 
438             H264_DEC_DEBUG_PRINT("The input bytes is: %d",
439                                  ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes);
440             ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
441 
442             if(ps_ip->s_ivd_video_decode_ip_t.u4_size
443                             != sizeof(ih264d_video_decode_ip_t)&&
444                             ps_ip->s_ivd_video_decode_ip_t.u4_size != offsetof(ivd_video_decode_ip_t, s_out_buffer))
445             {
446                 ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
447                                 << IVD_UNSUPPORTEDPARAM;
448                 ps_op->s_ivd_video_decode_op_t.u4_error_code |=
449                                 IVD_IP_API_STRUCT_SIZE_INCORRECT;
450                 return (IV_FAIL);
451             }
452 
453             if(ps_op->s_ivd_video_decode_op_t.u4_size
454                             != sizeof(ih264d_video_decode_op_t)&&
455                             ps_op->s_ivd_video_decode_op_t.u4_size != offsetof(ivd_video_decode_op_t, u4_output_present))
456             {
457                 ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
458                                 << IVD_UNSUPPORTEDPARAM;
459                 ps_op->s_ivd_video_decode_op_t.u4_error_code |=
460                                 IVD_OP_API_STRUCT_SIZE_INCORRECT;
461                 return (IV_FAIL);
462             }
463 
464         }
465             break;
466 
467         case IVD_CMD_DELETE:
468         {
469             ih264d_delete_ip_t *ps_ip =
470                             (ih264d_delete_ip_t *)pv_api_ip;
471             ih264d_delete_op_t *ps_op =
472                             (ih264d_delete_op_t *)pv_api_op;
473 
474             ps_op->s_ivd_delete_op_t.u4_error_code = 0;
475 
476             if(ps_ip->s_ivd_delete_ip_t.u4_size
477                             != sizeof(ih264d_delete_ip_t))
478             {
479                 ps_op->s_ivd_delete_op_t.u4_error_code |= 1
480                                 << IVD_UNSUPPORTEDPARAM;
481                 ps_op->s_ivd_delete_op_t.u4_error_code |=
482                                 IVD_IP_API_STRUCT_SIZE_INCORRECT;
483                 return (IV_FAIL);
484             }
485 
486             if(ps_op->s_ivd_delete_op_t.u4_size
487                             != sizeof(ih264d_delete_op_t))
488             {
489                 ps_op->s_ivd_delete_op_t.u4_error_code |= 1
490                                 << IVD_UNSUPPORTEDPARAM;
491                 ps_op->s_ivd_delete_op_t.u4_error_code |=
492                                 IVD_OP_API_STRUCT_SIZE_INCORRECT;
493                 return (IV_FAIL);
494             }
495 
496         }
497             break;
498 
499         case IVD_CMD_VIDEO_CTL:
500         {
501             UWORD32 *pu4_ptr_cmd;
502             UWORD32 sub_command;
503 
504             pu4_ptr_cmd = (UWORD32 *)pv_api_ip;
505             pu4_ptr_cmd += 2;
506             sub_command = *pu4_ptr_cmd;
507 
508             switch(sub_command)
509             {
510                 case IVD_CMD_CTL_SETPARAMS:
511                 {
512                     ih264d_ctl_set_config_ip_t *ps_ip;
513                     ih264d_ctl_set_config_op_t *ps_op;
514                     ps_ip = (ih264d_ctl_set_config_ip_t *)pv_api_ip;
515                     ps_op = (ih264d_ctl_set_config_op_t *)pv_api_op;
516 
517                     if(ps_ip->s_ivd_ctl_set_config_ip_t.u4_size
518                                     != sizeof(ih264d_ctl_set_config_ip_t))
519                     {
520                         ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1
521                                         << IVD_UNSUPPORTEDPARAM;
522                         ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
523                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
524                         return IV_FAIL;
525                     }
526                 }
527                     //no break; is needed here
528                 case IVD_CMD_CTL_SETDEFAULT:
529                 {
530                     ih264d_ctl_set_config_op_t *ps_op;
531                     ps_op = (ih264d_ctl_set_config_op_t *)pv_api_op;
532                     if(ps_op->s_ivd_ctl_set_config_op_t.u4_size
533                                     != sizeof(ih264d_ctl_set_config_op_t))
534                     {
535                         ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1
536                                         << IVD_UNSUPPORTEDPARAM;
537                         ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
538                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
539                         return IV_FAIL;
540                     }
541                 }
542                     break;
543 
544                 case IVD_CMD_CTL_GETPARAMS:
545                 {
546                     ih264d_ctl_getstatus_ip_t *ps_ip;
547                     ih264d_ctl_getstatus_op_t *ps_op;
548 
549                     ps_ip = (ih264d_ctl_getstatus_ip_t *)pv_api_ip;
550                     ps_op = (ih264d_ctl_getstatus_op_t *)pv_api_op;
551                     if(ps_ip->s_ivd_ctl_getstatus_ip_t.u4_size
552                                     != sizeof(ih264d_ctl_getstatus_ip_t))
553                     {
554                         ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1
555                                         << IVD_UNSUPPORTEDPARAM;
556                         ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
557                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
558                         return IV_FAIL;
559                     }
560                     if(ps_op->s_ivd_ctl_getstatus_op_t.u4_size
561                                     != sizeof(ih264d_ctl_getstatus_op_t))
562                     {
563                         ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1
564                                         << IVD_UNSUPPORTEDPARAM;
565                         ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
566                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
567                         return IV_FAIL;
568                     }
569                 }
570                     break;
571 
572                 case IVD_CMD_CTL_GETBUFINFO:
573                 {
574                     ih264d_ctl_getbufinfo_ip_t *ps_ip;
575                     ih264d_ctl_getbufinfo_op_t *ps_op;
576                     ps_ip = (ih264d_ctl_getbufinfo_ip_t *)pv_api_ip;
577                     ps_op = (ih264d_ctl_getbufinfo_op_t *)pv_api_op;
578 
579                     if(ps_ip->s_ivd_ctl_getbufinfo_ip_t.u4_size
580                                     != sizeof(ih264d_ctl_getbufinfo_ip_t))
581                     {
582                         ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1
583                                         << IVD_UNSUPPORTEDPARAM;
584                         ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
585                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
586                         return IV_FAIL;
587                     }
588                     if(ps_op->s_ivd_ctl_getbufinfo_op_t.u4_size
589                                     != sizeof(ih264d_ctl_getbufinfo_op_t))
590                     {
591                         ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1
592                                         << IVD_UNSUPPORTEDPARAM;
593                         ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
594                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
595                         return IV_FAIL;
596                     }
597                 }
598                     break;
599 
600                 case IVD_CMD_CTL_GETVERSION:
601                 {
602                     ih264d_ctl_getversioninfo_ip_t *ps_ip;
603                     ih264d_ctl_getversioninfo_op_t *ps_op;
604                     ps_ip = (ih264d_ctl_getversioninfo_ip_t *)pv_api_ip;
605                     ps_op = (ih264d_ctl_getversioninfo_op_t *)pv_api_op;
606                     if(ps_ip->s_ivd_ctl_getversioninfo_ip_t.u4_size
607                                     != sizeof(ih264d_ctl_getversioninfo_ip_t))
608                     {
609                         ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1
610                                         << IVD_UNSUPPORTEDPARAM;
611                         ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
612                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
613                         return IV_FAIL;
614                     }
615                     if(ps_op->s_ivd_ctl_getversioninfo_op_t.u4_size
616                                     != sizeof(ih264d_ctl_getversioninfo_op_t))
617                     {
618                         ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1
619                                         << IVD_UNSUPPORTEDPARAM;
620                         ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
621                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
622                         return IV_FAIL;
623                     }
624                 }
625                     break;
626 
627                 case IVD_CMD_CTL_FLUSH:
628                 {
629                     ih264d_ctl_flush_ip_t *ps_ip;
630                     ih264d_ctl_flush_op_t *ps_op;
631                     ps_ip = (ih264d_ctl_flush_ip_t *)pv_api_ip;
632                     ps_op = (ih264d_ctl_flush_op_t *)pv_api_op;
633                     if(ps_ip->s_ivd_ctl_flush_ip_t.u4_size
634                                     != sizeof(ih264d_ctl_flush_ip_t))
635                     {
636                         ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1
637                                         << IVD_UNSUPPORTEDPARAM;
638                         ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
639                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
640                         return IV_FAIL;
641                     }
642                     if(ps_op->s_ivd_ctl_flush_op_t.u4_size
643                                     != sizeof(ih264d_ctl_flush_op_t))
644                     {
645                         ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1
646                                         << IVD_UNSUPPORTEDPARAM;
647                         ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
648                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
649                         return IV_FAIL;
650                     }
651                 }
652                     break;
653 
654                 case IVD_CMD_CTL_RESET:
655                 {
656                     ih264d_ctl_reset_ip_t *ps_ip;
657                     ih264d_ctl_reset_op_t *ps_op;
658                     ps_ip = (ih264d_ctl_reset_ip_t *)pv_api_ip;
659                     ps_op = (ih264d_ctl_reset_op_t *)pv_api_op;
660                     if(ps_ip->s_ivd_ctl_reset_ip_t.u4_size
661                                     != sizeof(ih264d_ctl_reset_ip_t))
662                     {
663                         ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1
664                                         << IVD_UNSUPPORTEDPARAM;
665                         ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
666                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
667                         return IV_FAIL;
668                     }
669                     if(ps_op->s_ivd_ctl_reset_op_t.u4_size
670                                     != sizeof(ih264d_ctl_reset_op_t))
671                     {
672                         ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1
673                                         << IVD_UNSUPPORTEDPARAM;
674                         ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
675                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
676                         return IV_FAIL;
677                     }
678                 }
679                     break;
680 
681                 case IH264D_CMD_CTL_DEGRADE:
682                 {
683                     ih264d_ctl_degrade_ip_t *ps_ip;
684                     ih264d_ctl_degrade_op_t *ps_op;
685 
686                     ps_ip = (ih264d_ctl_degrade_ip_t *)pv_api_ip;
687                     ps_op = (ih264d_ctl_degrade_op_t *)pv_api_op;
688 
689                     if(ps_ip->u4_size != sizeof(ih264d_ctl_degrade_ip_t))
690                     {
691                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
692                         ps_op->u4_error_code |=
693                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
694                         return IV_FAIL;
695                     }
696 
697                     if(ps_op->u4_size != sizeof(ih264d_ctl_degrade_op_t))
698                     {
699                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
700                         ps_op->u4_error_code |=
701                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
702                         return IV_FAIL;
703                     }
704 
705                     if((ps_ip->i4_degrade_pics < 0)
706                                     || (ps_ip->i4_degrade_pics > 4)
707                                     || (ps_ip->i4_nondegrade_interval < 0)
708                                     || (ps_ip->i4_degrade_type < 0)
709                                     || (ps_ip->i4_degrade_type > 15))
710                     {
711                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
712                         return IV_FAIL;
713                     }
714 
715                     break;
716                 }
717 
718                 case IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS:
719                 {
720                     ih264d_ctl_get_frame_dimensions_ip_t *ps_ip;
721                     ih264d_ctl_get_frame_dimensions_op_t *ps_op;
722 
723                     ps_ip = (ih264d_ctl_get_frame_dimensions_ip_t *)pv_api_ip;
724                     ps_op = (ih264d_ctl_get_frame_dimensions_op_t *)pv_api_op;
725 
726                     if(ps_ip->u4_size
727                                     != sizeof(ih264d_ctl_get_frame_dimensions_ip_t))
728                     {
729                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
730                         ps_op->u4_error_code |=
731                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
732                         return IV_FAIL;
733                     }
734 
735                     if(ps_op->u4_size
736                                     != sizeof(ih264d_ctl_get_frame_dimensions_op_t))
737                     {
738                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
739                         ps_op->u4_error_code |=
740                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
741                         return IV_FAIL;
742                     }
743 
744                     break;
745                 }
746 
747                 case IH264D_CMD_CTL_SET_NUM_CORES:
748                 {
749                     ih264d_ctl_set_num_cores_ip_t *ps_ip;
750                     ih264d_ctl_set_num_cores_op_t *ps_op;
751 
752                     ps_ip = (ih264d_ctl_set_num_cores_ip_t *)pv_api_ip;
753                     ps_op = (ih264d_ctl_set_num_cores_op_t *)pv_api_op;
754 
755                     if(ps_ip->u4_size != sizeof(ih264d_ctl_set_num_cores_ip_t))
756                     {
757                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
758                         ps_op->u4_error_code |=
759                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
760                         return IV_FAIL;
761                     }
762 
763                     if(ps_op->u4_size != sizeof(ih264d_ctl_set_num_cores_op_t))
764                     {
765                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
766                         ps_op->u4_error_code |=
767                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
768                         return IV_FAIL;
769                     }
770 
771                     if((ps_ip->u4_num_cores != 1) && (ps_ip->u4_num_cores != 2)
772                                     && (ps_ip->u4_num_cores != 3)
773                                     && (ps_ip->u4_num_cores != 4))
774                     {
775                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
776                         return IV_FAIL;
777                     }
778                     break;
779                 }
780                 case IH264D_CMD_CTL_SET_PROCESSOR:
781                 {
782                     ih264d_ctl_set_processor_ip_t *ps_ip;
783                     ih264d_ctl_set_processor_op_t *ps_op;
784 
785                     ps_ip = (ih264d_ctl_set_processor_ip_t *)pv_api_ip;
786                     ps_op = (ih264d_ctl_set_processor_op_t *)pv_api_op;
787 
788                     if(ps_ip->u4_size != sizeof(ih264d_ctl_set_processor_ip_t))
789                     {
790                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
791                         ps_op->u4_error_code |=
792                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
793                         return IV_FAIL;
794                     }
795 
796                     if(ps_op->u4_size != sizeof(ih264d_ctl_set_processor_op_t))
797                     {
798                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
799                         ps_op->u4_error_code |=
800                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
801                         return IV_FAIL;
802                     }
803 
804                     break;
805                 }
806                 default:
807                     *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
808                     *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD;
809                     return IV_FAIL;
810                     break;
811             }
812         }
813             break;
814     }
815 
816     return IV_SUCCESS;
817 }
818 
819 
820 /**
821  *******************************************************************************
822  *
823  * @brief
824  *  Sets Processor type
825  *
826  * @par Description:
827  *  Sets Processor type
828  *
829  * @param[in] ps_codec_obj
830  *  Pointer to codec object at API level
831  *
832  * @param[in] pv_api_ip
833  *  Pointer to input argument structure
834  *
835  * @param[out] pv_api_op
836  *  Pointer to output argument structure
837  *
838  * @returns  Status
839  *
840  * @remarks
841  *
842  *
843  *******************************************************************************
844  */
845 
ih264d_set_processor(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)846 WORD32 ih264d_set_processor(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
847 {
848     ih264d_ctl_set_processor_ip_t *ps_ip;
849     ih264d_ctl_set_processor_op_t *ps_op;
850     dec_struct_t *ps_codec = (dec_struct_t *)dec_hdl->pv_codec_handle;
851 
852     ps_ip = (ih264d_ctl_set_processor_ip_t *)pv_api_ip;
853     ps_op = (ih264d_ctl_set_processor_op_t *)pv_api_op;
854 
855     ps_codec->e_processor_arch = (IVD_ARCH_T)ps_ip->u4_arch;
856     ps_codec->e_processor_soc = (IVD_SOC_T)ps_ip->u4_soc;
857 
858     ih264d_init_function_ptr(ps_codec);
859 
860     ps_op->u4_error_code = 0;
861     return IV_SUCCESS;
862 }
863 
864 
865 /**************************************************************************
866  * \if Function name : ih264d_init_decoder \endif
867  *
868  *
869  * \brief
870  *    Initializes the decoder
871  *
872  * \param apiVersion               : Version of the api being used.
873  * \param errorHandlingMechanism   : Mechanism to be used for errror handling.
874  * \param postFilteringType: Type of post filtering operation to be used.
875  * \param uc_outputFormat: Format of the decoded picture [default 4:2:0].
876  * \param uc_dispBufs: Number of Display Buffers.
877  * \param p_NALBufAPI: Pointer to NAL Buffer API.
878  * \param p_DispBufAPI: Pointer to Display Buffer API.
879  * \param ih264d_dec_mem_manager  :Pointer to the function that will be called by decoder
880  *                        for memory allocation and freeing.
881  *
882  * \return
883  *    0 on Success and -1 on error
884  *
885  **************************************************************************
886  */
ih264d_init_decoder(void * ps_dec_params)887 void ih264d_init_decoder(void * ps_dec_params)
888 {
889     dec_struct_t * ps_dec = (dec_struct_t *)ps_dec_params;
890     dec_slice_params_t *ps_cur_slice;
891     pocstruct_t *ps_prev_poc, *ps_cur_poc;
892     WORD32 size;
893 
894     size = sizeof(pred_info_t) * 2 * 32;
895     memset(ps_dec->ps_pred, 0 , size);
896 
897     size = sizeof(disp_mgr_t);
898     memset(ps_dec->pv_disp_buf_mgr, 0 , size);
899 
900     size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
901     memset(ps_dec->pv_pic_buf_mgr, 0, size);
902 
903     size = sizeof(dec_err_status_t);
904     memset(ps_dec->ps_dec_err_status, 0, size);
905 
906     size = sizeof(sei);
907     memset(ps_dec->ps_sei, 0, size);
908 
909     size = sizeof(dpb_commands_t);
910     memset(ps_dec->ps_dpb_cmds, 0, size);
911 
912     size = sizeof(dec_bit_stream_t);
913     memset(ps_dec->ps_bitstrm, 0, size);
914 
915     size = sizeof(dec_slice_params_t);
916     memset(ps_dec->ps_cur_slice, 0, size);
917 
918     size = MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t));
919     memset(ps_dec->pv_scratch_sps_pps, 0, size);
920 
921     size = sizeof(ctxt_inc_mb_info_t);
922     memset(ps_dec->ps_left_mb_ctxt_info, 0, size);
923 
924     size = (sizeof(neighbouradd_t) << 2);
925     memset(ps_dec->ps_left_mvpred_addr, 0 ,size);
926 
927     size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
928     memset(ps_dec->pv_mv_buf_mgr, 0, size);
929 
930     /* Free any dynamic buffers that are allocated */
931     ih264d_free_dynamic_bufs(ps_dec);
932 
933     ps_cur_slice = ps_dec->ps_cur_slice;
934     ps_dec->init_done = 0;
935 
936     ps_dec->u4_num_cores = 1;
937 
938     ps_dec->u2_pic_ht = ps_dec->u2_pic_wd = 0;
939 
940     ps_dec->u1_separate_parse = DEFAULT_SEPARATE_PARSE;
941     ps_dec->u4_app_disable_deblk_frm = 0;
942     ps_dec->i4_degrade_type = 0;
943     ps_dec->i4_degrade_pics = 0;
944 
945     ps_dec->i4_app_skip_mode = IVD_SKIP_NONE;
946     ps_dec->i4_dec_skip_mode = IVD_SKIP_NONE;
947 
948     memset(ps_dec->ps_pps, 0,
949            ((sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS));
950     memset(ps_dec->ps_sps, 0,
951            ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS));
952 
953     /* Initialization of function pointers ih264d_deblock_picture function*/
954 
955     ps_dec->p_DeblockPicture[0] = ih264d_deblock_picture_non_mbaff;
956     ps_dec->p_DeblockPicture[1] = ih264d_deblock_picture_mbaff;
957 
958     ps_dec->s_cab_dec_env.pv_codec_handle = ps_dec;
959 
960     ps_dec->u4_num_fld_in_frm = 0;
961 
962     ps_dec->ps_dpb_mgr->pv_codec_handle = ps_dec;
963 
964     /* Initialize the sei validity u4_flag with zero indiacting sei is not valid*/
965     ps_dec->ps_sei->u1_is_valid = 0;
966 
967     /* decParams Initializations */
968     ps_dec->ps_cur_pps = NULL;
969     ps_dec->ps_cur_sps = NULL;
970     ps_dec->u1_init_dec_flag = 0;
971     ps_dec->u1_first_slice_in_stream = 1;
972     ps_dec->u1_first_pb_nal_in_pic = 1;
973     ps_dec->u1_last_pic_not_decoded = 0;
974     ps_dec->u4_app_disp_width = 0;
975     ps_dec->i4_header_decoded = 0;
976     ps_dec->u4_total_frames_decoded = 0;
977 
978     ps_dec->i4_error_code = 0;
979     ps_dec->i4_content_type = -1;
980     ps_dec->ps_cur_slice->u1_mbaff_frame_flag = 0;
981 
982     ps_dec->ps_dec_err_status->u1_err_flag = ACCEPT_ALL_PICS; //REJECT_PB_PICS;
983     ps_dec->ps_dec_err_status->u1_cur_pic_type = PIC_TYPE_UNKNOWN;
984     ps_dec->ps_dec_err_status->u4_frm_sei_sync = SYNC_FRM_DEFAULT;
985     ps_dec->ps_dec_err_status->u4_cur_frm = INIT_FRAME;
986     ps_dec->ps_dec_err_status->u1_pic_aud_i = PIC_TYPE_UNKNOWN;
987 
988     ps_dec->u1_pr_sl_type = 0xFF;
989     ps_dec->u2_mbx = 0xffff;
990     ps_dec->u2_mby = 0;
991     ps_dec->u2_total_mbs_coded = 0;
992 
993     /* POC initializations */
994     ps_prev_poc = &ps_dec->s_prev_pic_poc;
995     ps_cur_poc = &ps_dec->s_cur_pic_poc;
996     ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb = 0;
997     ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb = 0;
998     ps_prev_poc->i4_delta_pic_order_cnt_bottom =
999                     ps_cur_poc->i4_delta_pic_order_cnt_bottom = 0;
1000     ps_prev_poc->i4_delta_pic_order_cnt[0] =
1001                     ps_cur_poc->i4_delta_pic_order_cnt[0] = 0;
1002     ps_prev_poc->i4_delta_pic_order_cnt[1] =
1003                     ps_cur_poc->i4_delta_pic_order_cnt[1] = 0;
1004     ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
1005     ps_prev_poc->i4_top_field_order_count = ps_cur_poc->i4_top_field_order_count =
1006                     0;
1007     ps_prev_poc->i4_bottom_field_order_count =
1008                     ps_cur_poc->i4_bottom_field_order_count = 0;
1009     ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field = 0;
1010     ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
1011     ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst = 0;
1012     ps_cur_slice->u1_mmco_equalto5 = 0;
1013     ps_cur_slice->u2_frame_num = 0;
1014 
1015     ps_dec->i4_max_poc = 0;
1016     ps_dec->i4_prev_max_display_seq = 0;
1017     ps_dec->u1_recon_mb_grp = 4;
1018 
1019     /* Field PIC initializations */
1020     ps_dec->u1_second_field = 0;
1021     ps_dec->s_prev_seq_params.u1_eoseq_pending = 0;
1022 
1023     /* Set the cropping parameters as zero */
1024     ps_dec->u2_crop_offset_y = 0;
1025     ps_dec->u2_crop_offset_uv = 0;
1026 
1027     /* The Initial Frame Rate Info is not Present */
1028     ps_dec->i4_vui_frame_rate = -1;
1029     ps_dec->i4_pic_type = -1;
1030     ps_dec->i4_frametype = -1;
1031     ps_dec->i4_content_type = -1;
1032 
1033     ps_dec->u1_res_changed = 0;
1034 
1035 
1036     ps_dec->u1_frame_decoded_flag = 0;
1037 
1038     /* Set the default frame seek mask mode */
1039     ps_dec->u4_skip_frm_mask = SKIP_NONE;
1040 
1041     /********************************************************/
1042     /* Initialize CAVLC residual decoding function pointers */
1043     /********************************************************/
1044     ps_dec->pf_cavlc_4x4res_block[0] = ih264d_cavlc_4x4res_block_totalcoeff_1;
1045     ps_dec->pf_cavlc_4x4res_block[1] =
1046                     ih264d_cavlc_4x4res_block_totalcoeff_2to10;
1047     ps_dec->pf_cavlc_4x4res_block[2] =
1048                     ih264d_cavlc_4x4res_block_totalcoeff_11to16;
1049 
1050     ps_dec->pf_cavlc_parse4x4coeff[0] = ih264d_cavlc_parse4x4coeff_n0to7;
1051     ps_dec->pf_cavlc_parse4x4coeff[1] = ih264d_cavlc_parse4x4coeff_n8;
1052 
1053     ps_dec->pf_cavlc_parse_8x8block[0] =
1054                     ih264d_cavlc_parse_8x8block_none_available;
1055     ps_dec->pf_cavlc_parse_8x8block[1] =
1056                     ih264d_cavlc_parse_8x8block_left_available;
1057     ps_dec->pf_cavlc_parse_8x8block[2] =
1058                     ih264d_cavlc_parse_8x8block_top_available;
1059     ps_dec->pf_cavlc_parse_8x8block[3] =
1060                     ih264d_cavlc_parse_8x8block_both_available;
1061 
1062     /***************************************************************************/
1063     /* Initialize Bs calculation function pointers for P and B, 16x16/non16x16 */
1064     /***************************************************************************/
1065     ps_dec->pf_fill_bs1[0][0] = ih264d_fill_bs1_16x16mb_pslice;
1066     ps_dec->pf_fill_bs1[0][1] = ih264d_fill_bs1_non16x16mb_pslice;
1067 
1068     ps_dec->pf_fill_bs1[1][0] = ih264d_fill_bs1_16x16mb_bslice;
1069     ps_dec->pf_fill_bs1[1][1] = ih264d_fill_bs1_non16x16mb_bslice;
1070 
1071     ps_dec->pf_fill_bs_xtra_left_edge[0] =
1072                     ih264d_fill_bs_xtra_left_edge_cur_frm;
1073     ps_dec->pf_fill_bs_xtra_left_edge[1] =
1074                     ih264d_fill_bs_xtra_left_edge_cur_fld;
1075 
1076     /* Initialize Reference Pic Buffers */
1077     ih264d_init_ref_bufs(ps_dec->ps_dpb_mgr);
1078 
1079     ps_dec->u2_prv_frame_num = 0;
1080     ps_dec->u1_top_bottom_decoded = 0;
1081     ps_dec->u1_dangling_field = 0;
1082 
1083     ps_dec->s_cab_dec_env.cabac_table = gau4_ih264d_cabac_table;
1084 
1085     ps_dec->pu1_left_mv_ctxt_inc = ps_dec->u1_left_mv_ctxt_inc_arr[0];
1086     ps_dec->pi1_left_ref_idx_ctxt_inc =
1087                     &ps_dec->i1_left_ref_idx_ctx_inc_arr[0][0];
1088     ps_dec->pu1_left_yuv_dc_csbp = &ps_dec->u1_yuv_dc_csbp_topmb;
1089 
1090     /* ! */
1091     /* Initializing flush frame u4_flag */
1092     ps_dec->u1_flushfrm = 0;
1093 
1094     {
1095         ps_dec->s_cab_dec_env.pv_codec_handle = (void*)ps_dec;
1096         ps_dec->ps_bitstrm->pv_codec_handle = (void*)ps_dec;
1097         ps_dec->ps_cur_slice->pv_codec_handle = (void*)ps_dec;
1098         ps_dec->ps_dpb_mgr->pv_codec_handle = (void*)ps_dec;
1099     }
1100 
1101     memset(ps_dec->disp_bufs, 0, (MAX_DISP_BUFS_NEW) * sizeof(disp_buf_t));
1102     memset(ps_dec->u4_disp_buf_mapping, 0,
1103            (MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
1104     memset(ps_dec->u4_disp_buf_to_be_freed, 0,
1105            (MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
1106     memset(ps_dec->ps_cur_slice, 0, sizeof(dec_slice_params_t));
1107 
1108     ih264d_init_arch(ps_dec);
1109     ih264d_init_function_ptr(ps_dec);
1110     ps_dec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
1111     ps_dec->init_done = 1;
1112 
1113 }
ih264d_free_static_bufs(iv_obj_t * dec_hdl)1114 WORD32 ih264d_free_static_bufs(iv_obj_t *dec_hdl)
1115 {
1116     dec_struct_t *ps_dec;
1117 
1118     void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
1119     void *pv_mem_ctxt;
1120 
1121     ps_dec = (dec_struct_t *)dec_hdl->pv_codec_handle;
1122     pf_aligned_free = ps_dec->pf_aligned_free;
1123     pv_mem_ctxt = ps_dec->pv_mem_ctxt;
1124 
1125     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sps);
1126     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pps);
1127     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_dec_thread_handle);
1128     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_bs_deblk_thread_handle);
1129     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dpb_mgr);
1130     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pred);
1131     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_disp_buf_mgr);
1132     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_pic_buf_mgr);
1133     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pic_buf_base);
1134     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dec_err_status);
1135     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sei);
1136     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dpb_cmds);
1137     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_bitstrm);
1138     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_cur_slice);
1139     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_scratch_sps_pps);
1140     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_bits_buf_static);
1141     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ppv_map_ref_idx_to_poc_base);
1142     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->p_cabac_ctxt_table_t);
1143     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_left_mb_ctxt_info);
1144     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_ref_buff_base);
1145     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pi2_pred1);
1146     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_temp_mc_buffer);
1147     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_init_dpb_base);
1148     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu4_mbaff_wt_mat);
1149     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu4_wts_ofsts_mat);
1150     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_left_mvpred_addr);
1151     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_mv_buf_mgr);
1152     PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_col_mv_base);
1153     PS_DEC_ALIGNED_FREE(ps_dec, dec_hdl->pv_codec_handle);
1154 
1155     if(dec_hdl)
1156     {
1157         pf_aligned_free(pv_mem_ctxt, dec_hdl);
1158     }
1159     return IV_SUCCESS;
1160 }
1161 /*****************************************************************************/
1162 /*                                                                           */
1163 /*  Function Name : ih264d_create                                              */
1164 /*                                                                           */
1165 /*  Description   : creates decoder                                          */
1166 /*                                                                           */
1167 /*  Inputs        :iv_obj_t decoder handle                                   */
1168 /*                :pv_api_ip pointer to input structure                      */
1169 /*                :pv_api_op pointer to output structure                     */
1170 /*  Outputs       :                                                          */
1171 /*  Returns       : void                                                     */
1172 /*                                                                           */
1173 /*  Issues        : none                                                     */
1174 /*                                                                           */
1175 /*  Revision History:                                                        */
1176 /*                                                                           */
1177 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1178 /*         22 10 2008    100356         Draft                                */
1179 /*                                                                           */
1180 /*****************************************************************************/
ih264d_allocate_static_bufs(iv_obj_t ** dec_hdl,void * pv_api_ip,void * pv_api_op)1181 WORD32 ih264d_allocate_static_bufs(iv_obj_t **dec_hdl, void *pv_api_ip, void *pv_api_op)
1182 {
1183     ih264d_create_ip_t *ps_create_ip;
1184     ih264d_create_op_t *ps_create_op;
1185     void *pv_buf;
1186     UWORD8 *pu1_buf;
1187     dec_struct_t *ps_dec;
1188     void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
1189     void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
1190     void *pv_mem_ctxt;
1191     WORD32 size;
1192 
1193     ps_create_ip = (ih264d_create_ip_t *)pv_api_ip;
1194     ps_create_op = (ih264d_create_op_t *)pv_api_op;
1195 
1196     ps_create_op->s_ivd_create_op_t.u4_error_code = 0;
1197 
1198     pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc;
1199     pf_aligned_free = ps_create_ip->s_ivd_create_ip_t.pf_aligned_free;
1200     pv_mem_ctxt  = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
1201 
1202     /* Initialize return handle to NULL */
1203     ps_create_op->s_ivd_create_op_t.pv_handle = NULL;
1204     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(iv_obj_t));
1205     RETURN_IF((NULL == pv_buf), IV_FAIL);
1206     *dec_hdl = (iv_obj_t *)pv_buf;
1207     ps_create_op->s_ivd_create_op_t.pv_handle = *dec_hdl;
1208 
1209     (*dec_hdl)->pv_codec_handle = NULL;
1210     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(dec_struct_t));
1211     RETURN_IF((NULL == pv_buf), IV_FAIL);
1212     (*dec_hdl)->pv_codec_handle = (dec_struct_t *)pv_buf;
1213     ps_dec = (dec_struct_t *)pv_buf;
1214 
1215     memset(ps_dec, 0, sizeof(dec_struct_t));
1216 
1217 #ifndef LOGO_EN
1218     ps_dec->u4_share_disp_buf = ps_create_ip->s_ivd_create_ip_t.u4_share_disp_buf;
1219 #else
1220     ps_dec->u4_share_disp_buf = 0;
1221 #endif
1222 
1223     ps_dec->u1_chroma_format =
1224                     (UWORD8)(ps_create_ip->s_ivd_create_ip_t.e_output_format);
1225 
1226     if((ps_dec->u1_chroma_format != IV_YUV_420P)
1227                     && (ps_dec->u1_chroma_format
1228                                     != IV_YUV_420SP_UV)
1229                     && (ps_dec->u1_chroma_format
1230                                     != IV_YUV_420SP_VU))
1231     {
1232         ps_dec->u4_share_disp_buf = 0;
1233     }
1234 
1235     ps_dec->pf_aligned_alloc = pf_aligned_alloc;
1236     ps_dec->pf_aligned_free = pf_aligned_free;
1237     ps_dec->pv_mem_ctxt = pv_mem_ctxt;
1238 
1239 
1240     size = ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS);
1241     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1242     RETURN_IF((NULL == pv_buf), IV_FAIL);
1243     ps_dec->ps_sps = pv_buf;
1244 
1245     size = (sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS;
1246     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1247     RETURN_IF((NULL == pv_buf), IV_FAIL);
1248     ps_dec->ps_pps = pv_buf;
1249 
1250     size = ithread_get_handle_size();
1251     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1252     RETURN_IF((NULL == pv_buf), IV_FAIL);
1253     ps_dec->pv_dec_thread_handle = pv_buf;
1254 
1255     size = ithread_get_handle_size();
1256     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1257     RETURN_IF((NULL == pv_buf), IV_FAIL);
1258     ps_dec->pv_bs_deblk_thread_handle = pv_buf;
1259 
1260     size = sizeof(dpb_manager_t);
1261     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1262     RETURN_IF((NULL == pv_buf), IV_FAIL);
1263     ps_dec->ps_dpb_mgr = pv_buf;
1264 
1265     size = sizeof(pred_info_t) * 2 * 32;
1266     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1267     RETURN_IF((NULL == pv_buf), IV_FAIL);
1268     ps_dec->ps_pred = pv_buf;
1269 
1270     size = sizeof(disp_mgr_t);
1271     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1272     RETURN_IF((NULL == pv_buf), IV_FAIL);
1273     ps_dec->pv_disp_buf_mgr = pv_buf;
1274 
1275     size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
1276     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1277     RETURN_IF((NULL == pv_buf), IV_FAIL);
1278     ps_dec->pv_pic_buf_mgr = pv_buf;
1279 
1280     size = sizeof(struct pic_buffer_t) * (H264_MAX_REF_PICS * 2);
1281     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1282     RETURN_IF((NULL == pv_buf), IV_FAIL);
1283     ps_dec->ps_pic_buf_base = pv_buf;
1284 
1285     size = sizeof(dec_err_status_t);
1286     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1287     RETURN_IF((NULL == pv_buf), IV_FAIL);
1288     ps_dec->ps_dec_err_status = (dec_err_status_t *)pv_buf;
1289 
1290     size = sizeof(sei);
1291     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1292     RETURN_IF((NULL == pv_buf), IV_FAIL);
1293     ps_dec->ps_sei = (sei *)pv_buf;
1294 
1295     size = sizeof(dpb_commands_t);
1296     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1297     RETURN_IF((NULL == pv_buf), IV_FAIL);
1298     ps_dec->ps_dpb_cmds = (dpb_commands_t *)pv_buf;
1299 
1300     size = sizeof(dec_bit_stream_t);
1301     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1302     RETURN_IF((NULL == pv_buf), IV_FAIL);
1303     ps_dec->ps_bitstrm = (dec_bit_stream_t *)pv_buf;
1304 
1305     size = sizeof(dec_slice_params_t);
1306     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1307     RETURN_IF((NULL == pv_buf), IV_FAIL);
1308     ps_dec->ps_cur_slice = (dec_slice_params_t *)pv_buf;
1309 
1310     size = MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t));
1311     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1312     RETURN_IF((NULL == pv_buf), IV_FAIL);
1313     ps_dec->pv_scratch_sps_pps = pv_buf;
1314 
1315 
1316     ps_dec->u4_static_bits_buf_size = 256000;
1317     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, ps_dec->u4_static_bits_buf_size);
1318     RETURN_IF((NULL == pv_buf), IV_FAIL);
1319     ps_dec->pu1_bits_buf_static = pv_buf;
1320 
1321 
1322     size = ((TOTAL_LIST_ENTRIES + PAD_MAP_IDX_POC)
1323                         * sizeof(void *));
1324     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1325     RETURN_IF((NULL == pv_buf), IV_FAIL);
1326     ps_dec->ppv_map_ref_idx_to_poc_base = pv_buf;
1327     memset(ps_dec->ppv_map_ref_idx_to_poc_base, 0, size);
1328 
1329     ps_dec->ppv_map_ref_idx_to_poc = ps_dec->ppv_map_ref_idx_to_poc_base + OFFSET_MAP_IDX_POC;
1330 
1331 
1332     size = (sizeof(bin_ctxt_model_t) * NUM_CABAC_CTXTS);
1333     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1334     RETURN_IF((NULL == pv_buf), IV_FAIL);
1335     ps_dec->p_cabac_ctxt_table_t = pv_buf;
1336 
1337 
1338 
1339     size = sizeof(ctxt_inc_mb_info_t);
1340     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1341     RETURN_IF((NULL == pv_buf), IV_FAIL);
1342     ps_dec->ps_left_mb_ctxt_info = pv_buf;
1343 
1344 
1345 
1346     size = MAX_REF_BUF_SIZE * 2;
1347     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1348     RETURN_IF((NULL == pv_buf), IV_FAIL);
1349     ps_dec->pu1_ref_buff_base = pv_buf;
1350     ps_dec->pu1_ref_buff = ps_dec->pu1_ref_buff_base + MAX_REF_BUF_SIZE;
1351 
1352 
1353     size = ((sizeof(WORD16)) * PRED_BUFFER_WIDTH
1354                         * PRED_BUFFER_HEIGHT * 2);
1355     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1356     RETURN_IF((NULL == pv_buf), IV_FAIL);
1357     ps_dec->pi2_pred1 = pv_buf;
1358 
1359 
1360     size = sizeof(UWORD8) * (MB_LUM_SIZE);
1361     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1362     RETURN_IF((NULL == pv_buf), IV_FAIL);
1363     ps_dec->pu1_temp_mc_buffer = pv_buf;
1364 
1365 
1366 
1367 
1368     size = 8 * MAX_REF_BUFS * sizeof(struct pic_buffer_t);
1369     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1370     RETURN_IF((NULL == pv_buf), IV_FAIL);
1371 
1372     ps_dec->pu1_init_dpb_base = pv_buf;
1373     pu1_buf = pv_buf;
1374     ps_dec->ps_dpb_mgr->ps_init_dpb[0][0] = (struct pic_buffer_t *)pu1_buf;
1375 
1376     pu1_buf += size / 2;
1377     ps_dec->ps_dpb_mgr->ps_init_dpb[1][0] = (struct pic_buffer_t *)pu1_buf;
1378 
1379     size = (sizeof(UWORD32) * 3
1380                         * (MAX_FRAMES * MAX_FRAMES))
1381                         << 3;
1382     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1383     RETURN_IF((NULL == pv_buf), IV_FAIL);
1384     ps_dec->pu4_mbaff_wt_mat = pv_buf;
1385 
1386     size = sizeof(UWORD32) * 2 * 3
1387                         * (MAX_FRAMES * MAX_FRAMES);
1388     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1389     RETURN_IF((NULL == pv_buf), IV_FAIL);
1390     ps_dec->pu4_wts_ofsts_mat = pv_buf;
1391 
1392 
1393     size = (sizeof(neighbouradd_t) << 2);
1394     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1395     RETURN_IF((NULL == pv_buf), IV_FAIL);
1396     ps_dec->ps_left_mvpred_addr = pv_buf;
1397 
1398 
1399     size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
1400     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1401     RETURN_IF((NULL == pv_buf), IV_FAIL);
1402     ps_dec->pv_mv_buf_mgr = pv_buf;
1403 
1404 
1405     size =  sizeof(col_mv_buf_t) * (H264_MAX_REF_PICS * 2);
1406     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1407     RETURN_IF((NULL == pv_buf), IV_FAIL);
1408     ps_dec->ps_col_mv_base = pv_buf;
1409     memset(ps_dec->ps_col_mv_base, 0, size);
1410 
1411     {
1412         UWORD8 i;
1413         struct pic_buffer_t *ps_init_dpb;
1414         ps_init_dpb = ps_dec->ps_dpb_mgr->ps_init_dpb[0][0];
1415         for(i = 0; i < 2 * MAX_REF_BUFS; i++)
1416         {
1417             ps_init_dpb->pu1_buf1 = NULL;
1418             ps_init_dpb->u1_long_term_frm_idx = MAX_REF_BUFS + 1;
1419             ps_dec->ps_dpb_mgr->ps_init_dpb[0][i] = ps_init_dpb;
1420             ps_dec->ps_dpb_mgr->ps_mod_dpb[0][i] = ps_init_dpb;
1421             ps_init_dpb++;
1422         }
1423 
1424         ps_init_dpb = ps_dec->ps_dpb_mgr->ps_init_dpb[1][0];
1425         for(i = 0; i < 2 * MAX_REF_BUFS; i++)
1426         {
1427             ps_init_dpb->pu1_buf1 = NULL;
1428             ps_init_dpb->u1_long_term_frm_idx = MAX_REF_BUFS + 1;
1429             ps_dec->ps_dpb_mgr->ps_init_dpb[1][i] = ps_init_dpb;
1430             ps_dec->ps_dpb_mgr->ps_mod_dpb[1][i] = ps_init_dpb;
1431             ps_init_dpb++;
1432         }
1433     }
1434     ih264d_init_decoder(ps_dec);
1435 
1436     return IV_SUCCESS;
1437 }
1438 
1439 
1440 /*****************************************************************************/
1441 /*                                                                           */
1442 /*  Function Name : ih264d_create                                              */
1443 /*                                                                           */
1444 /*  Description   : creates decoder                                          */
1445 /*                                                                           */
1446 /*  Inputs        :iv_obj_t decoder handle                                   */
1447 /*                :pv_api_ip pointer to input structure                      */
1448 /*                :pv_api_op pointer to output structure                     */
1449 /*  Outputs       :                                                          */
1450 /*  Returns       : void                                                     */
1451 /*                                                                           */
1452 /*  Issues        : none                                                     */
1453 /*                                                                           */
1454 /*  Revision History:                                                        */
1455 /*                                                                           */
1456 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1457 /*         22 10 2008    100356         Draft                                */
1458 /*                                                                           */
1459 /*****************************************************************************/
ih264d_create(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)1460 WORD32 ih264d_create(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
1461 {
1462     ih264d_create_op_t *ps_create_op;
1463 
1464     WORD32 ret;
1465 
1466     ps_create_op = (ih264d_create_op_t *)pv_api_op;
1467 
1468     ps_create_op->s_ivd_create_op_t.u4_error_code = 0;
1469 
1470     ret = ih264d_allocate_static_bufs(&dec_hdl, pv_api_ip, pv_api_op);
1471 
1472     /* If allocation of some buffer fails, then free buffers allocated till then */
1473     if((IV_FAIL == ret) && (NULL != dec_hdl))
1474     {
1475         ih264d_free_static_bufs(dec_hdl);
1476         ps_create_op->s_ivd_create_op_t.u4_error_code = IVD_MEM_ALLOC_FAILED;
1477         ps_create_op->s_ivd_create_op_t.u4_error_code = 1 << IVD_FATALERROR;
1478 
1479         return IV_FAIL;
1480     }
1481 
1482     return IV_SUCCESS;
1483 }
1484 
1485 /*****************************************************************************/
1486 /*                                                                           */
1487 /*  Function Name :  ih264d_map_error                                        */
1488 /*                                                                           */
1489 /*  Description   :  Maps error codes to IVD error groups                    */
1490 /*                                                                           */
1491 /*  Inputs        :                                                          */
1492 /*  Globals       : <Does it use any global variables?>                      */
1493 /*  Outputs       :                                                          */
1494 /*  Returns       : void                                                     */
1495 /*                                                                           */
1496 /*  Issues        : none                                                     */
1497 /*                                                                           */
1498 /*  Revision History:                                                        */
1499 /*                                                                           */
1500 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1501 /*         22 10 2008    100356         Draft                                */
1502 /*                                                                           */
1503 /*****************************************************************************/
ih264d_map_error(UWORD32 i4_err_status)1504 UWORD32 ih264d_map_error(UWORD32 i4_err_status)
1505 {
1506     UWORD32 temp = 0;
1507 
1508     switch(i4_err_status)
1509     {
1510         case ERROR_MEM_ALLOC_ISRAM_T:
1511         case ERROR_MEM_ALLOC_SDRAM_T:
1512         case ERROR_BUF_MGR:
1513         case ERROR_MB_GROUP_ASSGN_T:
1514         case ERROR_FRAME_LIMIT_OVER:
1515         case ERROR_ACTUAL_RESOLUTION_GREATER_THAN_INIT:
1516         case ERROR_PROFILE_NOT_SUPPORTED:
1517         case ERROR_INIT_NOT_DONE:
1518         case IVD_MEM_ALLOC_FAILED:
1519             temp = 1 << IVD_FATALERROR;
1520             H264_DEC_DEBUG_PRINT("\nFatal Error\n");
1521             break;
1522 
1523         case ERROR_DBP_MANAGER_T:
1524         case ERROR_GAPS_IN_FRM_NUM:
1525         case ERROR_UNKNOWN_NAL:
1526         case ERROR_INV_MB_SLC_GRP_T:
1527         case ERROR_MULTIPLE_SLC_GRP_T:
1528         case ERROR_UNKNOWN_LEVEL:
1529         case ERROR_UNAVAIL_PICBUF_T:
1530         case ERROR_UNAVAIL_MVBUF_T:
1531         case ERROR_UNAVAIL_DISPBUF_T:
1532         case ERROR_NUM_REF:
1533         case ERROR_REFIDX_ORDER_T:
1534         case ERROR_PIC0_NOT_FOUND_T:
1535         case ERROR_MB_TYPE:
1536         case ERROR_SUB_MB_TYPE:
1537         case ERROR_CBP:
1538         case ERROR_REF_IDX:
1539         case ERROR_NUM_MV:
1540         case ERROR_CHROMA_PRED_MODE:
1541         case ERROR_INTRAPRED:
1542         case ERROR_NEXT_MB_ADDRESS_T:
1543         case ERROR_MB_ADDRESS_T:
1544         case ERROR_PIC1_NOT_FOUND_T:
1545         case ERROR_CAVLC_NUM_COEFF_T:
1546         case ERROR_CAVLC_SCAN_POS_T:
1547         case ERROR_PRED_WEIGHT_TABLE_T:
1548         case ERROR_CORRUPTED_SLICE:
1549             temp = 1 << IVD_CORRUPTEDDATA;
1550             break;
1551 
1552         case ERROR_NOT_SUPP_RESOLUTION:
1553         case ERROR_FEATURE_UNAVAIL:
1554         case ERROR_ACTUAL_LEVEL_GREATER_THAN_INIT:
1555             temp = 1 << IVD_UNSUPPORTEDINPUT;
1556             break;
1557 
1558         case ERROR_INVALID_PIC_PARAM:
1559         case ERROR_INVALID_SEQ_PARAM:
1560         case ERROR_EGC_EXCEED_32_1_T:
1561         case ERROR_EGC_EXCEED_32_2_T:
1562         case ERROR_INV_RANGE_TEV_T:
1563         case ERROR_INV_SLC_TYPE_T:
1564         case ERROR_INV_POC_TYPE_T:
1565         case ERROR_INV_RANGE_QP_T:
1566         case ERROR_INV_SPS_PPS_T:
1567         case ERROR_INV_SLICE_HDR_T:
1568             temp = 1 << IVD_CORRUPTEDHEADER;
1569             break;
1570 
1571         case ERROR_EOB_FLUSHBITS_T:
1572         case ERROR_EOB_GETBITS_T:
1573         case ERROR_EOB_GETBIT_T:
1574         case ERROR_EOB_BYPASS_T:
1575         case ERROR_EOB_DECISION_T:
1576         case ERROR_EOB_TERMINATE_T:
1577         case ERROR_EOB_READCOEFF4X4CAB_T:
1578             temp = 1 << IVD_INSUFFICIENTDATA;
1579             break;
1580         case ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED:
1581         case ERROR_DISP_WIDTH_RESET_TO_PIC_WIDTH:
1582             temp = 1 << IVD_UNSUPPORTEDPARAM | 1 << IVD_FATALERROR;
1583             break;
1584 
1585         case ERROR_DANGLING_FIELD_IN_PIC:
1586             temp = 1 << IVD_APPLIEDCONCEALMENT;
1587             break;
1588 
1589     }
1590 
1591     return temp;
1592 
1593 }
1594 
1595 /*****************************************************************************/
1596 /*                                                                           */
1597 /*  Function Name :  ih264d_video_decode                                     */
1598 /*                                                                           */
1599 /*  Description   :  handle video decode API command                         */
1600 /*                                                                           */
1601 /*  Inputs        :iv_obj_t decoder handle                                   */
1602 /*                :pv_api_ip pointer to input structure                      */
1603 /*                :pv_api_op pointer to output structure                     */
1604 /*  Outputs       :                                                          */
1605 /*  Returns       : void                                                     */
1606 /*                                                                           */
1607 /*  Issues        : none                                                     */
1608 /*                                                                           */
1609 /*  Revision History:                                                        */
1610 /*                                                                           */
1611 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1612 /*         22 10 2008    100356         Draft                                */
1613 /*                                                                           */
1614 /*****************************************************************************/
1615 
ih264d_video_decode(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)1616 WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
1617 {
1618     /* ! */
1619 
1620     dec_struct_t * ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
1621 
1622     WORD32 i4_err_status = 0;
1623     UWORD8 *pu1_buf = NULL;
1624     WORD32 buflen;
1625     UWORD32 u4_max_ofst, u4_length_of_start_code = 0;
1626 
1627     UWORD32 bytes_consumed = 0;
1628     UWORD32 cur_slice_is_nonref = 0;
1629     UWORD32 u4_next_is_aud;
1630     UWORD32 u4_first_start_code_found = 0;
1631     WORD32 ret = 0,api_ret_value = IV_SUCCESS;
1632     WORD32 header_data_left = 0,frame_data_left = 0;
1633     UWORD8 *pu1_bitstrm_buf;
1634     ivd_video_decode_ip_t *ps_dec_ip;
1635     ivd_video_decode_op_t *ps_dec_op;
1636 
1637     ithread_set_name((void*)"Parse_thread");
1638 
1639     ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip;
1640     ps_dec_op = (ivd_video_decode_op_t *)pv_api_op;
1641 
1642     {
1643         UWORD32 u4_size;
1644         u4_size = ps_dec_op->u4_size;
1645         memset(ps_dec_op, 0, sizeof(ivd_video_decode_op_t));
1646         ps_dec_op->u4_size = u4_size;
1647     }
1648 
1649     ps_dec->pv_dec_out = ps_dec_op;
1650     if(ps_dec->init_done != 1)
1651     {
1652         return IV_FAIL;
1653     }
1654 
1655     /*Data memory barries instruction,so that bitstream write by the application is complete*/
1656     DATA_SYNC();
1657 
1658     if(0 == ps_dec->u1_flushfrm)
1659     {
1660         if(ps_dec_ip->pv_stream_buffer == NULL)
1661         {
1662             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1663             ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL;
1664             return IV_FAIL;
1665         }
1666         if(ps_dec_ip->u4_num_Bytes <= 0)
1667         {
1668             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1669             ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV;
1670             return IV_FAIL;
1671 
1672         }
1673     }
1674     ps_dec->u1_pic_decode_done = 0;
1675 
1676     ps_dec_op->u4_num_bytes_consumed = 0;
1677 
1678     ps_dec->ps_out_buffer = NULL;
1679 
1680     if(ps_dec_ip->u4_size
1681                     >= offsetof(ivd_video_decode_ip_t, s_out_buffer))
1682         ps_dec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
1683 
1684     ps_dec->u4_fmt_conv_cur_row = 0;
1685 
1686     ps_dec->u4_output_present = 0;
1687     ps_dec->s_disp_op.u4_error_code = 1;
1688     ps_dec->u4_fmt_conv_num_rows = FMT_CONV_NUM_ROWS;
1689     if(0 == ps_dec->u4_share_disp_buf
1690                     && ps_dec->i4_decode_header == 0)
1691     {
1692         UWORD32 i;
1693         if(ps_dec->ps_out_buffer->u4_num_bufs == 0)
1694         {
1695             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1696             ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
1697             return IV_FAIL;
1698         }
1699 
1700         for(i = 0; i < ps_dec->ps_out_buffer->u4_num_bufs; i++)
1701         {
1702             if(ps_dec->ps_out_buffer->pu1_bufs[i] == NULL)
1703             {
1704                 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1705                 ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL;
1706                 return IV_FAIL;
1707             }
1708 
1709             if(ps_dec->ps_out_buffer->u4_min_out_buf_size[i] == 0)
1710             {
1711                 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1712                 ps_dec_op->u4_error_code |=
1713                                 IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
1714                 return IV_FAIL;
1715             }
1716         }
1717     }
1718 
1719     if(ps_dec->u4_total_frames_decoded >= NUM_FRAMES_LIMIT)
1720     {
1721         ps_dec_op->u4_error_code = ERROR_FRAME_LIMIT_OVER;
1722         return IV_FAIL;
1723     }
1724 
1725     /* ! */
1726     ps_dec->u4_ts = ps_dec_ip->u4_ts;
1727 
1728     ps_dec_op->u4_error_code = 0;
1729     ps_dec_op->e_pic_type = -1;
1730     ps_dec_op->u4_output_present = 0;
1731     ps_dec_op->u4_frame_decoded_flag = 0;
1732 
1733     ps_dec->i4_frametype = -1;
1734     ps_dec->i4_content_type = -1;
1735     /*
1736      * For field pictures, set the bottom and top picture decoded u4_flag correctly.
1737      */
1738     {
1739         if((TOP_FIELD_ONLY | BOT_FIELD_ONLY) == ps_dec->u1_top_bottom_decoded)
1740         {
1741             ps_dec->u1_top_bottom_decoded = 0;
1742         }
1743     }
1744     ps_dec->u4_slice_start_code_found = 0;
1745 
1746     /* In case the deocder is not in flush mode(in shared mode),
1747      then decoder has to pick up a buffer to write current frame.
1748      Check if a frame is available in such cases */
1749 
1750     if(ps_dec->u1_init_dec_flag == 1 && ps_dec->u4_share_disp_buf == 1
1751                     && ps_dec->u1_flushfrm == 0)
1752     {
1753         UWORD32 i;
1754 
1755         WORD32 disp_avail = 0, free_id;
1756 
1757         /* Check if at least one buffer is available with the codec */
1758         /* If not then return to application with error */
1759         for(i = 0; i < ps_dec->u1_pic_bufs; i++)
1760         {
1761             if(0 == ps_dec->u4_disp_buf_mapping[i]
1762                             || 1 == ps_dec->u4_disp_buf_to_be_freed[i])
1763             {
1764                 disp_avail = 1;
1765                 break;
1766             }
1767 
1768         }
1769 
1770         if(0 == disp_avail)
1771         {
1772             /* If something is queued for display wait for that buffer to be returned */
1773 
1774             ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
1775             ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
1776             return (IV_FAIL);
1777         }
1778 
1779         while(1)
1780         {
1781             pic_buffer_t *ps_pic_buf;
1782             ps_pic_buf = (pic_buffer_t *)ih264_buf_mgr_get_next_free(
1783                             (buf_mgr_t *)ps_dec->pv_pic_buf_mgr, &free_id);
1784 
1785             if(ps_pic_buf == NULL)
1786             {
1787                 UWORD32 i, display_queued = 0;
1788 
1789                 /* check if any buffer was given for display which is not returned yet */
1790                 for(i = 0; i < (MAX_DISP_BUFS_NEW); i++)
1791                 {
1792                     if(0 != ps_dec->u4_disp_buf_mapping[i])
1793                     {
1794                         display_queued = 1;
1795                         break;
1796                     }
1797                 }
1798                 /* If some buffer is queued for display, then codec has to singal an error and wait
1799                  for that buffer to be returned.
1800                  If nothing is queued for display then codec has ownership of all display buffers
1801                  and it can reuse any of the existing buffers and continue decoding */
1802 
1803                 if(1 == display_queued)
1804                 {
1805                     /* If something is queued for display wait for that buffer to be returned */
1806                     ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
1807                     ps_dec_op->u4_error_code |= (1
1808                                     << IVD_UNSUPPORTEDPARAM);
1809                     return (IV_FAIL);
1810                 }
1811             }
1812             else
1813             {
1814                 /* If the buffer is with display, then mark it as in use and then look for a buffer again */
1815                 if(1 == ps_dec->u4_disp_buf_mapping[free_id])
1816                 {
1817                     ih264_buf_mgr_set_status(
1818                                     (buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
1819                                     free_id,
1820                                     BUF_MGR_IO);
1821                 }
1822                 else
1823                 {
1824                     /**
1825                      *  Found a free buffer for present call. Release it now.
1826                      *  Will be again obtained later.
1827                      */
1828                     ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
1829                                           free_id,
1830                                           BUF_MGR_IO);
1831                     break;
1832                 }
1833             }
1834         }
1835 
1836     }
1837 
1838     if(ps_dec->u1_flushfrm && ps_dec->u1_init_dec_flag)
1839     {
1840 
1841         ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer,
1842                                       &(ps_dec->s_disp_op));
1843         if(0 == ps_dec->s_disp_op.u4_error_code)
1844         {
1845             ps_dec->u4_fmt_conv_cur_row = 0;
1846             ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht;
1847             ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op),
1848                                   ps_dec->u4_fmt_conv_cur_row,
1849                                   ps_dec->u4_fmt_conv_num_rows);
1850             ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
1851             ps_dec->u4_output_present = 1;
1852 
1853         }
1854         ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op));
1855 
1856         ps_dec_op->u4_pic_wd = (UWORD32)ps_dec->u2_disp_width;
1857         ps_dec_op->u4_pic_ht = (UWORD32)ps_dec->u2_disp_height;
1858 
1859         ps_dec_op->u4_new_seq = 0;
1860 
1861         ps_dec_op->u4_output_present = ps_dec->u4_output_present;
1862         ps_dec_op->u4_progressive_frame_flag =
1863                         ps_dec->s_disp_op.u4_progressive_frame_flag;
1864         ps_dec_op->e_output_format =
1865                         ps_dec->s_disp_op.e_output_format;
1866         ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf;
1867         ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type;
1868         ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts;
1869         ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
1870 
1871         /*In the case of flush ,since no frame is decoded set pic type as invalid*/
1872         ps_dec_op->u4_is_ref_flag = -1;
1873         ps_dec_op->e_pic_type = IV_NA_FRAME;
1874         ps_dec_op->u4_frame_decoded_flag = 0;
1875 
1876         if(0 == ps_dec->s_disp_op.u4_error_code)
1877         {
1878             return (IV_SUCCESS);
1879         }
1880         else
1881             return (IV_FAIL);
1882 
1883     }
1884     if(ps_dec->u1_res_changed == 1)
1885     {
1886         /*if resolution has changed and all buffers have been flushed, reset decoder*/
1887         ih264d_init_decoder(ps_dec);
1888     }
1889 
1890     ps_dec->u4_prev_nal_skipped = 0;
1891 
1892     ps_dec->u2_cur_mb_addr = 0;
1893     ps_dec->u2_total_mbs_coded = 0;
1894     ps_dec->u2_cur_slice_num = 0;
1895     ps_dec->cur_dec_mb_num = 0;
1896     ps_dec->cur_recon_mb_num = 0;
1897     ps_dec->u4_first_slice_in_pic = 2;
1898     ps_dec->u1_first_pb_nal_in_pic = 1;
1899     ps_dec->u1_slice_header_done = 0;
1900     ps_dec->u1_dangling_field = 0;
1901 
1902     ps_dec->u4_dec_thread_created = 0;
1903     ps_dec->u4_bs_deblk_thread_created = 0;
1904     ps_dec->u4_cur_bs_mb_num = 0;
1905     ps_dec->u4_start_recon_deblk  = 0;
1906 
1907     DEBUG_THREADS_PRINTF(" Starting process call\n");
1908 
1909 
1910     ps_dec->u4_pic_buf_got = 0;
1911 
1912     do
1913     {
1914         WORD32 buf_size;
1915 
1916         pu1_buf = (UWORD8*)ps_dec_ip->pv_stream_buffer
1917                         + ps_dec_op->u4_num_bytes_consumed;
1918 
1919         u4_max_ofst = ps_dec_ip->u4_num_Bytes
1920                         - ps_dec_op->u4_num_bytes_consumed;
1921 
1922         /* If dynamic bitstream buffer is not allocated and
1923          * header decode is done, then allocate dynamic bitstream buffer
1924          */
1925         if((NULL == ps_dec->pu1_bits_buf_dynamic) &&
1926            (ps_dec->i4_header_decoded & 1))
1927         {
1928             WORD32 size;
1929 
1930             void *pv_buf;
1931             void *pv_mem_ctxt = ps_dec->pv_mem_ctxt;
1932             size = MAX(256000, ps_dec->u2_pic_wd * ps_dec->u2_pic_ht * 3 / 2);
1933             pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1934             RETURN_IF((NULL == pv_buf), IV_FAIL);
1935             ps_dec->pu1_bits_buf_dynamic = pv_buf;
1936             ps_dec->u4_dynamic_bits_buf_size = size;
1937         }
1938 
1939         if(ps_dec->pu1_bits_buf_dynamic)
1940         {
1941             pu1_bitstrm_buf = ps_dec->pu1_bits_buf_dynamic;
1942             buf_size = ps_dec->u4_dynamic_bits_buf_size;
1943         }
1944         else
1945         {
1946             pu1_bitstrm_buf = ps_dec->pu1_bits_buf_static;
1947             buf_size = ps_dec->u4_static_bits_buf_size;
1948         }
1949 
1950         u4_next_is_aud = 0;
1951 
1952         buflen = ih264d_find_start_code(pu1_buf, 0, u4_max_ofst,
1953                                                &u4_length_of_start_code,
1954                                                &u4_next_is_aud);
1955 
1956         if(buflen == -1)
1957             buflen = 0;
1958         /* Ignore bytes beyond the allocated size of intermediate buffer */
1959         buflen = MIN(buflen, buf_size);
1960 
1961         bytes_consumed = buflen + u4_length_of_start_code;
1962         ps_dec_op->u4_num_bytes_consumed += bytes_consumed;
1963 
1964         {
1965             UWORD8 u1_firstbyte, u1_nal_ref_idc;
1966 
1967             if(ps_dec->i4_app_skip_mode == IVD_SKIP_B)
1968             {
1969                 u1_firstbyte = *(pu1_buf + u4_length_of_start_code);
1970                 u1_nal_ref_idc = (UWORD8)(NAL_REF_IDC(u1_firstbyte));
1971                 if(u1_nal_ref_idc == 0)
1972                 {
1973                     /*skip non reference frames*/
1974                     cur_slice_is_nonref = 1;
1975                     continue;
1976                 }
1977                 else
1978                 {
1979                     if(1 == cur_slice_is_nonref)
1980                     {
1981                         /*We have encountered a referenced frame,return to app*/
1982                         ps_dec_op->u4_num_bytes_consumed -=
1983                                         bytes_consumed;
1984                         ps_dec_op->e_pic_type = IV_B_FRAME;
1985                         ps_dec_op->u4_error_code =
1986                                         IVD_DEC_FRM_SKIPPED;
1987                         ps_dec_op->u4_error_code |= (1
1988                                         << IVD_UNSUPPORTEDPARAM);
1989                         ps_dec_op->u4_frame_decoded_flag = 0;
1990                         ps_dec_op->u4_size =
1991                                         sizeof(ivd_video_decode_op_t);
1992                         /*signal the decode thread*/
1993                         ih264d_signal_decode_thread(ps_dec);
1994                         /* close deblock thread if it is not closed yet*/
1995                         if(ps_dec->u4_num_cores == 3)
1996                         {
1997                             ih264d_signal_bs_deblk_thread(ps_dec);
1998                         }
1999 
2000                         return (IV_FAIL);
2001                     }
2002                 }
2003 
2004             }
2005 
2006         }
2007 
2008 
2009         if(buflen)
2010         {
2011             memcpy(pu1_bitstrm_buf, pu1_buf + u4_length_of_start_code,
2012                    buflen);
2013             /* Decoder may read extra 8 bytes near end of the frame */
2014             if((buflen + 8) < buf_size)
2015             {
2016                 memset(pu1_bitstrm_buf + buflen, 0, 8);
2017             }
2018             u4_first_start_code_found = 1;
2019 
2020         }
2021         else
2022         {
2023             /*start code not found*/
2024 
2025             if(u4_first_start_code_found == 0)
2026             {
2027                 /*no start codes found in current process call*/
2028 
2029                 ps_dec->i4_error_code = ERROR_START_CODE_NOT_FOUND;
2030                 ps_dec_op->u4_error_code |= 1 << IVD_INSUFFICIENTDATA;
2031 
2032                 if(ps_dec->u4_pic_buf_got == 0)
2033                 {
2034 
2035                     ih264d_fill_output_struct_from_context(ps_dec,
2036                                                            ps_dec_op);
2037 
2038                     ps_dec_op->u4_error_code = ps_dec->i4_error_code;
2039                     ps_dec_op->u4_frame_decoded_flag = 0;
2040 
2041                     return (IV_FAIL);
2042                 }
2043                 else
2044                 {
2045                     ps_dec->u1_pic_decode_done = 1;
2046                     continue;
2047                 }
2048             }
2049             else
2050             {
2051                 /* a start code has already been found earlier in the same process call*/
2052                 frame_data_left = 0;
2053                 continue;
2054             }
2055 
2056         }
2057 
2058         ps_dec->u4_return_to_app = 0;
2059         ret = ih264d_parse_nal_unit(dec_hdl, ps_dec_op,
2060                               pu1_bitstrm_buf, buflen);
2061         if(ret != OK)
2062         {
2063             UWORD32 error =  ih264d_map_error(ret);
2064             ps_dec_op->u4_error_code = error | ret;
2065             api_ret_value = IV_FAIL;
2066 
2067             if((ret == IVD_RES_CHANGED)
2068                             || (ret == IVD_MEM_ALLOC_FAILED)
2069                             || (ret == ERROR_UNAVAIL_PICBUF_T)
2070                             || (ret == ERROR_UNAVAIL_MVBUF_T)
2071                             || (ret == ERROR_INV_SPS_PPS_T))
2072             {
2073                 ps_dec->u4_slice_start_code_found = 0;
2074                 break;
2075             }
2076 
2077             if((ret == ERROR_INCOMPLETE_FRAME) || (ret == ERROR_DANGLING_FIELD_IN_PIC))
2078             {
2079                 ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
2080                 api_ret_value = IV_FAIL;
2081                 break;
2082             }
2083 
2084             if(ret == ERROR_IN_LAST_SLICE_OF_PIC)
2085             {
2086                 api_ret_value = IV_FAIL;
2087                 break;
2088             }
2089 
2090         }
2091 
2092         if(ps_dec->u4_return_to_app)
2093         {
2094             /*We have encountered a referenced frame,return to app*/
2095             ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
2096             ps_dec_op->u4_error_code = IVD_DEC_FRM_SKIPPED;
2097             ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
2098             ps_dec_op->u4_frame_decoded_flag = 0;
2099             ps_dec_op->u4_size = sizeof(ivd_video_decode_op_t);
2100             /*signal the decode thread*/
2101             ih264d_signal_decode_thread(ps_dec);
2102             /* close deblock thread if it is not closed yet*/
2103             if(ps_dec->u4_num_cores == 3)
2104             {
2105                 ih264d_signal_bs_deblk_thread(ps_dec);
2106             }
2107             return (IV_FAIL);
2108 
2109         }
2110 
2111 
2112 
2113         header_data_left = ((ps_dec->i4_decode_header == 1)
2114                         && (ps_dec->i4_header_decoded != 3)
2115                         && (ps_dec_op->u4_num_bytes_consumed
2116                                         < ps_dec_ip->u4_num_Bytes));
2117         frame_data_left = (((ps_dec->i4_decode_header == 0)
2118                         && ((ps_dec->u1_pic_decode_done == 0)
2119                                         || (u4_next_is_aud == 1)))
2120                         && (ps_dec_op->u4_num_bytes_consumed
2121                                         < ps_dec_ip->u4_num_Bytes));
2122     }
2123     while(( header_data_left == 1)||(frame_data_left == 1));
2124 
2125     if((ps_dec->u4_slice_start_code_found == 1)
2126             && (ret != IVD_MEM_ALLOC_FAILED)
2127             && ps_dec->u2_total_mbs_coded < ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
2128     {
2129         // last slice - missing/corruption
2130         WORD32 num_mb_skipped;
2131         WORD32 prev_slice_err;
2132         pocstruct_t temp_poc;
2133         WORD32 ret1;
2134 
2135         num_mb_skipped = (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
2136                             - ps_dec->u2_total_mbs_coded;
2137 
2138         if(ps_dec->u4_first_slice_in_pic && (ps_dec->u4_pic_buf_got == 0))
2139             prev_slice_err = 1;
2140         else
2141             prev_slice_err = 2;
2142 
2143         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,
2144                                    &temp_poc, prev_slice_err);
2145 
2146         if((ret1 == ERROR_UNAVAIL_PICBUF_T) || (ret1 == ERROR_UNAVAIL_MVBUF_T))
2147         {
2148             return IV_FAIL;
2149         }
2150     }
2151 
2152     if((ret == IVD_RES_CHANGED)
2153                     || (ret == IVD_MEM_ALLOC_FAILED)
2154                     || (ret == ERROR_UNAVAIL_PICBUF_T)
2155                     || (ret == ERROR_UNAVAIL_MVBUF_T)
2156                     || (ret == ERROR_INV_SPS_PPS_T))
2157     {
2158 
2159         /* signal the decode thread */
2160         ih264d_signal_decode_thread(ps_dec);
2161         /* close deblock thread if it is not closed yet */
2162         if(ps_dec->u4_num_cores == 3)
2163         {
2164             ih264d_signal_bs_deblk_thread(ps_dec);
2165         }
2166         /* dont consume bitstream for change in resolution case */
2167         if(ret == IVD_RES_CHANGED)
2168         {
2169             ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
2170         }
2171         return IV_FAIL;
2172     }
2173 
2174 
2175     if(ps_dec->u1_separate_parse)
2176     {
2177         /* If Format conversion is not complete,
2178          complete it here */
2179         if(ps_dec->u4_num_cores == 2)
2180         {
2181 
2182             /*do deblocking of all mbs*/
2183             if((ps_dec->u4_nmb_deblk == 0) &&(ps_dec->u4_start_recon_deblk == 1) && (ps_dec->ps_cur_sps->u1_mb_aff_flag == 0))
2184             {
2185                 UWORD32 u4_num_mbs,u4_max_addr;
2186                 tfr_ctxt_t s_tfr_ctxt;
2187                 tfr_ctxt_t *ps_tfr_cxt = &s_tfr_ctxt;
2188                 pad_mgr_t *ps_pad_mgr = &ps_dec->s_pad_mgr;
2189 
2190                 /*BS is done for all mbs while parsing*/
2191                 u4_max_addr = (ps_dec->u2_frm_wd_in_mbs * ps_dec->u2_frm_ht_in_mbs) - 1;
2192                 ps_dec->u4_cur_bs_mb_num = u4_max_addr + 1;
2193 
2194 
2195                 ih264d_init_deblk_tfr_ctxt(ps_dec, ps_pad_mgr, ps_tfr_cxt,
2196                                            ps_dec->u2_frm_wd_in_mbs, 0);
2197 
2198 
2199                 u4_num_mbs = u4_max_addr
2200                                 - ps_dec->u4_cur_deblk_mb_num + 1;
2201 
2202                 DEBUG_PERF_PRINTF("mbs left for deblocking= %d \n",u4_num_mbs);
2203 
2204                 if(u4_num_mbs != 0)
2205                     ih264d_check_mb_map_deblk(ps_dec, u4_num_mbs,
2206                                                    ps_tfr_cxt,1);
2207 
2208                 ps_dec->u4_start_recon_deblk  = 0;
2209 
2210             }
2211 
2212         }
2213 
2214         /*signal the decode thread*/
2215         ih264d_signal_decode_thread(ps_dec);
2216         /* close deblock thread if it is not closed yet*/
2217         if(ps_dec->u4_num_cores == 3)
2218         {
2219             ih264d_signal_bs_deblk_thread(ps_dec);
2220         }
2221     }
2222 
2223 
2224     DATA_SYNC();
2225 
2226 
2227     if((ps_dec_op->u4_error_code & 0xff)
2228                     != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED)
2229     {
2230         ps_dec_op->u4_pic_wd = (UWORD32)ps_dec->u2_disp_width;
2231         ps_dec_op->u4_pic_ht = (UWORD32)ps_dec->u2_disp_height;
2232     }
2233 
2234 //Report if header (sps and pps) has not been decoded yet
2235     if(ps_dec->i4_header_decoded != 3)
2236     {
2237         ps_dec_op->u4_error_code |= (1 << IVD_INSUFFICIENTDATA);
2238 
2239     }
2240 
2241     if(ps_dec->i4_decode_header == 1 && ps_dec->i4_header_decoded != 3)
2242     {
2243         ps_dec_op->u4_error_code |= (1 << IVD_INSUFFICIENTDATA);
2244 
2245     }
2246     if(ps_dec->u4_prev_nal_skipped)
2247     {
2248         /*We have encountered a referenced frame,return to app*/
2249         ps_dec_op->u4_error_code = IVD_DEC_FRM_SKIPPED;
2250         ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
2251         ps_dec_op->u4_frame_decoded_flag = 0;
2252         ps_dec_op->u4_size = sizeof(ivd_video_decode_op_t);
2253         /* close deblock thread if it is not closed yet*/
2254         if(ps_dec->u4_num_cores == 3)
2255         {
2256             ih264d_signal_bs_deblk_thread(ps_dec);
2257         }
2258         return (IV_FAIL);
2259 
2260     }
2261 
2262     if((ps_dec->u4_slice_start_code_found == 1)
2263                     && (ERROR_DANGLING_FIELD_IN_PIC != i4_err_status))
2264     {
2265         /*
2266          * For field pictures, set the bottom and top picture decoded u4_flag correctly.
2267          */
2268 
2269         if(ps_dec->ps_cur_slice->u1_field_pic_flag)
2270         {
2271             if(1 == ps_dec->ps_cur_slice->u1_bottom_field_flag)
2272             {
2273                 ps_dec->u1_top_bottom_decoded |= BOT_FIELD_ONLY;
2274             }
2275             else
2276             {
2277                 ps_dec->u1_top_bottom_decoded |= TOP_FIELD_ONLY;
2278             }
2279         }
2280 
2281         /* if new frame in not found (if we are still getting slices from previous frame)
2282          * ih264d_deblock_display is not called. Such frames will not be added to reference /display
2283          */
2284         if((ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC) == 0)
2285         {
2286             /* Calling Function to deblock Picture and Display */
2287             ret = ih264d_deblock_display(ps_dec);
2288             if(ret != 0)
2289             {
2290                 return IV_FAIL;
2291             }
2292         }
2293 
2294 
2295         /*set to complete ,as we dont support partial frame decode*/
2296         if(ps_dec->i4_header_decoded == 3)
2297         {
2298             ps_dec->u2_total_mbs_coded = ps_dec->ps_cur_sps->u2_max_mb_addr + 1;
2299         }
2300 
2301         /*Update the i4_frametype at the end of picture*/
2302         if(ps_dec->ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL)
2303         {
2304             ps_dec->i4_frametype = IV_IDR_FRAME;
2305         }
2306         else if(ps_dec->i4_pic_type == B_SLICE)
2307         {
2308             ps_dec->i4_frametype = IV_B_FRAME;
2309         }
2310         else if(ps_dec->i4_pic_type == P_SLICE)
2311         {
2312             ps_dec->i4_frametype = IV_P_FRAME;
2313         }
2314         else if(ps_dec->i4_pic_type == I_SLICE)
2315         {
2316             ps_dec->i4_frametype = IV_I_FRAME;
2317         }
2318         else
2319         {
2320             H264_DEC_DEBUG_PRINT("Shouldn't come here\n");
2321         }
2322 
2323         //Update the content type
2324         ps_dec->i4_content_type = ps_dec->ps_cur_slice->u1_field_pic_flag;
2325 
2326         ps_dec->u4_total_frames_decoded = ps_dec->u4_total_frames_decoded + 2;
2327         ps_dec->u4_total_frames_decoded = ps_dec->u4_total_frames_decoded
2328                         - ps_dec->ps_cur_slice->u1_field_pic_flag;
2329 
2330     }
2331 
2332     /* close deblock thread if it is not closed yet*/
2333     if(ps_dec->u4_num_cores == 3)
2334     {
2335         ih264d_signal_bs_deblk_thread(ps_dec);
2336     }
2337 
2338 
2339     {
2340         /* In case the decoder is configured to run in low delay mode,
2341          * then get display buffer and then format convert.
2342          * Note in this mode, format conversion does not run paralelly in a thread and adds to the codec cycles
2343          */
2344 
2345         if((IVD_DECODE_FRAME_OUT == ps_dec->e_frm_out_mode)
2346                         && ps_dec->u1_init_dec_flag)
2347         {
2348 
2349             ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer,
2350                                           &(ps_dec->s_disp_op));
2351             if(0 == ps_dec->s_disp_op.u4_error_code)
2352             {
2353                 ps_dec->u4_fmt_conv_cur_row = 0;
2354                 ps_dec->u4_output_present = 1;
2355             }
2356         }
2357 
2358         ih264d_fill_output_struct_from_context(ps_dec, ps_dec_op);
2359 
2360         /* If Format conversion is not complete,
2361          complete it here */
2362         if(ps_dec->u4_output_present &&
2363           (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
2364         {
2365             ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht
2366                             - ps_dec->u4_fmt_conv_cur_row;
2367             ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op),
2368                                   ps_dec->u4_fmt_conv_cur_row,
2369                                   ps_dec->u4_fmt_conv_num_rows);
2370             ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
2371         }
2372 
2373         ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op));
2374     }
2375 
2376     if(ps_dec->i4_decode_header == 1 && (ps_dec->i4_header_decoded & 1) == 1)
2377     {
2378         ps_dec_op->u4_progressive_frame_flag = 1;
2379         if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
2380         {
2381             if((0 == ps_dec->ps_sps->u1_frame_mbs_only_flag)
2382                             && (0 == ps_dec->ps_sps->u1_mb_aff_flag))
2383                 ps_dec_op->u4_progressive_frame_flag = 0;
2384 
2385         }
2386     }
2387 
2388     /*Data memory barrier instruction,so that yuv write by the library is complete*/
2389     DATA_SYNC();
2390 
2391     H264_DEC_DEBUG_PRINT("The num bytes consumed: %d\n",
2392                          ps_dec_op->u4_num_bytes_consumed);
2393     return api_ret_value;
2394 }
2395 
ih264d_get_version(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)2396 WORD32 ih264d_get_version(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
2397 {
2398     char version_string[MAXVERSION_STRLEN + 1];
2399     UWORD32 version_string_len;
2400 
2401     ivd_ctl_getversioninfo_ip_t *ps_ip;
2402     ivd_ctl_getversioninfo_op_t *ps_op;
2403 
2404     ps_ip = (ivd_ctl_getversioninfo_ip_t *)pv_api_ip;
2405     ps_op = (ivd_ctl_getversioninfo_op_t *)pv_api_op;
2406     UNUSED(dec_hdl);
2407     ps_op->u4_error_code = IV_SUCCESS;
2408 
2409     VERSION(version_string, CODEC_NAME, CODEC_RELEASE_TYPE, CODEC_RELEASE_VER,
2410             CODEC_VENDOR);
2411 
2412     if((WORD32)ps_ip->u4_version_buffer_size <= 0)
2413     {
2414         ps_op->u4_error_code = IH264D_VERS_BUF_INSUFFICIENT;
2415         return (IV_FAIL);
2416     }
2417 
2418     version_string_len = strnlen(version_string, MAXVERSION_STRLEN) + 1;
2419 
2420     if(ps_ip->u4_version_buffer_size >= version_string_len) //(WORD32)sizeof(sizeof(version_string)))
2421     {
2422         memcpy(ps_ip->pv_version_buffer, version_string, version_string_len);
2423         ps_op->u4_error_code = IV_SUCCESS;
2424     }
2425     else
2426     {
2427         ps_op->u4_error_code = IH264D_VERS_BUF_INSUFFICIENT;
2428         return IV_FAIL;
2429     }
2430     return (IV_SUCCESS);
2431 }
2432 
2433 /*****************************************************************************/
2434 /*                                                                           */
2435 /*  Function Name :   ih264d_get_display_frame                               */
2436 /*                                                                           */
2437 /*  Description   :                                                          */
2438 /*  Inputs        :iv_obj_t decoder handle                                   */
2439 /*                :pv_api_ip pointer to input structure                      */
2440 /*                :pv_api_op pointer to output structure                     */
2441 /*  Outputs       :                                                          */
2442 /*  Returns       : void                                                     */
2443 /*                                                                           */
2444 /*  Issues        : none                                                     */
2445 /*                                                                           */
2446 /*  Revision History:                                                        */
2447 /*                                                                           */
2448 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
2449 /*         22 10 2008    100356         Draft                                */
2450 /*                                                                           */
2451 /*****************************************************************************/
ih264d_get_display_frame(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)2452 WORD32 ih264d_get_display_frame(iv_obj_t *dec_hdl,
2453                                 void *pv_api_ip,
2454                                 void *pv_api_op)
2455 {
2456 
2457     UNUSED(dec_hdl);
2458     UNUSED(pv_api_ip);
2459     UNUSED(pv_api_op);
2460     // This function is no longer needed, output is returned in the process()
2461     return IV_FAIL;
2462 }
2463 
2464 /*****************************************************************************/
2465 /*                                                                           */
2466 /*  Function Name :  ih264d_set_display_frame                                */
2467 /*                                                                           */
2468 /*  Description   :                                                          */
2469 /*                                                                           */
2470 /*  Inputs        :iv_obj_t decoder handle                                   */
2471 /*                :pv_api_ip pointer to input structure                      */
2472 /*                :pv_api_op pointer to output structure                     */
2473 /*  Outputs       :                                                          */
2474 /*  Returns       : void                                                     */
2475 /*                                                                           */
2476 /*  Issues        : none                                                     */
2477 /*                                                                           */
2478 /*  Revision History:                                                        */
2479 /*                                                                           */
2480 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
2481 /*         22 10 2008    100356         Draft                                */
2482 /*                                                                           */
2483 /*****************************************************************************/
ih264d_set_display_frame(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)2484 WORD32 ih264d_set_display_frame(iv_obj_t *dec_hdl,
2485                                 void *pv_api_ip,
2486                                 void *pv_api_op)
2487 {
2488 
2489     ivd_set_display_frame_ip_t *dec_disp_ip;
2490     ivd_set_display_frame_op_t *dec_disp_op;
2491 
2492     UWORD32 i;
2493     dec_struct_t * ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
2494 
2495     dec_disp_ip = (ivd_set_display_frame_ip_t *)pv_api_ip;
2496     dec_disp_op = (ivd_set_display_frame_op_t *)pv_api_op;
2497     dec_disp_op->u4_error_code = 0;
2498 
2499 
2500     ps_dec->u4_num_disp_bufs = 0;
2501     if(ps_dec->u4_share_disp_buf)
2502     {
2503         UWORD32 u4_num_bufs = dec_disp_ip->num_disp_bufs;
2504 
2505         u4_num_bufs = MIN(u4_num_bufs, MAX_DISP_BUFS_NEW);
2506 
2507         ps_dec->u4_num_disp_bufs = u4_num_bufs;
2508         for(i = 0; i < u4_num_bufs; i++)
2509         {
2510             ps_dec->disp_bufs[i].u4_num_bufs =
2511                             dec_disp_ip->s_disp_buffer[i].u4_num_bufs;
2512 
2513             ps_dec->disp_bufs[i].buf[0] =
2514                             dec_disp_ip->s_disp_buffer[i].pu1_bufs[0];
2515             ps_dec->disp_bufs[i].buf[1] =
2516                             dec_disp_ip->s_disp_buffer[i].pu1_bufs[1];
2517             ps_dec->disp_bufs[i].buf[2] =
2518                             dec_disp_ip->s_disp_buffer[i].pu1_bufs[2];
2519 
2520             ps_dec->disp_bufs[i].u4_bufsize[0] =
2521                             dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[0];
2522             ps_dec->disp_bufs[i].u4_bufsize[1] =
2523                             dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[1];
2524             ps_dec->disp_bufs[i].u4_bufsize[2] =
2525                             dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[2];
2526 
2527         }
2528     }
2529     return IV_SUCCESS;
2530 
2531 }
2532 
2533 /*****************************************************************************/
2534 /*                                                                           */
2535 /*  Function Name : ih264d_set_flush_mode                                    */
2536 /*                                                                           */
2537 /*  Description   :                                                          */
2538 /*                                                                           */
2539 /*  Inputs        :iv_obj_t decoder handle                                   */
2540 /*                :pv_api_ip pointer to input structure                      */
2541 /*                :pv_api_op pointer to output structure                     */
2542 /*  Globals       : <Does it use any global variables?>                      */
2543 /*  Outputs       :                                                          */
2544 /*  Returns       : void                                                     */
2545 /*                                                                           */
2546 /*  Issues        : none                                                     */
2547 /*                                                                           */
2548 /*  Revision History:                                                        */
2549 /*                                                                           */
2550 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
2551 /*         22 10 2008    100356         Draft                                */
2552 /*                                                                           */
2553 /*****************************************************************************/
ih264d_set_flush_mode(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)2554 WORD32 ih264d_set_flush_mode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
2555 {
2556     dec_struct_t * ps_dec;
2557     ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t*)pv_api_op;
2558     ps_ctl_op->u4_error_code = 0;
2559 
2560     ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
2561     UNUSED(pv_api_ip);
2562     /* ! */
2563     /* Signal flush frame control call */
2564     ps_dec->u1_flushfrm = 1;
2565 
2566     if(ps_dec->u1_init_dec_flag == 1)
2567     {
2568         ih264d_release_pics_in_dpb((void *)ps_dec, ps_dec->u1_pic_bufs);
2569         ih264d_release_display_bufs(ps_dec);
2570     }
2571 
2572     ps_ctl_op->u4_error_code = 0;
2573 
2574     return IV_SUCCESS;
2575 }
2576 
2577 /*****************************************************************************/
2578 /*                                                                           */
2579 /*  Function Name : ih264d_get_status                                        */
2580 /*                                                                           */
2581 /*  Description   :                                                          */
2582 /*                                                                           */
2583 /*  Inputs        :iv_obj_t decoder handle                                   */
2584 /*                :pv_api_ip pointer to input structure                      */
2585 /*                :pv_api_op pointer to output structure                     */
2586 /*  Globals       : <Does it use any global variables?>                      */
2587 /*  Outputs       :                                                          */
2588 /*  Returns       : void                                                     */
2589 /*                                                                           */
2590 /*  Issues        : none                                                     */
2591 /*                                                                           */
2592 /*  Revision History:                                                        */
2593 /*                                                                           */
2594 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
2595 /*         22 10 2008    100356         Draft                                */
2596 /*                                                                           */
2597 /*****************************************************************************/
2598 
ih264d_get_status(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)2599 WORD32 ih264d_get_status(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
2600 {
2601 
2602     UWORD32 i;
2603     dec_struct_t * ps_dec;
2604     UWORD32 pic_wd, pic_ht;
2605     ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t*)pv_api_op;
2606     UNUSED(pv_api_ip);
2607     ps_ctl_op->u4_error_code = 0;
2608 
2609     ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
2610 
2611 
2612     if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
2613     {
2614         ps_ctl_op->u4_pic_ht = ps_dec->u2_disp_height;
2615         ps_ctl_op->u4_pic_wd = ps_dec->u2_disp_width;
2616 
2617         if(0 == ps_dec->u4_share_disp_buf)
2618         {
2619             pic_wd = ps_dec->u2_disp_width;
2620             pic_ht = ps_dec->u2_disp_height;
2621 
2622         }
2623         else
2624         {
2625             pic_wd = ps_dec->u2_frm_wd_y;
2626             pic_ht = ps_dec->u2_frm_ht_y;
2627         }
2628     }
2629     else
2630     {
2631         pic_wd = 0;
2632         pic_ht = 0;
2633 
2634         ps_ctl_op->u4_pic_ht = pic_wd;
2635         ps_ctl_op->u4_pic_wd = pic_ht;
2636 
2637         if(1 == ps_dec->u4_share_disp_buf)
2638         {
2639             pic_wd += (PAD_LEN_Y_H << 1);
2640             pic_ht += (PAD_LEN_Y_V << 2);
2641 
2642         }
2643 
2644     }
2645 
2646     if(ps_dec->u4_app_disp_width > pic_wd)
2647         pic_wd = ps_dec->u4_app_disp_width;
2648     if(0 == ps_dec->u4_share_disp_buf)
2649         ps_ctl_op->u4_num_disp_bufs = 1;
2650     else
2651     {
2652         if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
2653         {
2654             if((ps_dec->ps_cur_sps->u1_vui_parameters_present_flag == 1) &&
2655                (1 == ps_dec->ps_cur_sps->s_vui.u1_bitstream_restriction_flag))
2656             {
2657                 ps_ctl_op->u4_num_disp_bufs =
2658                                 ps_dec->ps_cur_sps->s_vui.u4_num_reorder_frames + 1;
2659             }
2660             else
2661             {
2662                 /*if VUI is not present assume maximum possible refrence frames for the level,
2663                  * as max reorder frames*/
2664                 ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size(ps_dec->ps_cur_sps);
2665             }
2666 
2667             ps_ctl_op->u4_num_disp_bufs +=
2668                             ps_dec->ps_cur_sps->u1_num_ref_frames + 1;
2669         }
2670         else
2671         {
2672             ps_ctl_op->u4_num_disp_bufs = 32;
2673         }
2674         ps_ctl_op->u4_num_disp_bufs = MAX(
2675                         ps_ctl_op->u4_num_disp_bufs, 6);
2676         ps_ctl_op->u4_num_disp_bufs = MIN(
2677                         ps_ctl_op->u4_num_disp_bufs, 32);
2678     }
2679 
2680     ps_ctl_op->u4_error_code = ps_dec->i4_error_code;
2681 
2682     ps_ctl_op->u4_frame_rate = 0; //make it proper
2683     ps_ctl_op->u4_bit_rate = 0; //make it proper
2684     ps_ctl_op->e_content_type = ps_dec->i4_content_type;
2685     ps_ctl_op->e_output_chroma_format = ps_dec->u1_chroma_format;
2686     ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
2687 
2688     if(ps_dec->u1_chroma_format == IV_YUV_420P)
2689     {
2690         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
2691     }
2692     else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
2693     {
2694         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
2695     }
2696     else if(ps_dec->u1_chroma_format == IV_RGB_565)
2697     {
2698         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
2699     }
2700     else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV)
2701                     || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
2702     {
2703         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
2704     }
2705 
2706     else
2707     {
2708         //Invalid chroma format; Error code may be updated, verify in testing if needed
2709         ps_ctl_op->u4_error_code = ERROR_FEATURE_UNAVAIL;
2710         return IV_FAIL;
2711     }
2712 
2713     for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
2714     {
2715         ps_ctl_op->u4_min_in_buf_size[i] = MAX(256000, pic_wd * pic_ht * 3 / 2);
2716     }
2717 
2718     /*!*/
2719     if(ps_dec->u1_chroma_format == IV_YUV_420P)
2720     {
2721         ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
2722         ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht)
2723                         >> 2;
2724         ps_ctl_op->u4_min_out_buf_size[2] = (pic_wd * pic_ht)
2725                         >> 2;
2726     }
2727     else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
2728     {
2729         ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht)
2730                         * 2;
2731         ps_ctl_op->u4_min_out_buf_size[1] =
2732                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2733     }
2734     else if(ps_dec->u1_chroma_format == IV_RGB_565)
2735     {
2736         ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht)
2737                         * 2;
2738         ps_ctl_op->u4_min_out_buf_size[1] =
2739                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2740     }
2741     else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV)
2742                     || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
2743     {
2744         ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
2745         ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht)
2746                         >> 1;
2747         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2748     }
2749 
2750     ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs;
2751     return IV_SUCCESS;
2752 }
2753 
2754 /*****************************************************************************/
2755 /*                                                                           */
2756 /*  Function Name :    ih264d_get_buf_info                                   */
2757 /*                                                                           */
2758 /*  Description   :                                                          */
2759 /*                                                                           */
2760 /*  Inputs        :iv_obj_t decoder handle                                   */
2761 /*                :pv_api_ip pointer to input structure                      */
2762 /*                :pv_api_op pointer to output structure                     */
2763 /*  Globals       : <Does it use any global variables?>                      */
2764 /*  Outputs       :                                                          */
2765 /*  Returns       : void                                                     */
2766 /*                                                                           */
2767 /*  Issues        : none                                                     */
2768 /*                                                                           */
2769 /*  Revision History:                                                        */
2770 /*                                                                           */
2771 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
2772 /*         22 10 2008    100356         Draft                                */
2773 /*                                                                           */
2774 /*****************************************************************************/
ih264d_get_buf_info(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)2775 WORD32 ih264d_get_buf_info(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
2776 {
2777 
2778     dec_struct_t * ps_dec;
2779     UWORD8 i = 0; // Default for 420P format
2780     UWORD16 pic_wd, pic_ht;
2781     ivd_ctl_getbufinfo_op_t *ps_ctl_op =
2782                     (ivd_ctl_getbufinfo_op_t*)pv_api_op;
2783     UNUSED(pv_api_ip);
2784     ps_ctl_op->u4_error_code = 0;
2785 
2786     ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
2787 
2788     ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
2789     if(ps_dec->u1_chroma_format == IV_YUV_420P)
2790         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
2791     else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
2792         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
2793     else if(ps_dec->u1_chroma_format == IV_RGB_565)
2794         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
2795     else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV)
2796                     || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
2797         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
2798 
2799     else
2800     {
2801         //Invalid chroma format; Error code may be updated, verify in testing if needed
2802         return IV_FAIL;
2803     }
2804 
2805     ps_ctl_op->u4_num_disp_bufs = 1;
2806 
2807 
2808     pic_wd = 0;
2809     pic_ht = 0;
2810 
2811     if(ps_dec->i4_header_decoded == 3)
2812     {
2813 
2814         if(0 == ps_dec->u4_share_disp_buf)
2815         {
2816             pic_wd = ps_dec->u2_disp_width;
2817             pic_ht = ps_dec->u2_disp_height;
2818 
2819         }
2820         else
2821         {
2822             pic_wd = ps_dec->u2_frm_wd_y;
2823             pic_ht = ps_dec->u2_frm_ht_y;
2824         }
2825 
2826     }
2827 
2828     for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
2829     {
2830         ps_ctl_op->u4_min_in_buf_size[i] = MAX(256000, pic_wd * pic_ht * 3 / 2);
2831     }
2832     if((WORD32)ps_dec->u4_app_disp_width > pic_wd)
2833         pic_wd = ps_dec->u4_app_disp_width;
2834 
2835     if(0 == ps_dec->u4_share_disp_buf)
2836         ps_ctl_op->u4_num_disp_bufs = 1;
2837     else
2838     {
2839         if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
2840         {
2841             if((ps_dec->ps_cur_sps->u1_vui_parameters_present_flag == 1) &&
2842                (1 == ps_dec->ps_cur_sps->s_vui.u1_bitstream_restriction_flag))
2843             {
2844                 ps_ctl_op->u4_num_disp_bufs =
2845                                 ps_dec->ps_cur_sps->s_vui.u4_num_reorder_frames + 1;
2846             }
2847             else
2848             {
2849                 /*if VUI is not present assume maximum possible refrence frames for the level,
2850                  * as max reorder frames*/
2851                 ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size(ps_dec->ps_cur_sps);
2852             }
2853 
2854             ps_ctl_op->u4_num_disp_bufs +=
2855                             ps_dec->ps_cur_sps->u1_num_ref_frames + 1;
2856 
2857         }
2858         else
2859         {
2860             ps_ctl_op->u4_num_disp_bufs = 32;
2861 
2862         }
2863 
2864         ps_ctl_op->u4_num_disp_bufs = MAX(
2865                         ps_ctl_op->u4_num_disp_bufs, 6);
2866         ps_ctl_op->u4_num_disp_bufs = MIN(
2867                         ps_ctl_op->u4_num_disp_bufs, 32);
2868     }
2869 
2870     /*!*/
2871     if(ps_dec->u1_chroma_format == IV_YUV_420P)
2872     {
2873         ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
2874         ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht)
2875                         >> 2;
2876         ps_ctl_op->u4_min_out_buf_size[2] = (pic_wd * pic_ht)
2877                         >> 2;
2878     }
2879     else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
2880     {
2881         ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht)
2882                         * 2;
2883         ps_ctl_op->u4_min_out_buf_size[1] =
2884                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2885     }
2886     else if(ps_dec->u1_chroma_format == IV_RGB_565)
2887     {
2888         ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht)
2889                         * 2;
2890         ps_ctl_op->u4_min_out_buf_size[1] =
2891                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2892     }
2893     else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV)
2894                     || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
2895     {
2896         ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
2897         ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht)
2898                         >> 1;
2899         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2900     }
2901     ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs;
2902 
2903     return IV_SUCCESS;
2904 }
2905 
2906 /*****************************************************************************/
2907 /*                                                                           */
2908 /*  Function Name : ih264d_set_params                                        */
2909 /*                                                                           */
2910 /*  Description   :                                                          */
2911 /*                                                                           */
2912 /*  Inputs        :iv_obj_t decoder handle                                   */
2913 /*                :pv_api_ip pointer to input structure                      */
2914 /*                :pv_api_op pointer to output structure                     */
2915 /*  Outputs       :                                                          */
2916 /*  Returns       : void                                                     */
2917 /*                                                                           */
2918 /*  Issues        : none                                                     */
2919 /*                                                                           */
2920 /*  Revision History:                                                        */
2921 /*                                                                           */
2922 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
2923 /*         22 10 2008    100356         Draft                                */
2924 /*                                                                           */
2925 /*****************************************************************************/
ih264d_set_params(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)2926 WORD32 ih264d_set_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
2927 {
2928 
2929     dec_struct_t * ps_dec;
2930     WORD32 ret = IV_SUCCESS;
2931 
2932     ivd_ctl_set_config_ip_t *ps_ctl_ip =
2933                     (ivd_ctl_set_config_ip_t *)pv_api_ip;
2934     ivd_ctl_set_config_op_t *ps_ctl_op =
2935                     (ivd_ctl_set_config_op_t *)pv_api_op;
2936 
2937     ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
2938 
2939     ps_dec->u4_skip_frm_mask = 0;
2940 
2941     ps_ctl_op->u4_error_code = 0;
2942 
2943     ps_dec->i4_app_skip_mode = ps_ctl_ip->e_frm_skip_mode;
2944 
2945     /*Is it really supported test it when you so the corner testing using test app*/
2946 
2947     if(ps_ctl_ip->e_frm_skip_mode != IVD_SKIP_NONE)
2948     {
2949 
2950         if(ps_ctl_ip->e_frm_skip_mode == IVD_SKIP_P)
2951             ps_dec->u4_skip_frm_mask |= 1 << P_SLC_BIT;
2952         else if(ps_ctl_ip->e_frm_skip_mode == IVD_SKIP_B)
2953             ps_dec->u4_skip_frm_mask |= 1 << B_SLC_BIT;
2954         else if(ps_ctl_ip->e_frm_skip_mode == IVD_SKIP_PB)
2955         {
2956             ps_dec->u4_skip_frm_mask |= 1 << B_SLC_BIT;
2957             ps_dec->u4_skip_frm_mask |= 1 << P_SLC_BIT;
2958         }
2959         else if(ps_ctl_ip->e_frm_skip_mode == IVD_SKIP_I)
2960             ps_dec->u4_skip_frm_mask |= 1 << I_SLC_BIT;
2961         else
2962         {
2963             //dynamic parameter not supported
2964             //Put an appropriate error code to return the error..
2965             //when you do the error code tests and after that remove this comment
2966             ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
2967             ret = IV_FAIL;
2968         }
2969     }
2970 
2971     if((0 != ps_dec->u4_app_disp_width)
2972                     && (ps_ctl_ip->u4_disp_wd
2973                                     != ps_dec->u4_app_disp_width))
2974     {
2975         ps_ctl_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
2976         ps_ctl_op->u4_error_code |= ERROR_DISP_WIDTH_INVALID;
2977         ret = IV_FAIL;
2978     }
2979     else
2980     {
2981         if(ps_ctl_ip->u4_disp_wd >= ps_dec->u2_pic_wd)
2982         {
2983             ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd;
2984         }
2985         else if(0 == ps_dec->i4_header_decoded)
2986         {
2987             ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd;
2988         }
2989         else if(ps_ctl_ip->u4_disp_wd == 0)
2990         {
2991             ps_dec->u4_app_disp_width = 0;
2992         }
2993         else
2994         {
2995             /*
2996              * Set the display width to zero. This will ensure that the wrong value we had stored (0xFFFFFFFF)
2997              * does not propogate.
2998              */
2999             ps_dec->u4_app_disp_width = 0;
3000             ps_ctl_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
3001             ps_ctl_op->u4_error_code |= ERROR_DISP_WIDTH_INVALID;
3002             ret = IV_FAIL;
3003         }
3004     }
3005     if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_FRAME)
3006         ps_dec->i4_decode_header = 0;
3007     else if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_HEADER)
3008         ps_dec->i4_decode_header = 1;
3009     else
3010     {
3011         ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
3012         ps_dec->i4_decode_header = 1;
3013         ret = IV_FAIL;
3014     }
3015     ps_dec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
3016 
3017     if((ps_ctl_ip->e_frm_out_mode != IVD_DECODE_FRAME_OUT) &&
3018        (ps_ctl_ip->e_frm_out_mode != IVD_DISPLAY_FRAME_OUT))
3019     {
3020         ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
3021         ret = IV_FAIL;
3022     }
3023     ps_dec->e_frm_out_mode = ps_ctl_ip->e_frm_out_mode;
3024     return ret;
3025 
3026 }
3027 
3028 /*****************************************************************************/
3029 /*                                                                           */
3030 /*  Function Name : ih264d_set_default_params                                */
3031 /*                                                                           */
3032 /*  Description   :                                                          */
3033 /*                                                                           */
3034 /*  Inputs        :iv_obj_t decoder handle                                   */
3035 /*                :pv_api_ip pointer to input structure                      */
3036 /*                :pv_api_op pointer to output structure                     */
3037 /*  Outputs       :                                                          */
3038 /*  Returns       : void                                                     */
3039 /*                                                                           */
3040 /*  Issues        : none                                                     */
3041 /*                                                                           */
3042 /*  Revision History:                                                        */
3043 /*                                                                           */
3044 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
3045 /*         08 08 2011   100421          Copied from set_params               */
3046 /*                                                                           */
3047 /*****************************************************************************/
ih264d_set_default_params(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3048 WORD32 ih264d_set_default_params(iv_obj_t *dec_hdl,
3049                                  void *pv_api_ip,
3050                                  void *pv_api_op)
3051 {
3052 
3053     dec_struct_t * ps_dec;
3054     WORD32 ret = IV_SUCCESS;
3055 
3056     ivd_ctl_set_config_op_t *ps_ctl_op =
3057                     (ivd_ctl_set_config_op_t *)pv_api_op;
3058     ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
3059     UNUSED(pv_api_ip);
3060 
3061 
3062     {
3063         ps_dec->u4_app_disp_width = 0;
3064         ps_dec->u4_skip_frm_mask = 0;
3065         ps_dec->i4_decode_header = 1;
3066 
3067         ps_ctl_op->u4_error_code = 0;
3068     }
3069 
3070 
3071     return ret;
3072 }
3073 /*****************************************************************************/
3074 /*                                                                           */
3075 /*  Function Name :  ih264d_reset                                            */
3076 /*                                                                           */
3077 /*  Description   :                                                          */
3078 /*                                                                           */
3079 /*  Inputs        :iv_obj_t decoder handle                                   */
3080 /*                :pv_api_ip pointer to input structure                      */
3081 /*                :pv_api_op pointer to output structure                     */
3082 /*  Globals       : <Does it use any global variables?>                      */
3083 /*  Outputs       :                                                          */
3084 /*  Returns       : void                                                     */
3085 /*                                                                           */
3086 /*  Issues        : none                                                     */
3087 /*                                                                           */
3088 /*  Revision History:                                                        */
3089 /*                                                                           */
3090 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
3091 /*         22 10 2008    100356         Draft                                */
3092 /*                                                                           */
3093 /*****************************************************************************/
ih264d_delete(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3094 WORD32 ih264d_delete(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
3095 {
3096     dec_struct_t *ps_dec;
3097     ih264d_delete_ip_t *ps_ip = (ih264d_delete_ip_t *)pv_api_ip;
3098     ih264d_delete_op_t *ps_op = (ih264d_delete_op_t *)pv_api_op;
3099 
3100     ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
3101     UNUSED(ps_ip);
3102     ps_op->s_ivd_delete_op_t.u4_error_code = 0;
3103     ih264d_free_dynamic_bufs(ps_dec);
3104     ih264d_free_static_bufs(dec_hdl);
3105     return IV_SUCCESS;
3106 }
3107 /*****************************************************************************/
3108 /*                                                                           */
3109 /*  Function Name :  ih264d_reset                                            */
3110 /*                                                                           */
3111 /*  Description   :                                                          */
3112 /*                                                                           */
3113 /*  Inputs        :iv_obj_t decoder handle                                   */
3114 /*                :pv_api_ip pointer to input structure                      */
3115 /*                :pv_api_op pointer to output structure                     */
3116 /*  Globals       : <Does it use any global variables?>                      */
3117 /*  Outputs       :                                                          */
3118 /*  Returns       : void                                                     */
3119 /*                                                                           */
3120 /*  Issues        : none                                                     */
3121 /*                                                                           */
3122 /*  Revision History:                                                        */
3123 /*                                                                           */
3124 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
3125 /*         22 10 2008    100356         Draft                                */
3126 /*                                                                           */
3127 /*****************************************************************************/
ih264d_reset(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3128 WORD32 ih264d_reset(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
3129 {
3130     dec_struct_t * ps_dec;
3131     ivd_ctl_reset_op_t *ps_ctl_op = (ivd_ctl_reset_op_t *)pv_api_op;
3132     UNUSED(pv_api_ip);
3133     ps_ctl_op->u4_error_code = 0;
3134 
3135     ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
3136 
3137     if(ps_dec != NULL)
3138     {
3139         ih264d_init_decoder(ps_dec);
3140     }
3141     else
3142     {
3143         H264_DEC_DEBUG_PRINT(
3144                         "\nReset called without Initializing the decoder\n");
3145         ps_ctl_op->u4_error_code = ERROR_INIT_NOT_DONE;
3146     }
3147 
3148     return IV_SUCCESS;
3149 }
3150 
3151 /*****************************************************************************/
3152 /*                                                                           */
3153 /*  Function Name :  ih264d_ctl                                              */
3154 /*                                                                           */
3155 /*  Description   :                                                          */
3156 /*                                                                           */
3157 /*  Inputs        :iv_obj_t decoder handle                                   */
3158 /*                :pv_api_ip pointer to input structure                      */
3159 /*                :pv_api_op pointer to output structure                     */
3160 /*  Outputs       :                                                          */
3161 /*  Returns       : void                                                     */
3162 /*                                                                           */
3163 /*  Issues        : none                                                     */
3164 /*                                                                           */
3165 /*  Revision History:                                                        */
3166 /*                                                                           */
3167 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
3168 /*         22 10 2008    100356         Draft                                */
3169 /*                                                                           */
3170 /*****************************************************************************/
ih264d_ctl(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3171 WORD32 ih264d_ctl(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
3172 {
3173     ivd_ctl_set_config_ip_t *ps_ctl_ip;
3174     ivd_ctl_set_config_op_t *ps_ctl_op;
3175     WORD32 ret = IV_SUCCESS;
3176     UWORD32 subcommand;
3177     dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
3178 
3179     if(ps_dec->init_done != 1)
3180     {
3181         //Return proper Error Code
3182         return IV_FAIL;
3183     }
3184     ps_ctl_ip = (ivd_ctl_set_config_ip_t*)pv_api_ip;
3185     ps_ctl_op = (ivd_ctl_set_config_op_t*)pv_api_op;
3186     ps_ctl_op->u4_error_code = 0;
3187     subcommand = ps_ctl_ip->e_sub_cmd;
3188 
3189     switch(subcommand)
3190     {
3191         case IVD_CMD_CTL_GETPARAMS:
3192             ret = ih264d_get_status(dec_hdl, (void *)pv_api_ip,
3193                                     (void *)pv_api_op);
3194             break;
3195         case IVD_CMD_CTL_SETPARAMS:
3196             ret = ih264d_set_params(dec_hdl, (void *)pv_api_ip,
3197                                     (void *)pv_api_op);
3198             break;
3199         case IVD_CMD_CTL_RESET:
3200             ret = ih264d_reset(dec_hdl, (void *)pv_api_ip, (void *)pv_api_op);
3201             break;
3202         case IVD_CMD_CTL_SETDEFAULT:
3203             ret = ih264d_set_default_params(dec_hdl, (void *)pv_api_ip,
3204                                             (void *)pv_api_op);
3205             break;
3206         case IVD_CMD_CTL_FLUSH:
3207             ret = ih264d_set_flush_mode(dec_hdl, (void *)pv_api_ip,
3208                                         (void *)pv_api_op);
3209             break;
3210         case IVD_CMD_CTL_GETBUFINFO:
3211             ret = ih264d_get_buf_info(dec_hdl, (void *)pv_api_ip,
3212                                       (void *)pv_api_op);
3213             break;
3214         case IVD_CMD_CTL_GETVERSION:
3215             ret = ih264d_get_version(dec_hdl, (void *)pv_api_ip,
3216                                      (void *)pv_api_op);
3217             break;
3218         case IH264D_CMD_CTL_DEGRADE:
3219             ret = ih264d_set_degrade(dec_hdl, (void *)pv_api_ip,
3220                                      (void *)pv_api_op);
3221             break;
3222 
3223         case IH264D_CMD_CTL_SET_NUM_CORES:
3224             ret = ih264d_set_num_cores(dec_hdl, (void *)pv_api_ip,
3225                                        (void *)pv_api_op);
3226             break;
3227         case IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS:
3228             ret = ih264d_get_frame_dimensions(dec_hdl, (void *)pv_api_ip,
3229                                               (void *)pv_api_op);
3230             break;
3231         case IH264D_CMD_CTL_SET_PROCESSOR:
3232             ret = ih264d_set_processor(dec_hdl, (void *)pv_api_ip,
3233                                        (void *)pv_api_op);
3234             break;
3235         default:
3236             H264_DEC_DEBUG_PRINT("\ndo nothing\n")
3237             ;
3238             break;
3239     }
3240 
3241     return ret;
3242 }
3243 /*****************************************************************************/
3244 /*                                                                           */
3245 /*  Function Name :   ih264d_rel_display_frame                               */
3246 /*                                                                           */
3247 /*  Description   :                                                          */
3248 /*                                                                           */
3249 /*  Inputs        :iv_obj_t decoder handle                                   */
3250 /*                :pv_api_ip pointer to input structure                      */
3251 /*                :pv_api_op pointer to output structure                     */
3252 /*  Outputs       :                                                          */
3253 /*  Returns       : void                                                     */
3254 /*                                                                           */
3255 /*  Issues        : none                                                     */
3256 /*                                                                           */
3257 /*  Revision History:                                                        */
3258 /*                                                                           */
3259 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
3260 /*         22 10 2008    100356         Draft                                */
3261 /*                                                                           */
3262 /*****************************************************************************/
ih264d_rel_display_frame(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3263 WORD32 ih264d_rel_display_frame(iv_obj_t *dec_hdl,
3264                                 void *pv_api_ip,
3265                                 void *pv_api_op)
3266 {
3267 
3268     ivd_rel_display_frame_ip_t *ps_rel_ip;
3269     ivd_rel_display_frame_op_t *ps_rel_op;
3270     UWORD32 buf_released = 0;
3271 
3272     UWORD32 u4_ts = -1;
3273     dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
3274 
3275     ps_rel_ip = (ivd_rel_display_frame_ip_t *)pv_api_ip;
3276     ps_rel_op = (ivd_rel_display_frame_op_t *)pv_api_op;
3277     ps_rel_op->u4_error_code = 0;
3278     u4_ts = ps_rel_ip->u4_disp_buf_id;
3279 
3280     if(0 == ps_dec->u4_share_disp_buf)
3281     {
3282         ps_dec->u4_disp_buf_mapping[u4_ts] = 0;
3283         ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 0;
3284         return IV_SUCCESS;
3285     }
3286 
3287     if(ps_dec->pv_pic_buf_mgr != NULL)
3288     {
3289         if(1 == ps_dec->u4_disp_buf_mapping[u4_ts])
3290         {
3291             ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
3292                                   ps_rel_ip->u4_disp_buf_id,
3293                                   BUF_MGR_IO);
3294             ps_dec->u4_disp_buf_mapping[u4_ts] = 0;
3295             buf_released = 1;
3296         }
3297     }
3298 
3299     if((1 == ps_dec->u4_share_disp_buf) && (0 == buf_released))
3300         ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 1;
3301 
3302     return IV_SUCCESS;
3303 }
3304 
3305 /**
3306  *******************************************************************************
3307  *
3308  * @brief
3309  *  Sets degrade params
3310  *
3311  * @par Description:
3312  *  Sets degrade params.
3313  *  Refer to ih264d_ctl_degrade_ip_t definition for details
3314  *
3315  * @param[in] ps_codec_obj
3316  *  Pointer to codec object at API level
3317  *
3318  * @param[in] pv_api_ip
3319  *  Pointer to input argument structure
3320  *
3321  * @param[out] pv_api_op
3322  *  Pointer to output argument structure
3323  *
3324  * @returns  Status
3325  *
3326  * @remarks
3327  *
3328  *
3329  *******************************************************************************
3330  */
3331 
ih264d_set_degrade(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3332 WORD32 ih264d_set_degrade(iv_obj_t *ps_codec_obj,
3333                           void *pv_api_ip,
3334                           void *pv_api_op)
3335 {
3336     ih264d_ctl_degrade_ip_t *ps_ip;
3337     ih264d_ctl_degrade_op_t *ps_op;
3338     dec_struct_t *ps_codec = (dec_struct_t *)ps_codec_obj->pv_codec_handle;
3339 
3340     ps_ip = (ih264d_ctl_degrade_ip_t *)pv_api_ip;
3341     ps_op = (ih264d_ctl_degrade_op_t *)pv_api_op;
3342 
3343     ps_codec->i4_degrade_type = ps_ip->i4_degrade_type;
3344     ps_codec->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval;
3345     ps_codec->i4_degrade_pics = ps_ip->i4_degrade_pics;
3346 
3347     ps_op->u4_error_code = 0;
3348     ps_codec->i4_degrade_pic_cnt = 0;
3349 
3350     return IV_SUCCESS;
3351 }
3352 
ih264d_get_frame_dimensions(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3353 WORD32 ih264d_get_frame_dimensions(iv_obj_t *dec_hdl,
3354                                    void *pv_api_ip,
3355                                    void *pv_api_op)
3356 {
3357     ih264d_ctl_get_frame_dimensions_ip_t *ps_ip;
3358     ih264d_ctl_get_frame_dimensions_op_t *ps_op;
3359     dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
3360     UWORD32 disp_wd, disp_ht, buffer_wd, buffer_ht, x_offset, y_offset;
3361 
3362     ps_ip = (ih264d_ctl_get_frame_dimensions_ip_t *)pv_api_ip;
3363 
3364     ps_op = (ih264d_ctl_get_frame_dimensions_op_t *)pv_api_op;
3365     UNUSED(ps_ip);
3366     if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
3367     {
3368         disp_wd = ps_dec->u2_disp_width;
3369         disp_ht = ps_dec->u2_disp_height;
3370 
3371         if(0 == ps_dec->u4_share_disp_buf)
3372         {
3373             buffer_wd = disp_wd;
3374             buffer_ht = disp_ht;
3375         }
3376         else
3377         {
3378             buffer_wd = ps_dec->u2_frm_wd_y;
3379             buffer_ht = ps_dec->u2_frm_ht_y;
3380         }
3381     }
3382     else
3383     {
3384         disp_wd = 0;
3385         disp_ht = 0;
3386 
3387         if(0 == ps_dec->u4_share_disp_buf)
3388         {
3389             buffer_wd = disp_wd;
3390             buffer_ht = disp_ht;
3391         }
3392         else
3393         {
3394             buffer_wd = ALIGN16(disp_wd) + (PAD_LEN_Y_H << 1);
3395             buffer_ht = ALIGN16(disp_ht) + (PAD_LEN_Y_V << 2);
3396         }
3397     }
3398     if(ps_dec->u4_app_disp_width > buffer_wd)
3399         buffer_wd = ps_dec->u4_app_disp_width;
3400 
3401     if(0 == ps_dec->u4_share_disp_buf)
3402     {
3403         x_offset = 0;
3404         y_offset = 0;
3405     }
3406     else
3407     {
3408         y_offset = (PAD_LEN_Y_V << 1);
3409         x_offset = PAD_LEN_Y_H;
3410 
3411         if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid))
3412                         && (0 != ps_dec->u2_crop_offset_y))
3413         {
3414             y_offset += ps_dec->u2_crop_offset_y / ps_dec->u2_frm_wd_y;
3415             x_offset += ps_dec->u2_crop_offset_y % ps_dec->u2_frm_wd_y;
3416         }
3417     }
3418 
3419     ps_op->u4_disp_wd[0] = disp_wd;
3420     ps_op->u4_disp_ht[0] = disp_ht;
3421     ps_op->u4_buffer_wd[0] = buffer_wd;
3422     ps_op->u4_buffer_ht[0] = buffer_ht;
3423     ps_op->u4_x_offset[0] = x_offset;
3424     ps_op->u4_y_offset[0] = y_offset;
3425 
3426     ps_op->u4_disp_wd[1] = ps_op->u4_disp_wd[2] = ((ps_op->u4_disp_wd[0] + 1)
3427                     >> 1);
3428     ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1)
3429                     >> 1);
3430     ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0]
3431                     >> 1);
3432     ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0]
3433                     >> 1);
3434     ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] =
3435                     (ps_op->u4_x_offset[0] >> 1);
3436     ps_op->u4_y_offset[1] = ps_op->u4_y_offset[2] =
3437                     (ps_op->u4_y_offset[0] >> 1);
3438 
3439     if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV)
3440                     || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
3441     {
3442         ps_op->u4_disp_wd[2] = 0;
3443         ps_op->u4_disp_ht[2] = 0;
3444         ps_op->u4_buffer_wd[2] = 0;
3445         ps_op->u4_buffer_ht[2] = 0;
3446         ps_op->u4_x_offset[2] = 0;
3447         ps_op->u4_y_offset[2] = 0;
3448 
3449         ps_op->u4_disp_wd[1] <<= 1;
3450         ps_op->u4_buffer_wd[1] <<= 1;
3451         ps_op->u4_x_offset[1] <<= 1;
3452     }
3453 
3454     return IV_SUCCESS;
3455 
3456 }
3457 
ih264d_set_num_cores(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3458 WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
3459 {
3460     ih264d_ctl_set_num_cores_ip_t *ps_ip;
3461     ih264d_ctl_set_num_cores_op_t *ps_op;
3462     dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
3463 
3464     ps_ip = (ih264d_ctl_set_num_cores_ip_t *)pv_api_ip;
3465     ps_op = (ih264d_ctl_set_num_cores_op_t *)pv_api_op;
3466     ps_op->u4_error_code = 0;
3467     ps_dec->u4_num_cores = ps_ip->u4_num_cores;
3468     if(ps_dec->u4_num_cores == 1)
3469     {
3470         ps_dec->u1_separate_parse = 0;
3471     }
3472     else
3473     {
3474         ps_dec->u1_separate_parse = 1;
3475     }
3476 
3477     /*using only upto three threads currently*/
3478     if(ps_dec->u4_num_cores > 3)
3479         ps_dec->u4_num_cores = 3;
3480 
3481     return IV_SUCCESS;
3482 }
3483 
ih264d_fill_output_struct_from_context(dec_struct_t * ps_dec,ivd_video_decode_op_t * ps_dec_op)3484 void ih264d_fill_output_struct_from_context(dec_struct_t *ps_dec,
3485                                             ivd_video_decode_op_t *ps_dec_op)
3486 {
3487     if((ps_dec_op->u4_error_code & 0xff)
3488                     != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED)
3489     {
3490         ps_dec_op->u4_pic_wd = (UWORD32)ps_dec->u2_disp_width;
3491         ps_dec_op->u4_pic_ht = (UWORD32)ps_dec->u2_disp_height;
3492     }
3493     ps_dec_op->e_pic_type = ps_dec->i4_frametype;
3494 
3495     ps_dec_op->u4_new_seq = 0;
3496     ps_dec_op->u4_output_present = ps_dec->u4_output_present;
3497     ps_dec_op->u4_progressive_frame_flag =
3498                     ps_dec->s_disp_op.u4_progressive_frame_flag;
3499 
3500     ps_dec_op->u4_is_ref_flag = 1;
3501     if(ps_dec_op->u4_frame_decoded_flag)
3502     {
3503         if(ps_dec->ps_cur_slice->u1_nal_ref_idc == 0)
3504             ps_dec_op->u4_is_ref_flag = 0;
3505     }
3506 
3507     ps_dec_op->e_output_format = ps_dec->s_disp_op.e_output_format;
3508     ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf;
3509     ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type;
3510     ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts;
3511     ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
3512 }
3513 
3514 /*****************************************************************************/
3515 /*                                                                           */
3516 /*  Function Name : ih264d_api_function                                      */
3517 /*                                                                           */
3518 /*  Description   :                                                          */
3519 /*                                                                           */
3520 /*  Inputs        :iv_obj_t decoder handle                                   */
3521 /*                :pv_api_ip pointer to input structure                      */
3522 /*                :pv_api_op pointer to output structure                     */
3523 /*  Outputs       :                                                          */
3524 /*  Returns       : void                                                     */
3525 /*                                                                           */
3526 /*  Issues        : none                                                     */
3527 /*                                                                           */
3528 /*  Revision History:                                                        */
3529 /*                                                                           */
3530 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
3531 /*         22 10 2008    100356         Draft                                */
3532 /*                                                                           */
3533 /*****************************************************************************/
ih264d_api_function(iv_obj_t * dec_hdl,void * pv_api_ip,void * pv_api_op)3534 IV_API_CALL_STATUS_T ih264d_api_function(iv_obj_t *dec_hdl,
3535                                               void *pv_api_ip,
3536                                               void *pv_api_op)
3537 {
3538     UWORD32 command;
3539     UWORD32 *pu2_ptr_cmd;
3540     UWORD32 u4_api_ret;
3541     IV_API_CALL_STATUS_T e_status;
3542     e_status = api_check_struct_sanity(dec_hdl, pv_api_ip, pv_api_op);
3543 
3544     if(e_status != IV_SUCCESS)
3545     {
3546         UWORD32 *ptr_err;
3547 
3548         ptr_err = (UWORD32 *)pv_api_op;
3549         UNUSED(ptr_err);
3550         H264_DEC_DEBUG_PRINT("error code = %d\n", *(ptr_err + 1));
3551         return IV_FAIL;
3552     }
3553 
3554     pu2_ptr_cmd = (UWORD32 *)pv_api_ip;
3555     pu2_ptr_cmd++;
3556 
3557     command = *pu2_ptr_cmd;
3558 //    H264_DEC_DEBUG_PRINT("inside lib = %d\n",command);
3559     switch(command)
3560     {
3561 
3562         case IVD_CMD_CREATE:
3563             u4_api_ret = ih264d_create(dec_hdl, (void *)pv_api_ip,
3564                                      (void *)pv_api_op);
3565             break;
3566         case IVD_CMD_DELETE:
3567             u4_api_ret = ih264d_delete(dec_hdl, (void *)pv_api_ip,
3568                                      (void *)pv_api_op);
3569             break;
3570 
3571         case IVD_CMD_VIDEO_DECODE:
3572             u4_api_ret = ih264d_video_decode(dec_hdl, (void *)pv_api_ip,
3573                                              (void *)pv_api_op);
3574             break;
3575 
3576         case IVD_CMD_GET_DISPLAY_FRAME:
3577             u4_api_ret = ih264d_get_display_frame(dec_hdl, (void *)pv_api_ip,
3578                                                   (void *)pv_api_op);
3579 
3580             break;
3581 
3582         case IVD_CMD_SET_DISPLAY_FRAME:
3583             u4_api_ret = ih264d_set_display_frame(dec_hdl, (void *)pv_api_ip,
3584                                                   (void *)pv_api_op);
3585 
3586             break;
3587 
3588         case IVD_CMD_REL_DISPLAY_FRAME:
3589             u4_api_ret = ih264d_rel_display_frame(dec_hdl, (void *)pv_api_ip,
3590                                                   (void *)pv_api_op);
3591             break;
3592 
3593         case IVD_CMD_VIDEO_CTL:
3594             u4_api_ret = ih264d_ctl(dec_hdl, (void *)pv_api_ip,
3595                                     (void *)pv_api_op);
3596             break;
3597         default:
3598             u4_api_ret = IV_FAIL;
3599             break;
3600     }
3601 
3602     return u4_api_ret;
3603 }
3604