videoeditorengine/avcedit/src/bitbuffer.cpp
branchRCL_3
changeset 3 e0b5df5c0969
parent 0 951a5db380a0
child 5 4c409de21d23
equal deleted inserted replaced
0:951a5db380a0 3:e0b5df5c0969
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include <string.h>
       
    21 #include "globals.h"
       
    22 #include "nrctyp32.h"
       
    23 #include "bitbuffer.h"
       
    24 
       
    25 #include "parameterset.h"
       
    26 
       
    27 
       
    28 /*
       
    29  * Static functions
       
    30  */
       
    31 
       
    32 static int removeStartCodeEmulationBytes(bitbuffer_s *bitbuf);
       
    33 static int addStartCodeEmulationBytes(bitbuffer_s *bitbuf);
       
    34 
       
    35 
       
    36 /*
       
    37  *
       
    38  * bibOpen:
       
    39  *
       
    40  * Parameters:
       
    41  *
       
    42  * Function:
       
    43  *      Open bitbuffer
       
    44  *
       
    45  * Returns:
       
    46  *      Pointer to bitbuffer object or NULL for allocation failure.
       
    47  *
       
    48  */
       
    49 bitbuffer_s *bibOpen()
       
    50 {
       
    51   bitbuffer_s *bitbuf;
       
    52 
       
    53   bitbuf = (bitbuffer_s *)User::Alloc(sizeof(bitbuffer_s));
       
    54 
       
    55   if (bitbuf != NULL)
       
    56     memset(bitbuf, 0, sizeof(bitbuffer_s));
       
    57 
       
    58   return bitbuf;
       
    59 }
       
    60 
       
    61 
       
    62 /*
       
    63  *
       
    64  * bibInit:
       
    65  *
       
    66  * Parameters:
       
    67  *      bitbuf                Bitbuffer object
       
    68  *      streamBytes           Pointer to data
       
    69  *      length                Data length in bytes
       
    70  *
       
    71  * Function:
       
    72  *      Initialize bitbuffer
       
    73  *
       
    74  * Returns:
       
    75  *      BIB_ok for ok, BIB_ERROR for error
       
    76  *
       
    77  */
       
    78 int bibInit(bitbuffer_s *bitbuf, u_int8 *streamBytes, int length)
       
    79 {
       
    80   bitbuf->data           = streamBytes;
       
    81   bitbuf->dataLen        = length;
       
    82   bitbuf->bytePos        = 0;
       
    83   bitbuf->bitpos         = 0;
       
    84   bitbuf->errorStatus    = BIB_OK;
       
    85 
       
    86 #if ENCAPSULATED_NAL_PAYLOAD
       
    87   if (removeStartCodeEmulationBytes(bitbuf) < 0)
       
    88     return BIB_ERROR;
       
    89 #endif
       
    90 
       
    91   return BIB_OK;
       
    92 }
       
    93 
       
    94 
       
    95 /*
       
    96  *
       
    97  * bibClose:
       
    98  *
       
    99  * Parameters:
       
   100  *      bitbuf                Bitbuffer object
       
   101  *
       
   102  * Function:
       
   103  *      Close bitbuffer
       
   104  *
       
   105  * Returns:
       
   106  *      -
       
   107  *
       
   108  */
       
   109 void bibClose(bitbuffer_s *bitbuf)
       
   110 {
       
   111   User::Free(bitbuf);
       
   112 }
       
   113 
       
   114 
       
   115 /*
       
   116  *
       
   117  * removeStartCodeEmulationBytes:
       
   118  *
       
   119  * Parameters:
       
   120  *      bitbuf                Bitbuffer object
       
   121  *
       
   122  * Function:
       
   123  *      Remove start code emulation bytes from the bitbuffer
       
   124  *
       
   125  * Returns:
       
   126  *      -
       
   127  *
       
   128  */
       
   129 static int removeStartCodeEmulationBytes(bitbuffer_s *bitbuf)
       
   130 {
       
   131   	TInt i;
       
   132   	TInt j;
       
   133   	TInt numZero;
       
   134   	TInt32 lastBytes;
       
   135 
       
   136 
       
   137   	// Skip the start code if it exists
       
   138   	numZero = 0;
       
   139   	i = 0;
       
   140   	while (i < bitbuf->dataLen) 
       
   141   	{
       
   142     	if (bitbuf->data[i] == 0)
       
   143       		numZero++;
       
   144     	else if (numZero > 1 && bitbuf->data[i] == 1) 
       
   145     	{
       
   146       		// Start code found
       
   147       		i++;
       
   148       		break;
       
   149     	}
       
   150     	else 
       
   151     	{
       
   152       		// No start code found 
       
   153       		i = 0;
       
   154       		break;
       
   155     	}
       
   156     	i++;
       
   157   	}
       
   158 
       
   159   	// Convert EBSP to RBSP. Note that the nal head byte is kept within the buffer
       
   160   	lastBytes = 0xffffffff;
       
   161   	j = 0;
       
   162   	while (i < bitbuf->dataLen) 
       
   163   	{
       
   164     	lastBytes = (lastBytes << 8) | bitbuf->data[i];
       
   165     	if ((lastBytes & 0xffffff) != 0x000003) 
       
   166     	{
       
   167 	      	bitbuf->data[j] = bitbuf->data[i];
       
   168 	      	j++;
       
   169     	}
       
   170     	i++;
       
   171   	}
       
   172 
       
   173   	// If bytes were removed, set as many bytes zero at the end of the buffer
       
   174   	if (j < bitbuf->dataLen)
       
   175   	{
       
   176   		// Prevention bytes have been removed, set the last bytes to zero
       
   177   		TInt removedBytes = bitbuf->dataLen - j;
       
   178   		for (i=0; i<removedBytes; i++)
       
   179   		{
       
   180   			bitbuf->data[bitbuf->dataLen-1-i] = 0;
       
   181   		}
       
   182 	}
       
   183   	
       
   184   	// Adjust the bitbuffer dataLen
       
   185   	bitbuf->dataLen = j;
       
   186 
       
   187   	return BIB_OK;
       
   188 }
       
   189 
       
   190 
       
   191 /*
       
   192  *
       
   193  * bibGetBitFunc:
       
   194  *
       
   195  * Parameters:
       
   196  *      bitbuf                Bitbuffer object
       
   197  *
       
   198  * Function:
       
   199  *      Get next bit from bitbuffer.
       
   200  *
       
   201  * Returns:
       
   202  *      Next bit in bitbuffer or BIB_ERR_NO_BITS if no bits left.
       
   203  *
       
   204  */
       
   205 int bibGetBitFunc(bitbuffer_s *bitbuf)
       
   206 {
       
   207   /* If there are no bits left in buffer return an error */
       
   208   if (bitbuf->bitpos == 0 && bitbuf->bytePos >= bitbuf->dataLen) {
       
   209     bitbuf->errorStatus = BIB_ERR_NO_BITS;
       
   210     return 0;
       
   211   }
       
   212 
       
   213   /* Fill bitbuf->currentBits with bits */
       
   214   while (bitbuf->bitpos <= 24 && bitbuf->bytePos < bitbuf->dataLen) {
       
   215     bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++];
       
   216     bitbuf->bitpos += 8;
       
   217   }
       
   218 
       
   219   /* Return bit */
       
   220   bitbuf->bitpos--;
       
   221   return (bitbuf->currentBits >> bitbuf->bitpos) & 1;
       
   222 }
       
   223 
       
   224 
       
   225 /*
       
   226  *
       
   227  * bibGetBitsFunc:
       
   228  *
       
   229  * Parameters:
       
   230  *      bitbuf                Bitbuffer object
       
   231  *      n                     Number of bits requested
       
   232  *
       
   233  * Function:
       
   234  *      Get next n bits from bitbuffer.
       
   235  *
       
   236  *      NOTE: maximum of 24 bits can be fetched
       
   237  *
       
   238  * Returns:
       
   239  *      Next n bits from bitbuffer
       
   240  *
       
   241  */
       
   242 int32 bibGetBitsFunc(bitbuffer_s *bitbuf, int n)
       
   243 {
       
   244   /* Fill bitbuf->currentBits with bits */
       
   245   while (n > bitbuf->bitpos && bitbuf->bytePos < bitbuf->dataLen) {
       
   246     bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++];
       
   247     bitbuf->bitpos += 8;
       
   248   }
       
   249 
       
   250   /* If there are not enought bits there was an error */
       
   251   if (n > bitbuf->bitpos) {
       
   252     bitbuf->errorStatus = BIB_ERR_NO_BITS;
       
   253     return 0;
       
   254   }
       
   255 
       
   256   /* Return bits */
       
   257   bitbuf->bitpos -= n;
       
   258   return (bitbuf->currentBits >> (bitbuf->bitpos)) & ~(((u_int32)-1)<<n);
       
   259 }
       
   260 
       
   261 
       
   262 /*
       
   263  *
       
   264  * bibShowBitsFunc:
       
   265  *
       
   266  * Parameters:
       
   267  *      bitbuf                Bitbuffer object
       
   268  *      n                     Number of bits requested
       
   269  *
       
   270  * Function:
       
   271  *      Get next n bits from bitbuffer without advancing bitbuffer pointer.
       
   272  *      This function will not failt even if there are not enough bits in
       
   273  *      the bitbuffer.
       
   274  *
       
   275  *      NOTE: maximum of 24 bits can be fetched
       
   276  *
       
   277  * Returns:
       
   278  *      Next n bits of bitbuffer
       
   279  *
       
   280  */
       
   281 int32 bibShowBitsFunc(bitbuffer_s *bitbuf, int n)
       
   282 {
       
   283   /* Fill bitbuf->currentBits with bits */
       
   284   while (n > bitbuf->bitpos && bitbuf->bytePos < bitbuf->dataLen) {
       
   285     bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++];
       
   286     bitbuf->bitpos += 8;
       
   287   }
       
   288 
       
   289   /* Check if there are enought bits in currentBits */
       
   290   if (n <= bitbuf->bitpos)
       
   291     /* Return bits normally */
       
   292     return (bitbuf->currentBits >> (bitbuf->bitpos-n)) & ~(((u_int32)-1)<<n);
       
   293   else
       
   294     /* Return bits padded with zero bits */
       
   295     return (bitbuf->currentBits << (n-bitbuf->bitpos)) & ~(((u_int32)-1)<<n);
       
   296 }
       
   297 
       
   298 
       
   299 /*
       
   300  *
       
   301  * bibSkipBitsFunc:
       
   302  *
       
   303  * Parameters:
       
   304  *      bitbuf                Bitbuffer object
       
   305  *      n                     Number of bits to skip
       
   306  *
       
   307  * Function:
       
   308  *      Skip next n bits in the bitbuffer
       
   309  *
       
   310  * Returns:
       
   311  *      BIB_OK for no error and BIB_ERR_NO_BITS for end of buffer.
       
   312  *
       
   313  */
       
   314 int bibSkipBitsFunc(bitbuffer_s *bitbuf, int n)
       
   315 {
       
   316   /* Fill bitbuf->currentBits with bits */
       
   317   while (n > bitbuf->bitpos && bitbuf->bytePos < bitbuf->dataLen) {
       
   318     bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++];
       
   319     bitbuf->bitpos += 8;
       
   320   }
       
   321 
       
   322   bitbuf->bitpos -= n;
       
   323 
       
   324   /* Check for buffer underrun */
       
   325   if (bitbuf->bitpos < 0) {
       
   326     bitbuf->errorStatus = BIB_ERR_NO_BITS;
       
   327     return BIB_ERR_NO_BITS;
       
   328   }
       
   329 
       
   330   return BIB_OK;
       
   331 }
       
   332 
       
   333 
       
   334 /*
       
   335  *
       
   336  * bibGetByte:
       
   337  *
       
   338  * Parameters:
       
   339  *      bitbuf                Bitbuffer object
       
   340  *      byteRet               Return pointer for byte
       
   341  *
       
   342  * Function:
       
   343  *      Get next byte aligned byte from bitbuffer.
       
   344  *
       
   345  * Returns:
       
   346  *      1 for End Of Stream, 0 otherwise
       
   347  *
       
   348  */
       
   349 int bibGetByte(bitbuffer_s *bitbuf, int *byteRet)
       
   350 {
       
   351   if (bitbuf->bitpos >= 8) {
       
   352     bitbuf->bitpos = bitbuf->bitpos & ~7;
       
   353     *byteRet = (bitbuf->currentBits >> (bitbuf->bitpos - 8)) & 0xff;
       
   354     bitbuf->bitpos -= 8;
       
   355   }
       
   356   else {
       
   357     bitbuf->bitpos = 0;
       
   358 
       
   359     if (bitbuf->bytePos >= bitbuf->dataLen) {
       
   360       return 1;
       
   361     }
       
   362 
       
   363     *byteRet = bitbuf->data[bitbuf->bytePos++];
       
   364   }
       
   365 
       
   366   return 0;
       
   367 }
       
   368 
       
   369 
       
   370 /*
       
   371  *
       
   372  * bibByteAlign:
       
   373  *
       
   374  * Parameters:
       
   375  *      bitbuf                Bitbuffer object
       
   376  *
       
   377  * Function:
       
   378  *      Set bitbuffer pointer to next byte aligned position.
       
   379  *
       
   380  * Returns:
       
   381  *      Number of bits skipped as a result of aligning.
       
   382  *
       
   383  */
       
   384 int bibByteAlign(bitbuffer_s *bitbuf)
       
   385 {
       
   386   int bitpos = bitbuf->bitpos;
       
   387 
       
   388   bitbuf->bitpos = bitbuf->bitpos & ~7;
       
   389 
       
   390   return (bitpos - bitbuf->bitpos);
       
   391 }
       
   392 
       
   393 
       
   394 /*
       
   395  * bibSkipTrailingBits:
       
   396  *
       
   397  * Parameters:
       
   398  *      bitbuf                Bitbuffer object
       
   399  *
       
   400  * Function:
       
   401  *      Skip the trailing bits at the end of a NAL unit
       
   402  *
       
   403  * Returns:
       
   404  *      The number of bits being skipped or <0 for error.
       
   405  */
       
   406 int bibSkipTrailingBits(bitbuffer_s *bitbuf)
       
   407 {
       
   408   int ret;
       
   409   int len = 0;
       
   410   int bit = 0;
       
   411 
       
   412   bit = bibGetBitFunc(bitbuf);
       
   413   len++;
       
   414 
       
   415   ret = bibGetStatus(bitbuf);
       
   416   if (ret < 0)
       
   417     return ret;
       
   418 
       
   419   /* First we expect to receive 1 bit */
       
   420   if (bit != 1) {
       
   421     bibRaiseError(bitbuf, BIB_INCORRECT_TRAILING_BIT);
       
   422     return BIB_INCORRECT_TRAILING_BIT;
       
   423   }
       
   424 
       
   425   /* Remaining bits in current byte should be zero */
       
   426   while ( bitbuf->bitpos % 8 != 0 ) {  
       
   427     bibGetBit(bitbuf, &bit);
       
   428     len++;
       
   429     if (bit != 0) {
       
   430       bibRaiseError(bitbuf, BIB_INCORRECT_TRAILING_BIT);
       
   431       return BIB_INCORRECT_TRAILING_BIT;
       
   432     }
       
   433   }
       
   434 
       
   435   ret = bibGetStatus(bitbuf);
       
   436   if (ret < 0)
       
   437     return ret;
       
   438 
       
   439   return len;
       
   440 }
       
   441 
       
   442 
       
   443 /*
       
   444  * bibMoreRbspData:
       
   445  *
       
   446  * Parameters:
       
   447  *      bitbuf                Bitbuffer object
       
   448  *
       
   449  * Function:
       
   450  *      Check if there is more RBSP data in the bitbuffer.
       
   451  *
       
   452  * Returns:
       
   453  *      0: no more rbsp data
       
   454  *      1: more rbsp data
       
   455  */
       
   456 int bibMoreRbspData(bitbuffer_s *bitbuf)
       
   457 {
       
   458   int numBytesLeft;
       
   459   u_int32 lastBits;
       
   460 
       
   461   numBytesLeft = bitbuf->dataLen - bitbuf->bytePos;
       
   462 
       
   463   if (numBytesLeft >= 2 || (numBytesLeft*8 + bitbuf->bitpos >= 9))
       
   464     /* If there are at least 9 bits left, it is certain to have more rbsp data */
       
   465     return 1;
       
   466 
       
   467   if (numBytesLeft == 0 && bitbuf->bitpos == 0)
       
   468     /* Something may be wrong. Normally, there should be at least one bit left */
       
   469     return 0;
       
   470 
       
   471   if (numBytesLeft == 1) {
       
   472     /* Insert last byte to currentBits */
       
   473     bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++];
       
   474     bitbuf->bitpos += 8;
       
   475   }
       
   476 
       
   477   /* Copy the last bits into "lastBits", then compare it with 0x1..00 */
       
   478   lastBits = bitbuf->currentBits & ~(((u_int32)-1)<<bitbuf->bitpos);
       
   479 
       
   480   if (lastBits == ((u_int32)1 << (bitbuf->bitpos-1)))
       
   481     return 0;
       
   482   else
       
   483     return 1;
       
   484 }
       
   485 
       
   486 
       
   487 /*
       
   488  * bibGetNumOfRemainingBits:
       
   489  *
       
   490  * Parameters:
       
   491  *      bitbuf                Bitbuffer object
       
   492  *
       
   493  * Function:
       
   494  *      Return number of bits in bitbuffer.
       
   495  *
       
   496  * Returns:
       
   497  *      Number of bits
       
   498  */
       
   499 int32 bibGetNumRemainingBits(bitbuffer_s *bitbuf)
       
   500 {
       
   501   return bitbuf->bitpos + 8*(bitbuf->dataLen - bitbuf->bytePos);
       
   502 }
       
   503 
       
   504 
       
   505 // syncBitBufferBitpos
       
   506 // Synchronizes the input bit buffer's bit position to be between one and eight, 
       
   507 // modifies the byte position and current bits if required.
       
   508 void syncBitBufferBitpos(bitbuffer_s *bitbuf)
       
   509 {
       
   510 	// To be able to edit the bitbuffer, reset the bit position to be eight at the maximum
       
   511 	while (bitbuf->bitpos > 8)
       
   512 	{
       
   513 		// If bit position is modified, then modify byte position and current bits accordingly
       
   514 		bitbuf->bitpos -= 8;
       
   515 		bitbuf->bytePos--;
       
   516 		bitbuf->currentBits >>= 8;
       
   517 	}
       
   518 }
       
   519 
       
   520 
       
   521 // addStartCodeEmulationBytes
       
   522 // Adds start code emulation bytes to the input bit buffer.
       
   523 static int addStartCodeEmulationBytes(bitbuffer_s *bitbuf)
       
   524 {
       
   525   	TInt i = 0;
       
   526   	TInt32 lastBytes;
       
   527 
       
   528 
       
   529   	// Add prevention bytes that were removed for processing
       
   530   	lastBytes = 0xffffffff;
       
   531   	while (i < bitbuf->dataLen) 
       
   532   	{
       
   533     	lastBytes = (lastBytes << 8) | bitbuf->data[i];
       
   534     	
       
   535     	if(((lastBytes & 0xffff) == 0x0000) && ((i+1) < bitbuf->dataLen) && (bitbuf->data[i+1] < 4))
       
   536     	{
       
   537 			// Add byte(s) to the bit buffer
       
   538 			TInt error = AddBytesToBuffer(bitbuf, 1);
       
   539 
       
   540 			if (error != 0)
       
   541 				return error;
       
   542 
       
   543     		// Adjust data length
       
   544     		bitbuf->dataLen++;
       
   545 
       
   546     		// Make room for the emulation prevention byte 0x03 to the buffer
       
   547     		for (TInt k=bitbuf->dataLen; k>i; k--)
       
   548     		{
       
   549     			bitbuf->data[k] = bitbuf->data[k-1];
       
   550     		}
       
   551     		
       
   552     		// Add the emulation prevention byte to the buffer
       
   553       		bitbuf->data[i+1] = 0x03;
       
   554     	}
       
   555     	
       
   556     	i++;
       
   557   	}
       
   558 	return KErrNone;
       
   559 }
       
   560 
       
   561 
       
   562 // bibEnd
       
   563 // Takes care of the bit buffer after the frame has been processed.
       
   564 int bibEnd(bitbuffer_s *bitbuf)
       
   565 {
       
   566 #if ENCAPSULATED_NAL_PAYLOAD
       
   567   	return addStartCodeEmulationBytes(bitbuf);
       
   568 #endif
       
   569 }
       
   570 
       
   571 
       
   572 // addStartCodeEmulationBytesSlice
       
   573 // Adds start code emulation bytes to the input bit buffer.
       
   574 static void addStartCodeEmulationBytesSlice(bitbuffer_s *bitbuf)
       
   575 {
       
   576   	TInt i = 0;
       
   577   	TInt32 lastBytes;
       
   578 
       
   579 
       
   580   	// Add prevention bytes that were removed for processing
       
   581   	lastBytes = 0xffffffff;
       
   582   	while (i < bitbuf->dataLen) 
       
   583   	{
       
   584     	lastBytes = (lastBytes << 8) | bitbuf->data[i];
       
   585     	
       
   586     	if(((lastBytes & 0xffff) == 0x0000) && ((i+1) < bitbuf->dataLen) && (bitbuf->data[i+1] < 4))
       
   587     	{
       
   588     		// Make room for the emulation prevention byte 0x03 to the buffer
       
   589     		for (TInt k=bitbuf->dataLen; k>i; k--)
       
   590     		{
       
   591     			bitbuf->data[k] = bitbuf->data[k-1];
       
   592     		}
       
   593     		// Adjust data length
       
   594     		bitbuf->dataLen++;
       
   595     		
       
   596     		// Add the emulation prevention byte to the buffer
       
   597       		bitbuf->data[i+1] = 0x03;
       
   598     	}
       
   599     	
       
   600     	i++;
       
   601   	}
       
   602 }
       
   603 
       
   604 
       
   605 // bibEndSlice
       
   606 // Takes care of the bit buffer after the frame has been processed.
       
   607 void bibEndSlice(bitbuffer_s *bitbuf)
       
   608 {
       
   609 #if ENCAPSULATED_NAL_PAYLOAD
       
   610   	addStartCodeEmulationBytesSlice(bitbuf);
       
   611 #endif
       
   612 }
       
   613