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_nal.c
     22 *
     23 * @brief
     24 *  Contains functions for NAL level such as search start code etc
     25 *
     26 * @author
     27 *  Harish
     28 *
     29 * @par List of Functions:
     30 *
     31 * @remarks
     32 *  None
     33 *
     34 *******************************************************************************
     35 */
     36 /*****************************************************************************/
     37 /* File Includes                                                             */
     38 /*****************************************************************************/
     39 #include <stdio.h>
     40 #include <stddef.h>
     41 #include <stdlib.h>
     42 #include <string.h>
     43 #include <assert.h>
     44 
     45 #include "ihevc_typedefs.h"
     46 #include "iv.h"
     47 #include "ivd.h"
     48 #include "ihevcd_cxa.h"
     49 
     50 #include "ihevc_defs.h"
     51 #include "ihevc_debug.h"
     52 #include "ihevc_structs.h"
     53 #include "ihevc_macros.h"
     54 #include "ihevc_platform_macros.h"
     55 #include "ihevc_cabac_tables.h"
     56 
     57 
     58 #include "ihevcd_defs.h"
     59 #include "ihevcd_function_selector.h"
     60 #include "ihevcd_structs.h"
     61 #include "ihevcd_error.h"
     62 #include "ihevcd_nal.h"
     63 #include "ihevcd_bitstream.h"
     64 #include "ihevcd_parse_headers.h"
     65 #include "ihevcd_parse_slice.h"
     66 #include "ihevcd_debug.h"
     67 /*****************************************************************************/
     68 /* Function Prototypes                                                       */
     69 /*****************************************************************************/
     70 
     71 /**
     72 *******************************************************************************
     73 *
     74 * @brief
     75 *  Search start code from the given buffer pointer
     76 *
     77 * @par Description:
     78 *  Search for start code  Return the offset of start code if start code is
     79 * found  If no start code is found till end of given bitstream  then treat
     80 * it as invalid NAL and return end of buffer as  offset
     81 *
     82 * @param[in] pu1_buf
     83 *  Pointer to bitstream
     84 *
     85 * @param[in] bytes_remaining
     86 *  Number of bytes remaining in the buffer
     87 *
     88 * @returns  Offset to the first byte in NAL after start code
     89 *
     90 * @remarks
     91 *  Incomplete start code at the end of input bitstream is  not handled. This
     92 * has to be taken care outside this func
     93 *
     94 *******************************************************************************
     95 */
     96 WORD32 ihevcd_nal_search_start_code(UWORD8 *pu1_buf, WORD32 bytes_remaining)
     97 {
     98     WORD32 ofst;
     99 
    100     WORD32 zero_byte_cnt;
    101     WORD32 start_code_found;
    102 
    103     ofst = -1;
    104 
    105     zero_byte_cnt = 0;
    106     start_code_found = 0;
    107     while(ofst < (bytes_remaining - 1))
    108     {
    109         ofst++;
    110         if(pu1_buf[ofst] != 0)
    111         {
    112             zero_byte_cnt = 0;
    113             continue;
    114         }
    115 
    116         zero_byte_cnt++;
    117         if((ofst < (bytes_remaining - 1)) &&
    118            (pu1_buf[ofst + 1] == START_CODE_PREFIX_BYTE) &&
    119            (zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE))
    120         {
    121             /* Found the start code */
    122             ofst++;
    123             start_code_found = 1;
    124             break;
    125         }
    126     }
    127     if((0 == start_code_found) && (ofst < bytes_remaining))
    128     {
    129         if((START_CODE_PREFIX_BYTE == pu1_buf[ofst]) &&
    130            (zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE))
    131         {
    132             /* Found a start code at the end*/
    133             ofst++;
    134         }
    135     }
    136     /* Since ofst started at -1, increment it by 1 */
    137     ofst++;
    138 
    139     return ofst;
    140 }
    141 
    142 /**
    143 *******************************************************************************
    144 *
    145 * @brief
    146 *  Remove emulation prevention byte present in the bitstream till next start
    147 * code is found. Emulation prevention byte  removed data is stored in a
    148 * different buffer
    149 *
    150 * @par Description:
    151 *  Assumption is first start code is already found and  pu1_buf is pointing
    152 * to a byte after the start code  Search for Next NAL's start code  Return
    153 * if start code is found  Remove any emulation prevention byte present  Copy
    154 * data to new buffer  If no start code is found, then treat complete buffer
    155 * as  one nal.
    156 *
    157 * @param[in] pu1_src
    158 *  Pointer to bitstream (excludes the initial the start code)
    159 *
    160 * @param[in] pu1_dst
    161 *  Pointer to destination buffer
    162 *
    163 * @param[in] bytes_remaining
    164 *  Number of bytes remaining
    165 *
    166 * @param[out] pi4_nal_len
    167 *  NAL length (length of bitstream parsed)
    168 *
    169 * @param[out] pi4_dst_len
    170 *  Destination bitstream size (length of bitstream parsed with emulation bytes
    171 * removed)
    172 *
    173 * @returns Error code from IHEVCD_ERROR_T
    174 *
    175 * @remarks
    176 *  Incomplete start code at the end of input bitstream is  not handled. This
    177 * has to be taken care outside this func
    178 *
    179 *******************************************************************************
    180 */
    181 IHEVCD_ERROR_T ihevcd_nal_remv_emuln_bytes(UWORD8 *pu1_src,
    182                                            UWORD8 *pu1_dst,
    183                                            WORD32 bytes_remaining,
    184                                            WORD32 *pi4_nal_len,
    185                                            WORD32 *pi4_dst_len)
    186 {
    187     WORD32 src_cnt;
    188     WORD32 dst_cnt;
    189     WORD32 zero_byte_cnt;
    190     WORD32 start_code_found;
    191     UWORD8 u1_src;
    192     IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    193 
    194     src_cnt = 0;
    195     dst_cnt = 0;
    196     zero_byte_cnt = 0;
    197     start_code_found = 0;
    198     while(src_cnt < (bytes_remaining - 1))
    199     {
    200         u1_src = pu1_src[src_cnt++];
    201 
    202         pu1_dst[dst_cnt++] = u1_src;
    203         if(u1_src != 0)
    204         {
    205             zero_byte_cnt = 0;
    206             continue;
    207         }
    208 
    209         zero_byte_cnt++;
    210         if(zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE)
    211         {
    212             u1_src = pu1_src[src_cnt];
    213             if(START_CODE_PREFIX_BYTE == u1_src)
    214             {
    215                 /* Found the start code */
    216                 src_cnt -= zero_byte_cnt;
    217                 dst_cnt -= zero_byte_cnt;
    218                 start_code_found = 1;
    219                 break;
    220             }
    221             else if(EMULATION_PREVENT_BYTE == u1_src)
    222             {
    223                 /* Found the emulation prevention byte */
    224                 src_cnt++;
    225                 zero_byte_cnt = 0;
    226 
    227                 /* Decrement dst_cnt so that the next byte overwrites
    228                  * the emulation prevention byte already copied to dst above
    229                  */
    230             }
    231         }
    232 
    233     }
    234 
    235     if((0 == start_code_found) && (src_cnt < bytes_remaining))
    236     {
    237         u1_src = pu1_src[src_cnt++];
    238         if(zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE)
    239         {
    240 
    241             if(START_CODE_PREFIX_BYTE == u1_src)
    242             {
    243                 /* Found a start code at the end*/
    244                 src_cnt -= zero_byte_cnt;
    245             }
    246             else if(EMULATION_PREVENT_BYTE == u1_src)
    247             {
    248                 /* Found the emulation prevention byte at the end*/
    249                 src_cnt++;
    250                 /* Decrement dst_cnt so that the next byte overwrites
    251                  * the emulation prevention byte already copied to dst above
    252                  */
    253                 dst_cnt--;
    254             }
    255         }
    256         else
    257         {
    258             pu1_dst[dst_cnt++] = u1_src;
    259         }
    260 
    261 
    262     }
    263     *pi4_nal_len = src_cnt;
    264     *pi4_dst_len = dst_cnt;
    265     return ret;
    266 }
    267 /**
    268 *******************************************************************************
    269 *
    270 * @brief
    271 *  Decode given NAL unit's header
    272 *
    273 * @par Description:
    274 *  Call NAL unit's header decode  Section: 7.3.1.2
    275 *
    276 * @param[in] ps_bitstrm
    277 *  Pointer to bitstream context
    278 *
    279 * @param[out] ps_nal
    280 *  Pointer to NAL header
    281 *
    282 * @returns Error code from IHEVCD_ERROR_T
    283 *
    284 * @remarks
    285 *
    286 *
    287 *******************************************************************************
    288 */
    289 IHEVCD_ERROR_T ihevcd_nal_unit_header(bitstrm_t *ps_bitstrm, nal_header_t *ps_nal)
    290 {
    291     WORD32 unused;
    292     IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    293     UNUSED(unused);
    294     /* Syntax : forbidden_zero_bit */
    295     unused = ihevcd_bits_get(ps_bitstrm, 1);
    296 
    297     /* Syntax : nal_unit_type */
    298     ps_nal->i1_nal_unit_type = ihevcd_bits_get(ps_bitstrm, 6);
    299 
    300     /* Syntax : nuh_reserved_zero_6bits */
    301     unused = ihevcd_bits_get(ps_bitstrm, 6);
    302 
    303     /* Syntax : nuh_temporal_id_plus1 */
    304     ps_nal->i1_nuh_temporal_id = ihevcd_bits_get(ps_bitstrm, 3) - 1;
    305 
    306     return ret;
    307 
    308 }
    309 
    310 /**
    311 *******************************************************************************
    312 *
    313 * @brief
    314 *  Decode given NAL
    315 *
    316 * @par Description:
    317 *  Based on the NAL type call appropriate decode function  Section: 7.3.1.1
    318 *
    319 *
    320 * @param[in,out] ps_codec
    321 *  Pointer to codec context (Functions called within will modify contents of
    322 * ps_codec)
    323 *
    324 * @returns Error code from IHEVCD_ERROR_T
    325 *
    326 * @remarks
    327 *
    328 *
    329 *******************************************************************************
    330 */
    331 IHEVCD_ERROR_T ihevcd_nal_unit(codec_t *ps_codec)
    332 {
    333     IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    334 
    335     /* NAL Header */
    336     nal_header_t s_nal;
    337 
    338     ret = ihevcd_nal_unit_header(&ps_codec->s_parse.s_bitstrm, &s_nal);
    339     RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
    340 
    341     if(ps_codec->i4_slice_error)
    342         s_nal.i1_nal_unit_type = ps_codec->s_parse.ps_slice_hdr->i1_nal_unit_type;
    343 
    344     /* Setting RASL Output flag */
    345     switch(s_nal.i1_nal_unit_type)
    346     {
    347         case NAL_BLA_W_LP    :
    348         case NAL_BLA_W_DLP   :
    349         case NAL_BLA_N_LP    :
    350             ps_codec->i4_rasl_output_flag = 0;
    351             break;
    352 
    353         //TODO: After IDR, there is no case of open GOP
    354         //To be fixed appropriately by ignoring RASL only if the
    355         // required references are not found
    356         case NAL_IDR_W_LP    :
    357         case NAL_IDR_N_LP    :
    358             ps_codec->i4_rasl_output_flag = 1;
    359             break;
    360 
    361         case NAL_CRA         :
    362             ps_codec->i4_rasl_output_flag = (0 != ps_codec->i4_cra_as_first_pic) ? 0 : 1;
    363             break;
    364 
    365         default:
    366             break;
    367     }
    368 
    369     switch(s_nal.i1_nal_unit_type)
    370     {
    371         case NAL_BLA_W_LP    :
    372         case NAL_BLA_W_DLP   :
    373         case NAL_BLA_N_LP    :
    374         case NAL_IDR_W_LP    :
    375         case NAL_IDR_N_LP    :
    376         case NAL_CRA         :
    377         case NAL_TRAIL_N     :
    378         case NAL_TRAIL_R     :
    379         case NAL_TSA_N       :
    380         case NAL_TSA_R       :
    381         case NAL_STSA_N      :
    382         case NAL_STSA_R      :
    383         case NAL_RADL_N      :
    384         case NAL_RADL_R      :
    385         case NAL_RASL_N      :
    386         case NAL_RASL_R      :
    387             if(ps_codec->i4_header_mode)
    388                 return IHEVCD_SLICE_IN_HEADER_MODE;
    389 
    390             if((0 == ps_codec->i4_sps_done) ||
    391                             (0 == ps_codec->i4_pps_done))
    392             {
    393                 return IHEVCD_INVALID_HEADER;
    394             }
    395 
    396             ps_codec->i4_header_in_slice_mode = 0;
    397             ps_codec->i4_cra_as_first_pic = 0;
    398 
    399             ret = ihevcd_parse_slice_header(ps_codec, &s_nal);
    400             DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type);
    401             if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
    402             {
    403                 if((s_nal.i1_nal_unit_type != NAL_RASL_N && s_nal.i1_nal_unit_type != NAL_RASL_R) ||
    404                                 ps_codec->i4_rasl_output_flag ||
    405                                 ps_codec->i4_slice_error)
    406                     ret = ihevcd_parse_slice_data(ps_codec);
    407             }
    408             break;
    409 
    410         case NAL_VPS        :
    411             // ret = ihevcd_parse_vps(ps_codec);
    412             DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type);
    413             break;
    414 
    415         case NAL_SPS        :
    416             if(0 == ps_codec->i4_header_mode)
    417             {
    418                 ps_codec->i4_header_in_slice_mode = 1;
    419                 if(ps_codec->i4_sps_done &&
    420                                 ps_codec->i4_pic_present)
    421                     break;
    422             }
    423 
    424             ret = ihevcd_parse_sps(ps_codec);
    425             if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
    426             {
    427                 sps_t *ps_sps = ps_codec->ps_sps_base + MAX_SPS_CNT - 1;
    428                 ihevcd_copy_sps(ps_codec, ps_sps->i1_sps_id, MAX_SPS_CNT - 1);
    429             }
    430             ps_codec->i4_error_code = ret;
    431 
    432             DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type);
    433             break;
    434 
    435         case NAL_PPS        :
    436             if(0 == ps_codec->i4_header_mode)
    437             {
    438                 ps_codec->i4_header_in_slice_mode = 1;
    439                 if(ps_codec->i4_pps_done &&
    440                                 ps_codec->i4_pic_present)
    441                     break;
    442             }
    443 
    444             ret = ihevcd_parse_pps(ps_codec);
    445             if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
    446             {
    447                 pps_t *ps_pps = ps_codec->ps_pps_base + MAX_PPS_CNT - 1;
    448                 ihevcd_copy_pps(ps_codec, ps_pps->i1_pps_id, MAX_PPS_CNT - 1);
    449             }
    450             ps_codec->i4_error_code = ret;
    451             DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type);
    452             break;
    453 
    454         case NAL_PREFIX_SEI:
    455         case NAL_SUFFIX_SEI:
    456             if(IVD_DECODE_HEADER == ps_codec->i4_header_mode)
    457             {
    458                 return IHEVCD_SLICE_IN_HEADER_MODE;
    459             }
    460 
    461             ret = ihevcd_parse_sei(ps_codec, &s_nal);
    462             break;
    463 
    464         case NAL_EOS        :
    465             ps_codec->i4_cra_as_first_pic = 1;
    466             break;
    467 
    468         default:
    469             DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type);
    470             break;
    471     }
    472 
    473     return ret;
    474 }
    475 
    476