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
33uint32_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/*---------------------------------------*/
168int32_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///
188uint8_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