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