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