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.
481 lines
17 KiB
481 lines
17 KiB
/******************************************************************************
|
|
*
|
|
* 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.h
|
|
*
|
|
* @brief
|
|
* This file contains encoder bitstream engine related structures and
|
|
* interface prototypes
|
|
*
|
|
* @author
|
|
* ittiam
|
|
*
|
|
* @remarks
|
|
* none
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
|
|
#ifndef IH264E_BITSTREAM_H_
|
|
#define IH264E_BITSTREAM_H_
|
|
|
|
/*****************************************************************************/
|
|
/* Constant Macros */
|
|
/*****************************************************************************/
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @brief defines the maximum number of bits in a bitstream word
|
|
******************************************************************************
|
|
*/
|
|
#define WORD_SIZE 32
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @brief The number of consecutive zero bytes for emulation prevention check
|
|
******************************************************************************
|
|
*/
|
|
#define EPB_ZERO_BYTES 2
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @brief Emulation prevention insertion byte
|
|
******************************************************************************
|
|
*/
|
|
#define EPB_BYTE 0x03
|
|
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @brief Stream buffer allocated per frame should be atleast MIN_STREAM_SIZE
|
|
******************************************************************************
|
|
*/
|
|
#define MIN_STREAM_SIZE 0x800
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Function Macros */
|
|
/*****************************************************************************/
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @brief Macro to check if emulation prevention byte insertion is required
|
|
******************************************************************************
|
|
*/
|
|
#define INSERT_EPB(zero_run, next_byte) \
|
|
((zero_run) == EPB_ZERO_BYTES) && (0 == ((next_byte) & 0xFC))
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @brief returns the bit position of a leading 1 (msb) in a code value
|
|
******************************************************************************
|
|
*/
|
|
#if !MSVC
|
|
#define GETRANGE(r,value) \
|
|
{ \
|
|
r = 0; \
|
|
if(0 == value) \
|
|
r = 1; \
|
|
else \
|
|
{ \
|
|
r = 32-CLZ(value); \
|
|
}\
|
|
}
|
|
#else
|
|
#define GETRANGE(r,value) \
|
|
{ \
|
|
unsigned long msb_one_bit = 0; \
|
|
r = _BitScanReverse(&msb_one_bit, value) ? (UWORD32)(msb_one_bit + 1) : 1 ; \
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @brief returns bits required to code a value
|
|
******************************************************************************
|
|
*/
|
|
#define UE_LENGTH(bits,x) \
|
|
{ \
|
|
UWORD32 r_bit; \
|
|
GETRANGE(r_bit,x+1) \
|
|
bits =(((r_bit - 1) << 1)+1);\
|
|
} \
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @brief Inserts 1 byte and Emulation Prevention Byte(if any) into bitstream
|
|
* Increments the stream offset and zero run correspondingly
|
|
******************************************************************************
|
|
*/
|
|
#define PUTBYTE_EPB(ptr,off,byte,zero_run) \
|
|
{ \
|
|
if( INSERT_EPB(zero_run, byte) ) \
|
|
{ \
|
|
ptr[off] = EPB_BYTE; \
|
|
off++; \
|
|
zero_run = 0; \
|
|
} \
|
|
\
|
|
ptr[off] = byte; \
|
|
off++; \
|
|
zero_run = byte ? 0 : zero_run+1; \
|
|
} \
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @brief Ensures Byte alignment of the slice header
|
|
******************************************************************************
|
|
*/
|
|
#define BYTE_ALIGNMENT(ps_bitstrm) ih264e_put_rbsp_trailing_bits(ps_bitstrm)
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @brief Gets number of bits coded
|
|
******************************************************************************
|
|
*/
|
|
|
|
#define GET_NUM_BITS(ps_bitstream) ((ps_bitstream->u4_strm_buf_offset << 3) \
|
|
+ 32 - ps_bitstream->i4_bits_left_in_cw);
|
|
|
|
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @macro Align bitstream to byte - Remainig bits are filled with '1'
|
|
******************************************************************************
|
|
*/
|
|
#define BITSTREAM_BYTE_ALIGN(ps_bitstrm) \
|
|
if (ps_bitstrm->i4_bits_left_in_cw & 0x07) \
|
|
{ \
|
|
const WORD32 len = (WORD32)((ps_bitstrm->i4_bits_left_in_cw) & 0x07);\
|
|
ih264e_put_bits(ps_bitstrm, (UWORD32)((1 << len) - 1), len); \
|
|
} \
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Structures */
|
|
/*****************************************************************************/
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @brief Bitstream context for encoder
|
|
******************************************************************************
|
|
*/
|
|
typedef struct bitstrm
|
|
{
|
|
/** points to start of stream buffer. */
|
|
UWORD8 *pu1_strm_buffer;
|
|
|
|
/**
|
|
* max bitstream size (in bytes).
|
|
* Encoded stream shall not exceed this size.
|
|
*/
|
|
UWORD32 u4_max_strm_size;
|
|
|
|
/**
|
|
* byte offset (w.r.t pu1_strm_buffer) where next byte would be written
|
|
* Bitstream engine makes sure it would not corrupt data beyond
|
|
* u4_max_strm_size bytes
|
|
*/
|
|
UWORD32 u4_strm_buf_offset;
|
|
|
|
/**
|
|
* current bitstream word; It is a scratch word containing max of
|
|
* WORD_SIZE bits. Will be copied to stream buffer when the word is
|
|
* full
|
|
*/
|
|
UWORD32 u4_cur_word;
|
|
|
|
/**
|
|
* signifies number of bits available in u4_cur_word
|
|
* bits from msb to i4_bits_left_in_cw of u4_cur_word have already been
|
|
* inserted next bits would be inserted from pos [i4_bits_left_in_cw-1]
|
|
* Range of this variable [1 : WORD_SIZE]
|
|
*/
|
|
WORD32 i4_bits_left_in_cw;
|
|
|
|
/**
|
|
* signifies the number of consecutive zero bytes propogated from previous
|
|
* word. It is used for emulation prevention byte insertion in the stream
|
|
*/
|
|
WORD32 i4_zero_bytes_run;
|
|
|
|
} bitstrm_t;
|
|
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @brief Inserts 1 byte and Emulation Prevention Byte(if any) into bitstream
|
|
* Increments the stream offset and zero run correspondingly
|
|
******************************************************************************
|
|
*/
|
|
static inline IH264E_ERROR_T ih264e_put_byte_epb(bitstrm_t *ps_bitstrm, UWORD8 byte)
|
|
{
|
|
if (INSERT_EPB(ps_bitstrm->i4_zero_bytes_run, byte))
|
|
{
|
|
if ((ps_bitstrm->u4_strm_buf_offset + 1) >= ps_bitstrm->u4_max_strm_size)
|
|
{
|
|
return IH264E_BITSTREAM_BUFFER_OVERFLOW;
|
|
}
|
|
ps_bitstrm->pu1_strm_buffer[ps_bitstrm->u4_strm_buf_offset++] = EPB_BYTE;
|
|
ps_bitstrm->i4_zero_bytes_run = 0;
|
|
}
|
|
|
|
if ((ps_bitstrm->u4_strm_buf_offset + 1) >= ps_bitstrm->u4_max_strm_size)
|
|
{
|
|
return IH264E_BITSTREAM_BUFFER_OVERFLOW;
|
|
}
|
|
ps_bitstrm->pu1_strm_buffer[ps_bitstrm->u4_strm_buf_offset++] = byte;
|
|
ps_bitstrm->i4_zero_bytes_run = byte ? 0 : ps_bitstrm->i4_zero_bytes_run + 1;
|
|
|
|
return IH264E_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
* flush the bits in cur word byte by byte and copy to stream *
|
|
* (current word is assumed to be byte aligned) *
|
|
******************************************************************************
|
|
*/
|
|
#define BITSTREAM_FLUSH(ps_bitstrm, err) \
|
|
{ \
|
|
WORD32 i; \
|
|
for (i = WORD_SIZE; i > ps_bitstrm->i4_bits_left_in_cw; i -= 8) \
|
|
{ \
|
|
UWORD8 u1_next_byte = (ps_bitstrm->u4_cur_word >> (i - 8)) & 0xFF; \
|
|
err |= ih264e_put_byte_epb(ps_bitstrm, u1_next_byte); \
|
|
} \
|
|
ps_bitstrm->u4_cur_word = 0; \
|
|
ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; \
|
|
} \
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Extern Function Declarations */
|
|
/*****************************************************************************/
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @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
|
|
);
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @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. If the total bytes (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.
|
|
*
|
|
* @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
|
|
);
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @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
|
|
);
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @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
|
|
);
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @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
|
|
);
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @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
|
|
);
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @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
|
|
);
|
|
|
|
#endif /* IH264E_BITSTREAM_H_ */
|