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