| /****************************************************************************** |
| * |
| * 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); \ |
| } |
| |
| |
| /** |
| ****************************************************************************** |
| * 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) \ |
| { \ |
| 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; \ |
| PUTBYTE_EPB(ps_bitstrm->pu1_strm_buffer, ps_bitstrm->u4_strm_buf_offset,\ |
| u1_next_byte, ps_bitstrm->i4_zero_bytes_run); \ |
| } \ |
| ps_bitstrm->u4_cur_word = 0; \ |
| ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; \ |
| } \ |
| |
| |
| |
| |
| /*****************************************************************************/ |
| /* 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; |
| |
| |
| /*****************************************************************************/ |
| /* 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_ */ |