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