diff -r 951a5db380a0 -r e0b5df5c0969 videoeditorengine/avcedit/src/bitbuffer.cpp --- a/videoeditorengine/avcedit/src/bitbuffer.cpp Fri Jan 29 14:08:33 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,613 +0,0 @@ -/* -* Copyright (c) 2010 Ixonos Plc. -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - Initial contribution -* -* Contributors: -* Ixonos Plc -* -* Description: -* -*/ - - -#include -#include "globals.h" -#include "nrctyp32.h" -#include "bitbuffer.h" - -#include "parameterset.h" - - -/* - * Static functions - */ - -static int removeStartCodeEmulationBytes(bitbuffer_s *bitbuf); -static int addStartCodeEmulationBytes(bitbuffer_s *bitbuf); - - -/* - * - * bibOpen: - * - * Parameters: - * - * Function: - * Open bitbuffer - * - * Returns: - * Pointer to bitbuffer object or NULL for allocation failure. - * - */ -bitbuffer_s *bibOpen() -{ - bitbuffer_s *bitbuf; - - bitbuf = (bitbuffer_s *)User::Alloc(sizeof(bitbuffer_s)); - - if (bitbuf != NULL) - memset(bitbuf, 0, sizeof(bitbuffer_s)); - - return bitbuf; -} - - -/* - * - * bibInit: - * - * Parameters: - * bitbuf Bitbuffer object - * streamBytes Pointer to data - * length Data length in bytes - * - * Function: - * Initialize bitbuffer - * - * Returns: - * BIB_ok for ok, BIB_ERROR for error - * - */ -int bibInit(bitbuffer_s *bitbuf, u_int8 *streamBytes, int length) -{ - bitbuf->data = streamBytes; - bitbuf->dataLen = length; - bitbuf->bytePos = 0; - bitbuf->bitpos = 0; - bitbuf->errorStatus = BIB_OK; - -#if ENCAPSULATED_NAL_PAYLOAD - if (removeStartCodeEmulationBytes(bitbuf) < 0) - return BIB_ERROR; -#endif - - return BIB_OK; -} - - -/* - * - * bibClose: - * - * Parameters: - * bitbuf Bitbuffer object - * - * Function: - * Close bitbuffer - * - * Returns: - * - - * - */ -void bibClose(bitbuffer_s *bitbuf) -{ - User::Free(bitbuf); -} - - -/* - * - * removeStartCodeEmulationBytes: - * - * Parameters: - * bitbuf Bitbuffer object - * - * Function: - * Remove start code emulation bytes from the bitbuffer - * - * Returns: - * - - * - */ -static int removeStartCodeEmulationBytes(bitbuffer_s *bitbuf) -{ - TInt i; - TInt j; - TInt numZero; - TInt32 lastBytes; - - - // Skip the start code if it exists - numZero = 0; - i = 0; - while (i < bitbuf->dataLen) - { - if (bitbuf->data[i] == 0) - numZero++; - else if (numZero > 1 && bitbuf->data[i] == 1) - { - // Start code found - i++; - break; - } - else - { - // No start code found - i = 0; - break; - } - i++; - } - - // Convert EBSP to RBSP. Note that the nal head byte is kept within the buffer - lastBytes = 0xffffffff; - j = 0; - while (i < bitbuf->dataLen) - { - lastBytes = (lastBytes << 8) | bitbuf->data[i]; - if ((lastBytes & 0xffffff) != 0x000003) - { - bitbuf->data[j] = bitbuf->data[i]; - j++; - } - i++; - } - - // If bytes were removed, set as many bytes zero at the end of the buffer - if (j < bitbuf->dataLen) - { - // Prevention bytes have been removed, set the last bytes to zero - TInt removedBytes = bitbuf->dataLen - j; - for (i=0; idata[bitbuf->dataLen-1-i] = 0; - } - } - - // Adjust the bitbuffer dataLen - bitbuf->dataLen = j; - - return BIB_OK; -} - - -/* - * - * bibGetBitFunc: - * - * Parameters: - * bitbuf Bitbuffer object - * - * Function: - * Get next bit from bitbuffer. - * - * Returns: - * Next bit in bitbuffer or BIB_ERR_NO_BITS if no bits left. - * - */ -int bibGetBitFunc(bitbuffer_s *bitbuf) -{ - /* If there are no bits left in buffer return an error */ - if (bitbuf->bitpos == 0 && bitbuf->bytePos >= bitbuf->dataLen) { - bitbuf->errorStatus = BIB_ERR_NO_BITS; - return 0; - } - - /* Fill bitbuf->currentBits with bits */ - while (bitbuf->bitpos <= 24 && bitbuf->bytePos < bitbuf->dataLen) { - bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++]; - bitbuf->bitpos += 8; - } - - /* Return bit */ - bitbuf->bitpos--; - return (bitbuf->currentBits >> bitbuf->bitpos) & 1; -} - - -/* - * - * bibGetBitsFunc: - * - * Parameters: - * bitbuf Bitbuffer object - * n Number of bits requested - * - * Function: - * Get next n bits from bitbuffer. - * - * NOTE: maximum of 24 bits can be fetched - * - * Returns: - * Next n bits from bitbuffer - * - */ -int32 bibGetBitsFunc(bitbuffer_s *bitbuf, int n) -{ - /* Fill bitbuf->currentBits with bits */ - while (n > bitbuf->bitpos && bitbuf->bytePos < bitbuf->dataLen) { - bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++]; - bitbuf->bitpos += 8; - } - - /* If there are not enought bits there was an error */ - if (n > bitbuf->bitpos) { - bitbuf->errorStatus = BIB_ERR_NO_BITS; - return 0; - } - - /* Return bits */ - bitbuf->bitpos -= n; - return (bitbuf->currentBits >> (bitbuf->bitpos)) & ~(((u_int32)-1)<currentBits with bits */ - while (n > bitbuf->bitpos && bitbuf->bytePos < bitbuf->dataLen) { - bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++]; - bitbuf->bitpos += 8; - } - - /* Check if there are enought bits in currentBits */ - if (n <= bitbuf->bitpos) - /* Return bits normally */ - return (bitbuf->currentBits >> (bitbuf->bitpos-n)) & ~(((u_int32)-1)<currentBits << (n-bitbuf->bitpos)) & ~(((u_int32)-1)<currentBits with bits */ - while (n > bitbuf->bitpos && bitbuf->bytePos < bitbuf->dataLen) { - bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++]; - bitbuf->bitpos += 8; - } - - bitbuf->bitpos -= n; - - /* Check for buffer underrun */ - if (bitbuf->bitpos < 0) { - bitbuf->errorStatus = BIB_ERR_NO_BITS; - return BIB_ERR_NO_BITS; - } - - return BIB_OK; -} - - -/* - * - * bibGetByte: - * - * Parameters: - * bitbuf Bitbuffer object - * byteRet Return pointer for byte - * - * Function: - * Get next byte aligned byte from bitbuffer. - * - * Returns: - * 1 for End Of Stream, 0 otherwise - * - */ -int bibGetByte(bitbuffer_s *bitbuf, int *byteRet) -{ - if (bitbuf->bitpos >= 8) { - bitbuf->bitpos = bitbuf->bitpos & ~7; - *byteRet = (bitbuf->currentBits >> (bitbuf->bitpos - 8)) & 0xff; - bitbuf->bitpos -= 8; - } - else { - bitbuf->bitpos = 0; - - if (bitbuf->bytePos >= bitbuf->dataLen) { - return 1; - } - - *byteRet = bitbuf->data[bitbuf->bytePos++]; - } - - return 0; -} - - -/* - * - * bibByteAlign: - * - * Parameters: - * bitbuf Bitbuffer object - * - * Function: - * Set bitbuffer pointer to next byte aligned position. - * - * Returns: - * Number of bits skipped as a result of aligning. - * - */ -int bibByteAlign(bitbuffer_s *bitbuf) -{ - int bitpos = bitbuf->bitpos; - - bitbuf->bitpos = bitbuf->bitpos & ~7; - - return (bitpos - bitbuf->bitpos); -} - - -/* - * bibSkipTrailingBits: - * - * Parameters: - * bitbuf Bitbuffer object - * - * Function: - * Skip the trailing bits at the end of a NAL unit - * - * Returns: - * The number of bits being skipped or <0 for error. - */ -int bibSkipTrailingBits(bitbuffer_s *bitbuf) -{ - int ret; - int len = 0; - int bit = 0; - - bit = bibGetBitFunc(bitbuf); - len++; - - ret = bibGetStatus(bitbuf); - if (ret < 0) - return ret; - - /* First we expect to receive 1 bit */ - if (bit != 1) { - bibRaiseError(bitbuf, BIB_INCORRECT_TRAILING_BIT); - return BIB_INCORRECT_TRAILING_BIT; - } - - /* Remaining bits in current byte should be zero */ - while ( bitbuf->bitpos % 8 != 0 ) { - bibGetBit(bitbuf, &bit); - len++; - if (bit != 0) { - bibRaiseError(bitbuf, BIB_INCORRECT_TRAILING_BIT); - return BIB_INCORRECT_TRAILING_BIT; - } - } - - ret = bibGetStatus(bitbuf); - if (ret < 0) - return ret; - - return len; -} - - -/* - * bibMoreRbspData: - * - * Parameters: - * bitbuf Bitbuffer object - * - * Function: - * Check if there is more RBSP data in the bitbuffer. - * - * Returns: - * 0: no more rbsp data - * 1: more rbsp data - */ -int bibMoreRbspData(bitbuffer_s *bitbuf) -{ - int numBytesLeft; - u_int32 lastBits; - - numBytesLeft = bitbuf->dataLen - bitbuf->bytePos; - - if (numBytesLeft >= 2 || (numBytesLeft*8 + bitbuf->bitpos >= 9)) - /* If there are at least 9 bits left, it is certain to have more rbsp data */ - return 1; - - if (numBytesLeft == 0 && bitbuf->bitpos == 0) - /* Something may be wrong. Normally, there should be at least one bit left */ - return 0; - - if (numBytesLeft == 1) { - /* Insert last byte to currentBits */ - bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++]; - bitbuf->bitpos += 8; - } - - /* Copy the last bits into "lastBits", then compare it with 0x1..00 */ - lastBits = bitbuf->currentBits & ~(((u_int32)-1)<bitpos); - - if (lastBits == ((u_int32)1 << (bitbuf->bitpos-1))) - return 0; - else - return 1; -} - - -/* - * bibGetNumOfRemainingBits: - * - * Parameters: - * bitbuf Bitbuffer object - * - * Function: - * Return number of bits in bitbuffer. - * - * Returns: - * Number of bits - */ -int32 bibGetNumRemainingBits(bitbuffer_s *bitbuf) -{ - return bitbuf->bitpos + 8*(bitbuf->dataLen - bitbuf->bytePos); -} - - -// syncBitBufferBitpos -// Synchronizes the input bit buffer's bit position to be between one and eight, -// modifies the byte position and current bits if required. -void syncBitBufferBitpos(bitbuffer_s *bitbuf) -{ - // To be able to edit the bitbuffer, reset the bit position to be eight at the maximum - while (bitbuf->bitpos > 8) - { - // If bit position is modified, then modify byte position and current bits accordingly - bitbuf->bitpos -= 8; - bitbuf->bytePos--; - bitbuf->currentBits >>= 8; - } -} - - -// addStartCodeEmulationBytes -// Adds start code emulation bytes to the input bit buffer. -static int addStartCodeEmulationBytes(bitbuffer_s *bitbuf) -{ - TInt i = 0; - TInt32 lastBytes; - - - // Add prevention bytes that were removed for processing - lastBytes = 0xffffffff; - while (i < bitbuf->dataLen) - { - lastBytes = (lastBytes << 8) | bitbuf->data[i]; - - if(((lastBytes & 0xffff) == 0x0000) && ((i+1) < bitbuf->dataLen) && (bitbuf->data[i+1] < 4)) - { - // Add byte(s) to the bit buffer - TInt error = AddBytesToBuffer(bitbuf, 1); - - if (error != 0) - return error; - - // Adjust data length - bitbuf->dataLen++; - - // Make room for the emulation prevention byte 0x03 to the buffer - for (TInt k=bitbuf->dataLen; k>i; k--) - { - bitbuf->data[k] = bitbuf->data[k-1]; - } - - // Add the emulation prevention byte to the buffer - bitbuf->data[i+1] = 0x03; - } - - i++; - } - return KErrNone; -} - - -// bibEnd -// Takes care of the bit buffer after the frame has been processed. -int bibEnd(bitbuffer_s *bitbuf) -{ -#if ENCAPSULATED_NAL_PAYLOAD - return addStartCodeEmulationBytes(bitbuf); -#endif -} - - -// addStartCodeEmulationBytesSlice -// Adds start code emulation bytes to the input bit buffer. -static void addStartCodeEmulationBytesSlice(bitbuffer_s *bitbuf) -{ - TInt i = 0; - TInt32 lastBytes; - - - // Add prevention bytes that were removed for processing - lastBytes = 0xffffffff; - while (i < bitbuf->dataLen) - { - lastBytes = (lastBytes << 8) | bitbuf->data[i]; - - if(((lastBytes & 0xffff) == 0x0000) && ((i+1) < bitbuf->dataLen) && (bitbuf->data[i+1] < 4)) - { - // Make room for the emulation prevention byte 0x03 to the buffer - for (TInt k=bitbuf->dataLen; k>i; k--) - { - bitbuf->data[k] = bitbuf->data[k-1]; - } - // Adjust data length - bitbuf->dataLen++; - - // Add the emulation prevention byte to the buffer - bitbuf->data[i+1] = 0x03; - } - - i++; - } -} - - -// bibEndSlice -// Takes care of the bit buffer after the frame has been processed. -void bibEndSlice(bitbuffer_s *bitbuf) -{ -#if ENCAPSULATED_NAL_PAYLOAD - addStartCodeEmulationBytesSlice(bitbuf); -#endif -} -