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_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  */
    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  */
    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  */
    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         {
    461             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
    462             ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
    463             return IV_FAIL;
    464         }
    465 
    466         for(i = 0; i < ps_dec_ip->s_out_buffer.u4_num_bufs; i++)
    467         {
    468             if(ps_dec_ip->s_out_buffer.pu1_bufs[i] == NULL)
    469             {
    470                 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
    471                 ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL;
    472                 return IV_FAIL;
    473             }
    474 
    475             if(ps_dec_ip->s_out_buffer.u4_min_out_buf_size[i] == 0)
    476             {
    477                 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
    478                 ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
    479                 return IV_FAIL;
    480             }
    481         }
    482     }
    483 
    484     ps_codec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
    485     ps_codec->u4_ts = ps_dec_ip->u4_ts;
    486     if(ps_codec->i4_flush_mode)
    487     {
    488 
    489         ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
    490         ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
    491 
    492         ps_dec_op->u4_new_seq = 0;
    493 
    494         ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get(
    495                         (disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id);
    496         /* In case of non-shared mode, then convert/copy the frame to output buffer */
    497         /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
    498         if((ps_codec->ps_disp_buf)
    499                         && ((0 == ps_codec->i4_share_disp_buf)
    500                                         || (IV_YUV_420P
    501                                                         == ps_codec->e_chroma_fmt)))
    502         {
    503 
    504             process_ctxt_t *ps_proc = &ps_codec->as_process[prev_proc_idx];
    505             if(0 == ps_proc->i4_init_done)
    506             {
    507                 ihevcd_init_proc_ctxt(ps_proc, 0);
    508             }
    509 
    510             /* Output buffer check */
    511             ret = ihevcd_check_out_buf_size(ps_codec);
    512             RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
    513 
    514             /* Set remaining number of rows to be processed */
    515             ret = ihevcd_fmt_conv(ps_codec, &ps_codec->as_process[prev_proc_idx],
    516                                   ps_dec_ip->s_out_buffer.pu1_bufs[0],
    517                                   ps_dec_ip->s_out_buffer.pu1_bufs[1],
    518                                   ps_dec_ip->s_out_buffer.pu1_bufs[2], 0,
    519                                   ps_codec->i4_disp_ht);
    520 
    521             ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
    522                                   ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
    523         }
    524 
    525         ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op);
    526 
    527         if(1 == ps_dec_op->u4_output_present)
    528         {
    529             WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
    530             WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
    531 
    532             if(ypos < 0)
    533                 ypos = 0;
    534 
    535             if(xpos < 0)
    536                 xpos = 0;
    537 
    538             INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
    539                         ps_dec_ip->s_out_buffer.pu1_bufs[1],
    540                         ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
    541                         xpos,
    542                         ypos,
    543                         ps_codec->e_chroma_fmt,
    544                         ps_codec->i4_disp_wd,
    545                         ps_codec->i4_disp_ht);
    546         }
    547 
    548 
    549         if(NULL == ps_codec->ps_disp_buf)
    550         {
    551             /* If in flush mode and there are no more buffers to flush,
    552              * check for the reset flag and reset the decoder */
    553             if(ps_codec->i4_reset_flag)
    554             {
    555                 ihevcd_init(ps_codec);
    556             }
    557             return (IV_FAIL);
    558         }
    559 
    560         return (IV_SUCCESS);
    561 
    562     }
    563     /* In case of shared mode, check if there is a free buffer for reconstruction */
    564     if((0 == ps_codec->i4_header_mode) && (1 == ps_codec->i4_share_disp_buf))
    565     {
    566         WORD32 buf_status;
    567         buf_status = 1;
    568         if(ps_codec->pv_pic_buf_mgr)
    569             buf_status = ihevc_buf_mgr_check_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr);
    570 
    571         /* If there is no free buffer, then return with an error code */
    572         if(0 == buf_status)
    573         {
    574             ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
    575             ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
    576             return IV_FAIL;
    577         }
    578     }
    579     ps_codec->i4_bytes_remaining = ps_dec_ip->u4_num_Bytes;
    580     ps_codec->pu1_inp_bitsbuf = (UWORD8 *)ps_dec_ip->pv_stream_buffer;
    581     ps_codec->s_parse.i4_end_of_frame = 0;
    582 
    583     ps_codec->i4_pic_present = 0;
    584     ps_codec->i4_slice_error = 0;
    585     ps_codec->ps_disp_buf = NULL;
    586 
    587     if(ps_codec->i4_num_cores > 1)
    588     {
    589         ithread_set_affinity(0);
    590     }
    591     while(MIN_START_CODE_LEN < ps_codec->i4_bytes_remaining)
    592     {
    593         WORD32 nal_len;
    594         WORD32 nal_ofst;
    595         WORD32 bits_len;
    596 
    597         if(ps_codec->i4_slice_error)
    598         {
    599             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));
    600             WORD32 next_slice_addr = ps_slice_hdr_next->i2_ctb_x +
    601                             ps_slice_hdr_next->i2_ctb_y * ps_codec->s_parse.ps_sps->i2_pic_wd_in_ctb;
    602             if(ps_codec->s_parse.i4_next_ctb_indx == next_slice_addr)
    603                 ps_codec->i4_slice_error = 0;
    604         }
    605 
    606         if(ps_codec->pu1_bitsbuf_dynamic)
    607         {
    608             ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_dynamic;
    609             ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_dynamic;
    610         }
    611         else
    612         {
    613             ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_static;
    614             ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_static;
    615         }
    616 
    617         nal_ofst = ihevcd_nal_search_start_code(ps_codec->pu1_inp_bitsbuf,
    618                                                 ps_codec->i4_bytes_remaining);
    619 
    620         ps_codec->i4_nal_ofst = nal_ofst;
    621         {
    622             WORD32 bytes_remaining = ps_codec->i4_bytes_remaining - nal_ofst;
    623 
    624             bytes_remaining = MIN((UWORD32)bytes_remaining, ps_codec->u4_bitsbuf_size);
    625             ihevcd_nal_remv_emuln_bytes(ps_codec->pu1_inp_bitsbuf + nal_ofst,
    626                                         ps_codec->pu1_bitsbuf,
    627                                         bytes_remaining,
    628                                         &nal_len, &bits_len);
    629 
    630             /* Decoder may read upto 8 extra bytes at the end of frame */
    631             /* These are not used, but still set them to zero to avoid uninitialized reads */
    632             if(bits_len < (WORD32)(ps_codec->u4_bitsbuf_size - 8))
    633             {
    634                 memset(ps_codec->pu1_bitsbuf + bits_len, 0, 2 * sizeof(UWORD32));
    635             }
    636         }
    637         /* This may be used to update the offsets for tiles and entropy sync row offsets */
    638         ps_codec->i4_num_emln_bytes = nal_len - bits_len;
    639         ps_codec->i4_nal_len = nal_len;
    640 
    641         ihevcd_bits_init(&ps_codec->s_parse.s_bitstrm, ps_codec->pu1_bitsbuf,
    642                          bits_len);
    643 
    644         ret = ihevcd_nal_unit(ps_codec);
    645 
    646         /* If the frame is incomplete and
    647          * the bytes remaining is zero or a header is received,
    648          * complete the frame treating it to be in error */
    649         if(ps_codec->i4_pic_present &&
    650                         (ps_codec->s_parse.i4_next_ctb_indx != ps_codec->s_parse.ps_sps->i4_pic_size_in_ctb))
    651         {
    652             if((ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN) ||
    653                             (ps_codec->i4_header_in_slice_mode))
    654             {
    655                 slice_header_t *ps_slice_hdr_next;
    656 
    657                 ps_codec->s_parse.i4_cur_slice_idx--;
    658                 if(ps_codec->s_parse.i4_cur_slice_idx < 0)
    659                     ps_codec->s_parse.i4_cur_slice_idx = 0;
    660 
    661                 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));
    662                 ps_slice_hdr_next->i2_ctb_x = 0;
    663                 ps_slice_hdr_next->i2_ctb_y = ps_codec->s_parse.ps_sps->i2_pic_ht_in_ctb;
    664                 ps_codec->i4_slice_error = 1;
    665                 continue;
    666             }
    667         }
    668 
    669         if(IHEVCD_IGNORE_SLICE == ret)
    670         {
    671             ps_codec->s_parse.i4_cur_slice_idx = MAX(0, (ps_codec->s_parse.i4_cur_slice_idx - 1));
    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