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