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 (byte != 0)
107        {
108            *write_pnt++ = byte;
109            stream->write_pos++;
110            stream->count_zeros = 0;
111        }
112        else
113        {
114            stream->count_zeros++;
115            *write_pnt++ = byte;
116            stream->write_pos++;
117            if (stream->count_zeros == 2)
118            {   /* for num_bits = 32, this can add 2 more bytes extra for EPBS */
119                *write_pnt++ = 0x3;
120                stream->write_pos++;
121                stream->count_zeros = 0;
122            }
123        }
124    }
125
126    /* reset current_word and bit_left */
127    stream->current_word = 0;
128    stream->bit_left = WORD_SIZE;
129
130    return AVCENC_SUCCESS;
131}
132
133/* ======================================================================== */
134/*  Function : BitstreamWriteBits()                                         */
135/*  Date     : 3/29/2004                                                    */
136/*  Purpose  : Write up to machine word.                                    */
137/*  In/out   : Unused bits in 'code' must be all zeros.                     */
138/*  Return   : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is  */
139/*              full.                                                       */
140/*  Modified :                                                              */
141/* ======================================================================== */
142AVCEnc_Status BitstreamWriteBits(AVCEncBitstream *stream, int nBits, uint code)
143{
144    AVCEnc_Status status = AVCENC_SUCCESS;
145    int bit_left = stream->bit_left;
146    uint current_word = stream->current_word;
147
148    //DEBUG_LOG(userData,AVC_LOGTYPE_INFO,"BitstreamWriteBits",nBits,-1);
149
150    if (nBits > WORD_SIZE) /* has to be taken care of specially */
151    {
152        return AVCENC_FAIL; /* for now */
153        /* otherwise, break it down to 2 write of less than 16 bits at a time. */
154    }
155
156    if (nBits <= bit_left) /* more bits left in current_word */
157    {
158        stream->current_word = (current_word << nBits) | code;
159        stream->bit_left -= nBits;
160        if (stream->bit_left == 0) /* prepare for the next word */
161        {
162            status = AVCBitstreamSaveWord(stream);
163            return status;
164        }
165    }
166    else
167    {
168        stream->current_word = (current_word << bit_left) | (code >> (nBits - bit_left));
169
170        nBits -= bit_left;
171
172        stream->bit_left = 0;
173
174        status = AVCBitstreamSaveWord(stream); /* save current word */
175
176        stream->bit_left = WORD_SIZE - nBits;
177
178        stream->current_word = code; /* no extra masking for code, must be handled before saving */
179    }
180
181    return status;
182}
183
184
185/* ======================================================================== */
186/*  Function : BitstreamWrite1Bit()                                         */
187/*  Date     : 3/30/2004                                                    */
188/*  Purpose  : Write 1 bit                                                  */
189/*  In/out   : Unused bits in 'code' must be all zeros.                     */
190/*  Return   : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is  */
191/*              full.                                                       */
192/*  Modified :                                                              */
193/* ======================================================================== */
194AVCEnc_Status BitstreamWrite1Bit(AVCEncBitstream *stream, uint code)
195{
196    AVCEnc_Status status;
197    uint current_word = stream->current_word;
198
199    //DEBUG_LOG(userData,AVC_LOGTYPE_INFO,"BitstreamWrite1Bit",code,-1);
200
201    //if(1 <= bit_left) /* more bits left in current_word */
202    /* we can assume that there always be positive bit_left in the current word */
203    stream->current_word = (current_word << 1) | code;
204    stream->bit_left--;
205    if (stream->bit_left == 0) /* prepare for the next word */
206    {
207        status = AVCBitstreamSaveWord(stream);
208        return status;
209    }
210
211    return AVCENC_SUCCESS;
212}
213
214
215/* ======================================================================== */
216/*  Function : BitstreamTrailingBits()                                      */
217/*  Date     : 3/31/2004                                                    */
218/*  Purpose  : Add trailing bits and report the final EBSP size.            */
219/*  In/out   :                                                              */
220/*  Return   : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is  */
221/*              full.                                                       */
222/*  Modified :                                                              */
223/* ======================================================================== */
224AVCEnc_Status BitstreamTrailingBits(AVCEncBitstream *bitstream, uint *nal_size)
225{
226    (void)(nal_size);
227
228    AVCEnc_Status status;
229    int bit_left = bitstream->bit_left;
230
231    bit_left &= 0x7; /* modulo by 8 */
232    if (bit_left == 0) bit_left = 8;
233    /* bitstream->bit_left == 0 cannot happen here since it would have been Saved already */
234
235    status = BitstreamWriteBits(bitstream, bit_left, trailing_bits[bit_left]);
236
237    if (status != AVCENC_SUCCESS)
238    {
239        return status;
240    }
241
242    /* if it's not saved, save it. */
243    //if(bitstream->bit_left<(WORD_SIZE<<3)) /* in fact, no need to check */
244    {
245        status = AVCBitstreamSaveWord(bitstream);
246    }
247
248    return status;
249}
250
251/* check whether it's byte-aligned */
252bool byte_aligned(AVCEncBitstream *stream)
253{
254    if (stream->bit_left % 8)
255        return false;
256    else
257        return true;
258}
259
260
261/* determine whether overrun buffer can be used or not */
262AVCEnc_Status AVCBitstreamUseOverrunBuffer(AVCEncBitstream* stream, int numExtraBytes)
263{
264    AVCEncObject *encvid = (AVCEncObject*)stream->encvid;
265
266    if (stream->overrunBuffer != NULL) // overrunBuffer is set
267    {
268        if (stream->bitstreamBuffer != stream->overrunBuffer) // not already used
269        {
270            if (stream->write_pos + numExtraBytes >= stream->oBSize)
271            {
272                stream->oBSize = stream->write_pos + numExtraBytes + 100;
273                stream->oBSize &= (~0x3); // make it multiple of 4
274
275                // allocate new overrun Buffer
276                if (encvid->overrunBuffer)
277                {
278                    encvid->avcHandle->CBAVC_Free(encvid->avcHandle->userData,
279                                                  encvid->overrunBuffer);
280                }
281
282                encvid->oBSize = stream->oBSize;
283                encvid->overrunBuffer = (uint8*) encvid->avcHandle->CBAVC_Malloc(encvid->avcHandle->userData,
284                                        stream->oBSize, DEFAULT_ATTR);
285
286                stream->overrunBuffer = encvid->overrunBuffer;
287                if (stream->overrunBuffer == NULL)
288                {
289                    return AVCENC_FAIL;
290                }
291            }
292
293            // copy everything to overrun buffer and start using it.
294            memcpy(stream->overrunBuffer, stream->bitstreamBuffer, stream->write_pos);
295            stream->bitstreamBuffer = stream->overrunBuffer;
296            stream->buf_size = stream->oBSize;
297        }
298        else // overrun buffer is already used
299        {
300            stream->oBSize = stream->write_pos + numExtraBytes + 100;
301            stream->oBSize &= (~0x3); // make it multiple of 4
302
303            // allocate new overrun buffer
304            encvid->oBSize = stream->oBSize;
305            encvid->overrunBuffer = (uint8*) encvid->avcHandle->CBAVC_Malloc(encvid->avcHandle->userData,
306                                    stream->oBSize, DEFAULT_ATTR);
307
308            if (encvid->overrunBuffer == NULL)
309            {
310                return AVCENC_FAIL;
311            }
312
313
314            // copy from the old buffer to new buffer
315            memcpy(encvid->overrunBuffer, stream->overrunBuffer, stream->write_pos);
316            // free old buffer
317            encvid->avcHandle->CBAVC_Free(encvid->avcHandle->userData,
318                                          stream->overrunBuffer);
319
320            // assign pointer to new buffer
321            stream->overrunBuffer = encvid->overrunBuffer;
322            stream->bitstreamBuffer = stream->overrunBuffer;
323            stream->buf_size = stream->oBSize;
324        }
325
326        return AVCENC_SUCCESS;
327    }
328    else // overrunBuffer is not enable.
329    {
330        return AVCENC_FAIL;
331    }
332
333}
334
335
336
337