You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
589 lines
15 KiB
589 lines
15 KiB
/******************************************************************************
|
|
*
|
|
* 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 += 32;
|
|
ps_bitstrm->u4_bit_ofst -= abs_numbits;
|
|
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) - 8;
|
|
u4_size_in_bits <<= 3;
|
|
if(u4_size_in_bits > u4_bits_consumed)
|
|
{
|
|
return (u4_size_in_bits - u4_bits_consumed);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @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);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|