Home | History | Annotate | Download | only in src
      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 
     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 /* ======================================================================== */
     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 /* ======================================================================== */
    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 /* ======================================================================== */
    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 /* ======================================================================== */
    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 */
    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 */
    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