1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 #include "avcenc_lib.h"
19
20 #define WORD_SIZE 32
21
22 /* array for trailing bit pattern as function of number of bits */
23 /* the first one is unused. */
24 const static uint8 trailing_bits[9] = {0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
25
26 /* ======================================================================== */
27 /* Function : BitstreamInit() */
28 /* Date : 11/4/2003 */
29 /* Purpose : Populate bitstream structure with bitstream buffer and size */
30 /* it also initializes internal data */
31 /* In/out : */
32 /* Return : AVCENC_SUCCESS if successed, AVCENC_FAIL if failed. */
33 /* Modified : */
34 /* ======================================================================== */
35 /* |--------|--------|----~~~~~-----|---------|---------|---------|
36 ^ ^write_pos ^buf_size
37 bitstreamBuffer <--------->
38 current_word
39
40 |-----xxxxxxxxxxxxx| = current_word 32 or 16 bits
41 <---->
42 bit_left
43 ======================================================================== */
44
BitstreamEncInit(AVCEncBitstream * stream,uint8 * buffer,int buf_size,uint8 * overrunBuffer,int oBSize)45 AVCEnc_Status BitstreamEncInit(AVCEncBitstream *stream, uint8 *buffer, int buf_size,
46 uint8 *overrunBuffer, int oBSize)
47 {
48 if (stream == NULL || buffer == NULL || buf_size <= 0)
49 {
50 return AVCENC_BITSTREAM_INIT_FAIL;
51 }
52
53 stream->bitstreamBuffer = buffer;
54
55 stream->buf_size = buf_size;
56
57 stream->write_pos = 0;
58
59 stream->count_zeros = 0;
60
61 stream->current_word = 0;
62
63 stream->bit_left = WORD_SIZE;
64
65 stream->overrunBuffer = overrunBuffer;
66
67 stream->oBSize = oBSize;
68
69 return AVCENC_SUCCESS;
70 }
71
72 /* ======================================================================== */
73 /* Function : AVCBitstreamSaveWord() */
74 /* Date : 3/29/2004 */
75 /* Purpose : Save the current_word into the buffer, byte-swap, and */
76 /* add emulation prevention insertion. */
77 /* In/out : */
78 /* Return : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is */
79 /* full. */
80 /* Modified : */
81 /* ======================================================================== */
AVCBitstreamSaveWord(AVCEncBitstream * stream)82 AVCEnc_Status AVCBitstreamSaveWord(AVCEncBitstream *stream)
83 {
84 int num_bits;
85 uint8 *write_pnt, byte;
86 uint current_word;
87
88 /* check number of bytes in current_word, must always be byte-aligned!!!! */
89 num_bits = WORD_SIZE - stream->bit_left; /* must be multiple of 8 !!*/
90
91 if (stream->buf_size - stream->write_pos <= (num_bits >> 3) + 2) /* 2 more bytes for possible EPBS */
92 {
93 if (AVCENC_SUCCESS != AVCBitstreamUseOverrunBuffer(stream, (num_bits >> 3) + 2))
94 {
95 return AVCENC_BITSTREAM_BUFFER_FULL;
96 }
97 }
98
99 /* write word, byte-by-byte */
100 write_pnt = stream->bitstreamBuffer + stream->write_pos;
101 current_word = stream->current_word;
102 while (num_bits) /* no need to check stream->buf_size and stream->write_pos, taken care already */
103 {
104 num_bits -= 8;
105 byte = (current_word >> num_bits) & 0xFF;
106 if (stream->count_zeros == 2)
107 { /* for num_bits = 32, this can add 2 more bytes extra for EPBS */
108 if (byte <= 3)
109 {
110 *write_pnt++ = 0x3;
111 stream->write_pos++;
112 stream->count_zeros = 0;
113 }
114 }
115 if (byte != 0)
116 {
117 *write_pnt++ = byte;
118 stream->write_pos++;
119 stream->count_zeros = 0;
120 }
121 else
122 {
123 stream->count_zeros++;
124 *write_pnt++ = byte;
125 stream->write_pos++;
126 }
127 }
128
129 /* reset current_word and bit_left */
130 stream->current_word = 0;
131 stream->bit_left = WORD_SIZE;
132
133 return AVCENC_SUCCESS;
134 }
135
136 /* ======================================================================== */
137 /* Function : BitstreamWriteBits() */
138 /* Date : 3/29/2004 */
139 /* Purpose : Write up to machine word. */
140 /* In/out : Unused bits in 'code' must be all zeros. */
141 /* Return : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is */
142 /* full. */
143 /* Modified : */
144 /* ======================================================================== */
BitstreamWriteBits(AVCEncBitstream * stream,int nBits,uint code)145 AVCEnc_Status BitstreamWriteBits(AVCEncBitstream *stream, int nBits, uint code)
146 {
147 AVCEnc_Status status = AVCENC_SUCCESS;
148 int bit_left = stream->bit_left;
149 uint current_word = stream->current_word;
150
151 //DEBUG_LOG(userData,AVC_LOGTYPE_INFO,"BitstreamWriteBits",nBits,-1);
152
153 if (nBits > WORD_SIZE) /* has to be taken care of specially */
154 {
155 return AVCENC_FAIL; /* for now */
156 /* otherwise, break it down to 2 write of less than 16 bits at a time. */
157 }
158
159 if (nBits <= bit_left) /* more bits left in current_word */
160 {
161 stream->current_word = (current_word << nBits) | code;
162 stream->bit_left -= nBits;
163 if (stream->bit_left == 0) /* prepare for the next word */
164 {
165 status = AVCBitstreamSaveWord(stream);
166 return status;
167 }
168 }
169 else
170 {
171 stream->current_word = (current_word << bit_left) | (code >> (nBits - bit_left));
172
173 nBits -= bit_left;
174
175 stream->bit_left = 0;
176
177 status = AVCBitstreamSaveWord(stream); /* save current word */
178
179 stream->bit_left = WORD_SIZE - nBits;
180
181 stream->current_word = code; /* no extra masking for code, must be handled before saving */
182 }
183
184 return status;
185 }
186
187
188 /* ======================================================================== */
189 /* Function : BitstreamWrite1Bit() */
190 /* Date : 3/30/2004 */
191 /* Purpose : Write 1 bit */
192 /* In/out : Unused bits in 'code' must be all zeros. */
193 /* Return : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is */
194 /* full. */
195 /* Modified : */
196 /* ======================================================================== */
BitstreamWrite1Bit(AVCEncBitstream * stream,uint code)197 AVCEnc_Status BitstreamWrite1Bit(AVCEncBitstream *stream, uint code)
198 {
199 AVCEnc_Status status;
200 uint current_word = stream->current_word;
201
202 //DEBUG_LOG(userData,AVC_LOGTYPE_INFO,"BitstreamWrite1Bit",code,-1);
203
204 //if(1 <= bit_left) /* more bits left in current_word */
205 /* we can assume that there always be positive bit_left in the current word */
206 stream->current_word = (current_word << 1) | code;
207 stream->bit_left--;
208 if (stream->bit_left == 0) /* prepare for the next word */
209 {
210 status = AVCBitstreamSaveWord(stream);
211 return status;
212 }
213
214 return AVCENC_SUCCESS;
215 }
216
217
218 /* ======================================================================== */
219 /* Function : BitstreamTrailingBits() */
220 /* Date : 3/31/2004 */
221 /* Purpose : Add trailing bits and report the final EBSP size. */
222 /* In/out : */
223 /* Return : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is */
224 /* full. */
225 /* Modified : */
226 /* ======================================================================== */
BitstreamTrailingBits(AVCEncBitstream * bitstream,uint * nal_size)227 AVCEnc_Status BitstreamTrailingBits(AVCEncBitstream *bitstream, uint *nal_size)
228 {
229 (void)(nal_size);
230
231 AVCEnc_Status status;
232 int bit_left = bitstream->bit_left;
233
234 bit_left &= 0x7; /* modulo by 8 */
235 if (bit_left == 0) bit_left = 8;
236 /* bitstream->bit_left == 0 cannot happen here since it would have been Saved already */
237
238 status = BitstreamWriteBits(bitstream, bit_left, trailing_bits[bit_left]);
239
240 if (status != AVCENC_SUCCESS)
241 {
242 return status;
243 }
244
245 /* if it's not saved, save it. */
246 //if(bitstream->bit_left<(WORD_SIZE<<3)) /* in fact, no need to check */
247 {
248 status = AVCBitstreamSaveWord(bitstream);
249 }
250
251 return status;
252 }
253
254 /* check whether it's byte-aligned */
byte_aligned(AVCEncBitstream * stream)255 bool byte_aligned(AVCEncBitstream *stream)
256 {
257 if (stream->bit_left % 8)
258 return false;
259 else
260 return true;
261 }
262
263
264 /* determine whether overrun buffer can be used or not */
AVCBitstreamUseOverrunBuffer(AVCEncBitstream * stream,int numExtraBytes)265 AVCEnc_Status AVCBitstreamUseOverrunBuffer(AVCEncBitstream* stream, int numExtraBytes)
266 {
267 AVCEncObject *encvid = (AVCEncObject*)stream->encvid;
268
269 if (stream->overrunBuffer != NULL) // overrunBuffer is set
270 {
271 if (stream->bitstreamBuffer != stream->overrunBuffer) // not already used
272 {
273 if (stream->write_pos + numExtraBytes >= stream->oBSize)
274 {
275 stream->oBSize = stream->write_pos + numExtraBytes + 100;
276 stream->oBSize &= (~0x3); // make it multiple of 4
277
278 // allocate new overrun Buffer
279 if (encvid->overrunBuffer)
280 {
281 encvid->avcHandle->CBAVC_Free(encvid->avcHandle->userData,
282 encvid->overrunBuffer);
283 }
284
285 encvid->oBSize = stream->oBSize;
286 encvid->overrunBuffer = (uint8*) encvid->avcHandle->CBAVC_Malloc(encvid->avcHandle->userData,
287 stream->oBSize, DEFAULT_ATTR);
288
289 stream->overrunBuffer = encvid->overrunBuffer;
290 if (stream->overrunBuffer == NULL)
291 {
292 return AVCENC_FAIL;
293 }
294 }
295
296 // copy everything to overrun buffer and start using it.
297 memcpy(stream->overrunBuffer, stream->bitstreamBuffer, stream->write_pos);
298 stream->bitstreamBuffer = stream->overrunBuffer;
299 stream->buf_size = stream->oBSize;
300 }
301 else // overrun buffer is already used
302 {
303 stream->oBSize = stream->write_pos + numExtraBytes + 100;
304 stream->oBSize &= (~0x3); // make it multiple of 4
305
306 // allocate new overrun buffer
307 encvid->oBSize = stream->oBSize;
308 encvid->overrunBuffer = (uint8*) encvid->avcHandle->CBAVC_Malloc(encvid->avcHandle->userData,
309 stream->oBSize, DEFAULT_ATTR);
310
311 if (encvid->overrunBuffer == NULL)
312 {
313 return AVCENC_FAIL;
314 }
315
316
317 // copy from the old buffer to new buffer
318 memcpy(encvid->overrunBuffer, stream->overrunBuffer, stream->write_pos);
319 // free old buffer
320 encvid->avcHandle->CBAVC_Free(encvid->avcHandle->userData,
321 stream->overrunBuffer);
322
323 // assign pointer to new buffer
324 stream->overrunBuffer = encvid->overrunBuffer;
325 stream->bitstreamBuffer = stream->overrunBuffer;
326 stream->buf_size = stream->oBSize;
327 }
328
329 return AVCENC_SUCCESS;
330 }
331 else // overrunBuffer is not enable.
332 {
333 return AVCENC_FAIL;
334 }
335
336 }
337
338
339
340