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,ivd_video_decode_ip_t * ps_dec_ip,ivd_video_decode_op_t * ps_dec_op)185 static void ihevcd_fill_outargs(codec_t *ps_codec,
186                                 ivd_video_decode_ip_t *ps_dec_ip,
187                                 ivd_video_decode_op_t *ps_dec_op)
188 {
189 
190     ps_dec_op->u4_error_code = ihevcd_map_error((IHEVCD_ERROR_T)ps_codec->i4_error_code);
191     ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes
192                     - ps_codec->i4_bytes_remaining;
193     if(ps_codec->i4_sps_done)
194     {
195         ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
196         ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
197     }
198     else
199     {
200         ps_dec_op->u4_pic_wd = 0;
201         ps_dec_op->u4_pic_ht = 0;
202     }
203 
204     ps_dec_op->e_pic_type = ps_codec->e_dec_pic_type;
205     ps_dec_op->u4_frame_decoded_flag = ps_codec->i4_pic_present;
206     ps_dec_op->u4_new_seq = 0;
207 
208     ps_dec_op->u4_output_present = 0;
209     ps_dec_op->u4_progressive_frame_flag = 1;
210     ps_dec_op->i4_display_index = -1;
211     ps_dec_op->i4_reorder_depth = -1;
212     if(ps_codec->i4_sps_done)
213     {
214         sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
215         profile_tier_lvl_info_t *ps_ptl;
216         ps_ptl = &ps_sps->s_ptl;
217         if((0 == ps_ptl->s_ptl_gen.i1_general_progressive_source_flag) &&
218            (1 == ps_ptl->s_ptl_gen.i1_general_interlaced_source_flag))
219         {
220             ps_dec_op->u4_progressive_frame_flag = 0;
221         }
222         ps_dec_op->i4_reorder_depth =
223                         ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
224     }
225 
226     ps_dec_op->u4_is_ref_flag = 1;
227     ps_dec_op->e_output_format = ps_codec->e_chroma_fmt;
228     ps_dec_op->u4_is_ref_flag = 1;
229 
230     ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
231     ps_dec_op->u4_ts = (UWORD32)(-1);
232     ps_dec_op->u4_disp_buf_id = ps_codec->i4_disp_buf_id;
233     if(ps_codec->i4_flush_mode)
234     {
235         ps_dec_op->u4_num_bytes_consumed = 0;
236         /*In the case of flush ,since no frame is decoded set pic type as invalid*/
237         ps_dec_op->u4_is_ref_flag = 0;
238         ps_dec_op->e_pic_type = IV_NA_FRAME;
239         ps_dec_op->u4_frame_decoded_flag = 0;
240 
241     }
242     /* If there is a display buffer */
243     if(ps_codec->ps_disp_buf)
244     {
245         pic_buf_t *ps_disp_buf = ps_codec->ps_disp_buf;
246         sei_params_t *ps_sei = &ps_disp_buf->s_sei_params;
247 
248         if(ps_sei->i1_sei_parameters_present_flag &&
249            ps_sei->i1_pic_timing_params_present_flag)
250         {
251             UWORD32 u4_pic_struct;
252             u4_pic_struct = ps_sei->s_pic_timing_sei_params.u4_pic_struct;
253             switch(u4_pic_struct)
254             {
255                 case 1:
256                     ps_dec_op->e4_fld_type = IV_TOP_FLD;
257                     ps_dec_op->u4_progressive_frame_flag = 0;
258                     break;
259                 case 2:
260                     ps_dec_op->e4_fld_type = IV_BOT_FLD;
261                     ps_dec_op->u4_progressive_frame_flag = 0;
262                     break;
263                 case 0:
264                 default:
265                     ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
266                     ps_dec_op->u4_progressive_frame_flag = 1;
267                     break;
268             }
269         }
270         ps_dec_op->i4_display_index = ps_disp_buf->i4_abs_poc;
271         ps_dec_op->u4_output_present = 1;
272         ps_dec_op->u4_ts = ps_disp_buf->u4_ts;
273         if((ps_codec->i4_flush_mode == 0) && (ps_codec->s_parse.i4_end_of_frame == 0))
274             ps_dec_op->u4_output_present = 0;
275         ps_dec_op->s_disp_frm_buf.u4_y_wd = ps_codec->i4_disp_wd;
276         ps_dec_op->s_disp_frm_buf.u4_y_ht = ps_codec->i4_disp_ht;
277 
278         if(ps_codec->i4_share_disp_buf)
279         {
280             ps_dec_op->s_disp_frm_buf.pv_y_buf = ps_disp_buf->pu1_luma;
281             if(ps_codec->e_chroma_fmt != IV_YUV_420P)
282             {
283                 ps_dec_op->s_disp_frm_buf.pv_u_buf = ps_disp_buf->pu1_chroma;
284                 ps_dec_op->s_disp_frm_buf.pv_v_buf = NULL;
285             }
286             else
287             {
288                 WORD32 i;
289                 UWORD8 *pu1_u_dst = NULL, *pu1_v_dst = NULL;
290                 for(i = 0; i < ps_codec->i4_share_disp_buf_cnt; i++)
291                 {
292                     WORD32 diff = ps_disp_buf->pu1_luma - ps_codec->s_disp_buffer[i].pu1_bufs[0];
293                     if(diff == (ps_codec->i4_strd * PAD_TOP + PAD_LEFT))
294                     {
295                         pu1_u_dst = ps_codec->s_disp_buffer[i].pu1_bufs[1];
296                         pu1_u_dst += (ps_codec->i4_strd * PAD_TOP) / 4 + (PAD_LEFT / 2);
297 
298                         pu1_v_dst = ps_codec->s_disp_buffer[i].pu1_bufs[2];
299                         pu1_v_dst += (ps_codec->i4_strd * PAD_TOP) / 4 + (PAD_LEFT / 2);
300                         break;
301                     }
302                 }
303                 ps_dec_op->s_disp_frm_buf.pv_u_buf = pu1_u_dst;
304                 ps_dec_op->s_disp_frm_buf.pv_v_buf = pu1_v_dst;
305             }
306             ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_strd;
307         }
308         else
309         {
310             ps_dec_op->s_disp_frm_buf.pv_y_buf =
311                             ps_dec_ip->s_out_buffer.pu1_bufs[0];
312             ps_dec_op->s_disp_frm_buf.pv_u_buf =
313                             ps_dec_ip->s_out_buffer.pu1_bufs[1];
314             ps_dec_op->s_disp_frm_buf.pv_v_buf =
315                             ps_dec_ip->s_out_buffer.pu1_bufs[2];
316             ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_disp_strd;
317         }
318 
319         if((IV_YUV_420SP_VU == ps_codec->e_chroma_fmt)
320                         || (IV_YUV_420SP_UV == ps_codec->e_chroma_fmt))
321         {
322             ps_dec_op->s_disp_frm_buf.u4_u_strd =
323                             ps_dec_op->s_disp_frm_buf.u4_y_strd;
324             ps_dec_op->s_disp_frm_buf.u4_v_strd = 0;
325             ps_dec_op->s_disp_frm_buf.u4_u_wd =
326                             ps_dec_op->s_disp_frm_buf.u4_y_wd;
327             ps_dec_op->s_disp_frm_buf.u4_v_wd = 0;
328             ps_dec_op->s_disp_frm_buf.u4_u_ht =
329                             ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
330             ps_dec_op->s_disp_frm_buf.u4_v_ht = 0;
331         }
332         else if(IV_YUV_420P == ps_codec->e_chroma_fmt)
333         {
334             ps_dec_op->s_disp_frm_buf.u4_u_strd =
335                             ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
336             ps_dec_op->s_disp_frm_buf.u4_v_strd =
337                             ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
338             ps_dec_op->s_disp_frm_buf.u4_u_wd =
339                             ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
340             ps_dec_op->s_disp_frm_buf.u4_v_wd =
341                             ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
342             ps_dec_op->s_disp_frm_buf.u4_u_ht =
343                             ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
344             ps_dec_op->s_disp_frm_buf.u4_v_ht =
345                             ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
346         }
347 
348     }
349     else if(ps_codec->i4_flush_mode)
350     {
351         ps_dec_op->u4_error_code = IHEVCD_END_OF_SEQUENCE;
352         /* Come out of flush mode */
353         ps_codec->i4_flush_mode = 0;
354     }
355 
356 }
357 
358 /**
359  *******************************************************************************
360  *
361  * @brief
362  *  Codec process call
363  *
364  * @par Description:
365  *  Codec process call  Tests for few error checks  Handle flush and decode
366  * header related code  Parse bitstream for start codes  For each NAL unit
367  * call decode NAL function  Once a complete frame is decoded (in frame
368  * decode mode)  Fill output arguments and return
369  *
370  * @param[in] ps_codec_obj
371  *  Pointer to codec object at API level
372  *
373  * @param[in] pv_api_ip
374  *  Pointer to input argument structure
375  *
376  * @param[in] pv_api_op
377  *  Pointer to output argument structure
378  *
379  * @returns  Status
380  *
381  * @remarks
382  *
383  *
384  *******************************************************************************
385  */
ihevcd_decode(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)386 WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
387 {
388     WORD32 ret = IV_SUCCESS;
389     codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
390     ivd_video_decode_ip_t *ps_dec_ip;
391     ivd_video_decode_op_t *ps_dec_op;
392 
393     WORD32 proc_idx = 0;
394     WORD32 prev_proc_idx = 0;
395 
396     /* Initialize error code */
397     ps_codec->i4_error_code = 0;
398     /* Initialize bytes remaining */
399     ps_codec->i4_bytes_remaining = 0;
400 
401     ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip;
402     ps_dec_op = (ivd_video_decode_op_t *)pv_api_op;
403 
404     {
405         UWORD32 u4_size = ps_dec_op->u4_size;
406         memset(ps_dec_op, 0, sizeof(ivd_video_decode_op_t));
407         ps_dec_op->u4_size = u4_size; //Restore size field
408     }
409     if(ps_codec->i4_init_done != 1)
410     {
411         ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
412         ps_dec_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
413         return IV_FAIL;
414     }
415 
416     if(ps_codec->u4_pic_cnt >= NUM_FRAMES_LIMIT)
417     {
418         ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
419         ps_dec_op->u4_error_code |= IHEVCD_NUM_FRAMES_LIMIT_REACHED;
420         return IV_FAIL;
421     }
422 
423     /* If reset flag is set, flush the existing buffers */
424     if(ps_codec->i4_reset_flag)
425     {
426         ps_codec->i4_flush_mode = 1;
427     }
428 
429     /*Data memory barries instruction,so that bitstream write by the application is complete*/
430     //arm_dsb();
431     /* In case the decoder is not in flush mode check for input buffer validity */
432     if(0 == ps_codec->i4_flush_mode)
433     {
434         if(ps_dec_ip->pv_stream_buffer == NULL)
435         {
436             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
437             ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL;
438             return IV_FAIL;
439         }
440         if(ps_dec_ip->u4_num_Bytes <= MIN_START_CODE_LEN)
441         {
442             if((WORD32)ps_dec_ip->u4_num_Bytes > 0)
443                 ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes;
444             else
445                 ps_dec_op->u4_num_bytes_consumed = 0;
446 
447             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
448             ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV;
449             return IV_FAIL;
450 
451         }
452     }
453 
454 #ifdef APPLY_CONCEALMENT
455     {
456         WORD32 num_mbs;
457 
458         num_mbs = (ps_codec->i4_wd * ps_codec->i4_ht + 255) >> 8;
459         /* Reset MB Count at the beginning of every process call */
460         ps_codec->mb_count = 0;
461         memset(ps_codec->mb_map, 0, ((num_mbs + 7) >> 3));
462     }
463 #endif
464 
465     if(0 == ps_codec->i4_share_disp_buf && ps_codec->i4_header_mode == 0)
466     {
467         UWORD32 i;
468         if((ps_dec_ip->s_out_buffer.u4_num_bufs <= 0) ||
469            (ps_dec_ip->s_out_buffer.u4_num_bufs > IVD_VIDDEC_MAX_IO_BUFFERS))
470         {
471             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
472             ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
473             return IV_FAIL;
474         }
475 
476         for(i = 0; i < ps_dec_ip->s_out_buffer.u4_num_bufs; i++)
477         {
478             if(ps_dec_ip->s_out_buffer.pu1_bufs[i] == NULL)
479             {
480                 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
481                 ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL;
482                 return IV_FAIL;
483             }
484 
485             if(ps_dec_ip->s_out_buffer.u4_min_out_buf_size[i] == 0)
486             {
487                 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
488                 ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
489                 return IV_FAIL;
490             }
491         }
492     }
493 
494     ps_codec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
495     ps_codec->u4_ts = ps_dec_ip->u4_ts;
496     if(ps_codec->i4_flush_mode)
497     {
498 
499         ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
500         ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
501 
502         ps_dec_op->u4_new_seq = 0;
503 
504         ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get(
505                         (disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id);
506         /* In case of non-shared mode, then convert/copy the frame to output buffer */
507         /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
508         if((ps_codec->ps_disp_buf)
509                         && ((0 == ps_codec->i4_share_disp_buf)
510                                         || (IV_YUV_420P
511                                                         == ps_codec->e_chroma_fmt)))
512         {
513 
514             process_ctxt_t *ps_proc = &ps_codec->as_process[prev_proc_idx];
515             if(0 == ps_proc->i4_init_done)
516             {
517                 ihevcd_init_proc_ctxt(ps_proc, 0);
518             }
519 
520             /* Output buffer check */
521             ret = ihevcd_check_out_buf_size(ps_codec);
522             RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
523 
524             /* Set remaining number of rows to be processed */
525             ret = ihevcd_fmt_conv(ps_codec, &ps_codec->as_process[prev_proc_idx],
526                                   ps_dec_ip->s_out_buffer.pu1_bufs[0],
527                                   ps_dec_ip->s_out_buffer.pu1_bufs[1],
528                                   ps_dec_ip->s_out_buffer.pu1_bufs[2], 0,
529                                   ps_codec->i4_disp_ht);
530 
531             ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
532                                   ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
533         }
534 
535         ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op);
536 
537         if(1 == ps_dec_op->u4_output_present)
538         {
539             WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
540             WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
541 
542             if(ypos < 0)
543                 ypos = 0;
544 
545             if(xpos < 0)
546                 xpos = 0;
547 
548             INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
549                         ps_dec_ip->s_out_buffer.pu1_bufs[1],
550                         ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
551                         xpos,
552                         ypos,
553                         ps_codec->e_chroma_fmt,
554                         ps_codec->i4_disp_wd,
555                         ps_codec->i4_disp_ht);
556         }
557 
558 
559         if(NULL == ps_codec->ps_disp_buf)
560         {
561             /* If in flush mode and there are no more buffers to flush,
562              * check for the reset flag and reset the decoder */
563             if(ps_codec->i4_reset_flag)
564             {
565                 ihevcd_init(ps_codec);
566             }
567             return (IV_FAIL);
568         }
569 
570         return (IV_SUCCESS);
571 
572     }
573     /* In case of shared mode, check if there is a free buffer for reconstruction */
574     if((0 == ps_codec->i4_header_mode) && (1 == ps_codec->i4_share_disp_buf))
575     {
576         WORD32 buf_status;
577         buf_status = 1;
578         if(ps_codec->pv_pic_buf_mgr)
579             buf_status = ihevc_buf_mgr_check_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr);
580 
581         /* If there is no free buffer, then return with an error code */
582         if(0 == buf_status)
583         {
584             ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
585             ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
586             return IV_FAIL;
587         }
588     }
589     ps_codec->i4_bytes_remaining = ps_dec_ip->u4_num_Bytes;
590     ps_codec->pu1_inp_bitsbuf = (UWORD8 *)ps_dec_ip->pv_stream_buffer;
591     ps_codec->s_parse.i4_end_of_frame = 0;
592 
593     ps_codec->i4_pic_present = 0;
594     ps_codec->i4_slice_error = 0;
595     ps_codec->ps_disp_buf = NULL;
596 
597     if(ps_codec->i4_num_cores > 1)
598     {
599         ithread_set_affinity(0);
600     }
601     while(MIN_START_CODE_LEN < ps_codec->i4_bytes_remaining)
602     {
603         WORD32 nal_len;
604         WORD32 nal_ofst;
605         WORD32 bits_len;
606 
607         if(ps_codec->i4_slice_error)
608         {
609             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));
610             WORD32 next_slice_addr = ps_slice_hdr_next->i2_ctb_x +
611                             ps_slice_hdr_next->i2_ctb_y * ps_codec->s_parse.ps_sps->i2_pic_wd_in_ctb;
612             if(ps_codec->s_parse.i4_next_ctb_indx == next_slice_addr)
613                 ps_codec->i4_slice_error = 0;
614         }
615 
616         if(ps_codec->pu1_bitsbuf_dynamic)
617         {
618             ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_dynamic;
619             ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_dynamic;
620         }
621         else
622         {
623             ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_static;
624             ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_static;
625         }
626 
627         nal_ofst = ihevcd_nal_search_start_code(ps_codec->pu1_inp_bitsbuf,
628                                                 ps_codec->i4_bytes_remaining);
629         /* If there is no start code found, consume the data and break */
630         if(nal_ofst == ps_codec->i4_bytes_remaining)
631         {
632             ps_codec->pu1_inp_bitsbuf += nal_ofst;
633             ps_codec->i4_bytes_remaining -= nal_ofst;
634             break;
635         }
636 
637         ps_codec->i4_nal_ofst = nal_ofst;
638         {
639             WORD32 bytes_remaining = ps_codec->i4_bytes_remaining - nal_ofst;
640 
641             bytes_remaining = MIN((UWORD32)bytes_remaining, ps_codec->u4_bitsbuf_size);
642             ihevcd_nal_remv_emuln_bytes(ps_codec->pu1_inp_bitsbuf + nal_ofst,
643                                         ps_codec->pu1_bitsbuf,
644                                         bytes_remaining,
645                                         &nal_len, &bits_len);
646 
647             /* Decoder may read upto 8 extra bytes at the end of frame */
648             /* These are not used, but still set them to zero to avoid uninitialized reads */
649             if(bits_len < (WORD32)(ps_codec->u4_bitsbuf_size - 8))
650             {
651                 memset(ps_codec->pu1_bitsbuf + bits_len, 0, 2 * sizeof(UWORD32));
652             }
653         }
654         /* This may be used to update the offsets for tiles and entropy sync row offsets */
655         ps_codec->i4_num_emln_bytes = nal_len - bits_len;
656         ps_codec->i4_nal_len = nal_len;
657 
658         ihevcd_bits_init(&ps_codec->s_parse.s_bitstrm, ps_codec->pu1_bitsbuf,
659                          bits_len);
660 
661         ret = ihevcd_nal_unit(ps_codec);
662 
663         /* If the frame is incomplete and
664          * the bytes remaining is zero or a header is received,
665          * complete the frame treating it to be in error */
666         if(ps_codec->i4_pic_present &&
667                         (ps_codec->s_parse.i4_next_ctb_indx != ps_codec->s_parse.ps_sps->i4_pic_size_in_ctb))
668         {
669             if((ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN) ||
670                             (ps_codec->i4_header_in_slice_mode))
671             {
672                 slice_header_t *ps_slice_hdr_next;
673 
674                 ps_codec->s_parse.i4_cur_slice_idx--;
675                 if(ps_codec->s_parse.i4_cur_slice_idx < 0)
676                     ps_codec->s_parse.i4_cur_slice_idx = 0;
677 
678                 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));
679                 ps_slice_hdr_next->i2_ctb_x = 0;
680                 ps_slice_hdr_next->i2_ctb_y = ps_codec->s_parse.ps_sps->i2_pic_ht_in_ctb;
681                 ps_codec->i4_slice_error = 1;
682                 continue;
683             }
684         }
685 
686         if(IHEVCD_IGNORE_SLICE == ret)
687         {
688             ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
689             ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
690 
691             continue;
692         }
693 
694         if(IVD_RES_CHANGED == ret)
695         {
696             break;
697         }
698 
699         /* Update bytes remaining and bytes consumed and input bitstream pointer */
700         /* Do not consume the NAL in the following cases */
701         /* Slice header reached during header decode mode */
702         /* TODO: Next picture's slice reached */
703         if(ret != IHEVCD_SLICE_IN_HEADER_MODE)
704         {
705             if((0 == ps_codec->i4_slice_error) ||
706                             (ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN))
707             {
708                 ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
709                 ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
710             }
711             if(ret != IHEVCD_SUCCESS)
712                 break;
713 
714             if(ps_codec->s_parse.i4_end_of_frame)
715                 break;
716         }
717         else
718         {
719             ret = IHEVCD_SUCCESS;
720             break;
721         }
722 
723         /* Allocate dynamic bitstream buffer once SPS is decoded */
724         if((ps_codec->u4_allocate_dynamic_done == 0) && ps_codec->i4_sps_done)
725         {
726             WORD32 ret;
727             ret = ihevcd_allocate_dynamic_bufs(ps_codec);
728             if(ret != IV_SUCCESS)
729             {
730                 /* Free any dynamic buffers that are allocated */
731                 ihevcd_free_dynamic_bufs(ps_codec);
732                 ps_codec->i4_error_code = IVD_MEM_ALLOC_FAILED;
733                 ps_dec_op->u4_error_code = 1 << IVD_FATALERROR;
734                 ps_dec_op->u4_error_code |= IVD_MEM_ALLOC_FAILED;
735 
736                 return IV_FAIL;
737             }
738         }
739 
740         BREAK_AFTER_SLICE_NAL();
741     }
742 
743     if(1 == ps_codec->i4_pic_present && 0 == ps_codec->s_parse.i4_end_of_frame)
744     {
745         slice_header_t *ps_slice_hdr_next;
746         ps_codec->i4_slice_error = 1;
747         ps_codec->s_parse.i4_cur_slice_idx--;
748         if(ps_codec->s_parse.i4_cur_slice_idx < 0)
749             ps_codec->s_parse.i4_cur_slice_idx = 0;
750 
751         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));
752         ps_slice_hdr_next->i2_ctb_x = -1;
753         ps_slice_hdr_next->i2_ctb_y = -1;
754 
755         ihevcd_parse_slice_data(ps_codec);
756         ASSERT(ps_codec->s_parse.i4_end_of_frame != 0);
757     }
758 
759     if(1 == ps_codec->i4_pic_present)
760     {
761         WORD32 i;
762         sps_t *ps_sps = ps_codec->s_parse.ps_sps;
763         ps_codec->i4_first_pic_done = 1;
764 
765         /*TODO temporary fix: end_of_frame is checked before adding format conversion to job queue         */
766         if(ps_codec->i4_num_cores > 1 && ps_codec->s_parse.i4_end_of_frame)
767         {
768 
769             /* Add job queue for format conversion / frame copy for each ctb row */
770             /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
771             process_ctxt_t *ps_proc;
772 
773             /* i4_num_cores - 1 contexts are currently being used by other threads */
774             ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
775 
776             if((ps_codec->ps_disp_buf) &&
777                ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
778             {
779                 /* If format conversion jobs were not issued in pic_init() add them here */
780                 if((0 == ps_codec->u4_enable_fmt_conv_ahead) ||
781                                 (ps_codec->i4_disp_buf_id == ps_proc->i4_cur_pic_buf_id))
782                     for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
783                     {
784                         proc_job_t s_job;
785                         IHEVCD_ERROR_T ret;
786                         s_job.i4_cmd = CMD_FMTCONV;
787                         s_job.i2_ctb_cnt = 0;
788                         s_job.i2_ctb_x = 0;
789                         s_job.i2_ctb_y = i;
790                         s_job.i2_slice_idx = 0;
791                         s_job.i4_tu_coeff_data_ofst = 0;
792                         ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
793                                                 &s_job, sizeof(proc_job_t), 1);
794                         if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
795                             return (WORD32)ret;
796                     }
797             }
798             /* Reached end of frame : Signal terminate */
799             /* The terminate flag is checked only after all the jobs are dequeued */
800             ret = ihevcd_jobq_terminate((jobq_t *)ps_codec->s_parse.pv_proc_jobq);
801 
802             while(1)
803             {
804                 IHEVCD_ERROR_T ret;
805                 proc_job_t s_job;
806                 process_ctxt_t *ps_proc;
807 
808                 /* i4_num_cores - 1 contexts are currently being used by other threads */
809                 ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
810 
811                 ret = ihevcd_jobq_dequeue((jobq_t *)ps_proc->pv_proc_jobq, &s_job,
812                                           sizeof(proc_job_t), 1);
813                 if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret)
814                     break;
815 
816                 ps_proc->i4_ctb_cnt = s_job.i2_ctb_cnt;
817                 ps_proc->i4_ctb_x = s_job.i2_ctb_x;
818                 ps_proc->i4_ctb_y = s_job.i2_ctb_y;
819                 ps_proc->i4_cur_slice_idx = s_job.i2_slice_idx;
820 
821                 if(CMD_PROCESS == s_job.i4_cmd)
822                 {
823                     ihevcd_init_proc_ctxt(ps_proc, s_job.i4_tu_coeff_data_ofst);
824 
825                     ihevcd_process(ps_proc);
826                 }
827                 else if(CMD_FMTCONV == s_job.i4_cmd)
828                 {
829                     sps_t *ps_sps = ps_codec->s_parse.ps_sps;
830                     WORD32 num_rows = 1 << ps_sps->i1_log2_ctb_size;
831                     if(0 == ps_proc->i4_init_done)
832                     {
833                         ihevcd_init_proc_ctxt(ps_proc, 0);
834                     }
835 
836                     num_rows = MIN(num_rows, (ps_codec->i4_disp_ht - (s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size)));
837                     if(num_rows < 0)
838                         num_rows = 0;
839 
840                     ihevcd_fmt_conv(ps_codec, ps_proc,
841                                     ps_dec_ip->s_out_buffer.pu1_bufs[0],
842                                     ps_dec_ip->s_out_buffer.pu1_bufs[1],
843                                     ps_dec_ip->s_out_buffer.pu1_bufs[2],
844                                     s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size,
845                                     num_rows);
846                 }
847             }
848         }
849         /* In case of non-shared mode and while running in single core mode, then convert/copy the frame to output buffer */
850         /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
851         else if((ps_codec->ps_disp_buf) && ((0 == ps_codec->i4_share_disp_buf) ||
852                                             (IV_YUV_420P == ps_codec->e_chroma_fmt)) &&
853                         (ps_codec->s_parse.i4_end_of_frame))
854         {
855             process_ctxt_t *ps_proc = &ps_codec->as_process[proc_idx];
856             /* Set remaining number of rows to be processed */
857             ps_codec->s_fmt_conv.i4_num_rows = ps_codec->i4_disp_ht
858                             - ps_codec->s_fmt_conv.i4_cur_row;
859             if(0 == ps_proc->i4_init_done)
860             {
861                 ihevcd_init_proc_ctxt(ps_proc, 0);
862             }
863 
864             if(ps_codec->s_fmt_conv.i4_num_rows < 0)
865                 ps_codec->s_fmt_conv.i4_num_rows = 0;
866 
867             ret = ihevcd_fmt_conv(ps_codec, ps_proc,
868                                   ps_dec_ip->s_out_buffer.pu1_bufs[0],
869                                   ps_dec_ip->s_out_buffer.pu1_bufs[1],
870                                   ps_dec_ip->s_out_buffer.pu1_bufs[2],
871                                   ps_codec->s_fmt_conv.i4_cur_row,
872                                   ps_codec->s_fmt_conv.i4_num_rows);
873             ps_codec->s_fmt_conv.i4_cur_row += ps_codec->s_fmt_conv.i4_num_rows;
874 
875         }
876 
877 
878         DEBUG_DUMP_MV_MAP(ps_codec);
879 
880         /* Mark MV Buf as needed for reference */
881         ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_mv_buf_mgr,
882                                  ps_codec->as_process[proc_idx].i4_cur_mv_bank_buf_id,
883                                  BUF_MGR_REF);
884 
885         /* Mark pic buf as needed for reference */
886         ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
887                                  ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
888                                  BUF_MGR_REF);
889 
890         /* Mark pic buf as needed for display */
891         ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
892                                  ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
893                                  BUF_MGR_DISP);
894 
895         /* Insert the current picture as short term reference */
896         ihevc_dpb_mgr_insert_ref((dpb_mgr_t *)ps_codec->pv_dpb_mgr,
897                                  ps_codec->as_process[proc_idx].ps_cur_pic,
898                                  ps_codec->as_process[proc_idx].i4_cur_pic_buf_id);
899 
900         /* If a frame was displayed (in non-shared mode), then release it from display manager */
901         if((0 == ps_codec->i4_share_disp_buf) && (ps_codec->ps_disp_buf))
902             ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
903                                   ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
904 
905         /* Wait for threads */
906         for(i = 0; i < (ps_codec->i4_num_cores - 1); i++)
907         {
908             if(ps_codec->ai4_process_thread_created[i])
909             {
910 #ifdef KEEP_THREADS_ACTIVE
911                 ret = ithread_mutex_lock(ps_codec->apv_proc_done_mutex[i]);
912                 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
913 
914                 while(!ps_codec->ai4_process_done[i])
915                 {
916                     ithread_cond_wait(ps_codec->apv_proc_done_condition[i],
917                                       ps_codec->apv_proc_done_mutex[i]);
918                 }
919                 ps_codec->ai4_process_done[i] = 0;
920                 ret = ithread_mutex_unlock(ps_codec->apv_proc_done_mutex[i]);
921                 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
922 #else
923                 ithread_join(ps_codec->apv_process_thread_handle[i], NULL);
924                 ps_codec->ai4_process_thread_created[i] = 0;
925 #endif
926             }
927         }
928 
929         DEBUG_VALIDATE_PADDED_REGION(&ps_codec->as_process[proc_idx]);
930         if(ps_codec->u4_pic_cnt > 0)
931         {
932             DEBUG_DUMP_PIC_PU(ps_codec);
933         }
934         DEBUG_DUMP_PIC_BUFFERS(ps_codec);
935 
936         /* Increment the number of pictures decoded */
937         ps_codec->u4_pic_cnt++;
938     }
939     ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op);
940 
941     if(1 == ps_dec_op->u4_output_present)
942     {
943         WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
944         WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
945 
946         if(ypos < 0)
947             ypos = 0;
948 
949         if(xpos < 0)
950             xpos = 0;
951 
952         INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
953                     ps_dec_ip->s_out_buffer.pu1_bufs[1],
954                     ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
955                     xpos,
956                     ypos,
957                     ps_codec->e_chroma_fmt,
958                     ps_codec->i4_disp_wd,
959                     ps_codec->i4_disp_ht);
960     }
961 
962 
963     return ret;
964 }
965 
966