10c1bc742181ded4930842b46e9507372f0b1b963James Dong/*
20c1bc742181ded4930842b46e9507372f0b1b963James Dong * Copyright (C) 2009 The Android Open Source Project
30c1bc742181ded4930842b46e9507372f0b1b963James Dong *
40c1bc742181ded4930842b46e9507372f0b1b963James Dong * Licensed under the Apache License, Version 2.0 (the "License");
50c1bc742181ded4930842b46e9507372f0b1b963James Dong * you may not use this file except in compliance with the License.
60c1bc742181ded4930842b46e9507372f0b1b963James Dong * You may obtain a copy of the License at
70c1bc742181ded4930842b46e9507372f0b1b963James Dong *
80c1bc742181ded4930842b46e9507372f0b1b963James Dong *      http://www.apache.org/licenses/LICENSE-2.0
90c1bc742181ded4930842b46e9507372f0b1b963James Dong *
100c1bc742181ded4930842b46e9507372f0b1b963James Dong * Unless required by applicable law or agreed to in writing, software
110c1bc742181ded4930842b46e9507372f0b1b963James Dong * distributed under the License is distributed on an "AS IS" BASIS,
120c1bc742181ded4930842b46e9507372f0b1b963James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130c1bc742181ded4930842b46e9507372f0b1b963James Dong * See the License for the specific language governing permissions and
140c1bc742181ded4930842b46e9507372f0b1b963James Dong * limitations under the License.
150c1bc742181ded4930842b46e9507372f0b1b963James Dong */
160c1bc742181ded4930842b46e9507372f0b1b963James Dong
170c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------
180c1bc742181ded4930842b46e9507372f0b1b963James Dong
190c1bc742181ded4930842b46e9507372f0b1b963James Dong    Table of contents
200c1bc742181ded4930842b46e9507372f0b1b963James Dong
210c1bc742181ded4930842b46e9507372f0b1b963James Dong     1. Include headers
220c1bc742181ded4930842b46e9507372f0b1b963James Dong     2. External compiler flags
230c1bc742181ded4930842b46e9507372f0b1b963James Dong     3. Module defines
240c1bc742181ded4930842b46e9507372f0b1b963James Dong     4. Local function prototypes
250c1bc742181ded4930842b46e9507372f0b1b963James Dong     5. Functions
260c1bc742181ded4930842b46e9507372f0b1b963James Dong          h264bsdGetBits
270c1bc742181ded4930842b46e9507372f0b1b963James Dong          h264bsdShowBits32
280c1bc742181ded4930842b46e9507372f0b1b963James Dong          h264bsdFlushBits
290c1bc742181ded4930842b46e9507372f0b1b963James Dong          h264bsdIsByteAligned
300c1bc742181ded4930842b46e9507372f0b1b963James Dong
310c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/
320c1bc742181ded4930842b46e9507372f0b1b963James Dong
330c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------
340c1bc742181ded4930842b46e9507372f0b1b963James Dong    1. Include headers
350c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/
360c1bc742181ded4930842b46e9507372f0b1b963James Dong
370c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "h264bsd_util.h"
380c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "h264bsd_stream.h"
390c1bc742181ded4930842b46e9507372f0b1b963James Dong
400c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------
410c1bc742181ded4930842b46e9507372f0b1b963James Dong    2. External compiler flags
420c1bc742181ded4930842b46e9507372f0b1b963James Dong--------------------------------------------------------------------------------
430c1bc742181ded4930842b46e9507372f0b1b963James Dong
440c1bc742181ded4930842b46e9507372f0b1b963James Dong--------------------------------------------------------------------------------
450c1bc742181ded4930842b46e9507372f0b1b963James Dong    3. Module defines
460c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/
470c1bc742181ded4930842b46e9507372f0b1b963James Dong
480c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------
490c1bc742181ded4930842b46e9507372f0b1b963James Dong    4. Local function prototypes
500c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/
510c1bc742181ded4930842b46e9507372f0b1b963James Dong
520c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------
530c1bc742181ded4930842b46e9507372f0b1b963James Dong
540c1bc742181ded4930842b46e9507372f0b1b963James Dong    Function: h264bsdGetBits
550c1bc742181ded4930842b46e9507372f0b1b963James Dong
560c1bc742181ded4930842b46e9507372f0b1b963James Dong        Functional description:
570c1bc742181ded4930842b46e9507372f0b1b963James Dong            Read and remove bits from the stream buffer.
580c1bc742181ded4930842b46e9507372f0b1b963James Dong
590c1bc742181ded4930842b46e9507372f0b1b963James Dong        Input:
600c1bc742181ded4930842b46e9507372f0b1b963James Dong            pStrmData   pointer to stream data structure
610c1bc742181ded4930842b46e9507372f0b1b963James Dong            numBits     number of bits to read
620c1bc742181ded4930842b46e9507372f0b1b963James Dong
630c1bc742181ded4930842b46e9507372f0b1b963James Dong        Output:
640c1bc742181ded4930842b46e9507372f0b1b963James Dong            none
650c1bc742181ded4930842b46e9507372f0b1b963James Dong
660c1bc742181ded4930842b46e9507372f0b1b963James Dong        Returns:
670c1bc742181ded4930842b46e9507372f0b1b963James Dong            bits read from stream
680c1bc742181ded4930842b46e9507372f0b1b963James Dong            END_OF_STREAM if not enough bits left
690c1bc742181ded4930842b46e9507372f0b1b963James Dong
700c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/
710c1bc742181ded4930842b46e9507372f0b1b963James Dong
720c1bc742181ded4930842b46e9507372f0b1b963James Dongu32 h264bsdGetBits(strmData_t *pStrmData, u32 numBits)
730c1bc742181ded4930842b46e9507372f0b1b963James Dong{
740c1bc742181ded4930842b46e9507372f0b1b963James Dong
750c1bc742181ded4930842b46e9507372f0b1b963James Dong    u32 out;
760c1bc742181ded4930842b46e9507372f0b1b963James Dong
770c1bc742181ded4930842b46e9507372f0b1b963James Dong    ASSERT(pStrmData);
780c1bc742181ded4930842b46e9507372f0b1b963James Dong    ASSERT(numBits < 32);
790c1bc742181ded4930842b46e9507372f0b1b963James Dong
800c1bc742181ded4930842b46e9507372f0b1b963James Dong    out = h264bsdShowBits32(pStrmData) >> (32 - numBits);
810c1bc742181ded4930842b46e9507372f0b1b963James Dong
820c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (h264bsdFlushBits(pStrmData, numBits) == HANTRO_OK)
830c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
840c1bc742181ded4930842b46e9507372f0b1b963James Dong        return(out);
850c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
860c1bc742181ded4930842b46e9507372f0b1b963James Dong    else
870c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
880c1bc742181ded4930842b46e9507372f0b1b963James Dong        return(END_OF_STREAM);
890c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
900c1bc742181ded4930842b46e9507372f0b1b963James Dong
910c1bc742181ded4930842b46e9507372f0b1b963James Dong}
920c1bc742181ded4930842b46e9507372f0b1b963James Dong
930c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------
940c1bc742181ded4930842b46e9507372f0b1b963James Dong
950c1bc742181ded4930842b46e9507372f0b1b963James Dong    Function: h264bsdShowBits32
960c1bc742181ded4930842b46e9507372f0b1b963James Dong
970c1bc742181ded4930842b46e9507372f0b1b963James Dong        Functional description:
980c1bc742181ded4930842b46e9507372f0b1b963James Dong            Read 32 bits from the stream buffer. Buffer is left as it is, i.e.
990c1bc742181ded4930842b46e9507372f0b1b963James Dong            no bits are removed. First bit read from the stream is the MSB of
1000c1bc742181ded4930842b46e9507372f0b1b963James Dong            the return value. If there is not enough bits in the buffer ->
1010c1bc742181ded4930842b46e9507372f0b1b963James Dong            bits beyong the end of the stream are set to '0' in the return
1020c1bc742181ded4930842b46e9507372f0b1b963James Dong            value.
1030c1bc742181ded4930842b46e9507372f0b1b963James Dong
1040c1bc742181ded4930842b46e9507372f0b1b963James Dong        Input:
1050c1bc742181ded4930842b46e9507372f0b1b963James Dong            pStrmData   pointer to stream data structure
1060c1bc742181ded4930842b46e9507372f0b1b963James Dong
1070c1bc742181ded4930842b46e9507372f0b1b963James Dong        Output:
1080c1bc742181ded4930842b46e9507372f0b1b963James Dong            none
1090c1bc742181ded4930842b46e9507372f0b1b963James Dong
1100c1bc742181ded4930842b46e9507372f0b1b963James Dong        Returns:
1110c1bc742181ded4930842b46e9507372f0b1b963James Dong            bits read from stream
1120c1bc742181ded4930842b46e9507372f0b1b963James Dong
1130c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/
1140c1bc742181ded4930842b46e9507372f0b1b963James Dong
1150c1bc742181ded4930842b46e9507372f0b1b963James Dongu32 h264bsdShowBits32(strmData_t *pStrmData)
1160c1bc742181ded4930842b46e9507372f0b1b963James Dong{
1170c1bc742181ded4930842b46e9507372f0b1b963James Dong
1180c1bc742181ded4930842b46e9507372f0b1b963James Dong    i32 bits, shift;
1190c1bc742181ded4930842b46e9507372f0b1b963James Dong    u32 out;
1200c1bc742181ded4930842b46e9507372f0b1b963James Dong    u8 *pStrm;
1210c1bc742181ded4930842b46e9507372f0b1b963James Dong
1220c1bc742181ded4930842b46e9507372f0b1b963James Dong    ASSERT(pStrmData);
1230c1bc742181ded4930842b46e9507372f0b1b963James Dong    ASSERT(pStrmData->pStrmCurrPos);
1240c1bc742181ded4930842b46e9507372f0b1b963James Dong    ASSERT(pStrmData->bitPosInWord < 8);
1250c1bc742181ded4930842b46e9507372f0b1b963James Dong    ASSERT(pStrmData->bitPosInWord ==
1260c1bc742181ded4930842b46e9507372f0b1b963James Dong           (pStrmData->strmBuffReadBits & 0x7));
1270c1bc742181ded4930842b46e9507372f0b1b963James Dong
1280c1bc742181ded4930842b46e9507372f0b1b963James Dong    pStrm = pStrmData->pStrmCurrPos;
1290c1bc742181ded4930842b46e9507372f0b1b963James Dong
1300c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* number of bits left in the buffer */
1310c1bc742181ded4930842b46e9507372f0b1b963James Dong    bits = (i32)pStrmData->strmBuffSize*8 - (i32)pStrmData->strmBuffReadBits;
1320c1bc742181ded4930842b46e9507372f0b1b963James Dong
1330c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* at least 32-bits in the buffer */
1340c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (bits >= 32)
1350c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
1360c1bc742181ded4930842b46e9507372f0b1b963James Dong        u32 bitPosInWord = pStrmData->bitPosInWord;
1370c1bc742181ded4930842b46e9507372f0b1b963James Dong        out = ((u32)pStrm[0] << 24) | ((u32)pStrm[1] << 16) |
1380c1bc742181ded4930842b46e9507372f0b1b963James Dong              ((u32)pStrm[2] <<  8) | ((u32)pStrm[3]);
1390c1bc742181ded4930842b46e9507372f0b1b963James Dong
1400c1bc742181ded4930842b46e9507372f0b1b963James Dong        if (bitPosInWord)
1410c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1420c1bc742181ded4930842b46e9507372f0b1b963James Dong            u32 byte = (u32)pStrm[4];
1430c1bc742181ded4930842b46e9507372f0b1b963James Dong            u32 tmp = (8-bitPosInWord);
1440c1bc742181ded4930842b46e9507372f0b1b963James Dong            out <<= bitPosInWord;
1450c1bc742181ded4930842b46e9507372f0b1b963James Dong            out |= byte>>tmp;
1460c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1470c1bc742181ded4930842b46e9507372f0b1b963James Dong        return (out);
1480c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1490c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* at least one bit in the buffer */
1500c1bc742181ded4930842b46e9507372f0b1b963James Dong    else if (bits > 0)
1510c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
1520c1bc742181ded4930842b46e9507372f0b1b963James Dong        shift = (i32)(24 + pStrmData->bitPosInWord);
1530c1bc742181ded4930842b46e9507372f0b1b963James Dong        out = (u32)(*pStrm++) << shift;
1540c1bc742181ded4930842b46e9507372f0b1b963James Dong        bits -= (i32)(8 - pStrmData->bitPosInWord);
1550c1bc742181ded4930842b46e9507372f0b1b963James Dong        while (bits > 0)
1560c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
1570c1bc742181ded4930842b46e9507372f0b1b963James Dong            shift -= 8;
1580c1bc742181ded4930842b46e9507372f0b1b963James Dong            out |= (u32)(*pStrm++) << shift;
1590c1bc742181ded4930842b46e9507372f0b1b963James Dong            bits -= 8;
1600c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1610c1bc742181ded4930842b46e9507372f0b1b963James Dong        return (out);
1620c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1630c1bc742181ded4930842b46e9507372f0b1b963James Dong    else
1640c1bc742181ded4930842b46e9507372f0b1b963James Dong        return (0);
1650c1bc742181ded4930842b46e9507372f0b1b963James Dong
1660c1bc742181ded4930842b46e9507372f0b1b963James Dong}
1670c1bc742181ded4930842b46e9507372f0b1b963James Dong
1680c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------
1690c1bc742181ded4930842b46e9507372f0b1b963James Dong
1700c1bc742181ded4930842b46e9507372f0b1b963James Dong    Function: h264bsdFlushBits
1710c1bc742181ded4930842b46e9507372f0b1b963James Dong
1720c1bc742181ded4930842b46e9507372f0b1b963James Dong        Functional description:
1730c1bc742181ded4930842b46e9507372f0b1b963James Dong            Remove bits from the stream buffer
1740c1bc742181ded4930842b46e9507372f0b1b963James Dong
1750c1bc742181ded4930842b46e9507372f0b1b963James Dong        Input:
1760c1bc742181ded4930842b46e9507372f0b1b963James Dong            pStrmData       pointer to stream data structure
1770c1bc742181ded4930842b46e9507372f0b1b963James Dong            numBits         number of bits to remove
1780c1bc742181ded4930842b46e9507372f0b1b963James Dong
1790c1bc742181ded4930842b46e9507372f0b1b963James Dong        Output:
1800c1bc742181ded4930842b46e9507372f0b1b963James Dong            none
1810c1bc742181ded4930842b46e9507372f0b1b963James Dong
1820c1bc742181ded4930842b46e9507372f0b1b963James Dong        Returns:
1830c1bc742181ded4930842b46e9507372f0b1b963James Dong            HANTRO_OK       success
1840c1bc742181ded4930842b46e9507372f0b1b963James Dong            END_OF_STREAM   not enough bits left
1850c1bc742181ded4930842b46e9507372f0b1b963James Dong
1860c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/
1870c1bc742181ded4930842b46e9507372f0b1b963James Dong#ifndef H264DEC_NEON
1880c1bc742181ded4930842b46e9507372f0b1b963James Dongu32 h264bsdFlushBits(strmData_t *pStrmData, u32 numBits)
1890c1bc742181ded4930842b46e9507372f0b1b963James Dong{
1900c1bc742181ded4930842b46e9507372f0b1b963James Dong
1910c1bc742181ded4930842b46e9507372f0b1b963James Dong    ASSERT(pStrmData);
1920c1bc742181ded4930842b46e9507372f0b1b963James Dong    ASSERT(pStrmData->pStrmBuffStart);
1930c1bc742181ded4930842b46e9507372f0b1b963James Dong    ASSERT(pStrmData->pStrmCurrPos);
1940c1bc742181ded4930842b46e9507372f0b1b963James Dong    ASSERT(pStrmData->bitPosInWord < 8);
1950c1bc742181ded4930842b46e9507372f0b1b963James Dong    ASSERT(pStrmData->bitPosInWord == (pStrmData->strmBuffReadBits & 0x7));
1960c1bc742181ded4930842b46e9507372f0b1b963James Dong
1970c1bc742181ded4930842b46e9507372f0b1b963James Dong    pStrmData->strmBuffReadBits += numBits;
1980c1bc742181ded4930842b46e9507372f0b1b963James Dong    pStrmData->bitPosInWord = pStrmData->strmBuffReadBits & 0x7;
1990c1bc742181ded4930842b46e9507372f0b1b963James Dong    if ( (pStrmData->strmBuffReadBits ) <= (8*pStrmData->strmBuffSize) )
2000c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
2010c1bc742181ded4930842b46e9507372f0b1b963James Dong        pStrmData->pStrmCurrPos = pStrmData->pStrmBuffStart +
2020c1bc742181ded4930842b46e9507372f0b1b963James Dong            (pStrmData->strmBuffReadBits >> 3);
2030c1bc742181ded4930842b46e9507372f0b1b963James Dong        return(HANTRO_OK);
2040c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
2050c1bc742181ded4930842b46e9507372f0b1b963James Dong    else
2060c1bc742181ded4930842b46e9507372f0b1b963James Dong        return(END_OF_STREAM);
2070c1bc742181ded4930842b46e9507372f0b1b963James Dong
2080c1bc742181ded4930842b46e9507372f0b1b963James Dong}
2090c1bc742181ded4930842b46e9507372f0b1b963James Dong#endif
2100c1bc742181ded4930842b46e9507372f0b1b963James Dong/*------------------------------------------------------------------------------
2110c1bc742181ded4930842b46e9507372f0b1b963James Dong
2120c1bc742181ded4930842b46e9507372f0b1b963James Dong    Function: h264bsdIsByteAligned
2130c1bc742181ded4930842b46e9507372f0b1b963James Dong
2140c1bc742181ded4930842b46e9507372f0b1b963James Dong        Functional description:
2150c1bc742181ded4930842b46e9507372f0b1b963James Dong            Check if current stream position is byte aligned.
2160c1bc742181ded4930842b46e9507372f0b1b963James Dong
2170c1bc742181ded4930842b46e9507372f0b1b963James Dong        Inputs:
2180c1bc742181ded4930842b46e9507372f0b1b963James Dong            pStrmData   pointer to stream data structure
2190c1bc742181ded4930842b46e9507372f0b1b963James Dong
2200c1bc742181ded4930842b46e9507372f0b1b963James Dong        Outputs:
2210c1bc742181ded4930842b46e9507372f0b1b963James Dong            none
2220c1bc742181ded4930842b46e9507372f0b1b963James Dong
2230c1bc742181ded4930842b46e9507372f0b1b963James Dong        Returns:
2240c1bc742181ded4930842b46e9507372f0b1b963James Dong            TRUE        stream is byte aligned
2250c1bc742181ded4930842b46e9507372f0b1b963James Dong            FALSE       stream is not byte aligned
2260c1bc742181ded4930842b46e9507372f0b1b963James Dong
2270c1bc742181ded4930842b46e9507372f0b1b963James Dong------------------------------------------------------------------------------*/
2280c1bc742181ded4930842b46e9507372f0b1b963James Dong
2290c1bc742181ded4930842b46e9507372f0b1b963James Dongu32 h264bsdIsByteAligned(strmData_t *pStrmData)
2300c1bc742181ded4930842b46e9507372f0b1b963James Dong{
2310c1bc742181ded4930842b46e9507372f0b1b963James Dong
2320c1bc742181ded4930842b46e9507372f0b1b963James Dong/* Variables */
2330c1bc742181ded4930842b46e9507372f0b1b963James Dong
2340c1bc742181ded4930842b46e9507372f0b1b963James Dong/* Code */
2350c1bc742181ded4930842b46e9507372f0b1b963James Dong
2360c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (!pStrmData->bitPosInWord)
2370c1bc742181ded4930842b46e9507372f0b1b963James Dong        return(HANTRO_TRUE);
2380c1bc742181ded4930842b46e9507372f0b1b963James Dong    else
2390c1bc742181ded4930842b46e9507372f0b1b963James Dong        return(HANTRO_FALSE);
2400c1bc742181ded4930842b46e9507372f0b1b963James Dong
2410c1bc742181ded4930842b46e9507372f0b1b963James Dong}
2420c1bc742181ded4930842b46e9507372f0b1b963James Dong
243