summaryrefslogtreecommitdiffstats
path: root/decoder/ihevcd_bitstream.c
diff options
context:
space:
mode:
Diffstat (limited to 'decoder/ihevcd_bitstream.c')
-rw-r--r--decoder/ihevcd_bitstream.c580
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);
+}
+
+
+
+
+
+