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