/* * * Copyright 2015 Rockchip Electronics Co. LTD * * 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. */ #ifndef __MPP_BITREAD_H__ #define __MPP_BITREAD_H__ #include #include #include "mpp_err.h" #include "mpp_common.h" #define __BITREAD_ERR __bitread_error #define READ_ONEBIT(bitctx, out)\ do {\ RK_S32 _out; \ bitctx->ret = mpp_read_bits(bitctx, 1, &_out); \ if (!bitctx->ret) { *out = _out; }\ else { goto __BITREAD_ERR; }\ } while (0) #define READ_BITS(bitctx, num_bits, out)\ do {\ RK_S32 _out; \ bitctx->ret = mpp_read_bits(bitctx, num_bits, &_out); \ if (!bitctx->ret) { *out = _out; }\ else { goto __BITREAD_ERR; }\ } while (0) #define READ_BITS_LONG(bitctx, num_bits, out)\ do {\ RK_U32 _out; \ bitctx->ret = mpp_read_longbits(bitctx, num_bits, &_out); \ if (!bitctx->ret) { *out = _out; }\ else { goto __BITREAD_ERR; }\ } while (0) #define SHOW_BITS(bitctx, num_bits, out)\ do {\ RK_S32 _out; \ bitctx->ret = mpp_show_bits(bitctx, num_bits, &_out); \ if (!bitctx->ret) { *out = _out; }\ else { goto __BITREAD_ERR; }\ } while (0) #define SHOW_BITS_LONG(bitctx, num_bits, out)\ do {\ RK_U32 _out; \ bitctx->ret = mpp_show_longbits(bitctx, num_bits, &_out); \ if (!bitctx->ret) { *out = _out; }\ else { goto __BITREAD_ERR; }\ } while (0) #define SKIP_BITS(bitctx, num_bits)\ do {\ bitctx->ret = mpp_skip_longbits(bitctx, num_bits); \ if (bitctx->ret) { goto __BITREAD_ERR; }\ } while (0) #define SKIP_BITS_LONG(bitctx, num_bits)\ do {\ bitctx->ret = mpp_skip_longbits(bitctx, num_bits); \ if (bitctx->ret) { goto __BITREAD_ERR; }\ } while (0) #define READ_UE(bitctx, out)\ do {\ RK_U32 _out; \ bitctx->ret = mpp_read_ue(bitctx, &_out); \ if (!bitctx->ret) { *out = _out; }\ else { goto __BITREAD_ERR; }\ } while (0) #define READ_SE(bitctx, out)\ do {\ RK_S32 _out; \ bitctx->ret = mpp_read_se(bitctx, &_out); \ if (!bitctx->ret) { *out = _out; }\ else { goto __BITREAD_ERR; }\ } while (0) typedef enum PseudoCodeType_e { PSEUDO_CODE_NONE = 0, PSEUDO_CODE_H264_H265, PSEUDO_CODE_H264_H265_SEI, PSEUDO_CODE_AVS2, PSEUDO_CODE_BUT } PseudoCodeType; typedef struct bitread_ctx_t { // Pointer to the next unread (not in curr_byte_) byte in the stream. RK_U8 *data_; // Bytes left in the stream (without the curr_byte_). RK_U32 bytes_left_; // Contents of the current byte; first unread bit starting at position // 8 - num_remaining_bits_in_curr_byte_ from MSB. RK_S64 curr_byte_; // Number of bits remaining in curr_byte_ RK_S32 num_remaining_bits_in_curr_byte_; // Used in emulation prevention three byte detection (see spec). // Initially set to 0xffff to accept all initial two-byte sequences. RK_S64 prev_two_bytes_; // Number of emulation presentation bytes (0x000003) we met. RK_S64 emulation_prevention_bytes_; // count PPS SPS SEI read bits RK_S32 used_bits; RK_U8 *buf; RK_S32 buf_len; // ctx MPP_RET ret; PseudoCodeType prevention_type; MPP_RET (*update_curbyte)(struct bitread_ctx_t *bitctx); } BitReadCtx_t; #ifdef __cplusplus extern "C" { #endif //!< set bit read context void mpp_set_bitread_ctx(BitReadCtx_t *bitctx, RK_U8 *data, RK_S32 size); //!< Read bits (1-31) MPP_RET mpp_read_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out); //!< Read bits (1-32) MPP_RET mpp_read_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_U32 *out); //!< Show bits (1-31) MPP_RET mpp_show_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out); //!< Show bits (1-32) MPP_RET mpp_show_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_U32 *out); //!< skip bits(1-31) MPP_RET mpp_skip_bits(BitReadCtx_t *bitctx, RK_S32 num_bits); //!< skip bits(1-32) MPP_RET mpp_skip_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits); //!< read ue(1-32) MPP_RET mpp_read_ue(BitReadCtx_t *bitctx, RK_U32* val); //!< read se(1-31) MPP_RET mpp_read_se(BitReadCtx_t *bitctx, RK_S32* val); void mpp_set_bitread_pseudo_code_type(BitReadCtx_t *bitctx, PseudoCodeType type); //!< check whether has more rbsp data(used in h264) RK_U32 mpp_has_more_rbsp_data(BitReadCtx_t * bitctx); //!< align bits and get current pointer RK_U8 *mpp_align_get_bits(BitReadCtx_t *bitctx); RK_S32 mpp_get_bits_left(BitReadCtx_t *bitctx); RK_S32 mpp_get_bits_count(BitReadCtx_t *bitctx); #ifdef __cplusplus } #endif #endif /* __MPP_BITREAD_H__ */