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