• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2 *
3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
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 /**
19  *******************************************************************************
20  * @file
21  *  ihevcd_decode.c
22  *
23  * @brief
24  *  Contains codecs main decode function
25  *
26  * @author
27  *  Harish
28  *
29  * @par List of Functions:
30  * - fill_outargs()
31  * - ihevcd_decode
32  * @remarks
33  *  None
34  *
35  *******************************************************************************
36  */
37 /*****************************************************************************/
38 /* File Includes                                                             */
39 /*****************************************************************************/
40 #include <stdio.h>
41 #include <stddef.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <assert.h>
45 
46 #include "ihevc_typedefs.h"
47 #include "iv.h"
48 #include "ivd.h"
49 #include "ihevcd_cxa.h"
50 #include "ithread.h"
51 
52 #include "ihevc_defs.h"
53 #include "ihevc_debug.h"
54 #include "ihevc_structs.h"
55 #include "ihevc_macros.h"
56 #include "ihevc_platform_macros.h"
57 #include "ihevc_cabac_tables.h"
58 #include "ihevc_disp_mgr.h"
59 #include "ihevc_buf_mgr.h"
60 #include "ihevc_dpb_mgr.h"
61 #include "ihevc_error.h"
62 
63 #include "ihevcd_defs.h"
64 #include "ihevcd_function_selector.h"
65 #include "ihevcd_structs.h"
66 #include "ihevcd_error.h"
67 #include "ihevcd_nal.h"
68 #include "ihevcd_bitstream.h"
69 #include "ihevcd_fmt_conv.h"
70 #include "ihevcd_job_queue.h"
71 #include "ihevcd_debug.h"
72 #include "ihevcd_parse_slice.h"
73 #include "ihevcd_process_slice.h"
74 #include "ihevcd_ittiam_logo.h"
75 #include "ihevcd_profile.h"
76 
77 #define NUM_FRAMES_LIMIT_ENABLED 0
78 
79 #if NUM_FRAMES_LIMIT_ENABLED
80 #define NUM_FRAMES_LIMIT 10000
81 #else
82 #define NUM_FRAMES_LIMIT 0x7FFFFFFF
83 #endif
84 
85 IHEVCD_ERROR_T ihevcd_check_out_buf_size(codec_t *ps_codec);
86 IHEVCD_ERROR_T ihevcd_fmt_conv(codec_t *ps_codec,
87                                process_ctxt_t *ps_proc,
88                                UWORD8 *pu1_y_dst,
89                                UWORD8 *pu1_u_dst,
90                                UWORD8 *pu1_v_dst,
91                                WORD32 cur_row,
92                                WORD32 num_rows);
93 WORD32 ihevcd_init(codec_t *ps_codec);
94 
95 WORD32 ihevcd_allocate_dynamic_bufs(codec_t *ps_codec);
96 WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec);
97 /*****************************************************************************/
98 /* Function Prototypes                                                       */
99 /*****************************************************************************/
100 
101 
102 /**
103  *******************************************************************************
104  *
105  * @brief Fills output arguments for decode process
106  *
107  * @par   Description
108  * Fills elements in the output structure based on the current state
109  *
110  * @param[in] ps_codec
111  * Codec context
112  *
113  * @param[in] ps_dec_ip
114  * Pointer to input structure
115  *
116  * @param[in] ps_dec_op
117  * Pointer to output structure
118  *
119  * @returns none
120  *
121  * @remarks
122  *
123  *******************************************************************************
124  */
ihevcd_map_error(IHEVCD_ERROR_T e_error)125 static UWORD32 ihevcd_map_error(IHEVCD_ERROR_T e_error)
126 {
127     UWORD32 error_code = 0;
128     error_code = e_error;
129     switch(error_code)
130     {
131         case IHEVCD_SUCCESS :
132             break;
133         case IHEVCD_INIT_NOT_DONE:
134         case IHEVCD_LEVEL_UNSUPPORTED:
135         case IHEVCD_NUM_REF_UNSUPPORTED:
136         case IHEVCD_NUM_REORDER_UNSUPPORTED:
137         case IHEVCD_NUM_EXTRA_DISP_UNSUPPORTED:
138         case IHEVCD_INSUFFICIENT_MEM_MVBANK:
139         case IHEVCD_INSUFFICIENT_MEM_PICBUF:
140         case IHEVCD_UNSUPPORTED_CHROMA_FMT_IDC:
141         case IHEVCD_UNSUPPORTED_BIT_DEPTH:
142         case IVD_MEM_ALLOC_FAILED:
143         case IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED:
144             error_code |= 1 << IVD_FATALERROR;
145             break;
146         case IHEVCD_INVALID_DISP_STRD:
147         case IHEVCD_CXA_VERS_BUF_INSUFFICIENT:
148         case IHEVCD_UNSUPPORTED_VPS_ID:
149         case IHEVCD_UNSUPPORTED_SPS_ID:
150         case IHEVCD_UNSUPPORTED_PPS_ID:
151         case IHEVCD_BUF_MGR_ERROR:
152         case IHEVCD_NO_FREE_MVBANK:
153         case IHEVCD_NO_FREE_PICBUF:
154         case IHEVCD_SLICE_IN_HEADER_MODE:
155         case IHEVCD_END_OF_SEQUENCE:
156             break;
157         default:
158             break;
159     }
160     return error_code;
161 }
162 /**
163  *******************************************************************************
164  *
165  * @brief Fills output arguments for decode process
166  *
167  * @par   Description
168  * Fills elements in the output structure based on the current state
169  *
170  * @param[in] ps_codec
171  * Codec context
172  *
173  * @param[in] ps_dec_ip
174  * Pointer to input structure
175  *
176  * @param[in] ps_dec_op
177  * Pointer to output structure
178  *
179  * @returns none
180  *
181  * @remarks
182  *
183  *******************************************************************************
184  */
ihevcd_fill_outargs(codec_t * ps_codec,void * pv_api_ip,void * pv_api_op)185 static void ihevcd_fill_outargs(codec_t *ps_codec,
186                                 void *pv_api_ip,
187                                 void *pv_api_op)
188 {
189 
190     ihevcd_cxa_video_decode_ip_t *ps_hevcd_dec_ip;
191     ihevcd_cxa_video_decode_op_t *ps_hevcd_dec_op;
192     ivd_video_decode_ip_t *ps_dec_ip;
193     ivd_video_decode_op_t *ps_dec_op;
194 
195     ps_hevcd_dec_ip = (ihevcd_cxa_video_decode_ip_t *)pv_api_ip;
196     ps_hevcd_dec_op = (ihevcd_cxa_video_decode_op_t *)pv_api_op;
197     ps_dec_ip = &ps_hevcd_dec_ip->s_ivd_video_decode_ip_t;
198     ps_dec_op = &ps_hevcd_dec_op->s_ivd_video_decode_op_t;
199 
200     ps_dec_op->u4_error_code = ihevcd_map_error((IHEVCD_ERROR_T)ps_codec->i4_error_code);
201     ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes
202                     - ps_codec->i4_bytes_remaining;
203     if(ps_codec->i4_sps_done)
204     {
205         ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
206         ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
207     }
208     else
209     {
210         ps_dec_op->u4_pic_wd = 0;
211         ps_dec_op->u4_pic_ht = 0;
212     }
213 
214     ps_dec_op->e_pic_type = ps_codec->e_dec_pic_type;
215     ps_dec_op->u4_frame_decoded_flag = ps_codec->i4_pic_present;
216     ps_dec_op->u4_new_seq = 0;
217 
218     ps_dec_op->u4_output_present = 0;
219     ps_dec_op->u4_progressive_frame_flag = 1;
220     ps_dec_op->i4_display_index = -1;
221     ps_dec_op->i4_reorder_depth = -1;
222     if(ps_codec->i4_sps_done)
223     {
224         sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
225         profile_tier_lvl_info_t *ps_ptl;
226         ps_ptl = &ps_sps->s_ptl;
227         if((0 == ps_ptl->s_ptl_gen.i1_general_progressive_source_flag) &&
228            (1 == ps_ptl->s_ptl_gen.i1_general_interlaced_source_flag))
229         {
230             ps_dec_op->u4_progressive_frame_flag = 0;
231         }
232         ps_dec_op->i4_reorder_depth =
233                         ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
234     }
235 
236     ps_dec_op->u4_is_ref_flag = 1;
237     ps_dec_op->e_output_format = ps_codec->e_chroma_fmt;
238     ps_dec_op->u4_is_ref_flag = 1;
239 
240     ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
241     ps_dec_op->u4_ts = (UWORD32)(-1);
242     ps_dec_op->u4_disp_buf_id = ps_codec->i4_disp_buf_id;
243     if(ps_codec->i4_flush_mode)
244     {
245         ps_dec_op->u4_num_bytes_consumed = 0;
246         /*In the case of flush ,since no frame is decoded set pic type as invalid*/
247         ps_dec_op->u4_is_ref_flag = 0;
248         ps_dec_op->e_pic_type = IV_NA_FRAME;
249         ps_dec_op->u4_frame_decoded_flag = 0;
250 
251     }
252     /* If there is a display buffer */
253     if(ps_codec->ps_disp_buf)
254     {
255         pic_buf_t *ps_disp_buf = ps_codec->ps_disp_buf;
256         sei_params_t *ps_sei = &ps_disp_buf->s_sei_params;
257 
258         if(ps_sei->i1_sei_parameters_present_flag &&
259            ps_sei->i1_pic_timing_params_present_flag)
260         {
261             UWORD32 u4_pic_struct;
262             u4_pic_struct = ps_sei->s_pic_timing_sei_params.u4_pic_struct;
263             switch(u4_pic_struct)
264             {
265                 case 1:
266                     ps_dec_op->e4_fld_type = IV_TOP_FLD;
267                     ps_dec_op->u4_progressive_frame_flag = 0;
268                     break;
269                 case 2:
270                     ps_dec_op->e4_fld_type = IV_BOT_FLD;
271                     ps_dec_op->u4_progressive_frame_flag = 0;
272                     break;
273                 case 0:
274                 default:
275                     ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
276                     ps_dec_op->u4_progressive_frame_flag = 1;
277                     break;
278             }
279         }
280         ps_dec_op->i4_display_index = ps_disp_buf->i4_abs_poc;
281         ps_dec_op->u4_output_present = 1;
282         ps_dec_op->u4_ts = ps_disp_buf->u4_ts;
283         if((ps_codec->i4_flush_mode == 0) && (ps_codec->s_parse.i4_end_of_frame == 0))
284             ps_dec_op->u4_output_present = 0;
285         ps_dec_op->s_disp_frm_buf.u4_y_wd = ps_codec->i4_disp_wd;
286         ps_dec_op->s_disp_frm_buf.u4_y_ht = ps_codec->i4_disp_ht;
287 
288         if(ps_codec->i4_share_disp_buf)
289         {
290             ps_dec_op->s_disp_frm_buf.pv_y_buf = ps_disp_buf->pu1_luma;
291             if(ps_codec->e_chroma_fmt != IV_YUV_420P)
292             {
293                 ps_dec_op->s_disp_frm_buf.pv_u_buf = ps_disp_buf->pu1_chroma;
294                 ps_dec_op->s_disp_frm_buf.pv_v_buf = NULL;
295             }
296             else
297             {
298                 WORD32 i;
299                 UWORD8 *pu1_u_dst = NULL, *pu1_v_dst = NULL;
300                 for(i = 0; i < ps_codec->i4_share_disp_buf_cnt; i++)
301                 {
302                     WORD32 diff = ps_disp_buf->pu1_luma - ps_codec->s_disp_buffer[i].pu1_bufs[0];
303                     if(diff == (ps_codec->i4_strd * PAD_TOP + PAD_LEFT))
304                     {
305                         pu1_u_dst = ps_codec->s_disp_buffer[i].pu1_bufs[1];
306                         pu1_u_dst += (ps_codec->i4_strd * PAD_TOP) / 4 + (PAD_LEFT / 2);
307 
308                         pu1_v_dst = ps_codec->s_disp_buffer[i].pu1_bufs[2];
309                         pu1_v_dst += (ps_codec->i4_strd * PAD_TOP) / 4 + (PAD_LEFT / 2);
310                         break;
311                     }
312                 }
313                 ps_dec_op->s_disp_frm_buf.pv_u_buf = pu1_u_dst;
314                 ps_dec_op->s_disp_frm_buf.pv_v_buf = pu1_v_dst;
315             }
316             ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_strd;
317         }
318         else
319         {
320             ps_dec_op->s_disp_frm_buf.pv_y_buf =
321                             ps_dec_ip->s_out_buffer.pu1_bufs[0];
322             ps_dec_op->s_disp_frm_buf.pv_u_buf =
323                             ps_dec_ip->s_out_buffer.pu1_bufs[1];
324             ps_dec_op->s_disp_frm_buf.pv_v_buf =
325                             ps_dec_ip->s_out_buffer.pu1_bufs[2];
326             ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_disp_strd;
327         }
328 
329         if((IV_YUV_420SP_VU == ps_codec->e_chroma_fmt)
330                         || (IV_YUV_420SP_UV == ps_codec->e_chroma_fmt))
331         {
332             ps_dec_op->s_disp_frm_buf.u4_u_strd =
333                             ps_dec_op->s_disp_frm_buf.u4_y_strd;
334             ps_dec_op->s_disp_frm_buf.u4_v_strd = 0;
335             ps_dec_op->s_disp_frm_buf.u4_u_wd =
336                             ps_dec_op->s_disp_frm_buf.u4_y_wd;
337             ps_dec_op->s_disp_frm_buf.u4_v_wd = 0;
338             ps_dec_op->s_disp_frm_buf.u4_u_ht =
339                             ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
340             ps_dec_op->s_disp_frm_buf.u4_v_ht = 0;
341         }
342         else if(IV_YUV_420P == ps_codec->e_chroma_fmt)
343         {
344             ps_dec_op->s_disp_frm_buf.u4_u_strd =
345                             ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
346             ps_dec_op->s_disp_frm_buf.u4_v_strd =
347                             ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
348             ps_dec_op->s_disp_frm_buf.u4_u_wd =
349                             ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
350             ps_dec_op->s_disp_frm_buf.u4_v_wd =
351                             ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
352             ps_dec_op->s_disp_frm_buf.u4_u_ht =
353                             ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
354             ps_dec_op->s_disp_frm_buf.u4_v_ht =
355                             ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
356         }
357 
358     }
359     else if(ps_codec->i4_flush_mode)
360     {
361         ps_dec_op->u4_error_code = IHEVCD_END_OF_SEQUENCE;
362         /* Come out of flush mode */
363         ps_codec->i4_flush_mode = 0;
364     }
365 
366     if(ps_codec->u1_enable_cu_info && ps_dec_op->u4_output_present)
367     {
368         WORD32 info_map_dst_strd = ALIGN8(ps_codec->i4_wd) >> 3;
369         WORD32 info_map_src_strd = ALIGN64(ps_codec->i4_wd) >> 3;
370         WORD32 info_map_ht = ALIGN8(ps_codec->i4_ht);
371         UWORD32 info_map_size = (ALIGN8(ps_codec->i4_wd) * info_map_ht) >> 6;
372         WORD32 vert_8x8;
373         UWORD8 *pu1_out_qp_map, *pu1_qp_map;
374         UWORD8 *pu1_out_blk_type_map, *pu1_type_map;
375 
376         if(ps_hevcd_dec_ip->pu1_8x8_blk_qp_map)
377         {
378             ps_hevcd_dec_op->pu1_8x8_blk_qp_map = ps_hevcd_dec_ip->pu1_8x8_blk_qp_map;
379             ps_hevcd_dec_op->u4_8x8_blk_qp_map_size = info_map_size;
380 
381             pu1_out_qp_map = ps_hevcd_dec_op->pu1_8x8_blk_qp_map;
382             pu1_qp_map = ps_codec->as_buf_id_info_map[ps_codec->i4_disp_buf_id].pu1_qp_map;
383             for(vert_8x8 = 0; vert_8x8 < info_map_ht; vert_8x8++)
384             {
385                 memcpy(pu1_out_qp_map, pu1_qp_map, info_map_dst_strd);
386                 pu1_out_qp_map += info_map_dst_strd;
387                 pu1_qp_map += info_map_src_strd;
388             }
389         }
390 
391         if(ps_hevcd_dec_ip->pu1_8x8_blk_type_map)
392         {
393             ps_hevcd_dec_op->pu1_8x8_blk_type_map = ps_hevcd_dec_ip->pu1_8x8_blk_type_map;
394             ps_hevcd_dec_op->u4_8x8_blk_type_map_size = info_map_size;
395 
396             pu1_out_blk_type_map = ps_hevcd_dec_op->pu1_8x8_blk_type_map;
397             pu1_type_map =
398                 ps_codec->as_buf_id_info_map[ps_codec->i4_disp_buf_id].pu1_cu_type_map;
399             for(vert_8x8 = 0; vert_8x8 < info_map_ht; vert_8x8++)
400             {
401                 memcpy(pu1_out_blk_type_map, pu1_type_map, info_map_dst_strd);
402                 pu1_out_blk_type_map += info_map_dst_strd;
403                 pu1_type_map += info_map_src_strd;
404             }
405         }
406     }
407 }
408 
409 /**
410  *******************************************************************************
411  *
412  * @brief
413  *  Codec process call
414  *
415  * @par Description:
416  *  Codec process call  Tests for few error checks  Handle flush and decode
417  * header related code  Parse bitstream for start codes  For each NAL unit
418  * call decode NAL function  Once a complete frame is decoded (in frame
419  * decode mode)  Fill output arguments and return
420  *
421  * @param[in] ps_codec_obj
422  *  Pointer to codec object at API level
423  *
424  * @param[in] pv_api_ip
425  *  Pointer to input argument structure
426  *
427  * @param[in] pv_api_op
428  *  Pointer to output argument structure
429  *
430  * @returns  Status
431  *
432  * @remarks
433  *
434  *
435  *******************************************************************************
436  */
ihevcd_decode(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)437 WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
438 {
439     WORD32 ret = IV_SUCCESS;
440     codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
441     ihevcd_cxa_video_decode_ip_t s_hevcd_dec_ip = {};
442     ihevcd_cxa_video_decode_ip_t *ps_hevcd_dec_ip;
443     ihevcd_cxa_video_decode_op_t *ps_hevcd_dec_op;
444     ivd_video_decode_ip_t *ps_dec_ip;
445     ivd_video_decode_op_t *ps_dec_op;
446 
447     WORD32 proc_idx = 0;
448     WORD32 prev_proc_idx = 0;
449 
450     /* Initialize error code */
451     ps_codec->i4_error_code = 0;
452     /* Initialize bytes remaining */
453     ps_codec->i4_bytes_remaining = 0;
454 
455     ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip;
456     memcpy(&s_hevcd_dec_ip, ps_dec_ip, ps_dec_ip->u4_size);
457     s_hevcd_dec_ip.s_ivd_video_decode_ip_t.u4_size = sizeof(ihevcd_cxa_video_decode_ip_t);
458 
459     ps_hevcd_dec_ip = &s_hevcd_dec_ip;
460     ps_dec_ip = &ps_hevcd_dec_ip->s_ivd_video_decode_ip_t;
461 
462     ps_hevcd_dec_op = (ihevcd_cxa_video_decode_op_t *)pv_api_op;
463     ps_dec_op = &ps_hevcd_dec_op->s_ivd_video_decode_op_t;
464 
465     {
466         UWORD32 u4_size = ps_dec_op->u4_size;
467         memset(ps_hevcd_dec_op, 0, u4_size);
468         ps_dec_op->u4_size = u4_size; //Restore size field
469     }
470     if(ps_codec->i4_init_done != 1)
471     {
472         ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
473         ps_dec_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
474         return IV_FAIL;
475     }
476 
477     if(ps_codec->u4_pic_cnt >= NUM_FRAMES_LIMIT)
478     {
479         ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
480         ps_dec_op->u4_error_code |= IHEVCD_NUM_FRAMES_LIMIT_REACHED;
481         return IV_FAIL;
482     }
483 
484     if(ps_codec->u1_enable_cu_info && ps_codec->i4_sps_done)
485     {
486         UWORD32 blk_qp_map_size = ps_hevcd_dec_ip->u4_8x8_blk_qp_map_size;
487         UWORD32 blk_type_map_size = ps_hevcd_dec_ip->u4_8x8_blk_type_map_size;
488         UWORD32 blk_8x8_map_size = (ALIGN8(ps_codec->i4_wd) * ALIGN8(ps_codec->i4_ht)) >> 6;
489 
490         if ((ps_hevcd_dec_ip->pu1_8x8_blk_qp_map && blk_qp_map_size < blk_8x8_map_size) ||
491             (ps_hevcd_dec_ip->pu1_8x8_blk_type_map && blk_type_map_size < blk_8x8_map_size))
492         {
493             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
494             ps_dec_op->u4_error_code |= IHEVCD_INSUFFICIENT_METADATA_BUFFER;
495             return IV_FAIL;
496         }
497      }
498 
499     /* If reset flag is set, flush the existing buffers */
500     if(ps_codec->i4_reset_flag)
501     {
502         ps_codec->i4_flush_mode = 1;
503     }
504 
505     /*Data memory barries instruction,so that bitstream write by the application is complete*/
506     //arm_dsb();
507     /* In case the decoder is not in flush mode check for input buffer validity */
508     if(0 == ps_codec->i4_flush_mode)
509     {
510         if(ps_dec_ip->pv_stream_buffer == NULL)
511         {
512             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
513             ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL;
514             return IV_FAIL;
515         }
516         if(ps_dec_ip->u4_num_Bytes <= MIN_START_CODE_LEN)
517         {
518             if((WORD32)ps_dec_ip->u4_num_Bytes > 0)
519                 ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes;
520             else
521                 ps_dec_op->u4_num_bytes_consumed = 0;
522 
523             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
524             ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV;
525             return IV_FAIL;
526 
527         }
528     }
529 
530 #ifdef APPLY_CONCEALMENT
531     {
532         WORD32 num_mbs;
533 
534         num_mbs = (ps_codec->i4_wd * ps_codec->i4_ht + 255) >> 8;
535         /* Reset MB Count at the beginning of every process call */
536         ps_codec->mb_count = 0;
537         memset(ps_codec->mb_map, 0, ((num_mbs + 7) >> 3));
538     }
539 #endif
540 
541     if(0 == ps_codec->i4_share_disp_buf && ps_codec->i4_header_mode == 0)
542     {
543         UWORD32 i;
544         if((ps_dec_ip->s_out_buffer.u4_num_bufs <= 0) ||
545            (ps_dec_ip->s_out_buffer.u4_num_bufs > IVD_VIDDEC_MAX_IO_BUFFERS))
546         {
547             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
548             ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
549             return IV_FAIL;
550         }
551 
552         for(i = 0; i < ps_dec_ip->s_out_buffer.u4_num_bufs; i++)
553         {
554             if(ps_dec_ip->s_out_buffer.pu1_bufs[i] == NULL)
555             {
556                 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
557                 ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL;
558                 return IV_FAIL;
559             }
560 
561             if(ps_dec_ip->s_out_buffer.u4_min_out_buf_size[i] == 0)
562             {
563                 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
564                 ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
565                 return IV_FAIL;
566             }
567         }
568     }
569 
570     ps_codec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
571     ps_codec->u4_ts = ps_dec_ip->u4_ts;
572     if(ps_codec->i4_flush_mode)
573     {
574 
575         ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
576         ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
577 
578         ps_dec_op->u4_new_seq = 0;
579 
580         ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get(
581                         (disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id);
582         /* In case of non-shared mode, then convert/copy the frame to output buffer */
583         /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
584         if((ps_codec->ps_disp_buf)
585                         && ((0 == ps_codec->i4_share_disp_buf)
586                                         || (IV_YUV_420P
587                                                         == ps_codec->e_chroma_fmt)))
588         {
589 
590             process_ctxt_t *ps_proc = &ps_codec->as_process[prev_proc_idx];
591             if(0 == ps_proc->i4_init_done)
592             {
593                 ihevcd_init_proc_ctxt(ps_proc, 0);
594             }
595 
596             /* Output buffer check */
597             ret = ihevcd_check_out_buf_size(ps_codec);
598             RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
599 
600             /* Set remaining number of rows to be processed */
601             ret = ihevcd_fmt_conv(ps_codec, &ps_codec->as_process[prev_proc_idx],
602                                   ps_dec_ip->s_out_buffer.pu1_bufs[0],
603                                   ps_dec_ip->s_out_buffer.pu1_bufs[1],
604                                   ps_dec_ip->s_out_buffer.pu1_bufs[2], 0,
605                                   ps_codec->i4_disp_ht);
606 
607             ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
608                                   ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
609         }
610 
611         ihevcd_fill_outargs(ps_codec, ps_hevcd_dec_ip, ps_hevcd_dec_op);
612 
613         if(1 == ps_dec_op->u4_output_present)
614         {
615             WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
616             WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
617 
618             if(ypos < 0)
619                 ypos = 0;
620 
621             if(xpos < 0)
622                 xpos = 0;
623 
624             INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
625                         ps_dec_ip->s_out_buffer.pu1_bufs[1],
626                         ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
627                         xpos,
628                         ypos,
629                         ps_codec->e_chroma_fmt,
630                         ps_codec->i4_disp_wd,
631                         ps_codec->i4_disp_ht);
632         }
633 
634 
635         if(NULL == ps_codec->ps_disp_buf)
636         {
637             /* If in flush mode and there are no more buffers to flush,
638              * check for the reset flag and reset the decoder */
639             if(ps_codec->i4_reset_flag)
640             {
641                 ihevcd_init(ps_codec);
642             }
643             return (IV_FAIL);
644         }
645 
646         return (IV_SUCCESS);
647 
648     }
649     /* In case of shared mode, check if there is a free buffer for reconstruction */
650     if((0 == ps_codec->i4_header_mode) && (1 == ps_codec->i4_share_disp_buf))
651     {
652         WORD32 buf_status;
653         buf_status = 1;
654         if(ps_codec->pv_pic_buf_mgr)
655             buf_status = ihevc_buf_mgr_check_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr);
656 
657         /* If there is no free buffer, then return with an error code */
658         if(0 == buf_status)
659         {
660             ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
661             ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
662             return IV_FAIL;
663         }
664     }
665     ps_codec->i4_bytes_remaining = ps_dec_ip->u4_num_Bytes;
666     ps_codec->pu1_inp_bitsbuf = (UWORD8 *)ps_dec_ip->pv_stream_buffer;
667     ps_codec->s_parse.i4_end_of_frame = 0;
668 
669     ps_codec->i4_pic_present = 0;
670     ps_codec->i4_slice_error = 0;
671     ps_codec->ps_disp_buf = NULL;
672 
673     if(ps_codec->i4_num_cores > 1)
674     {
675         ithread_set_affinity(0);
676     }
677     while(MIN_START_CODE_LEN < ps_codec->i4_bytes_remaining)
678     {
679         WORD32 nal_len;
680         WORD32 nal_ofst;
681         WORD32 bits_len;
682 
683         if(ps_codec->i4_slice_error)
684         {
685             slice_header_t *ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + (ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1));
686             WORD32 next_slice_addr = ps_slice_hdr_next->i2_ctb_x +
687                             ps_slice_hdr_next->i2_ctb_y * ps_codec->s_parse.ps_sps->i2_pic_wd_in_ctb;
688             if(ps_codec->s_parse.i4_next_ctb_indx == next_slice_addr)
689                 ps_codec->i4_slice_error = 0;
690         }
691 
692         if(ps_codec->pu1_bitsbuf_dynamic)
693         {
694             ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_dynamic;
695             ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_dynamic;
696         }
697         else
698         {
699             ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_static;
700             ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_static;
701         }
702 
703         nal_ofst = ihevcd_nal_search_start_code(ps_codec->pu1_inp_bitsbuf,
704                                                 ps_codec->i4_bytes_remaining);
705         /* If there is no start code found, consume the data and break */
706         if(nal_ofst == ps_codec->i4_bytes_remaining)
707         {
708             ps_codec->pu1_inp_bitsbuf += nal_ofst;
709             ps_codec->i4_bytes_remaining -= nal_ofst;
710             break;
711         }
712 
713         ps_codec->i4_nal_ofst = nal_ofst;
714         {
715             WORD32 bytes_remaining = ps_codec->i4_bytes_remaining - nal_ofst;
716 
717             bytes_remaining = MIN((UWORD32)bytes_remaining, ps_codec->u4_bitsbuf_size);
718             ihevcd_nal_remv_emuln_bytes(ps_codec->pu1_inp_bitsbuf + nal_ofst,
719                                         ps_codec->pu1_bitsbuf,
720                                         bytes_remaining,
721                                         &nal_len, &bits_len);
722 
723             /* Decoder may read upto 8 extra bytes at the end of frame */
724             /* These are not used, but still set them to zero to avoid uninitialized reads */
725             if(bits_len < (WORD32)(ps_codec->u4_bitsbuf_size - 8))
726             {
727                 memset(ps_codec->pu1_bitsbuf + bits_len, 0, 2 * sizeof(UWORD32));
728             }
729         }
730         /* This may be used to update the offsets for tiles and entropy sync row offsets */
731         ps_codec->i4_num_emln_bytes = nal_len - bits_len;
732         ps_codec->i4_nal_len = nal_len;
733 
734         ihevcd_bits_init(&ps_codec->s_parse.s_bitstrm, ps_codec->pu1_bitsbuf,
735                          bits_len);
736 
737         ret = ihevcd_nal_unit(ps_codec);
738 
739         /* If the frame is incomplete and
740          * the bytes remaining is zero or a header is received,
741          * complete the frame treating it to be in error */
742         if(ps_codec->i4_pic_present &&
743                         (ps_codec->s_parse.i4_next_ctb_indx != ps_codec->s_parse.ps_sps->i4_pic_size_in_ctb))
744         {
745             if((ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN) ||
746                             (ps_codec->i4_header_in_slice_mode))
747             {
748                 slice_header_t *ps_slice_hdr_next;
749 
750                 ps_codec->s_parse.i4_cur_slice_idx--;
751                 if(ps_codec->s_parse.i4_cur_slice_idx < 0)
752                     ps_codec->s_parse.i4_cur_slice_idx = 0;
753 
754                 ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + ((ps_codec->s_parse.i4_cur_slice_idx + 1) & (MAX_SLICE_HDR_CNT - 1));
755                 ps_slice_hdr_next->i2_ctb_x = 0;
756                 ps_slice_hdr_next->i2_ctb_y = ps_codec->s_parse.ps_sps->i2_pic_ht_in_ctb;
757                 ps_codec->i4_slice_error = 1;
758                 continue;
759             }
760         }
761 
762         if(IHEVCD_IGNORE_SLICE == ret)
763         {
764             ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
765             ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
766 
767             continue;
768         }
769 
770         if(IVD_RES_CHANGED == ret)
771         {
772             break;
773         }
774 
775         /* Update bytes remaining and bytes consumed and input bitstream pointer */
776         /* Do not consume the NAL in the following cases */
777         /* Slice header reached during header decode mode */
778         /* TODO: Next picture's slice reached */
779         if(ret != IHEVCD_SLICE_IN_HEADER_MODE)
780         {
781             if((0 == ps_codec->i4_slice_error) ||
782                             (ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN))
783             {
784                 ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
785                 ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
786             }
787             if(ret != IHEVCD_SUCCESS)
788                 break;
789 
790             if(ps_codec->s_parse.i4_end_of_frame)
791                 break;
792         }
793         else
794         {
795             ret = IHEVCD_SUCCESS;
796             break;
797         }
798 
799         /* Allocate dynamic bitstream buffer once SPS is decoded */
800         if((ps_codec->u4_allocate_dynamic_done == 0) && ps_codec->i4_sps_done)
801         {
802             WORD32 ret;
803             ret = ihevcd_allocate_dynamic_bufs(ps_codec);
804             if(ret != IV_SUCCESS)
805             {
806                 /* Free any dynamic buffers that are allocated */
807                 ihevcd_free_dynamic_bufs(ps_codec);
808                 ps_codec->i4_error_code = IVD_MEM_ALLOC_FAILED;
809                 ps_dec_op->u4_error_code = 1 << IVD_FATALERROR;
810                 ps_dec_op->u4_error_code |= IVD_MEM_ALLOC_FAILED;
811 
812                 return IV_FAIL;
813             }
814         }
815 
816         BREAK_AFTER_SLICE_NAL();
817     }
818 
819     if(1 == ps_codec->i4_pic_present && 0 == ps_codec->s_parse.i4_end_of_frame)
820     {
821         slice_header_t *ps_slice_hdr_next;
822         ps_codec->i4_slice_error = 1;
823         ps_codec->s_parse.i4_cur_slice_idx--;
824         if(ps_codec->s_parse.i4_cur_slice_idx < 0)
825             ps_codec->s_parse.i4_cur_slice_idx = 0;
826 
827         ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + ((ps_codec->s_parse.i4_cur_slice_idx + 1) & (MAX_SLICE_HDR_CNT - 1));
828         ps_slice_hdr_next->i2_ctb_x = -1;
829         ps_slice_hdr_next->i2_ctb_y = -1;
830 
831         ihevcd_parse_slice_data(ps_codec);
832         ASSERT(ps_codec->s_parse.i4_end_of_frame != 0);
833     }
834 
835     if(1 == ps_codec->i4_pic_present)
836     {
837         WORD32 i;
838         sps_t *ps_sps = ps_codec->s_parse.ps_sps;
839         ps_codec->i4_first_pic_done = 1;
840 
841         /*TODO temporary fix: end_of_frame is checked before adding format conversion to job queue         */
842         if(ps_codec->i4_num_cores > 1 && ps_codec->s_parse.i4_end_of_frame)
843         {
844 
845             /* Add job queue for format conversion / frame copy for each ctb row */
846             /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
847             process_ctxt_t *ps_proc;
848 
849             /* i4_num_cores - 1 contexts are currently being used by other threads */
850             ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
851 
852             if((ps_codec->ps_disp_buf) &&
853                ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
854             {
855                 /* If format conversion jobs were not issued in pic_init() add them here */
856                 if((0 == ps_codec->u4_enable_fmt_conv_ahead) ||
857                                 (ps_codec->i4_disp_buf_id == ps_proc->i4_cur_pic_buf_id))
858                     for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
859                     {
860                         proc_job_t s_job;
861                         IHEVCD_ERROR_T ret;
862                         s_job.i4_cmd = CMD_FMTCONV;
863                         s_job.i2_ctb_cnt = 0;
864                         s_job.i2_ctb_x = 0;
865                         s_job.i2_ctb_y = i;
866                         s_job.i2_slice_idx = 0;
867                         s_job.i4_tu_coeff_data_ofst = 0;
868                         ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
869                                                 &s_job, sizeof(proc_job_t), 1);
870                         if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
871                             return (WORD32)ret;
872                     }
873             }
874             /* Reached end of frame : Signal terminate */
875             /* The terminate flag is checked only after all the jobs are dequeued */
876             ret = ihevcd_jobq_terminate((jobq_t *)ps_codec->s_parse.pv_proc_jobq);
877 
878             while(1)
879             {
880                 IHEVCD_ERROR_T ret;
881                 proc_job_t s_job;
882                 process_ctxt_t *ps_proc;
883 
884                 /* i4_num_cores - 1 contexts are currently being used by other threads */
885                 ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
886 
887                 ret = ihevcd_jobq_dequeue((jobq_t *)ps_proc->pv_proc_jobq, &s_job,
888                                           sizeof(proc_job_t), 1);
889                 if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret)
890                     break;
891 
892                 ps_proc->i4_ctb_cnt = s_job.i2_ctb_cnt;
893                 ps_proc->i4_ctb_x = s_job.i2_ctb_x;
894                 ps_proc->i4_ctb_y = s_job.i2_ctb_y;
895                 ps_proc->i4_cur_slice_idx = s_job.i2_slice_idx;
896 
897                 if(CMD_PROCESS == s_job.i4_cmd)
898                 {
899                     ihevcd_init_proc_ctxt(ps_proc, s_job.i4_tu_coeff_data_ofst);
900 
901                     ihevcd_process(ps_proc);
902                 }
903                 else if(CMD_FMTCONV == s_job.i4_cmd)
904                 {
905                     sps_t *ps_sps = ps_codec->s_parse.ps_sps;
906                     WORD32 num_rows = 1 << ps_sps->i1_log2_ctb_size;
907                     if(0 == ps_proc->i4_init_done)
908                     {
909                         ihevcd_init_proc_ctxt(ps_proc, 0);
910                     }
911 
912                     num_rows = MIN(num_rows, (ps_codec->i4_disp_ht - (s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size)));
913                     if(num_rows < 0)
914                         num_rows = 0;
915 
916                     ihevcd_fmt_conv(ps_codec, ps_proc,
917                                     ps_dec_ip->s_out_buffer.pu1_bufs[0],
918                                     ps_dec_ip->s_out_buffer.pu1_bufs[1],
919                                     ps_dec_ip->s_out_buffer.pu1_bufs[2],
920                                     s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size,
921                                     num_rows);
922                 }
923             }
924         }
925         /* In case of non-shared mode and while running in single core mode, then convert/copy the frame to output buffer */
926         /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
927         else if((ps_codec->ps_disp_buf) && ((0 == ps_codec->i4_share_disp_buf) ||
928                                             (IV_YUV_420P == ps_codec->e_chroma_fmt)) &&
929                         (ps_codec->s_parse.i4_end_of_frame))
930         {
931             process_ctxt_t *ps_proc = &ps_codec->as_process[proc_idx];
932             /* Set remaining number of rows to be processed */
933             ps_codec->s_fmt_conv.i4_num_rows = ps_codec->i4_disp_ht
934                             - ps_codec->s_fmt_conv.i4_cur_row;
935             if(0 == ps_proc->i4_init_done)
936             {
937                 ihevcd_init_proc_ctxt(ps_proc, 0);
938             }
939 
940             if(ps_codec->s_fmt_conv.i4_num_rows < 0)
941                 ps_codec->s_fmt_conv.i4_num_rows = 0;
942 
943             ret = ihevcd_fmt_conv(ps_codec, ps_proc,
944                                   ps_dec_ip->s_out_buffer.pu1_bufs[0],
945                                   ps_dec_ip->s_out_buffer.pu1_bufs[1],
946                                   ps_dec_ip->s_out_buffer.pu1_bufs[2],
947                                   ps_codec->s_fmt_conv.i4_cur_row,
948                                   ps_codec->s_fmt_conv.i4_num_rows);
949             ps_codec->s_fmt_conv.i4_cur_row += ps_codec->s_fmt_conv.i4_num_rows;
950 
951         }
952 
953 
954         DEBUG_DUMP_MV_MAP(ps_codec);
955 
956         /* Mark MV Buf as needed for reference */
957         ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_mv_buf_mgr,
958                                  ps_codec->as_process[proc_idx].i4_cur_mv_bank_buf_id,
959                                  BUF_MGR_REF);
960 
961         /* Mark pic buf as needed for reference */
962         ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
963                                  ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
964                                  BUF_MGR_REF);
965 
966         /* Mark pic buf as needed for display */
967         ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
968                                  ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
969                                  BUF_MGR_DISP);
970 
971         /* Insert the current picture as short term reference */
972         ihevc_dpb_mgr_insert_ref((dpb_mgr_t *)ps_codec->pv_dpb_mgr,
973                                  ps_codec->as_process[proc_idx].ps_cur_pic,
974                                  ps_codec->as_process[proc_idx].i4_cur_pic_buf_id);
975 
976         /* If a frame was displayed (in non-shared mode), then release it from display manager */
977         if((0 == ps_codec->i4_share_disp_buf) && (ps_codec->ps_disp_buf))
978             ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
979                                   ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
980 
981         /* Wait for threads */
982         for(i = 0; i < (ps_codec->i4_num_cores - 1); i++)
983         {
984             if(ps_codec->ai4_process_thread_created[i])
985             {
986 #ifdef KEEP_THREADS_ACTIVE
987                 ret = ithread_mutex_lock(ps_codec->apv_proc_done_mutex[i]);
988                 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
989 
990                 while(!ps_codec->ai4_process_done[i])
991                 {
992                     ithread_cond_wait(ps_codec->apv_proc_done_condition[i],
993                                       ps_codec->apv_proc_done_mutex[i]);
994                 }
995                 ps_codec->ai4_process_done[i] = 0;
996                 ret = ithread_mutex_unlock(ps_codec->apv_proc_done_mutex[i]);
997                 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
998 #else
999                 ithread_join(ps_codec->apv_process_thread_handle[i], NULL);
1000                 ps_codec->ai4_process_thread_created[i] = 0;
1001 #endif
1002             }
1003         }
1004 
1005         DEBUG_VALIDATE_PADDED_REGION(&ps_codec->as_process[proc_idx]);
1006         if(ps_codec->u4_pic_cnt > 0)
1007         {
1008             DEBUG_DUMP_PIC_PU(ps_codec);
1009         }
1010         DEBUG_DUMP_PIC_BUFFERS(ps_codec);
1011 
1012         /* Increment the number of pictures decoded */
1013         ps_codec->u4_pic_cnt++;
1014     }
1015     ihevcd_fill_outargs(ps_codec, ps_hevcd_dec_ip, ps_hevcd_dec_op);
1016 
1017     if(1 == ps_dec_op->u4_output_present)
1018     {
1019         WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
1020         WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
1021 
1022         if(ypos < 0)
1023             ypos = 0;
1024 
1025         if(xpos < 0)
1026             xpos = 0;
1027 
1028         INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
1029                     ps_dec_ip->s_out_buffer.pu1_bufs[1],
1030                     ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
1031                     xpos,
1032                     ypos,
1033                     ps_codec->e_chroma_fmt,
1034                     ps_codec->i4_disp_wd,
1035                     ps_codec->i4_disp_ht);
1036     }
1037 
1038 
1039     return ret;
1040 }
1041 
1042