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