diff options
Diffstat (limited to 'decoder/ihevcd_bitstream.c')
-rw-r--r-- | decoder/ihevcd_bitstream.c | 580 |
1 files changed, 580 insertions, 0 deletions
diff --git a/decoder/ihevcd_bitstream.c b/decoder/ihevcd_bitstream.c new file mode 100644 index 0000000..be9addb --- /dev/null +++ b/decoder/ihevcd_bitstream.c @@ -0,0 +1,580 @@ +/****************************************************************************** +* +* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore +* +* 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 +* ihevcd_bitstream.c +* +* @brief +* Contains functions for bitstream access +* +* @author +* Harish +* +* @par List of Functions: +* - ihevcd_bits_init() +* - ihevcd_bits_flush() +* - ihevcd_bits_flush_to_byte_boundary() +* - ihevcd_bits_nxt() +* - ihevcd_bits_nxt32() +* - ihevcd_bits_get() +* - ihevcd_bits_num_bits_remaining() +* - ihevcd_bits_num_bits_consumed() +* - ihevcd_sev() +* - ihevcd_uev() +* +* +* @remarks +* None +* +******************************************************************************* +*/ +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include "ihevc_typedefs.h" +#include "iv.h" +#include "ivd.h" +#include "ihevcd_cxa.h" + +#include "ihevc_defs.h" +#include "ihevc_debug.h" +#include "ihevc_structs.h" +#include "ihevc_macros.h" +#include "ihevc_platform_macros.h" +#include "ihevc_cabac_tables.h" + +#include "ihevcd_defs.h" +#include "ihevcd_function_selector.h" +#include "ihevcd_structs.h" +#include "ihevcd_error.h" +#include "ihevcd_bitstream.h" + +/*****************************************************************************/ +/* Function Prototypes */ +/*****************************************************************************/ + +/** +******************************************************************************* +* +* @brief +* Function used for bitstream structure initialization +* +* @par Description: +* Initialize bitstream structure elements +* +* @param[in] ps_bitstrm +* Pointer to bitstream structure +* +* @param[in] pu1_buf +* Pointer to bitstream data +* +* @param[in] u4_numbytes +* Number of bytes in bitstream +* +* @returns none +* +* @remarks +* Assumes pu1_buf is aligned to 4 bytes. If not aligned then all bitstream +* accesses will be unaligned and hence costlier. Since this is codec memory +* that holds emulation prevented data, assumption of aligned to 4 bytes is +* valid +* +******************************************************************************* +*/ +void ihevcd_bits_init(bitstrm_t *ps_bitstrm, + UWORD8 *pu1_buf, + UWORD32 u4_numbytes) +{ + UWORD32 u4_cur_word; + UWORD32 u4_nxt_word; + UWORD32 u4_temp; + UWORD32 *pu4_buf; + + pu4_buf = (UWORD32 *)pu1_buf; + u4_temp = *pu4_buf++; + u4_cur_word = ITT_BIG_ENDIAN(u4_temp); + u4_temp = *pu4_buf++; + u4_nxt_word = ITT_BIG_ENDIAN(u4_temp); + + ps_bitstrm->u4_bit_ofst = 0; + ps_bitstrm->pu1_buf_base = pu1_buf; + ps_bitstrm->pu4_buf = pu4_buf; + ps_bitstrm->u4_cur_word = u4_cur_word; + ps_bitstrm->u4_nxt_word = u4_nxt_word; + + ps_bitstrm->pu1_buf_max = pu1_buf + u4_numbytes + 8; + + return; +} + +/** +******************************************************************************* +* +* @brief +* Flushes given number of bits. Bits consumed increases by this number +* +* @par Description: +* Increment bit offset by numbits. If bit offset increases beyond 32, then +* move nxt_word to cur_word, read next word32 to nxt_word after endian +* conversion +* +* @param[in] ps_bitstrm +* Pointer to bitstream structure +* +* @param[in] u4_numbits +* Number of bits to be flushed +* +* @returns None +* +* @remarks +* +* +******************************************************************************* +*/ +void ihevcd_bits_flush(bitstrm_t *ps_bitstrm, UWORD32 u4_numbits) +{ + + BITS_FLUSH(ps_bitstrm->pu4_buf, + ps_bitstrm->u4_bit_ofst, + ps_bitstrm->u4_cur_word, + ps_bitstrm->u4_nxt_word, + u4_numbits); + + return; +} + +/** +******************************************************************************* +* +* @brief +* Flushes to next byte boundary.Bits consumed increases by this number +* +* @par Description: +* Compute number of bits remaining in the current byte then call +* ihevcd_bits_flush() bits with this number +* +* @param[in] ps_bitstrm +* Pointer to bitstream structure +* +* @returns None +* +* @remarks +* +* +******************************************************************************* +*/ +void ihevcd_bits_flush_to_byte_boundary(bitstrm_t *ps_bitstrm) +{ + UWORD32 u4_numbits; + u4_numbits = (ps_bitstrm->u4_bit_ofst) & 7; + + u4_numbits = 8 - u4_numbits; + + BITS_FLUSH(ps_bitstrm->pu4_buf, + ps_bitstrm->u4_bit_ofst, + ps_bitstrm->u4_cur_word, + ps_bitstrm->u4_nxt_word, + u4_numbits); + + return; +} + +/** +******************************************************************************* +* +* @brief +* Seeks by given number of bits in the bitstream from current position +* +* @par Description: +* Add given number of bits to bitstream offset and update pu4_buf, cur_word and +* nxt_word accordingly +* +* @param[in] ps_bitstrm +* Pointer to bitstream structure +* +* @param[in] numbits +* Number of bits to seek +* +* @returns None +* +* @remarks +* Assumes emulation prevention has been done before and the buffer does not +* contain any emulation prevention bytes +* +******************************************************************************* +*/ +void ihevcd_bits_seek(bitstrm_t *ps_bitstrm, WORD32 numbits) +{ + WORD32 val; + ASSERT(numbits >= -32); + ASSERT(numbits <= 32); + /* Check if Seeking backwards*/ + if(numbits < 0) + { + UWORD32 abs_numbits = -numbits; + if(ps_bitstrm->u4_bit_ofst >= abs_numbits) + { + /* If the current offset is greater than number of bits to seek back, + * then subtract abs_numbits from offset and return. + */ + ps_bitstrm->u4_bit_ofst -= abs_numbits; + return; + } + else + { + /* If the current offset is lesser than number of bits to seek back, + * then subtract abs_numbits from offset and add 32 and move cur_word to nxt_word + * and load cur_word appropriately and decrement pu4_buf + */ + ps_bitstrm->u4_bit_ofst -= abs_numbits; + ps_bitstrm->u4_bit_ofst += 32; + ps_bitstrm->pu4_buf--; + + val = *(ps_bitstrm->pu4_buf - 2); + ps_bitstrm->u4_nxt_word = ps_bitstrm->u4_cur_word; + ps_bitstrm->u4_cur_word = ITT_BIG_ENDIAN(val); + return; + } + } + else + { + /* Not supported/tested currently */ + ASSERT(1); + BITS_FLUSH(ps_bitstrm->pu4_buf, + ps_bitstrm->u4_bit_ofst, + ps_bitstrm->u4_cur_word, + ps_bitstrm->u4_nxt_word, + numbits); + + + } + return; +} +/** +******************************************************************************* +* +* @brief +* Snoops for next numbits number of bits from the bitstream this does not +* update the bitstream offset and does not consume the bits +* +* @par Description: +* Extract required number of bits from cur_word & nxt_word return these +* bits +* +* @param[in] ps_bitstrm +* Pointer to bitstream structure +* +* @param[in] u4_numbits +* Number of bits +* +* @returns Next u4_numbits number of bits +* +* @remarks +* +* +******************************************************************************* +*/ +UWORD32 ihevcd_bits_nxt(bitstrm_t *ps_bitstrm, UWORD32 u4_numbits) +{ + UWORD32 u4_bits_read; + + BITS_NXT(u4_bits_read, + ps_bitstrm->pu4_buf, + ps_bitstrm->u4_bit_ofst, + ps_bitstrm->u4_cur_word, + ps_bitstrm->u4_nxt_word, + u4_numbits); + return u4_bits_read; +} +/** +******************************************************************************* +* +* @brief +* Snoops for next 32 bits from the bitstream this does not update the +* bitstream offset and does not consume the bits +* +* @par Description: +* Extract required number of bits from cur_word & nxt_word return these +* bits +* +* @param[in] ps_bitstrm +* Pointer to bitstream structure +* +* @param[in] u4_numbits +* Number of bits +* +* @returns Next 32 bits +* +* @remarks +* +* +******************************************************************************* +*/ +UWORD32 ihevcd_bits_nxt32(bitstrm_t *ps_bitstrm, UWORD32 u4_numbits) +{ + UWORD32 u4_bits_read; + UNUSED(u4_numbits); + BITS_NXT32(u4_bits_read, + ps_bitstrm->pu4_buf, + ps_bitstrm->u4_bit_ofst, + ps_bitstrm->u4_cur_word, + ps_bitstrm->u4_nxt_word); + return u4_bits_read; +} + +/** +******************************************************************************* +* +* @brief +* Reads next numbits number of bits from the bitstream this updates the +* bitstream offset and consumes the bits +* +* @par Description: +* Extract required number of bits from cur_word & nxt_word return these +* bits +* +* @param[in] ps_bitstrm +* Pointer to bitstream structure +* +* @param[in] u4_numbits +* Number of bits +* +* @returns Bits read +* +* @remarks +* +* +******************************************************************************* +*/ +UWORD32 ihevcd_bits_get(bitstrm_t *ps_bitstrm, UWORD32 u4_numbits) +{ + UWORD32 u4_bits_read; + + BITS_GET(u4_bits_read, + ps_bitstrm->pu4_buf, + ps_bitstrm->u4_bit_ofst, + ps_bitstrm->u4_cur_word, + ps_bitstrm->u4_nxt_word, + u4_numbits); + return u4_bits_read; + +} + +/** +******************************************************************************* +* +* @brief +* Returns the number of bits remaining in the bitstream +* +* @par Description: +* Compute number of bits remaining based on current pointer and buffer base +* and current offset. Since 8 bytes are read at the start into cur_word and +* nxt_word and are not consumed, 8 has to be subtracted +* +* @param[in] ps_bitstrm +* Pointer to bitstream structure +* +* @returns Total number of bits remaining +* +* @remarks +* +* +******************************************************************************* +*/ +UWORD32 ihevcd_bits_num_bits_remaining(bitstrm_t *ps_bitstrm) +{ + UWORD32 u4_bits_consumed; + UWORD32 u4_size_in_bits; + + /* 8 bytes are read in cur_word and nxt_word at the start. Hence */ + /* subtract 8 bytes */ + u4_bits_consumed = (UWORD32)(((UWORD8 *)ps_bitstrm->pu4_buf - + (UWORD8 *)ps_bitstrm->pu1_buf_base - 8) << + 3) + ps_bitstrm->u4_bit_ofst; + + u4_size_in_bits = (UWORD32)(ps_bitstrm->pu1_buf_max - + ps_bitstrm->pu1_buf_base); + return (u4_size_in_bits - u4_bits_consumed); +} + +/** +******************************************************************************* +* +* @brief +* Returns the number of bits consumed in the bitstream +* +* @par Description: +* Compute number of bits consumed based on current pointer and buffer base +* and current offset. Since 8 bytes are read at the start into cur_word and +* nxt_word and are not consumed, 8 has to be subtracted +* +* @param[in] ps_bitstrm +* Pointer to bitstream structure +* +* @returns Total number of bits bits consumed +* +* @remarks +* +* +******************************************************************************* +*/ +UWORD32 ihevcd_bits_num_bits_consumed(bitstrm_t *ps_bitstrm) +{ + UWORD32 u4_bits_consumed; + /* 8 bytes are read in cur_word and nxt_word at the start. Hence */ + /* subtract 8 bytes */ + + u4_bits_consumed = (UWORD32)(((UWORD8 *)ps_bitstrm->pu4_buf - + (UWORD8 *)ps_bitstrm->pu1_buf_base - 8) << + 3) + ps_bitstrm->u4_bit_ofst; + return u4_bits_consumed; +} + +/** +******************************************************************************* +* +* @brief +* Reads unsigned integer 0-th order exp-golomb-coded syntax element from +* the bitstream Section: 9.2 +* +* @par Description: +* Extract required number of bits from cur_word & nxt_word return these +* bits +* +* @param[in] ps_bitstrm +* Pointer to bitstream structure +* +* @returns UEV decoded syntax element +* +* @remarks +* +* +******************************************************************************* +*/ +UWORD32 ihevcd_uev(bitstrm_t *ps_bitstrm) +{ + UWORD32 u4_bits_read; + UWORD32 u4_clz; + + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + BITS_NXT32(u4_bits_read, + ps_bitstrm->pu4_buf, + ps_bitstrm->u4_bit_ofst, + ps_bitstrm->u4_cur_word, + ps_bitstrm->u4_nxt_word); + + + u4_clz = CLZ(u4_bits_read); + + BITS_FLUSH(ps_bitstrm->pu4_buf, + ps_bitstrm->u4_bit_ofst, + ps_bitstrm->u4_cur_word, + ps_bitstrm->u4_nxt_word, + (u4_clz + 1)); + + u4_bits_read = 0; + if(u4_clz) + { + BITS_GET(u4_bits_read, + ps_bitstrm->pu4_buf, + ps_bitstrm->u4_bit_ofst, + ps_bitstrm->u4_cur_word, + ps_bitstrm->u4_nxt_word, + u4_clz); + } + return ((1 << u4_clz) + u4_bits_read - 1); + +} + +/** +******************************************************************************* +* +* @brief +* Reads signed integer 0-th order exp-golomb-coded syntax element from the +* bitstream. Function similar to get_uev Section: 9.2.1 +* +* @par Description: +* Extract required number of bits from cur_word & nxt_word return these +* bits +* +* @param[in] ps_bitstrm +* Pointer to bitstream structure +* +* @returns UEV decoded syntax element +* +* @remarks +* +* +******************************************************************************* +*/ +WORD32 ihevcd_sev(bitstrm_t *ps_bitstrm) +{ + UWORD32 u4_bits_read; + UWORD32 u4_clz; + UWORD32 u4_abs_val; + + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + BITS_NXT32(u4_bits_read, + ps_bitstrm->pu4_buf, + ps_bitstrm->u4_bit_ofst, + ps_bitstrm->u4_cur_word, + ps_bitstrm->u4_nxt_word); + + + u4_clz = CLZ(u4_bits_read); + + BITS_FLUSH(ps_bitstrm->pu4_buf, + ps_bitstrm->u4_bit_ofst, + ps_bitstrm->u4_cur_word, + ps_bitstrm->u4_nxt_word, + (u4_clz + 1)); + + u4_bits_read = 0; + if(u4_clz) + { + BITS_GET(u4_bits_read, + ps_bitstrm->pu4_buf, + ps_bitstrm->u4_bit_ofst, + ps_bitstrm->u4_cur_word, + ps_bitstrm->u4_nxt_word, + u4_clz); + } + u4_abs_val = ((1 << u4_clz) + u4_bits_read) >> 1; + if(u4_bits_read & 0x1) + return (-(WORD32)u4_abs_val); + else + return (u4_abs_val); +} + + + + + + |