blob: 99f53ca7c00739f570f734c19914bc81759964bf [file] [log] [blame]
/*
* Copyright (C) 2007-2008 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/**
*
* File Name: armCOMM_Bitstream.c
* OpenMAX DL: v1.0.2
* Revision: 9641
* Date: Thursday, February 7, 2008
*
*
*
*
* Defines bitstream encode and decode functions common to all codecs
*/
#include "omxtypes.h"
#include "armCOMM.h"
#include "armCOMM_Bitstream.h"
/***************************************
* Fixed bit length Decode
***************************************/
/**
* Function: armLookAheadBits()
*
* Description:
* Get the next N bits from the bitstream without advancing the bitstream pointer
*
* Parameters:
* [in] **ppBitStream
* [in] *pOffset
* [in] N=1...32
*
* Returns Value
*/
OMX_U32 armLookAheadBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N)
{
const OMX_U8 *pBitStream = *ppBitStream;
OMX_INT Offset = *pOffset;
OMX_U32 Value;
armAssert(Offset>=0 && Offset<=7);
armAssert(N>=1 && N<=32);
/* Read next 32 bits from stream */
Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
/* Return N bits */
return Value >> (32-N);
}
/**
* Function: armGetBits()
*
* Description:
* Read N bits from the bitstream
*
* Parameters:
* [in] *ppBitStream
* [in] *pOffset
* [in] N=1..32
*
* [out] *ppBitStream
* [out] *pOffset
* Returns Value
*/
OMX_U32 armGetBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N)
{
const OMX_U8 *pBitStream = *ppBitStream;
OMX_INT Offset = *pOffset;
OMX_U32 Value;
if(N == 0)
{
return 0;
}
armAssert(Offset>=0 && Offset<=7);
armAssert(N>=1 && N<=32);
/* Read next 32 bits from stream */
Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
/* Advance bitstream pointer by N bits */
Offset += N;
*ppBitStream = pBitStream + (Offset>>3);
*pOffset = Offset & 7;
/* Return N bits */
return Value >> (32-N);
}
/**
* Function: armByteAlign()
*
* Description:
* Align the pointer *ppBitStream to the next byte boundary
*
* Parameters:
* [in] *ppBitStream
* [in] *pOffset
*
* [out] *ppBitStream
* [out] *pOffset
*
**/
OMXVoid armByteAlign(const OMX_U8 **ppBitStream,OMX_INT *pOffset)
{
if(*pOffset > 0)
{
*ppBitStream += 1;
*pOffset = 0;
}
}
/**
* Function: armSkipBits()
*
* Description:
* Skip N bits from the value at *ppBitStream
*
* Parameters:
* [in] *ppBitStream
* [in] *pOffset
* [in] N
*
* [out] *ppBitStream
* [out] *pOffset
*
**/
OMXVoid armSkipBits(const OMX_U8 **ppBitStream,OMX_INT *pOffset,OMX_INT N)
{
OMX_INT Offset = *pOffset;
const OMX_U8 *pBitStream = *ppBitStream;
/* Advance bitstream pointer by N bits */
Offset += N;
*ppBitStream = pBitStream + (Offset>>3);
*pOffset = Offset & 7;
}
/***************************************
* Variable bit length Decode
***************************************/
/**
* Function: armUnPackVLC32()
*
* Description:
* Variable length decode of variable length symbol (max size 32 bits) read from
* the bit stream pointed by *ppBitStream at *pOffset by using the table
* pointed by pCodeBook
*
* Parameters:
* [in] *pBitStream
* [in] *pOffset
* [in] pCodeBook
*
* [out] *pBitStream
* [out] *pOffset
*
* Returns : Code Book Index if successfull.
* : ARM_NO_CODEBOOK_INDEX = -1 if search fails.
**/
#ifndef C_OPTIMIZED_IMPLEMENTATION
OMX_U16 armUnPackVLC32(
const OMX_U8 **ppBitStream,
OMX_INT *pOffset,
const ARM_VLC32 *pCodeBook
)
{
const OMX_U8 *pBitStream = *ppBitStream;
OMX_INT Offset = *pOffset;
OMX_U32 Value;
OMX_INT Index;
armAssert(Offset>=0 && Offset<=7);
/* Read next 32 bits from stream */
Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
/* Search through the codebook */
for (Index=0; pCodeBook->codeLen != 0; Index++)
{
if (pCodeBook->codeWord == (Value >> (32 - pCodeBook->codeLen)))
{
Offset = Offset + pCodeBook->codeLen;
*ppBitStream = pBitStream + (Offset >> 3) ;
*pOffset = Offset & 7;
return Index;
}
pCodeBook++;
}
/* No code match found */
return ARM_NO_CODEBOOK_INDEX;
}
#endif
/***************************************
* Fixed bit length Encode
***************************************/
/**
* Function: armPackBits
*
* Description:
* Pack a VLC code word into the bitstream
*
* Remarks:
*
* Parameters:
* [in] ppBitStream pointer to the pointer to the current byte
* in the bit stream.
* [in] pOffset pointer to the bit position in the byte
* pointed by *ppBitStream. Valid within 0
* to 7.
* [in] codeWord Code word that need to be inserted in to the
* bitstream
* [in] codeLength Length of the code word valid range 1...32
*
* [out] ppBitStream *ppBitStream is updated after the block is encoded,
* so that it points to the current byte in the bit
* stream buffer.
* [out] pBitOffset *pBitOffset is updated so that it points to the
* current bit position in the byte pointed by
* *ppBitStream.
*
* Return Value:
* Standard OMX_RESULT result. See enumeration for possible result codes.
*
*/
OMXResult armPackBits (
OMX_U8 **ppBitStream,
OMX_INT *pOffset,
OMX_U32 codeWord,
OMX_INT codeLength
)
{
OMX_U8 *pBitStream = *ppBitStream;
OMX_INT Offset = *pOffset;
OMX_U32 Value;
/* checking argument validity */
armRetArgErrIf(Offset < 0, OMX_Sts_BadArgErr);
armRetArgErrIf(Offset > 7, OMX_Sts_BadArgErr);
armRetArgErrIf(codeLength < 1, OMX_Sts_BadArgErr);
armRetArgErrIf(codeLength > 32, OMX_Sts_BadArgErr);
/* Prepare the first byte */
codeWord = codeWord << (32-codeLength);
Value = (pBitStream[0] >> (8-Offset)) << (8-Offset);
Value = Value | (codeWord >> (24+Offset));
/* Write out whole bytes */
while (8-Offset <= codeLength)
{
*pBitStream++ = (OMX_U8)Value;
codeWord = codeWord << (8-Offset);
codeLength = codeLength - (8-Offset);
Offset = 0;
Value = codeWord >> 24;
}
/* Write out final partial byte */
*pBitStream = (OMX_U8)Value;
*ppBitStream = pBitStream;
*pOffset = Offset + codeLength;
return OMX_Sts_NoErr;
}
/***************************************
* Variable bit length Encode
***************************************/
/**
* Function: armPackVLC32
*
* Description:
* Pack a VLC code word into the bitstream
*
* Remarks:
*
* Parameters:
* [in] ppBitStream pointer to the pointer to the current byte
* in the bit stream.
* [in] pBitOffset pointer to the bit position in the byte
* pointed by *ppBitStream. Valid within 0
* to 7.
* [in] code VLC code word that need to be inserted in to the
* bitstream
*
* [out] ppBitStream *ppBitStream is updated after the block is encoded,
* so that it points to the current byte in the bit
* stream buffer.
* [out] pBitOffset *pBitOffset is updated so that it points to the
* current bit position in the byte pointed by
* *ppBitStream.
*
* Return Value:
* Standard OMX_RESULT result. See enumeration for possible result codes.
*
*/
OMXResult armPackVLC32 (
OMX_U8 **ppBitStream,
OMX_INT *pBitOffset,
ARM_VLC32 code
)
{
return (armPackBits(ppBitStream, pBitOffset, code.codeWord, code.codeLen));
}
/*End of File*/