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. */
24const 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
45AVCEnc_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/* ======================================================================== */
82AVCEnc_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/* ======================================================================== */
145AVCEnc_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/* ======================================================================== */
197AVCEnc_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/* ======================================================================== */
227AVCEnc_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 */
255bool 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 */
265AVCEnc_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