This commit does not introduce any new functionality w.r.t previous commit. But it fixes few things. They are listed below: 1. Guard Bands in header files are fixed 2. Header files contains function definition comments. These are same as in source file. Maintaining same comment at two locations is unnecessary. These are removed. 3. Improved consistency and code indentation 4. Removed comments that dont align with implementation 5. Grouped headers of a workspace together
435 lines
15 KiB
C
435 lines
15 KiB
C
/******************************************************************************
|
|
*
|
|
* Copyright (C) 2015 The Android Open Source Project
|
|
*
|
|
* 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.
|
|
*
|
|
*****************************************************************************
|
|
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
|
|
*/
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @file
|
|
* ih264e_bitstream.c
|
|
*
|
|
* @brief
|
|
* This file contains function definitions related to bitstream generation
|
|
*
|
|
* @author
|
|
* ittiam
|
|
*
|
|
* @par List of Functions:
|
|
* - ih264e_bitstrm_init
|
|
* - ih264e_put_bits
|
|
* - ih264e_put_bit
|
|
* - ih264e_put_rbsp_trailing_bits
|
|
* - ih264e_put_uev
|
|
* - ih264e_put_sev
|
|
* - ih264e_put_nal_start_code_prefix
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
/*****************************************************************************/
|
|
/* File Includes */
|
|
/*****************************************************************************/
|
|
|
|
/* System Include Files */
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <stdarg.h>
|
|
#include <math.h>
|
|
|
|
/* User Include Files */
|
|
#include "ih264e_config.h"
|
|
#include "ih264_typedefs.h"
|
|
|
|
#include "ih264_debug.h"
|
|
#include "ih264_macros.h"
|
|
#include "ih264_defs.h"
|
|
#include "ih264_platform_macros.h"
|
|
|
|
#include "ih264e_error.h"
|
|
#include "ih264e_bitstream.h"
|
|
|
|
/*****************************************************************************/
|
|
/* Function Definitions */
|
|
/*****************************************************************************/
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief Initializes the encoder bitstream engine
|
|
*
|
|
* @par Description
|
|
* This routine needs to be called at start of slice/frame encode
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* pointer to bitstream context (handle)
|
|
*
|
|
* @param[in] p1_bitstrm_buf
|
|
* bitstream buffer pointer where the encoded stream is generated in byte order
|
|
*
|
|
* @param[in] u4_max_bitstrm_size
|
|
* indicates maximum bitstream buffer size. (in bytes)
|
|
* If actual stream size exceeds the maximum size, encoder should
|
|
* 1. Not corrupt data beyond u4_max_bitstrm_size bytes
|
|
* 2. Report an error back to application indicating overflow
|
|
*
|
|
* @return success or failure error code
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
IH264E_ERROR_T ih264e_bitstrm_init(bitstrm_t *ps_bitstrm,
|
|
UWORD8 *pu1_bitstrm_buf,
|
|
UWORD32 u4_max_bitstrm_size)
|
|
{
|
|
ps_bitstrm->pu1_strm_buffer = pu1_bitstrm_buf;
|
|
ps_bitstrm->u4_max_strm_size = u4_max_bitstrm_size;
|
|
|
|
/* Default init values for other members of bitstream context */
|
|
ps_bitstrm->u4_strm_buf_offset = 0;
|
|
ps_bitstrm->u4_cur_word = 0;
|
|
ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE;
|
|
ps_bitstrm->i4_zero_bytes_run = 0;
|
|
|
|
return(IH264E_SUCCESS);
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief puts a code with specified number of bits into the bitstream
|
|
*
|
|
* @par Description
|
|
* inserts code_len number of bits from lsb of code_val into the
|
|
* bitstream. updates context members like u4_cur_word, u4_strm_buf_offset and
|
|
* i4_bits_left_in_cw. If the total words (u4_strm_buf_offset) exceeds max
|
|
* available size (u4_max_strm_size), returns error without corrupting data
|
|
* beyond it
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* pointer to bitstream context (handle)
|
|
*
|
|
* @param[in] u4_code_val
|
|
* code value that needs to be inserted in the stream.
|
|
*
|
|
* @param[in] code_len
|
|
* indicates code length (in bits) of code_val that would be inserted in
|
|
* bitstream buffer size. Range of length[1:WORD_SIZE]
|
|
*
|
|
* @remarks Assumptions: all bits from bit position code_len to msb of
|
|
* code_val shall be zero
|
|
*
|
|
* @return success or failure error code
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
IH264E_ERROR_T ih264e_put_bits(bitstrm_t *ps_bitstrm,
|
|
UWORD32 u4_code_val,
|
|
WORD32 code_len)
|
|
{
|
|
UWORD32 u4_cur_word = ps_bitstrm->u4_cur_word;
|
|
WORD32 bits_left_in_cw = ps_bitstrm->i4_bits_left_in_cw;
|
|
|
|
|
|
/* check assumptions made in the module */
|
|
ASSERT(code_len > 0 && code_len <= WORD_SIZE);
|
|
|
|
if(code_len < WORD_SIZE)
|
|
ASSERT((u4_code_val >> code_len) == 0);
|
|
|
|
/* sanity check on the bitstream engine state */
|
|
ASSERT(bits_left_in_cw > 0 && bits_left_in_cw <= WORD_SIZE);
|
|
|
|
ASSERT(ps_bitstrm->i4_zero_bytes_run <= EPB_ZERO_BYTES);
|
|
|
|
ASSERT(ps_bitstrm->pu1_strm_buffer != NULL);
|
|
|
|
|
|
if(bits_left_in_cw > code_len)
|
|
{
|
|
/*******************************************************************/
|
|
/* insert the code in local bitstream word and return */
|
|
/* code is inserted in position of bits left (post decrement) */
|
|
/*******************************************************************/
|
|
bits_left_in_cw -= code_len;
|
|
u4_cur_word |= (u4_code_val << bits_left_in_cw);
|
|
|
|
ps_bitstrm->u4_cur_word = u4_cur_word;
|
|
ps_bitstrm->i4_bits_left_in_cw = bits_left_in_cw;
|
|
|
|
return(IH264E_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
/********************************************************************/
|
|
/* 1. insert partial code corresponding to bits left in cur word */
|
|
/* 2. flush all the bits of cur word to bitstream */
|
|
/* 3. insert emulation prevention bytes while flushing the bits */
|
|
/* 4. insert remaining bits of code starting from msb of cur word */
|
|
/* 5. update bitsleft in current word and stream buffer offset */
|
|
/********************************************************************/
|
|
WORD32 i, rem_bits = (code_len - bits_left_in_cw);
|
|
|
|
/* insert parital code corresponding to bits left in cur word */
|
|
u4_cur_word |= u4_code_val >> rem_bits;
|
|
|
|
for(i = WORD_SIZE; i > 0; i -= 8)
|
|
{
|
|
/* flush the bits in cur word byte by byte and copy to stream */
|
|
UWORD8 u1_next_byte = (u4_cur_word >> (i-8)) & 0xFF;
|
|
|
|
IH264E_ERROR_T status = ih264e_put_byte_epb(ps_bitstrm, u1_next_byte);
|
|
if (status != IH264E_SUCCESS) return status;
|
|
}
|
|
|
|
/* insert the remaining bits from code val into current word */
|
|
u4_cur_word = rem_bits ? (u4_code_val << (WORD_SIZE - rem_bits)) : 0;
|
|
|
|
/* update the state variables and return success */
|
|
ps_bitstrm->u4_cur_word = u4_cur_word;
|
|
ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE - rem_bits;
|
|
return (IH264E_SUCCESS);
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief inserts a 1-bit code into the bitstream
|
|
*
|
|
* @par Description
|
|
* inserts 1bit lsb of code_val into the bitstream
|
|
* updates context members like u4_cur_word, u4_strm_buf_offset and
|
|
* i4_bits_left_in_cw. If the total words (u4_strm_buf_offset) exceeds max
|
|
* available size (u4_max_strm_size), returns error without corrupting data
|
|
* beyond it
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* pointer to bitstream context (handle)
|
|
*
|
|
* @param[in] u4_code_val
|
|
* code value that needs to be inserted in the stream.
|
|
*
|
|
* @remarks Assumptions: all bits from bit position 1 to msb of code_val
|
|
* shall be zero
|
|
*
|
|
* @return success or failure error code
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
IH264E_ERROR_T ih264e_put_bit(bitstrm_t *ps_bitstrm, UWORD32 u4_code_val)
|
|
{
|
|
/* call the put bits function for 1 bit and return */
|
|
return(ih264e_put_bits(ps_bitstrm, u4_code_val, 1));
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief inserts rbsp trailing bits at the end of stream buffer (NAL)
|
|
*
|
|
* @par Description
|
|
* inserts rbsp trailing bits, updates context members like u4_cur_word and
|
|
* i4_bits_left_in_cw and flushes the same in the bitstream buffer. If the
|
|
* total words (u4_strm_buf_offset) exceeds max available size
|
|
* (u4_max_strm_size), returns error without corrupting data beyond it
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* pointer to bitstream context (handle)
|
|
*
|
|
* @return success or failure error code
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
IH264E_ERROR_T ih264e_put_rbsp_trailing_bits(bitstrm_t *ps_bitstrm)
|
|
{
|
|
WORD32 i;
|
|
UWORD32 u4_cur_word = ps_bitstrm->u4_cur_word;
|
|
WORD32 bits_left_in_cw = ps_bitstrm->i4_bits_left_in_cw;
|
|
WORD32 bytes_left_in_cw = (bits_left_in_cw - 1) >> 3;
|
|
|
|
/* insert a 1 at the end of current word and flush all the bits */
|
|
u4_cur_word |= (1 << (bits_left_in_cw - 1));
|
|
|
|
/* get the bits to be inserted in msbdb of the word */
|
|
//u4_cur_word <<= (WORD_SIZE - bytes_left_in_cw + 1);
|
|
|
|
for(i = WORD_SIZE; i > (bytes_left_in_cw*8); i -= 8)
|
|
{
|
|
/* flush the bits in cur word byte by byte and copy to stream */
|
|
UWORD8 u1_next_byte = (u4_cur_word >> (i-8)) & 0xFF;
|
|
|
|
IH264E_ERROR_T status = ih264e_put_byte_epb(ps_bitstrm, u1_next_byte);
|
|
if (status != IH264E_SUCCESS) return status;
|
|
}
|
|
|
|
/* Default init values for scratch variables of bitstream context */
|
|
ps_bitstrm->u4_cur_word = 0;
|
|
ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE;
|
|
ps_bitstrm->i4_zero_bytes_run = 0;
|
|
|
|
return (IH264E_SUCCESS);
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief puts exponential golomb code of a unsigned integer into bitstream
|
|
*
|
|
* @par Description
|
|
* computes uev code for given syntax element and inserts the same into
|
|
* bitstream by calling ih264e_put_bits() interface.
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* pointer to bitstream context (handle)
|
|
*
|
|
* @param[in] u4_code_num
|
|
* unsigned integer input whose golomb code is written in stream
|
|
*
|
|
* @remarks Assumptions: code value can be represented in less than 16bits
|
|
*
|
|
* @return success or failure error code
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
IH264E_ERROR_T ih264e_put_uev(bitstrm_t *ps_bitstrm, UWORD32 u4_code_num)
|
|
{
|
|
UWORD32 u4_bit_str, u4_range;
|
|
IH264E_ERROR_T e_error;
|
|
|
|
/* convert the codenum to exp-golomb bit code: Table 9-2 JCTVC-J1003_d7 */
|
|
u4_bit_str = u4_code_num + 1;
|
|
|
|
/* get range of the bit string and put using put_bits() */
|
|
GETRANGE(u4_range, u4_bit_str);
|
|
|
|
e_error = ih264e_put_bits(ps_bitstrm, u4_bit_str, (2 * u4_range - 1));
|
|
|
|
return(e_error);
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief puts exponential golomb code of a signed integer into bitstream
|
|
*
|
|
* @par Description
|
|
* computes sev code for given syntax element and inserts the same into
|
|
* bitstream by calling ih264e_put_bits() interface.
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* pointer to bitstream context (handle)
|
|
*
|
|
* @param[in] syntax_elem
|
|
* signed integer input whose golomb code is written in stream
|
|
*
|
|
* @remarks Assumptions: code value can be represented in less than 16bits
|
|
*
|
|
* @return success or failure error code
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
IH264E_ERROR_T ih264e_put_sev(bitstrm_t *ps_bitstrm, WORD32 syntax_elem)
|
|
{
|
|
UWORD32 u4_code_num, u4_bit_str, u4_range;
|
|
IH264E_ERROR_T e_error;
|
|
|
|
/************************************************************************/
|
|
/* convert the codenum to exp-golomb bit code for signed syntax element */
|
|
/* See Table9-2 and Table 9-3 of standard JCTVC-J1003_d7 */
|
|
/************************************************************************/
|
|
if(syntax_elem <= 0)
|
|
{
|
|
/* codeNum for non-positive integer = 2*abs(x) : Table9-3 */
|
|
u4_code_num = ((-syntax_elem) << 1);
|
|
}
|
|
else
|
|
{
|
|
/* codeNum for positive integer = 2x-1 : Table9-3 */
|
|
u4_code_num = (syntax_elem << 1) - 1;
|
|
}
|
|
|
|
/* convert the codenum to exp-golomb bit code: Table 9-2 JCTVC-J1003_d7 */
|
|
u4_bit_str = u4_code_num + 1;
|
|
|
|
/* get range of the bit string and put using put_bits() */
|
|
GETRANGE(u4_range, u4_bit_str);
|
|
|
|
e_error = ih264e_put_bits(ps_bitstrm, u4_bit_str, (2 * u4_range - 1));
|
|
|
|
return(e_error);
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief insert NAL start code prefix (0x000001) into bitstream with an option
|
|
* of inserting leading_zero_8bits (which makes startcode prefix as 0x00000001)
|
|
*
|
|
* @par Description
|
|
* Although start code prefix could have been put by calling ih264e_put_bits(),
|
|
* ih264e_put_nal_start_code_prefix() is specially added to make sure emulation
|
|
* prevention insertion is not done for the NAL start code prefix which will
|
|
* surely happen otherwise by calling ih264e_put_bits() interface.
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* pointer to bitstream context (handle)
|
|
*
|
|
* @param[in] insert_leading_zero_8bits
|
|
* flag indicating if one more zero bytes needs to prefixed before start code
|
|
*
|
|
* @return success or failure error code
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
IH264E_ERROR_T ih264e_put_nal_start_code_prefix(bitstrm_t *ps_bitstrm,
|
|
WORD32 insert_leading_zero_8bits)
|
|
{
|
|
UWORD32 u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset;
|
|
UWORD8* pu1_strm_buf = ps_bitstrm->pu1_strm_buffer;
|
|
|
|
/* Bitstream buffer overflow check assuming worst case of 4 bytes */
|
|
if((u4_strm_buf_offset + 4) >= ps_bitstrm->u4_max_strm_size)
|
|
{
|
|
return(IH264E_BITSTREAM_BUFFER_OVERFLOW);
|
|
}
|
|
|
|
/* Insert leading zero 8 bits conditionally */
|
|
if(insert_leading_zero_8bits)
|
|
{
|
|
pu1_strm_buf[u4_strm_buf_offset] = 0x00;
|
|
u4_strm_buf_offset++;
|
|
}
|
|
|
|
/* Insert NAL start code prefix 0x00 00 01 */
|
|
pu1_strm_buf[u4_strm_buf_offset] = 0x00;
|
|
u4_strm_buf_offset++;
|
|
|
|
pu1_strm_buf[u4_strm_buf_offset] = 0x00;
|
|
u4_strm_buf_offset++;
|
|
|
|
pu1_strm_buf[u4_strm_buf_offset] = 0x01;
|
|
u4_strm_buf_offset++;
|
|
|
|
/* update the stream offset */
|
|
ps_bitstrm->u4_strm_buf_offset = u4_strm_buf_offset;
|
|
|
|
return (IH264E_SUCCESS);
|
|
}
|
|
|