129a84457aed4c45bc900998b5e11c03023264208James Dong/* ------------------------------------------------------------------
229a84457aed4c45bc900998b5e11c03023264208James Dong * Copyright (C) 1998-2009 PacketVideo
329a84457aed4c45bc900998b5e11c03023264208James Dong *
429a84457aed4c45bc900998b5e11c03023264208James Dong * Licensed under the Apache License, Version 2.0 (the "License");
529a84457aed4c45bc900998b5e11c03023264208James Dong * you may not use this file except in compliance with the License.
629a84457aed4c45bc900998b5e11c03023264208James Dong * You may obtain a copy of the License at
729a84457aed4c45bc900998b5e11c03023264208James Dong *
829a84457aed4c45bc900998b5e11c03023264208James Dong *      http://www.apache.org/licenses/LICENSE-2.0
929a84457aed4c45bc900998b5e11c03023264208James Dong *
1029a84457aed4c45bc900998b5e11c03023264208James Dong * Unless required by applicable law or agreed to in writing, software
1129a84457aed4c45bc900998b5e11c03023264208James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1229a84457aed4c45bc900998b5e11c03023264208James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
1329a84457aed4c45bc900998b5e11c03023264208James Dong * express or implied.
1429a84457aed4c45bc900998b5e11c03023264208James Dong * See the License for the specific language governing permissions
1529a84457aed4c45bc900998b5e11c03023264208James Dong * and limitations under the License.
1629a84457aed4c45bc900998b5e11c03023264208James Dong * -------------------------------------------------------------------
1729a84457aed4c45bc900998b5e11c03023264208James Dong */
1829a84457aed4c45bc900998b5e11c03023264208James Dong#include "avcenc_lib.h"
1929a84457aed4c45bc900998b5e11c03023264208James Dong
2029a84457aed4c45bc900998b5e11c03023264208James Dong#define WORD_SIZE 32
2129a84457aed4c45bc900998b5e11c03023264208James Dong
2229a84457aed4c45bc900998b5e11c03023264208James Dong/* array for trailing bit pattern as function of number of bits */
2329a84457aed4c45bc900998b5e11c03023264208James Dong/* the first one is unused. */
2429a84457aed4c45bc900998b5e11c03023264208James Dongconst static uint8 trailing_bits[9] = {0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
2529a84457aed4c45bc900998b5e11c03023264208James Dong
2629a84457aed4c45bc900998b5e11c03023264208James Dong/* ======================================================================== */
2729a84457aed4c45bc900998b5e11c03023264208James Dong/*  Function : BitstreamInit()                                              */
2829a84457aed4c45bc900998b5e11c03023264208James Dong/*  Date     : 11/4/2003                                                    */
2929a84457aed4c45bc900998b5e11c03023264208James Dong/*  Purpose  : Populate bitstream structure with bitstream buffer and size  */
3029a84457aed4c45bc900998b5e11c03023264208James Dong/*             it also initializes internal data                            */
3129a84457aed4c45bc900998b5e11c03023264208James Dong/*  In/out   :                                                              */
3229a84457aed4c45bc900998b5e11c03023264208James Dong/*  Return   : AVCENC_SUCCESS if successed, AVCENC_FAIL if failed.              */
3329a84457aed4c45bc900998b5e11c03023264208James Dong/*  Modified :                                                              */
3429a84457aed4c45bc900998b5e11c03023264208James Dong/* ======================================================================== */
3529a84457aed4c45bc900998b5e11c03023264208James Dong/* |--------|--------|----~~~~~-----|---------|---------|---------|
3629a84457aed4c45bc900998b5e11c03023264208James Dong   ^                                          ^write_pos          ^buf_size
3729a84457aed4c45bc900998b5e11c03023264208James Dong   bitstreamBuffer                  <--------->
3829a84457aed4c45bc900998b5e11c03023264208James Dong                                    current_word
3929a84457aed4c45bc900998b5e11c03023264208James Dong
4029a84457aed4c45bc900998b5e11c03023264208James Dong   |-----xxxxxxxxxxxxx|  = current_word 32 or 16 bits
4129a84457aed4c45bc900998b5e11c03023264208James Dong    <---->
4229a84457aed4c45bc900998b5e11c03023264208James Dong     bit_left
4329a84457aed4c45bc900998b5e11c03023264208James Dong ======================================================================== */
4429a84457aed4c45bc900998b5e11c03023264208James Dong
4529a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status BitstreamEncInit(AVCEncBitstream *stream, uint8 *buffer, int buf_size,
4629a84457aed4c45bc900998b5e11c03023264208James Dong                               uint8 *overrunBuffer, int oBSize)
4729a84457aed4c45bc900998b5e11c03023264208James Dong{
4829a84457aed4c45bc900998b5e11c03023264208James Dong    if (stream == NULL || buffer == NULL || buf_size <= 0)
4929a84457aed4c45bc900998b5e11c03023264208James Dong    {
5029a84457aed4c45bc900998b5e11c03023264208James Dong        return AVCENC_BITSTREAM_INIT_FAIL;
5129a84457aed4c45bc900998b5e11c03023264208James Dong    }
5229a84457aed4c45bc900998b5e11c03023264208James Dong
5329a84457aed4c45bc900998b5e11c03023264208James Dong    stream->bitstreamBuffer = buffer;
5429a84457aed4c45bc900998b5e11c03023264208James Dong
5529a84457aed4c45bc900998b5e11c03023264208James Dong    stream->buf_size = buf_size;
5629a84457aed4c45bc900998b5e11c03023264208James Dong
5729a84457aed4c45bc900998b5e11c03023264208James Dong    stream->write_pos = 0;
5829a84457aed4c45bc900998b5e11c03023264208James Dong
5929a84457aed4c45bc900998b5e11c03023264208James Dong    stream->count_zeros = 0;
6029a84457aed4c45bc900998b5e11c03023264208James Dong
6129a84457aed4c45bc900998b5e11c03023264208James Dong    stream->current_word = 0;
6229a84457aed4c45bc900998b5e11c03023264208James Dong
6329a84457aed4c45bc900998b5e11c03023264208James Dong    stream->bit_left = WORD_SIZE;
6429a84457aed4c45bc900998b5e11c03023264208James Dong
6529a84457aed4c45bc900998b5e11c03023264208James Dong    stream->overrunBuffer = overrunBuffer;
6629a84457aed4c45bc900998b5e11c03023264208James Dong
6729a84457aed4c45bc900998b5e11c03023264208James Dong    stream->oBSize = oBSize;
6829a84457aed4c45bc900998b5e11c03023264208James Dong
6929a84457aed4c45bc900998b5e11c03023264208James Dong    return AVCENC_SUCCESS;
7029a84457aed4c45bc900998b5e11c03023264208James Dong}
7129a84457aed4c45bc900998b5e11c03023264208James Dong
7229a84457aed4c45bc900998b5e11c03023264208James Dong/* ======================================================================== */
7329a84457aed4c45bc900998b5e11c03023264208James Dong/*  Function : AVCBitstreamSaveWord()                                           */
7429a84457aed4c45bc900998b5e11c03023264208James Dong/*  Date     : 3/29/2004                                                    */
7529a84457aed4c45bc900998b5e11c03023264208James Dong/*  Purpose  : Save the current_word into the buffer, byte-swap, and        */
7629a84457aed4c45bc900998b5e11c03023264208James Dong/*              add emulation prevention insertion.                         */
7729a84457aed4c45bc900998b5e11c03023264208James Dong/*  In/out   :                                                              */
7829a84457aed4c45bc900998b5e11c03023264208James Dong/*  Return   : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is  */
7929a84457aed4c45bc900998b5e11c03023264208James Dong/*              full.                                                       */
8029a84457aed4c45bc900998b5e11c03023264208James Dong/*  Modified :                                                              */
8129a84457aed4c45bc900998b5e11c03023264208James Dong/* ======================================================================== */
8229a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status AVCBitstreamSaveWord(AVCEncBitstream *stream)
8329a84457aed4c45bc900998b5e11c03023264208James Dong{
8429a84457aed4c45bc900998b5e11c03023264208James Dong    int num_bits;
8529a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *write_pnt, byte;
8629a84457aed4c45bc900998b5e11c03023264208James Dong    uint current_word;
8729a84457aed4c45bc900998b5e11c03023264208James Dong
8829a84457aed4c45bc900998b5e11c03023264208James Dong    /* check number of bytes in current_word, must always be byte-aligned!!!! */
8929a84457aed4c45bc900998b5e11c03023264208James Dong    num_bits = WORD_SIZE - stream->bit_left; /* must be multiple of 8 !!*/
9029a84457aed4c45bc900998b5e11c03023264208James Dong
9129a84457aed4c45bc900998b5e11c03023264208James Dong    if (stream->buf_size - stream->write_pos <= (num_bits >> 3) + 2) /* 2 more bytes for possible EPBS */
9229a84457aed4c45bc900998b5e11c03023264208James Dong    {
9329a84457aed4c45bc900998b5e11c03023264208James Dong        if (AVCENC_SUCCESS != AVCBitstreamUseOverrunBuffer(stream, (num_bits >> 3) + 2))
9429a84457aed4c45bc900998b5e11c03023264208James Dong        {
9529a84457aed4c45bc900998b5e11c03023264208James Dong            return AVCENC_BITSTREAM_BUFFER_FULL;
9629a84457aed4c45bc900998b5e11c03023264208James Dong        }
9729a84457aed4c45bc900998b5e11c03023264208James Dong    }
9829a84457aed4c45bc900998b5e11c03023264208James Dong
9929a84457aed4c45bc900998b5e11c03023264208James Dong    /* write word, byte-by-byte */
10029a84457aed4c45bc900998b5e11c03023264208James Dong    write_pnt = stream->bitstreamBuffer + stream->write_pos;
10129a84457aed4c45bc900998b5e11c03023264208James Dong    current_word = stream->current_word;
10229a84457aed4c45bc900998b5e11c03023264208James Dong    while (num_bits) /* no need to check stream->buf_size and stream->write_pos, taken care already */
10329a84457aed4c45bc900998b5e11c03023264208James Dong    {
10429a84457aed4c45bc900998b5e11c03023264208James Dong        num_bits -= 8;
10529a84457aed4c45bc900998b5e11c03023264208James Dong        byte = (current_word >> num_bits) & 0xFF;
10604ed61b1004282a632cdc1277d93183e15a8df93Martin Storsjo        if (stream->count_zeros == 2)
10704ed61b1004282a632cdc1277d93183e15a8df93Martin Storsjo        {   /* for num_bits = 32, this can add 2 more bytes extra for EPBS */
10804ed61b1004282a632cdc1277d93183e15a8df93Martin Storsjo            if (byte <= 3)
10904ed61b1004282a632cdc1277d93183e15a8df93Martin Storsjo            {
11004ed61b1004282a632cdc1277d93183e15a8df93Martin Storsjo                *write_pnt++ = 0x3;
11104ed61b1004282a632cdc1277d93183e15a8df93Martin Storsjo                stream->write_pos++;
11204ed61b1004282a632cdc1277d93183e15a8df93Martin Storsjo                stream->count_zeros = 0;
11304ed61b1004282a632cdc1277d93183e15a8df93Martin Storsjo            }
11404ed61b1004282a632cdc1277d93183e15a8df93Martin Storsjo        }
11529a84457aed4c45bc900998b5e11c03023264208James Dong        if (byte != 0)
11629a84457aed4c45bc900998b5e11c03023264208James Dong        {
11729a84457aed4c45bc900998b5e11c03023264208James Dong            *write_pnt++ = byte;
11829a84457aed4c45bc900998b5e11c03023264208James Dong            stream->write_pos++;
11929a84457aed4c45bc900998b5e11c03023264208James Dong            stream->count_zeros = 0;
12029a84457aed4c45bc900998b5e11c03023264208James Dong        }
12129a84457aed4c45bc900998b5e11c03023264208James Dong        else
12229a84457aed4c45bc900998b5e11c03023264208James Dong        {
12329a84457aed4c45bc900998b5e11c03023264208James Dong            stream->count_zeros++;
12429a84457aed4c45bc900998b5e11c03023264208James Dong            *write_pnt++ = byte;
12529a84457aed4c45bc900998b5e11c03023264208James Dong            stream->write_pos++;
12629a84457aed4c45bc900998b5e11c03023264208James Dong        }
12729a84457aed4c45bc900998b5e11c03023264208James Dong    }
12829a84457aed4c45bc900998b5e11c03023264208James Dong
12929a84457aed4c45bc900998b5e11c03023264208James Dong    /* reset current_word and bit_left */
13029a84457aed4c45bc900998b5e11c03023264208James Dong    stream->current_word = 0;
13129a84457aed4c45bc900998b5e11c03023264208James Dong    stream->bit_left = WORD_SIZE;
13229a84457aed4c45bc900998b5e11c03023264208James Dong
13329a84457aed4c45bc900998b5e11c03023264208James Dong    return AVCENC_SUCCESS;
13429a84457aed4c45bc900998b5e11c03023264208James Dong}
13529a84457aed4c45bc900998b5e11c03023264208James Dong
13629a84457aed4c45bc900998b5e11c03023264208James Dong/* ======================================================================== */
13729a84457aed4c45bc900998b5e11c03023264208James Dong/*  Function : BitstreamWriteBits()                                         */
13829a84457aed4c45bc900998b5e11c03023264208James Dong/*  Date     : 3/29/2004                                                    */
13929a84457aed4c45bc900998b5e11c03023264208James Dong/*  Purpose  : Write up to machine word.                                    */
14029a84457aed4c45bc900998b5e11c03023264208James Dong/*  In/out   : Unused bits in 'code' must be all zeros.                     */
14129a84457aed4c45bc900998b5e11c03023264208James Dong/*  Return   : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is  */
14229a84457aed4c45bc900998b5e11c03023264208James Dong/*              full.                                                       */
14329a84457aed4c45bc900998b5e11c03023264208James Dong/*  Modified :                                                              */
14429a84457aed4c45bc900998b5e11c03023264208James Dong/* ======================================================================== */
14529a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status BitstreamWriteBits(AVCEncBitstream *stream, int nBits, uint code)
14629a84457aed4c45bc900998b5e11c03023264208James Dong{
14729a84457aed4c45bc900998b5e11c03023264208James Dong    AVCEnc_Status status = AVCENC_SUCCESS;
14829a84457aed4c45bc900998b5e11c03023264208James Dong    int bit_left = stream->bit_left;
14929a84457aed4c45bc900998b5e11c03023264208James Dong    uint current_word = stream->current_word;
15029a84457aed4c45bc900998b5e11c03023264208James Dong
15129a84457aed4c45bc900998b5e11c03023264208James Dong    //DEBUG_LOG(userData,AVC_LOGTYPE_INFO,"BitstreamWriteBits",nBits,-1);
15229a84457aed4c45bc900998b5e11c03023264208James Dong
15329a84457aed4c45bc900998b5e11c03023264208James Dong    if (nBits > WORD_SIZE) /* has to be taken care of specially */
15429a84457aed4c45bc900998b5e11c03023264208James Dong    {
15529a84457aed4c45bc900998b5e11c03023264208James Dong        return AVCENC_FAIL; /* for now */
15629a84457aed4c45bc900998b5e11c03023264208James Dong        /* otherwise, break it down to 2 write of less than 16 bits at a time. */
15729a84457aed4c45bc900998b5e11c03023264208James Dong    }
15829a84457aed4c45bc900998b5e11c03023264208James Dong
15929a84457aed4c45bc900998b5e11c03023264208James Dong    if (nBits <= bit_left) /* more bits left in current_word */
16029a84457aed4c45bc900998b5e11c03023264208James Dong    {
16129a84457aed4c45bc900998b5e11c03023264208James Dong        stream->current_word = (current_word << nBits) | code;
16229a84457aed4c45bc900998b5e11c03023264208James Dong        stream->bit_left -= nBits;
16329a84457aed4c45bc900998b5e11c03023264208James Dong        if (stream->bit_left == 0) /* prepare for the next word */
16429a84457aed4c45bc900998b5e11c03023264208James Dong        {
16529a84457aed4c45bc900998b5e11c03023264208James Dong            status = AVCBitstreamSaveWord(stream);
16629a84457aed4c45bc900998b5e11c03023264208James Dong            return status;
16729a84457aed4c45bc900998b5e11c03023264208James Dong        }
16829a84457aed4c45bc900998b5e11c03023264208James Dong    }
16929a84457aed4c45bc900998b5e11c03023264208James Dong    else
17029a84457aed4c45bc900998b5e11c03023264208James Dong    {
17129a84457aed4c45bc900998b5e11c03023264208James Dong        stream->current_word = (current_word << bit_left) | (code >> (nBits - bit_left));
17229a84457aed4c45bc900998b5e11c03023264208James Dong
17329a84457aed4c45bc900998b5e11c03023264208James Dong        nBits -= bit_left;
17429a84457aed4c45bc900998b5e11c03023264208James Dong
17529a84457aed4c45bc900998b5e11c03023264208James Dong        stream->bit_left = 0;
17629a84457aed4c45bc900998b5e11c03023264208James Dong
17729a84457aed4c45bc900998b5e11c03023264208James Dong        status = AVCBitstreamSaveWord(stream); /* save current word */
17829a84457aed4c45bc900998b5e11c03023264208James Dong
17929a84457aed4c45bc900998b5e11c03023264208James Dong        stream->bit_left = WORD_SIZE - nBits;
18029a84457aed4c45bc900998b5e11c03023264208James Dong
18129a84457aed4c45bc900998b5e11c03023264208James Dong        stream->current_word = code; /* no extra masking for code, must be handled before saving */
18229a84457aed4c45bc900998b5e11c03023264208James Dong    }
18329a84457aed4c45bc900998b5e11c03023264208James Dong
18429a84457aed4c45bc900998b5e11c03023264208James Dong    return status;
18529a84457aed4c45bc900998b5e11c03023264208James Dong}
18629a84457aed4c45bc900998b5e11c03023264208James Dong
18729a84457aed4c45bc900998b5e11c03023264208James Dong
18829a84457aed4c45bc900998b5e11c03023264208James Dong/* ======================================================================== */
18929a84457aed4c45bc900998b5e11c03023264208James Dong/*  Function : BitstreamWrite1Bit()                                         */
19029a84457aed4c45bc900998b5e11c03023264208James Dong/*  Date     : 3/30/2004                                                    */
19129a84457aed4c45bc900998b5e11c03023264208James Dong/*  Purpose  : Write 1 bit                                                  */
19229a84457aed4c45bc900998b5e11c03023264208James Dong/*  In/out   : Unused bits in 'code' must be all zeros.                     */
19329a84457aed4c45bc900998b5e11c03023264208James Dong/*  Return   : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is  */
19429a84457aed4c45bc900998b5e11c03023264208James Dong/*              full.                                                       */
19529a84457aed4c45bc900998b5e11c03023264208James Dong/*  Modified :                                                              */
19629a84457aed4c45bc900998b5e11c03023264208James Dong/* ======================================================================== */
19729a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status BitstreamWrite1Bit(AVCEncBitstream *stream, uint code)
19829a84457aed4c45bc900998b5e11c03023264208James Dong{
19929a84457aed4c45bc900998b5e11c03023264208James Dong    AVCEnc_Status status;
20029a84457aed4c45bc900998b5e11c03023264208James Dong    uint current_word = stream->current_word;
20129a84457aed4c45bc900998b5e11c03023264208James Dong
20229a84457aed4c45bc900998b5e11c03023264208James Dong    //DEBUG_LOG(userData,AVC_LOGTYPE_INFO,"BitstreamWrite1Bit",code,-1);
20329a84457aed4c45bc900998b5e11c03023264208James Dong
20429a84457aed4c45bc900998b5e11c03023264208James Dong    //if(1 <= bit_left) /* more bits left in current_word */
20529a84457aed4c45bc900998b5e11c03023264208James Dong    /* we can assume that there always be positive bit_left in the current word */
20629a84457aed4c45bc900998b5e11c03023264208James Dong    stream->current_word = (current_word << 1) | code;
20729a84457aed4c45bc900998b5e11c03023264208James Dong    stream->bit_left--;
20829a84457aed4c45bc900998b5e11c03023264208James Dong    if (stream->bit_left == 0) /* prepare for the next word */
20929a84457aed4c45bc900998b5e11c03023264208James Dong    {
21029a84457aed4c45bc900998b5e11c03023264208James Dong        status = AVCBitstreamSaveWord(stream);
21129a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
21229a84457aed4c45bc900998b5e11c03023264208James Dong    }
21329a84457aed4c45bc900998b5e11c03023264208James Dong
21429a84457aed4c45bc900998b5e11c03023264208James Dong    return AVCENC_SUCCESS;
21529a84457aed4c45bc900998b5e11c03023264208James Dong}
21629a84457aed4c45bc900998b5e11c03023264208James Dong
21729a84457aed4c45bc900998b5e11c03023264208James Dong
21829a84457aed4c45bc900998b5e11c03023264208James Dong/* ======================================================================== */
21929a84457aed4c45bc900998b5e11c03023264208James Dong/*  Function : BitstreamTrailingBits()                                      */
22029a84457aed4c45bc900998b5e11c03023264208James Dong/*  Date     : 3/31/2004                                                    */
22129a84457aed4c45bc900998b5e11c03023264208James Dong/*  Purpose  : Add trailing bits and report the final EBSP size.            */
22229a84457aed4c45bc900998b5e11c03023264208James Dong/*  In/out   :                                                              */
22329a84457aed4c45bc900998b5e11c03023264208James Dong/*  Return   : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is  */
22429a84457aed4c45bc900998b5e11c03023264208James Dong/*              full.                                                       */
22529a84457aed4c45bc900998b5e11c03023264208James Dong/*  Modified :                                                              */
22629a84457aed4c45bc900998b5e11c03023264208James Dong/* ======================================================================== */
22729a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status BitstreamTrailingBits(AVCEncBitstream *bitstream, uint *nal_size)
22829a84457aed4c45bc900998b5e11c03023264208James Dong{
22929a84457aed4c45bc900998b5e11c03023264208James Dong    (void)(nal_size);
23029a84457aed4c45bc900998b5e11c03023264208James Dong
23129a84457aed4c45bc900998b5e11c03023264208James Dong    AVCEnc_Status status;
23229a84457aed4c45bc900998b5e11c03023264208James Dong    int bit_left = bitstream->bit_left;
23329a84457aed4c45bc900998b5e11c03023264208James Dong
23429a84457aed4c45bc900998b5e11c03023264208James Dong    bit_left &= 0x7; /* modulo by 8 */
23529a84457aed4c45bc900998b5e11c03023264208James Dong    if (bit_left == 0) bit_left = 8;
23629a84457aed4c45bc900998b5e11c03023264208James Dong    /* bitstream->bit_left == 0 cannot happen here since it would have been Saved already */
23729a84457aed4c45bc900998b5e11c03023264208James Dong
23829a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWriteBits(bitstream, bit_left, trailing_bits[bit_left]);
23929a84457aed4c45bc900998b5e11c03023264208James Dong
24029a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)
24129a84457aed4c45bc900998b5e11c03023264208James Dong    {
24229a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
24329a84457aed4c45bc900998b5e11c03023264208James Dong    }
24429a84457aed4c45bc900998b5e11c03023264208James Dong
24529a84457aed4c45bc900998b5e11c03023264208James Dong    /* if it's not saved, save it. */
24629a84457aed4c45bc900998b5e11c03023264208James Dong    //if(bitstream->bit_left<(WORD_SIZE<<3)) /* in fact, no need to check */
24729a84457aed4c45bc900998b5e11c03023264208James Dong    {
24829a84457aed4c45bc900998b5e11c03023264208James Dong        status = AVCBitstreamSaveWord(bitstream);
24929a84457aed4c45bc900998b5e11c03023264208James Dong    }
25029a84457aed4c45bc900998b5e11c03023264208James Dong
25129a84457aed4c45bc900998b5e11c03023264208James Dong    return status;
25229a84457aed4c45bc900998b5e11c03023264208James Dong}
25329a84457aed4c45bc900998b5e11c03023264208James Dong
25429a84457aed4c45bc900998b5e11c03023264208James Dong/* check whether it's byte-aligned */
25529a84457aed4c45bc900998b5e11c03023264208James Dongbool byte_aligned(AVCEncBitstream *stream)
25629a84457aed4c45bc900998b5e11c03023264208James Dong{
25729a84457aed4c45bc900998b5e11c03023264208James Dong    if (stream->bit_left % 8)
25829a84457aed4c45bc900998b5e11c03023264208James Dong        return false;
25929a84457aed4c45bc900998b5e11c03023264208James Dong    else
26029a84457aed4c45bc900998b5e11c03023264208James Dong        return true;
26129a84457aed4c45bc900998b5e11c03023264208James Dong}
26229a84457aed4c45bc900998b5e11c03023264208James Dong
26329a84457aed4c45bc900998b5e11c03023264208James Dong
26429a84457aed4c45bc900998b5e11c03023264208James Dong/* determine whether overrun buffer can be used or not */
26529a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status AVCBitstreamUseOverrunBuffer(AVCEncBitstream* stream, int numExtraBytes)
26629a84457aed4c45bc900998b5e11c03023264208James Dong{
26729a84457aed4c45bc900998b5e11c03023264208James Dong    AVCEncObject *encvid = (AVCEncObject*)stream->encvid;
26829a84457aed4c45bc900998b5e11c03023264208James Dong
26929a84457aed4c45bc900998b5e11c03023264208James Dong    if (stream->overrunBuffer != NULL) // overrunBuffer is set
27029a84457aed4c45bc900998b5e11c03023264208James Dong    {
27129a84457aed4c45bc900998b5e11c03023264208James Dong        if (stream->bitstreamBuffer != stream->overrunBuffer) // not already used
27229a84457aed4c45bc900998b5e11c03023264208James Dong        {
27329a84457aed4c45bc900998b5e11c03023264208James Dong            if (stream->write_pos + numExtraBytes >= stream->oBSize)
27429a84457aed4c45bc900998b5e11c03023264208James Dong            {
27529a84457aed4c45bc900998b5e11c03023264208James Dong                stream->oBSize = stream->write_pos + numExtraBytes + 100;
27629a84457aed4c45bc900998b5e11c03023264208James Dong                stream->oBSize &= (~0x3); // make it multiple of 4
27729a84457aed4c45bc900998b5e11c03023264208James Dong
27829a84457aed4c45bc900998b5e11c03023264208James Dong                // allocate new overrun Buffer
27929a84457aed4c45bc900998b5e11c03023264208James Dong                if (encvid->overrunBuffer)
28029a84457aed4c45bc900998b5e11c03023264208James Dong                {
2812f3152dee8e763fd7eae9d7b71078d5c6aec5881Martin Storsjo                    encvid->avcHandle->CBAVC_Free(encvid->avcHandle->userData,
28223da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjo                                                  encvid->overrunBuffer);
28329a84457aed4c45bc900998b5e11c03023264208James Dong                }
28429a84457aed4c45bc900998b5e11c03023264208James Dong
28529a84457aed4c45bc900998b5e11c03023264208James Dong                encvid->oBSize = stream->oBSize;
28629a84457aed4c45bc900998b5e11c03023264208James Dong                encvid->overrunBuffer = (uint8*) encvid->avcHandle->CBAVC_Malloc(encvid->avcHandle->userData,
28729a84457aed4c45bc900998b5e11c03023264208James Dong                                        stream->oBSize, DEFAULT_ATTR);
28829a84457aed4c45bc900998b5e11c03023264208James Dong
28929a84457aed4c45bc900998b5e11c03023264208James Dong                stream->overrunBuffer = encvid->overrunBuffer;
29029a84457aed4c45bc900998b5e11c03023264208James Dong                if (stream->overrunBuffer == NULL)
29129a84457aed4c45bc900998b5e11c03023264208James Dong                {
29229a84457aed4c45bc900998b5e11c03023264208James Dong                    return AVCENC_FAIL;
29329a84457aed4c45bc900998b5e11c03023264208James Dong                }
29429a84457aed4c45bc900998b5e11c03023264208James Dong            }
29529a84457aed4c45bc900998b5e11c03023264208James Dong
29629a84457aed4c45bc900998b5e11c03023264208James Dong            // copy everything to overrun buffer and start using it.
29729a84457aed4c45bc900998b5e11c03023264208James Dong            memcpy(stream->overrunBuffer, stream->bitstreamBuffer, stream->write_pos);
29829a84457aed4c45bc900998b5e11c03023264208James Dong            stream->bitstreamBuffer = stream->overrunBuffer;
29929a84457aed4c45bc900998b5e11c03023264208James Dong            stream->buf_size = stream->oBSize;
30029a84457aed4c45bc900998b5e11c03023264208James Dong        }
30129a84457aed4c45bc900998b5e11c03023264208James Dong        else // overrun buffer is already used
30229a84457aed4c45bc900998b5e11c03023264208James Dong        {
30329a84457aed4c45bc900998b5e11c03023264208James Dong            stream->oBSize = stream->write_pos + numExtraBytes + 100;
30429a84457aed4c45bc900998b5e11c03023264208James Dong            stream->oBSize &= (~0x3); // make it multiple of 4
30529a84457aed4c45bc900998b5e11c03023264208James Dong
30629a84457aed4c45bc900998b5e11c03023264208James Dong            // allocate new overrun buffer
30729a84457aed4c45bc900998b5e11c03023264208James Dong            encvid->oBSize = stream->oBSize;
30829a84457aed4c45bc900998b5e11c03023264208James Dong            encvid->overrunBuffer = (uint8*) encvid->avcHandle->CBAVC_Malloc(encvid->avcHandle->userData,
30929a84457aed4c45bc900998b5e11c03023264208James Dong                                    stream->oBSize, DEFAULT_ATTR);
31029a84457aed4c45bc900998b5e11c03023264208James Dong
31129a84457aed4c45bc900998b5e11c03023264208James Dong            if (encvid->overrunBuffer == NULL)
31229a84457aed4c45bc900998b5e11c03023264208James Dong            {
31329a84457aed4c45bc900998b5e11c03023264208James Dong                return AVCENC_FAIL;
31429a84457aed4c45bc900998b5e11c03023264208James Dong            }
31529a84457aed4c45bc900998b5e11c03023264208James Dong
31629a84457aed4c45bc900998b5e11c03023264208James Dong
31729a84457aed4c45bc900998b5e11c03023264208James Dong            // copy from the old buffer to new buffer
31829a84457aed4c45bc900998b5e11c03023264208James Dong            memcpy(encvid->overrunBuffer, stream->overrunBuffer, stream->write_pos);
31929a84457aed4c45bc900998b5e11c03023264208James Dong            // free old buffer
3202f3152dee8e763fd7eae9d7b71078d5c6aec5881Martin Storsjo            encvid->avcHandle->CBAVC_Free(encvid->avcHandle->userData,
32123da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjo                                          stream->overrunBuffer);
32229a84457aed4c45bc900998b5e11c03023264208James Dong
32329a84457aed4c45bc900998b5e11c03023264208James Dong            // assign pointer to new buffer
32429a84457aed4c45bc900998b5e11c03023264208James Dong            stream->overrunBuffer = encvid->overrunBuffer;
32529a84457aed4c45bc900998b5e11c03023264208James Dong            stream->bitstreamBuffer = stream->overrunBuffer;
32629a84457aed4c45bc900998b5e11c03023264208James Dong            stream->buf_size = stream->oBSize;
32729a84457aed4c45bc900998b5e11c03023264208James Dong        }
32829a84457aed4c45bc900998b5e11c03023264208James Dong
32929a84457aed4c45bc900998b5e11c03023264208James Dong        return AVCENC_SUCCESS;
33029a84457aed4c45bc900998b5e11c03023264208James Dong    }
33129a84457aed4c45bc900998b5e11c03023264208James Dong    else // overrunBuffer is not enable.
33229a84457aed4c45bc900998b5e11c03023264208James Dong    {
33329a84457aed4c45bc900998b5e11c03023264208James Dong        return AVCENC_FAIL;
33429a84457aed4c45bc900998b5e11c03023264208James Dong    }
33529a84457aed4c45bc900998b5e11c03023264208James Dong
33629a84457aed4c45bc900998b5e11c03023264208James Dong}
33729a84457aed4c45bc900998b5e11c03023264208James Dong
33829a84457aed4c45bc900998b5e11c03023264208James Dong
33929a84457aed4c45bc900998b5e11c03023264208James Dong
340