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