Home | History | Annotate | Download | only in parser
      1 /* ///////////////////////////////////////////////////////////////////////
      2 //
      3 //               INTEL CORPORATION PROPRIETARY INFORMATION
      4 //  This software is supplied under the terms of a license agreement or
      5 //  nondisclosure agreement with Intel Corporation and may not be copied
      6 //  or disclosed except in accordance with the terms of that agreement.
      7 //        Copyright (c) 2001-2006 Intel Corporation. All Rights Reserved.
      8 //
      9 //  Description:    h264 bistream decoding
     10 //
     11 ///////////////////////////////////////////////////////////////////////*/
     12 
     13 
     14 #include "h264.h"
     15 #include "h264parse.h"
     16 #include "viddec_parser_ops.h"
     17 
     18 
     19 
     20 
     21 
     22 /**
     23    get_codeNum     :Get codenum based on sec 9.1 of H264 spec.
     24    @param      cxt : Buffer adress & size are part inputs, the cxt is updated
     25                      with codeNum & sign on sucess.
     26                      Assumption: codeNum is a max of 32 bits
     27 
     28    @retval       1 : Sucessfuly found a code num, cxt is updated with codeNum, sign, and size of code.
     29    @retval       0 : Couldn't find a code in the current buffer.
     30    be freed.
     31 */
     32 
     33 uint32_t h264_get_codeNum(void *parent, h264_Info* pInfo)
     34 {
     35    int32_t    leadingZeroBits= 0;
     36    uint32_t    temp = 0, match = 0, noOfBits = 0, count = 0;
     37    uint32_t   codeNum =0;
     38    uint32_t   bits_offset =0, byte_offset =0;
     39    uint8_t    is_emul =0;
     40    uint8_t    is_first_byte = 1;
     41    uint32_t   length =0;
     42    uint32_t   bits_need_add_in_first_byte =0;
     43    int32_t    bits_operation_result=0;
     44 
     45    //remove warning
     46    pInfo = pInfo;
     47 
     48    ////// Step 1: parse through zero bits until we find a bit with value 1.
     49    viddec_pm_get_au_pos(parent, &bits_offset, &byte_offset, &is_emul);
     50 
     51 
     52    while(!match)
     53    {
     54        if ((bits_offset != 0) && ( is_first_byte == 1))
     55        {
     56            //we handle byte at a time, if we have offset then for first
     57            //   byte handle only 8 - offset bits
     58            noOfBits = (uint8_t)(8 - bits_offset);
     59            bits_operation_result = viddec_pm_peek_bits(parent, &temp, noOfBits);
     60 
     61 
     62            temp = (temp << bits_offset);
     63            if(temp!=0)
     64            {
     65               bits_need_add_in_first_byte = bits_offset;
     66            }
     67            is_first_byte =0;
     68        }
     69        else
     70        {
     71            noOfBits = 8;/* always 8 bits as we read a byte at a time */
     72            bits_operation_result = viddec_pm_peek_bits(parent, &temp, 8);
     73 
     74        }
     75 
     76 	   if(-1==bits_operation_result)
     77 	   {
     78 	      return MAX_INT32_VALUE;
     79 	   }
     80 
     81        if(temp != 0)
     82        {
     83            // if byte!=0 we have at least one bit with value 1.
     84            count=1;
     85            while(((temp & 0x80) != 0x80) && (count <= noOfBits))
     86            {
     87                count++;
     88                temp = temp <<1;
     89            }
     90            //At this point we get the bit position of 1 in current byte(count).
     91 
     92            match = 1;
     93            leadingZeroBits += count;
     94        }
     95        else
     96        {
     97            // we don't have a 1 in current byte
     98            leadingZeroBits += noOfBits;
     99        }
    100 
    101        if(!match)
    102        {
    103            //actually move the bitoff by viddec_pm_get_bits
    104            viddec_pm_get_bits(parent, &temp, noOfBits);
    105        }
    106        else
    107        {
    108            //actually move the bitoff by viddec_pm_get_bits
    109            viddec_pm_get_bits(parent, &temp, count);
    110        }
    111 
    112    }
    113    ////// step 2: Now read the next (leadingZeroBits-1) bits to get the encoded value.
    114 
    115 
    116    if(match)
    117    {
    118 
    119        viddec_pm_get_au_pos(parent, &bits_offset, &byte_offset, &is_emul);
    120        /* bit position in current byte */
    121        //count = (uint8_t)((leadingZeroBits + bits_offset)& 0x7);
    122        count = ((count + bits_need_add_in_first_byte)& 0x7);
    123 
    124        leadingZeroBits --;
    125        length =  leadingZeroBits;
    126        codeNum = 0;
    127        noOfBits = 8 - count;
    128 
    129 
    130        while(leadingZeroBits > 0)
    131        {
    132            if(noOfBits < (uint32_t)leadingZeroBits)
    133            {
    134                viddec_pm_get_bits(parent, &temp, noOfBits);
    135 
    136 
    137                codeNum = (codeNum << noOfBits) | temp;
    138                leadingZeroBits -= noOfBits;
    139            }
    140            else
    141            {
    142                viddec_pm_get_bits(parent, &temp, leadingZeroBits);
    143 
    144                codeNum = (codeNum << leadingZeroBits) | temp;
    145                leadingZeroBits = 0;
    146            }
    147 
    148 
    149            noOfBits = 8;
    150        }
    151        // update codeNum = 2 ** (leadingZeroBits) -1 + read_bits(leadingZeroBits).
    152        codeNum = codeNum + (1 << length) -1;
    153 
    154     }
    155 
    156     viddec_pm_get_au_pos(parent, &bits_offset, &byte_offset, &is_emul);
    157     if(bits_offset!=0)
    158     {
    159       viddec_pm_peek_bits(parent, &temp, 8-bits_offset);
    160     }
    161 
    162     return codeNum;
    163 }
    164 
    165 
    166 /*---------------------------------------*/
    167 /*---------------------------------------*/
    168 int32_t h264_GetVLCElement(void *parent, h264_Info* pInfo, uint8_t bIsSigned)
    169 {
    170 	int32_t sval = 0;
    171 	signed char sign;
    172 
    173 	sval = h264_get_codeNum(parent , pInfo);
    174 
    175  	if(bIsSigned)  //get signed integer golomb code else the value is unsigned
    176 	{
    177 	  sign = (sval & 0x1)?1:-1;
    178 	  sval = (sval +1) >> 1;
    179 	  sval = sval * sign;
    180 	}
    181 
    182 	return sval;
    183 } // Ipp32s H264Bitstream::GetVLCElement(bool bIsSigned)
    184 
    185 ///
    186 /// Check whether more RBSP data left in current NAL
    187 ///
    188 uint8_t h264_More_RBSP_Data(void *parent, h264_Info * pInfo)
    189 {
    190 	uint8_t cnt = 0;
    191 
    192 	uint8_t  is_emul =0;
    193 	uint8_t 	cur_byte = 0;
    194 	int32_t  shift_bits =0;
    195 	uint32_t ctr_bit = 0;
    196 	uint32_t bits_offset =0, byte_offset =0;
    197 
    198    //remove warning
    199    pInfo = pInfo;
    200 
    201 	if (!viddec_pm_is_nomoredata(parent))
    202 		return 1;
    203 
    204 	viddec_pm_get_au_pos(parent, &bits_offset, &byte_offset, &is_emul);
    205 
    206 	shift_bits = 7-bits_offset;
    207 
    208 	// read one byte
    209 	viddec_pm_get_cur_byte(parent, &cur_byte);
    210 
    211 	ctr_bit = ((cur_byte)>> (shift_bits--)) & 0x01;
    212 
    213 	// a stop bit has to be one
    214 	if (ctr_bit==0)
    215 		return 1;
    216 
    217 	while (shift_bits>=0 && !cnt)
    218 	{
    219 		cnt |= (((cur_byte)>> (shift_bits--)) & 0x01);   // set up control bit
    220 	}
    221 
    222    return (cnt);
    223 }
    224 
    225 
    226 
    227 ///////////// EOF/////////////////////
    228 
    229