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 
h264_get_codeNum(void * parent,h264_Info * pInfo)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 /*---------------------------------------*/
h264_GetVLCElement(void * parent,h264_Info * pInfo,uint8_t bIsSigned)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 ///
h264_More_RBSP_Data(void * parent,h264_Info * pInfo)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