[h265]:add h265 paser and hal part code

git-svn-id: https://10.10.10.66:8443/svn/MediaProcessPlatform/trunk/mpp@293 6e48237b-75ef-9749-8fc9-41990f28c85a
This commit is contained in:
ChenSiyong
2015-09-24 01:29:14 +00:00
parent 8f1e6a3c84
commit 68ee293818
27 changed files with 10999 additions and 2 deletions

View File

@@ -39,6 +39,10 @@ typedef enum {
MPP_ERR_VPU_CODEC_INIT = MPP_ERR_BASE - 3, MPP_ERR_VPU_CODEC_INIT = MPP_ERR_BASE - 3,
MPP_ERR_STREAM = MPP_ERR_BASE - 4, MPP_ERR_STREAM = MPP_ERR_BASE - 4,
MPP_ERR_FATAL_THREAD = MPP_ERR_BASE - 5, MPP_ERR_FATAL_THREAD = MPP_ERR_BASE - 5,
MPP_ERR_NOMEM = MPP_ERR_BASE - 6,
MPP_ERR_PROTOL = MPP_ERR_BASE - 7,
MPP_FAIL_SPLIT_FRAME = MPP_ERR_BASE - 8,
MPP_ERR_VPUHW = MPP_ERR_BASE - 9,
MPP_EOS_STREAM_REACHED = MPP_ERR_BASE - 11, MPP_EOS_STREAM_REACHED = MPP_ERR_BASE - 11,
} MPP_RET; } MPP_RET;

View File

@@ -56,5 +56,16 @@ typedef signed long long int RK_S64;
#ifndef MODULE_TAG #ifndef MODULE_TAG
#define MODULE_TAG NULL #define MODULE_TAG NULL
#endif #endif
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
#ifndef INT64_C
#define INT64_C(c) (c ## LL)
#define UINT64_C(c) (c ## ULL)
#endif
#endif /*__RK_TYPE_H__*/ #endif /*__RK_TYPE_H__*/

View File

@@ -1 +1,23 @@
# vim: syntax=cmake # vim: syntax=cmake
set(H265D_PARSER_HDR
h265d_defs.h
h265d_parser.h
h265d_codec.h
)
set(H265D_PARSER_SRC
../../../mpp_bitread.c
h265d_parser.c
h265d_ps.c
h265d_refs.c
h265d_sei.c
h265d_parser2_syntax.c
)
add_library(h265d_parser STATIC
${H265D_PARSER_SRC} ${H265D_PARSER_HDR}
)
target_link_libraries(h265d_parser osal)
add_subdirectory(test)

View File

@@ -0,0 +1,154 @@
/*
*
* Copyright 2010 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.
*/
/*
* @file h265d_codec.h
* @brief
* @author csy(csy@rock-chips.com)
* @version 1.0.0
* @history
* 2015.7.15 : Create
*/
#ifndef __MPP_CODEC_H__
#define __MPP_CODEC_H__
#include "rk_type.h"
#include "mpp_common.h"
#include "vpu_api.h"
#include "mpp_frame.h"
#include "mpp_dec.h"
enum MppColorSpace {
MPPCOL_SPC_RGB = 0,
MPPCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
MPPCOL_SPC_UNSPECIFIED = 2,
MPPCOL_SPC_FCC = 4,
MPPCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
MPPCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
MPPCOL_SPC_SMPTE240M = 7,
MPPCOL_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
MPPCOL_SPC_NB , ///< Not part of ABI
};
enum MppColorRange {
MPPCOL_RANGE_UNSPECIFIED = 0,
MPPCOL_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
MPPCOL_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges
MPPCOL_RANGE_NB , ///< Not part of ABI
};
typedef struct MppRational {
RK_S32 num; ///< numerator
RK_S32 den; ///< denominator
} MppRational_t;
enum MppPictureStructure {
MPP_PICTURE_STRUCTURE_UNKNOWN, //< unknown
MPP_PICTURE_STRUCTURE_TOP_FIELD, //< coded as top field
MPP_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field
MPP_PICTURE_STRUCTURE_FRAME, //< coded as frame
};
#define END_NOT_FOUND (-100)
typedef struct SplitContext {
RK_U8 *buffer;
RK_U32 buffer_size;
RK_S32 index;
RK_S32 last_index;
RK_U32 state; ///< contains the last few bytes in MSB order
RK_S32 frame_start_found;
RK_S32 overread; ///< the number of bytes which where irreversibly read from the next frame
RK_S32 overread_index; ///< the index into ParseContext.buffer of the overread bytes
RK_U64 state64; ///< contains the last 8 bytes in MSB order
RK_S32 eos;
} SplitContext_t;
typedef struct H265dContext {
void *priv_data;
void *split_cxt;
/**
* for rk log printf
**/
// RK_LOG_CONTEX_t *log_ctx;
/**
* display width & height
**/
RK_S32 width, height;
/**
*codec decoder width & height
**/
RK_S32 coded_width, coded_height;
RK_U8 *extradata;
RK_U32 extradata_size;
VideoPacket_t *pkt;
/**
* Pixel format
**/
RK_U32 pix_fmt;
RK_U32 err_recognition;
/**
* sample aspect ratio (0 if unknown)
* That is the width of a pixel divided by the height of the pixel.
* Numerator and denominator must be relatively prime and smaller than 256 for some video standards.
* - decoding: Set by rkcodec.
*/
MppRational_t sample_aspect_ratio;
/**
* YUV colorspace type.
* - decoding: Set by rkcodec
*/
enum MppColorSpace colorspace;
/**
* MPEG vs JPEG YUV range.
* - decoding: Set by rkcodec
*/
enum MppColorRange color_range;
void *compare_info;
RK_U32 need_split;
} H265dContext_t;
#ifdef __cplusplus
extern "C" {
#endif
RK_S32 h265d_parser2_syntax(void *ctx);
RK_S32 h265d_syntax_fill_slice(void *ctx, MppBuffer *streambuf);
#ifdef __cplusplus
}
#endif
#endif /* __MPP_CODEC_H__ */

View File

@@ -0,0 +1,45 @@
/*
*
* Copyright 2010 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.
*/
/*
* @file h265d_defs.h
* @brief
* @author csy(csy@rock-chips.com)
* @version 1.0.0
* @history
* 2015.7.15 : Create
*/
#ifndef __H265D_DEF_H__
#define __H265D_DEF_H__
#ifdef VPS_EXTENSION
#define MAX_VPS_NUM_SCALABILITY_TYPES 16
#define MAX_VPS_LAYER_ID_PLUS1 MAX_LAYERS
#define MAX_VPS_LAYER_SETS_PLUS1 1024
#define VPS_EXTN_MASK_AND_DIM_INFO 1
#define VPS_MOVE_DIR_DEPENDENCY_FLAG 1
#define VPS_EXTN_DIRECT_REF_LAYERS 1
#define VPS_EXTN_PROFILE_INFO 1
#define VPS_PROFILE_OUTPUT_LAYERS 1
#define VPS_EXTN_OP_LAYER_SETS 1
#endif
#define DERIVE_LAYER_ID_LIST_VARIABLES 1
#endif /* H265D_DEF_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,755 @@
/*
*
* Copyright 2010 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.
*/
/*
* @file h265d_parser.h
* @brief
* @author csy(csy@rock-chips.com)
* @version 1.0.0
* @history
* 2015.7.15 : Create
*/
#ifndef __H265D_PARSER_H__
#define __H265D_PARSER_H__
#include "mpp_bitread.h"
#include "mpp_common.h"
#include "h265d_codec.h"
#include "mpp_frame.h"
#include "limits.h"
#include <string.h>
#include <mpp_mem.h>
#include "mpp_dec.h"
extern RK_U32 h265d_debug;
#define H265D_DBG_FUNCTION (0x00000001)
#define H265D_DBG_VPS (0x00000002)
#define H265D_DBG_SPS (0x00000004)
#define H265D_DBG_PPS (0x00000008)
#define H265D_DBG_SLICE_HDR (0x00000010)
#define H265D_DBG_SEI (0x00000020)
#define H265D_DBG_GLOBAL (0x00000040)
#define H265D_DBG_REF (0x00000080)
#define h265d_dbg(flag, fmt, ...) _mpp_dbg(h265d_debug, flag, fmt, ## __VA_ARGS__)
#define MAX_DPB_SIZE 16 // A.4.1
#define MAX_REFS 16
/**
* 7.4.2.1
*/
#define MAX_SUB_LAYERS 7
#define MAX_VPS_COUNT 16
#define MAX_SPS_COUNT 16
#define MAX_PPS_COUNT 64
#define MAX_SHORT_TERM_RPS_COUNT 64
#define MAX_CU_SIZE 128
//TODO: check if this is really the maximum
#define MAX_TRANSFORM_DEPTH 5
#define MAX_TB_SIZE 32
#define MAX_PB_SIZE 64
#define MAX_LOG2_CTB_SIZE 6
#define MAX_QP 51
#define DEFAULT_INTRA_TC_OFFSET 2
#define HEVC_CONTEXTS 183
#define MRG_MAX_NUM_CANDS 5
#define L0 0
#define L1 1
#define EPEL_EXTRA_BEFORE 1
#define EPEL_EXTRA_AFTER 2
#define EPEL_EXTRA 3
#define QPEL_EXTRA_BEFORE 3
#define QPEL_EXTRA_AFTER 4
#define QPEL_EXTRA 7
#define EDGE_EMU_BUFFER_STRIDE 80
#define MAX_FRAME_SIZE 2048000
#define MPP_INPUT_BUFFER_PADDING_SIZE 8
#define MPP_PROFILE_HEVC_MAIN 1
#define MPP_PROFILE_HEVC_MAIN_10 2
#define MPP_PROFILE_HEVC_MAIN_STILL_PICTURE 3
/**
* Value of the luma sample at position (x, y) in the 2D array tab.
*/
#define IS_IDR(s) (s->nal_unit_type == NAL_IDR_W_RADL || s->nal_unit_type == NAL_IDR_N_LP)
#define IS_BLA(s) (s->nal_unit_type == NAL_BLA_W_RADL || s->nal_unit_type == NAL_BLA_W_LP || \
s->nal_unit_type == NAL_BLA_N_LP)
#define IS_IRAP(s) (s->nal_unit_type >= 16 && s->nal_unit_type <= 23)
/**
* Table 7-3: NAL unit type codes
*/
enum NALUnitType {
NAL_TRAIL_N = 0,
NAL_TRAIL_R = 1,
NAL_TSA_N = 2,
NAL_TSA_R = 3,
NAL_STSA_N = 4,
NAL_STSA_R = 5,
NAL_RADL_N = 6,
NAL_RADL_R = 7,
NAL_RASL_N = 8,
NAL_RASL_R = 9,
NAL_BLA_W_LP = 16,
NAL_BLA_W_RADL = 17,
NAL_BLA_N_LP = 18,
NAL_IDR_W_RADL = 19,
NAL_IDR_N_LP = 20,
NAL_CRA_NUT = 21,
NAL_VPS = 32,
NAL_SPS = 33,
NAL_PPS = 34,
NAL_AUD = 35,
NAL_EOS_NUT = 36,
NAL_EOB_NUT = 37,
NAL_FD_NUT = 38,
NAL_SEI_PREFIX = 39,
NAL_SEI_SUFFIX = 40,
};
enum RPSType {
ST_CURR_BEF = 0,
ST_CURR_AFT,
ST_FOLL,
LT_CURR,
LT_FOLL,
NB_RPS_TYPE,
};
enum SliceType {
B_SLICE = 0,
P_SLICE = 1,
I_SLICE = 2,
};
typedef struct ShortTermRPS {
RK_U32 num_negative_pics;
RK_S32 num_delta_pocs;
RK_S32 rps_idx_num_delta_pocs;
RK_S32 delta_poc[32];
RK_U8 used[32];
} ShortTermRPS;
typedef struct LongTermRPS {
RK_S32 poc[32];
RK_U8 used[32];
RK_U8 nb_refs;
} LongTermRPS;
typedef struct RefPicList {
struct HEVCFrame *ref[MAX_REFS];
RK_S32 list[MAX_REFS];
RK_S32 isLongTerm[MAX_REFS];
RK_S32 nb_refs;
} RefPicList;
typedef struct RefPicListTab {
RefPicList refPicList[2];
} RefPicListTab;
typedef struct HEVCWindow {
RK_S32 left_offset;
RK_S32 right_offset;
RK_S32 top_offset;
RK_S32 bottom_offset;
} HEVCWindow;
typedef struct VUI {
MppRational_t sar;
RK_S32 overscan_info_present_flag;
RK_S32 overscan_appropriate_flag;
RK_S32 video_signal_type_present_flag;
RK_S32 video_format;
RK_S32 video_full_range_flag;
RK_S32 colour_description_present_flag;
RK_U8 colour_primaries;
RK_U8 transfer_characteristic;
RK_U8 matrix_coeffs;
RK_S32 chroma_loc_info_present_flag;
RK_S32 chroma_sample_loc_type_top_field;
RK_S32 chroma_sample_loc_type_bottom_field;
RK_S32 neutra_chroma_indication_flag;
RK_S32 field_seq_flag;
RK_S32 frame_field_info_present_flag;
RK_S32 default_display_window_flag;
HEVCWindow def_disp_win;
RK_S32 vui_timing_info_present_flag;
RK_U32 vui_num_units_in_tick;
RK_U32 vui_time_scale;
RK_S32 vui_poc_proportional_to_timing_flag;
RK_S32 vui_num_ticks_poc_diff_one_minus1;
RK_S32 vui_hrd_parameters_present_flag;
RK_S32 bitstream_restriction_flag;
RK_S32 tiles_fixed_structure_flag;
RK_S32 motion_vectors_over_pic_boundaries_flag;
RK_S32 restricted_ref_pic_lists_flag;
RK_S32 min_spatial_segmentation_idc;
RK_S32 max_bytes_per_pic_denom;
RK_S32 max_bits_per_min_cu_denom;
RK_S32 log2_max_mv_length_horizontal;
RK_S32 log2_max_mv_length_vertical;
} VUI;
typedef struct PTLCommon {
RK_U8 profile_space;
RK_U8 tier_flag;
RK_U8 profile_idc;
RK_U8 profile_compatibility_flag[32];
RK_U8 level_idc;
RK_U8 progressive_source_flag;
RK_U8 interlaced_source_flag;
RK_U8 non_packed_constraint_flag;
RK_U8 frame_only_constraint_flag;
} PTLCommon;
typedef struct PTL {
PTLCommon general_ptl;
PTLCommon sub_layer_ptl[MAX_SUB_LAYERS];
RK_U8 sub_layer_profile_present_flag[MAX_SUB_LAYERS];
RK_U8 sub_layer_level_present_flag[MAX_SUB_LAYERS];
RK_S32 sub_layer_profile_space[MAX_SUB_LAYERS];
RK_U8 sub_layer_tier_flag[MAX_SUB_LAYERS];
RK_S32 sub_layer_profile_idc[MAX_SUB_LAYERS];
RK_U8 sub_layer_profile_compatibility_flags[MAX_SUB_LAYERS][32];
RK_S32 sub_layer_level_idc[MAX_SUB_LAYERS];
} PTL;
typedef struct HEVCVPS {
RK_U8 vps_temporal_id_nesting_flag;
RK_S32 vps_max_layers;
RK_S32 vps_max_sub_layers; ///< vps_max_temporal_layers_minus1 + 1
PTL ptl;
RK_S32 vps_sub_layer_ordering_info_present_flag;
RK_U32 vps_max_dec_pic_buffering[MAX_SUB_LAYERS];
RK_U32 vps_num_reorder_pics[MAX_SUB_LAYERS];
RK_U32 vps_max_latency_increase[MAX_SUB_LAYERS];
RK_S32 vps_max_layer_id;
RK_S32 vps_num_layer_sets; ///< vps_num_layer_sets_minus1 + 1
RK_U8 vps_timing_info_present_flag;
RK_U32 vps_num_units_in_tick;
RK_U32 vps_time_scale;
RK_U8 vps_poc_proportional_to_timing_flag;
RK_S32 vps_num_ticks_poc_diff_one; ///< vps_num_ticks_poc_diff_one_minus1 + 1
RK_S32 vps_num_hrd_parameters;
RK_S32 vps_extension_flag;
} HEVCVPS;
typedef struct ScalingList {
/* This is a little wasteful, since sizeID 0 only needs 8 coeffs,
* and size ID 3 only has 2 arrays, not 6. */
RK_U8 sl[4][6][64];
RK_U8 sl_dc[2][6];
} ScalingList;
typedef struct HEVCSPS {
RK_U32 vps_id;
RK_S32 sps_id;
RK_S32 chroma_format_idc;
RK_U8 separate_colour_plane_flag;
///< output (i.e. cropped) values
RK_S32 output_width, output_height;
HEVCWindow output_window;
HEVCWindow pic_conf_win;
RK_S32 bit_depth;
RK_S32 bit_depth_chroma;///<- zrh add
RK_S32 pixel_shift;
RK_S32 pix_fmt;
RK_U32 log2_max_poc_lsb;
RK_S32 pcm_enabled_flag;
RK_S32 max_sub_layers;
struct {
int max_dec_pic_buffering;
int num_reorder_pics;
int max_latency_increase;
} temporal_layer[MAX_SUB_LAYERS];
VUI vui;
PTL ptl;
RK_U8 scaling_list_enable_flag;
ScalingList scaling_list;
RK_U32 nb_st_rps;
ShortTermRPS st_rps[MAX_SHORT_TERM_RPS_COUNT];
RK_U8 amp_enabled_flag;
RK_U8 sao_enabled;
RK_U8 long_term_ref_pics_present_flag;
RK_U16 lt_ref_pic_poc_lsb_sps[32];
RK_U8 used_by_curr_pic_lt_sps_flag[32];
RK_U8 num_long_term_ref_pics_sps;
struct {
RK_U8 bit_depth;
RK_U8 bit_depth_chroma;
RK_U32 log2_min_pcm_cb_size;
RK_U32 log2_max_pcm_cb_size;
RK_U8 loop_filter_disable_flag;
} pcm;
RK_U8 sps_temporal_mvp_enabled_flag;
RK_U8 sps_strong_intra_smoothing_enable_flag;
RK_U32 log2_min_cb_size;
RK_U32 log2_diff_max_min_coding_block_size;
RK_U32 log2_min_tb_size;
RK_U32 log2_max_trafo_size;
RK_S32 log2_ctb_size;
RK_U32 log2_min_pu_size;
RK_S32 max_transform_hierarchy_depth_inter;
RK_S32 max_transform_hierarchy_depth_intra;
///< coded frame dimension in various units
RK_S32 width;
RK_S32 height;
RK_S32 ctb_width;
RK_S32 ctb_height;
RK_S32 ctb_size;
RK_S32 min_cb_width;
RK_S32 min_cb_height;
RK_S32 min_tb_width;
RK_S32 min_tb_height;
RK_S32 min_pu_width;
RK_S32 min_pu_height;
RK_S32 hshift[3];
RK_S32 vshift[3];
RK_S32 qp_bd_offset;
#ifdef SCALED_REF_LAYER_OFFSETS
HEVCWindow scaled_ref_layer_window;
#endif
#ifdef REF_IDX_MFM
RK_S32 set_mfm_enabled_flag;
#endif
} HEVCSPS;
typedef struct HEVCPPS {
RK_S32 sps_id;
RK_S32 pps_id;
RK_U8 sign_data_hiding_flag;
RK_U8 cabac_init_present_flag;
RK_S32 num_ref_idx_l0_default_active; ///< num_ref_idx_l0_default_active_minus1 + 1
RK_S32 num_ref_idx_l1_default_active; ///< num_ref_idx_l1_default_active_minus1 + 1
RK_S32 pic_init_qp_minus26;
RK_U8 constrained_intra_pred_flag;
RK_U8 transform_skip_enabled_flag;
RK_U8 cu_qp_delta_enabled_flag;
RK_S32 diff_cu_qp_delta_depth;
RK_S32 cb_qp_offset;
RK_S32 cr_qp_offset;
RK_U8 pic_slice_level_chroma_qp_offsets_present_flag;
RK_U8 weighted_pred_flag;
RK_U8 weighted_bipred_flag;
RK_U8 output_flag_present_flag;
RK_U8 transquant_bypass_enable_flag;
RK_U8 dependent_slice_segments_enabled_flag;
RK_U8 tiles_enabled_flag;
RK_U8 entropy_coding_sync_enabled_flag;
RK_S32 num_tile_columns; ///< num_tile_columns_minus1 + 1
RK_S32 num_tile_rows; ///< num_tile_rows_minus1 + 1
RK_U8 uniform_spacing_flag;
RK_U8 loop_filter_across_tiles_enabled_flag;
RK_U8 seq_loop_filter_across_slices_enabled_flag;
RK_U8 deblocking_filter_control_present_flag;
RK_U8 deblocking_filter_override_enabled_flag;
RK_U8 disable_dbf;
RK_S32 beta_offset; ///< beta_offset_div2 * 2
RK_S32 tc_offset; ///< tc_offset_div2 * 2
RK_U8 scaling_list_data_present_flag;
ScalingList scaling_list;
RK_U8 lists_modification_present_flag;
RK_S32 log2_parallel_merge_level; ///< log2_parallel_merge_level_minus2 + 2
RK_S32 num_extra_slice_header_bits;
RK_U8 slice_header_extension_present_flag;
RK_U8 pps_extension_flag;
RK_U8 pps_extension_data_flag;
// Inferred parameters
RK_U32 *column_width; ///< ColumnWidth
RK_U32 *row_height; ///< RowHeight
RK_U32 *col_bd; ///< ColBd
RK_U32 *row_bd; ///< RowBd
RK_S32 *col_idxX;
RK_S32 *ctb_addr_rs_to_ts; ///< CtbAddrRSToTS
RK_S32 *ctb_addr_ts_to_rs; ///< CtbAddrTSToRS
RK_S32 *tile_id; ///< TileId
RK_S32 *tile_pos_rs; ///< TilePosRS
RK_S32 *min_cb_addr_zs; ///< MinCbAddrZS
RK_S32 *min_tb_addr_zs; ///< MinTbAddrZS
} HEVCPPS;
typedef struct SliceHeader {
RK_U32 pps_id;
///< address (in raster order) of the first block in the current slice segment
RK_U32 slice_segment_addr;
///< address (in raster order) of the first block in the current slice
RK_U32 slice_addr;
enum SliceType slice_type;
RK_S32 pic_order_cnt_lsb;
RK_U8 first_slice_in_pic_flag;
RK_U8 dependent_slice_segment_flag;
RK_U8 pic_output_flag;
RK_U8 colour_plane_id;
///< RPS coded in the slice header itself is stored here
int short_term_ref_pic_set_sps_flag;
int short_term_ref_pic_set_size;
ShortTermRPS slice_rps;
const ShortTermRPS *short_term_rps;
LongTermRPS long_term_rps;
RK_U32 list_entry_lx[2][32];
RK_U8 rpl_modification_flag[2];
RK_U8 no_output_of_prior_pics_flag;
RK_U8 slice_temporal_mvp_enabled_flag;
RK_U32 nb_refs[2];
RK_U8 slice_sample_adaptive_offset_flag[3];
RK_U8 mvd_l1_zero_flag;
RK_U8 cabac_init_flag;
RK_U8 disable_deblocking_filter_flag; ///< slice_header_disable_deblocking_filter_flag
RK_U8 slice_loop_filter_across_slices_enabled_flag;
RK_U8 collocated_list;
RK_U32 collocated_ref_idx;
RK_S32 slice_qp_delta;
RK_S32 slice_cb_qp_offset;
RK_S32 slice_cr_qp_offset;
RK_S32 beta_offset; ///< beta_offset_div2 * 2
RK_S32 tc_offset; ///< tc_offset_div2 * 2
RK_U32 max_num_merge_cand; ///< 5 - 5_minus_max_num_merge_cand
RK_S32 *entry_point_offset;
RK_S32 * offset;
RK_S32 * size;
RK_S32 num_entry_point_offsets;
RK_S8 slice_qp;
RK_U8 luma_log2_weight_denom;
RK_S16 chroma_log2_weight_denom;
RK_S16 luma_weight_l0[16];
RK_S16 chroma_weight_l0[16][2];
RK_S16 chroma_weight_l1[16][2];
RK_S16 luma_weight_l1[16];
RK_S16 luma_offset_l0[16];
RK_S16 chroma_offset_l0[16][2];
RK_S16 luma_offset_l1[16];
RK_S16 chroma_offset_l1[16][2];
#ifdef REF_IDX_FRAMEWORK
RK_S32 inter_layer_pred_enabled_flag;
#endif
#ifdef JCTVC_M0458_INTERLAYER_RPS_SIG
RK_S32 active_num_ILR_ref_idx; //< Active inter-layer reference pictures
RK_S32 inter_layer_pred_layer_idc[MAX_VPS_LAYER_ID_PLUS1];
#endif
RK_S32 slice_ctb_addr_rs;
} SliceHeader;
typedef struct CurrentFameInf {
HEVCVPS vps[MAX_VPS_COUNT];
HEVCSPS sps[MAX_SPS_COUNT];
HEVCPPS pps[MAX_PPS_COUNT];
SliceHeader sh;
} CurrentFameInf_t;
typedef struct DBParams {
RK_S32 beta_offset;
RK_S32 tc_offset;
} DBParams;
#define HEVC_FRAME_FLAG_OUTPUT (1 << 0)
#define HEVC_FRAME_FLAG_SHORT_REF (1 << 1)
#define HEVC_FRAME_FLAG_LONG_REF (1 << 2)
typedef struct HEVCFrame {
MppFrame frame;
RefPicList *refPicList;
RefPicListTab **rpl_tab;
RK_S32 ctb_count;
RK_S32 poc;
struct HEVCFrame *collocated_ref;
HEVCWindow window;
RK_U8 *rpl_tab_buf;
RK_U8 *rpl_buf;
/**
* A sequence counter, so that old frames are output first
* after a POC reset
*/
RK_U16 sequence;
/**
* A combination of HEVC_FRAME_FLAG_*
*/
RK_U8 flags;
RK_U32 slot_index;
} HEVCFrame;
typedef struct HEVCNAL {
RK_U8 *rbsp_buffer;
RK_S32 rbsp_buffer_size;
RK_S32 size;
const RK_U8 *data;
} HEVCNAL;
typedef struct HEVCLocalContext {
GetBitCxt_t gb;
} HEVCLocalContext;
typedef struct REF_PIC_DEC_INFO {
RK_U8 dbp_index;
RK_U8 is_long_term;
} REF_PIC_DEC_INFO;
typedef struct HEVCContext {
H265dContext_t *h265dctx;
HEVCLocalContext *HEVClc;
MppFrame frame;
const HEVCVPS *vps;
const HEVCSPS *sps;
const HEVCPPS *pps;
RK_U8 *vps_list[MAX_VPS_COUNT];
RK_U8 *sps_list[MAX_SPS_COUNT];
RK_U8 *pps_list[MAX_PPS_COUNT];
SliceHeader sh;
///< candidate references for the current frame
RefPicList rps[5];
enum NALUnitType nal_unit_type;
RK_S32 temporal_id; ///< temporal_id_plus1 - 1
HEVCFrame *ref;
HEVCFrame DPB[32];
RK_S32 poc;
RK_S32 pocTid0;
RK_S32 slice_idx; ///< number of the slice being currently decoded
RK_S32 eos; ///< current packet contains an EOS/EOB NAL
RK_S32 max_ra;
RK_S32 is_decoded;
/** used on BE to byteswap the lines for checksumming */
RK_U8 *checksum_buf;
RK_S32 checksum_buf_size;
/**
* Sequence counters for decoded and output frames, so that old
* frames are output first after a POC reset
*/
RK_U16 seq_decode;
RK_U16 seq_output;
RK_S32 wpp_err;
RK_S32 skipped_bytes;
RK_U8 *data;
HEVCNAL *nals;
RK_S32 nb_nals;
RK_S32 nals_allocated;
// type of the first VCL NAL of the current frame
enum NALUnitType first_nal_type;
RK_U8 context_initialized;
RK_U8 is_nalff; ///< this flag is != 0 if bitstream is encapsulated
///< as a format defined in 14496-15
RK_S32 temporal_layer_id;
RK_S32 decoder_id;
RK_S32 apply_defdispwin;
RK_S32 active_seq_parameter_set_id;
RK_S32 nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4)
RK_S32 nuh_layer_id;
/** frame packing arrangement variables */
RK_S32 sei_frame_packing_present;
RK_S32 frame_packing_arrangement_type;
RK_S32 content_interpretation_type;
RK_S32 quincunx_subsampling;
RK_S32 picture_struct;
/** 1 if the independent slice segment header was successfully parsed */
RK_U8 slice_initialized;
RK_S32 decode_checksum_sei;
RK_U8 scaling_list[81][1360];
RK_U8 scaling_list_listen[81];
RK_U8 sps_list_of_updated[MAX_SPS_COUNT];///< zrh add
RK_U8 pps_list_of_updated[MAX_PPS_COUNT];///< zrh add
RK_S32 rps_used[16];
RK_S32 nb_rps_used;
REF_PIC_DEC_INFO rps_pic_info[600][2][15]; // zrh add
RK_U8 lowdelay_flag[600];
RK_U8 rps_bit_offset[600];
RK_U8 rps_bit_offset_st[600];
RK_U8 slice_nb_rps_poc[600];
RK_S32 frame_size;
RK_S32 framestrid;
RK_U32 nb_frame;
RK_U8 output_frame_idx;
RK_U32 got_frame;
MppBufSlots slots;
HalDecTask *task;
void *hal_pic_private;
RK_S64 pts;
} HEVCContext;
RK_S32 mpp_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps,
const HEVCSPS *sps, RK_S32 is_slice_header);
RK_S32 mpp_hevc_decode_nal_vps(HEVCContext *s);
RK_S32 mpp_hevc_decode_nal_sps(HEVCContext *s);
RK_S32 mpp_hevc_decode_nal_pps(HEVCContext *s);
RK_S32 mpp_hevc_decode_nal_sei(HEVCContext *s);
RK_S32 mpp_hevc_extract_rbsp(HEVCContext *s, const RK_U8 *src, RK_S32 length,
HEVCNAL *nal);
/**
* Mark all frames in DPB as unused for reference.
*/
void mpp_hevc_clear_refs(HEVCContext *s);
/**
* Drop all frames currently in DPB.
*/
void mpp_hevc_flush_dpb(HEVCContext *s);
/**
* Compute POC of the current frame and return it.
*/
int mpp_hevc_compute_poc(HEVCContext *s, RK_S32 poc_lsb);
/**
* Construct the reference picture sets for the current frame.
*/
RK_S32 mpp_hevc_frame_rps(HEVCContext *s);
/**
* Construct the reference picture list(s) for the current slice.
*/
RK_S32 mpp_hevc_slice_rpl(HEVCContext *s);
/**
* Get the number of candidate references for the current frame.
*/
RK_S32 mpp_hevc_frame_nb_refs(HEVCContext *s);
RK_S32 mpp_hevc_set_new_ref(HEVCContext *s, MppFrame *frame, RK_S32 poc);
/**
* Find next frame in output order and put a reference to it in frame.
* @return 1 if a frame was output, 0 otherwise
*/
void mpp_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, RK_S32 flags);
void mpp_hevc_pps_free(RK_U8 *data);
#endif /* __H265D_PAESER_H__ */

View File

@@ -0,0 +1,311 @@
/*
*
* Copyright 2010 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.
*/
/*
* @file h265d_parser2_syntax.c
* @brief
* @author csy(csy@rock-chips.com)
* @version 1.0.0
* @history
* 2015.7.15 : Create
*/
#define MODULE_TAG "H265SYNATX"
#include "h265d_parser.h"
#include "h265d_syntax.h"
static void fill_picture_entry(DXVA_PicEntry_HEVC *pic,
unsigned index, unsigned flag)
{
mpp_assert((index & 0x7f) == index && (flag & 0x01) == flag);
pic->bPicEntry = index | (flag << 7);
}
static RK_S32 get_refpic_index(const DXVA_PicParams_HEVC *pp, int surface_index)
{
RK_U32 i;
for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefPicList); i++) {
if ((pp->RefPicList[i].bPicEntry & 0x7f) == surface_index) {
//mpp_err("retun %d slot_index = %d",i,surface_index);
return i;
}
}
return 0xff;
}
static void fill_picture_parameters(const HEVCContext *h,
DXVA_PicParams_HEVC *pp)
{
const HEVCFrame *current_picture = h->ref;
const HEVCPPS *pps = (HEVCPPS *)h->pps_list[h->sh.pps_id];
const HEVCSPS *sps = (HEVCSPS *)h->sps_list[pps->sps_id];
RK_U32 i, j;
memset(pp, 0, sizeof(*pp));
pp->PicWidthInMinCbsY = sps->min_cb_width;
pp->PicHeightInMinCbsY = sps->min_cb_height;
pp->pps_id = h->sh.pps_id;
pp->sps_id = pps->sps_id;
pp->vps_id = sps->vps_id;
pp->wFormatAndSequenceInfoFlags = (sps->chroma_format_idc << 0) |
(sps->separate_colour_plane_flag << 2) |
((sps->bit_depth - 8) << 3) |
((sps->bit_depth - 8) << 6) |
((sps->log2_max_poc_lsb - 4) << 9) |
(0 << 13) |
(0 << 14) |
(0 << 15);
fill_picture_entry(&pp->CurrPic, current_picture->slot_index, 0);
pp->sps_max_dec_pic_buffering_minus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering - 1;
pp->log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3;
pp->log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_coding_block_size;
pp->log2_min_transform_block_size_minus2 = sps->log2_min_tb_size - 2;
pp->log2_diff_max_min_transform_block_size = sps->log2_max_trafo_size - sps->log2_min_tb_size;
pp->max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter;
pp->max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra;
pp->num_short_term_ref_pic_sets = sps->nb_st_rps;
pp->num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps;
pp->num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1;
pp->num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1;
pp->init_qp_minus26 = pps->pic_init_qp_minus26;
if (h->sh.short_term_ref_pic_set_sps_flag == 0 && h->sh.short_term_rps) {
pp->ucNumDeltaPocsOfRefRpsIdx = h->sh.short_term_rps->rps_idx_num_delta_pocs;
pp->wNumBitsForShortTermRPSInSlice = h->sh.short_term_ref_pic_set_size;
}
pp->dwCodingParamToolFlags = (sps->scaling_list_enable_flag << 0) |
(sps->amp_enabled_flag << 1) |
(sps->sao_enabled << 2) |
(sps->pcm_enabled_flag << 3) |
((sps->pcm_enabled_flag ? (sps->pcm.bit_depth - 1) : 0) << 4) |
((sps->pcm_enabled_flag ? (sps->pcm.bit_depth_chroma - 1) : 0) << 8) |
((sps->pcm_enabled_flag ? (sps->pcm.log2_min_pcm_cb_size - 3) : 0) << 12) |
((sps->pcm_enabled_flag ? (sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size) : 0) << 14) |
(sps->pcm.loop_filter_disable_flag << 16) |
(sps->long_term_ref_pics_present_flag << 17) |
(sps->sps_temporal_mvp_enabled_flag << 18) |
(sps->sps_strong_intra_smoothing_enable_flag << 19) |
(pps->dependent_slice_segments_enabled_flag << 20) |
(pps->output_flag_present_flag << 21) |
(pps->num_extra_slice_header_bits << 22) |
(pps->sign_data_hiding_flag << 25) |
(pps->cabac_init_present_flag << 26) |
(0 << 27);
pp->dwCodingSettingPicturePropertyFlags = (pps->constrained_intra_pred_flag << 0) |
(pps->transform_skip_enabled_flag << 1) |
(pps->cu_qp_delta_enabled_flag << 2) |
(pps->pic_slice_level_chroma_qp_offsets_present_flag << 3) |
(pps->weighted_pred_flag << 4) |
(pps->weighted_bipred_flag << 5) |
(pps->transquant_bypass_enable_flag << 6) |
(pps->tiles_enabled_flag << 7) |
(pps->entropy_coding_sync_enabled_flag << 8) |
(pps->uniform_spacing_flag << 9) |
((pps->tiles_enabled_flag ? pps->loop_filter_across_tiles_enabled_flag : 0) << 10) |
(pps->seq_loop_filter_across_slices_enabled_flag << 11) |
(pps->deblocking_filter_override_enabled_flag << 12) |
(pps->disable_dbf << 13) |
(pps->lists_modification_present_flag << 14) |
(pps->slice_header_extension_present_flag << 15) |
(IS_IRAP(h) << 16) |
(IS_IDR(h) << 17) |
/* IntraPicFlag */
(IS_IRAP(h) << 18) |
(0 << 19);
pp->pps_cb_qp_offset = pps->cb_qp_offset;
pp->pps_cr_qp_offset = pps->cr_qp_offset;
if (pps->tiles_enabled_flag) {
pp->num_tile_columns_minus1 = pps->num_tile_columns - 1;
pp->num_tile_rows_minus1 = pps->num_tile_rows - 1;
if (!pps->uniform_spacing_flag) {
for (i = 0; i < (RK_U32)pps->num_tile_columns; i++)
pp->column_width_minus1[i] = pps->column_width[i] - 1;
for (i = 0; i < (RK_U32)pps->num_tile_rows; i++)
pp->row_height_minus1[i] = pps->row_height[i] - 1;
}
}
pp->diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth;
pp->pps_beta_offset_div2 = pps->beta_offset / 2;
pp->pps_tc_offset_div2 = pps->tc_offset / 2;
pp->log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2;
pp->CurrPicOrderCntVal = h->poc;
mpp_err("fill RefPicList from the DPB");
// fill RefPicList from the DPB
for (i = 0, j = 0; i < MPP_ARRAY_ELEMS(pp->RefPicList); i++) {
const HEVCFrame *frame = NULL;
while (!frame && j < MPP_ARRAY_ELEMS(h->DPB)) {
if (&h->DPB[j] != current_picture && (h->DPB[j].flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF)))
frame = &h->DPB[j];
j++;
}
if (frame) {
fill_picture_entry(&pp->RefPicList[i], frame->slot_index, !!(frame->flags & HEVC_FRAME_FLAG_LONG_REF));
pp->PicOrderCntValList[i] = frame->poc;
mpp_buf_slot_inc_hw_ref(h->slots, frame->slot_index);
h->task->refer[i] = frame->slot_index;
//mpp_err("ref[%d] = %d",i,frame->slot_index);
} else {
pp->RefPicList[i].bPicEntry = 0xff;
pp->PicOrderCntValList[i] = 0;
h->task->refer[i] = -1;
}
}
#define DO_REF_LIST(ref_idx, ref_list) { \
const RefPicList *rpl = &h->rps[ref_idx]; \
for (i = 0, j = 0; i < MPP_ARRAY_ELEMS(pp->ref_list); i++) { \
const HEVCFrame *frame = NULL; \
while (!frame && j < (RK_U32)rpl->nb_refs) \
frame = rpl->ref[j++]; \
if (frame) \
pp->ref_list[i] = get_refpic_index(pp, frame->slot_index); \
else \
pp->ref_list[i] = 0xff; \
} \
}
// Fill short term and long term lists
DO_REF_LIST(ST_CURR_BEF, RefPicSetStCurrBefore);
DO_REF_LIST(ST_CURR_AFT, RefPicSetStCurrAfter);
DO_REF_LIST(LT_CURR, RefPicSetLtCurr);
}
extern RK_U8 mpp_hevc_diag_scan4x4_x[16];
extern RK_U8 mpp_hevc_diag_scan4x4_y[16];
extern RK_U8 mpp_hevc_diag_scan8x8_x[64];
extern RK_U8 mpp_hevc_diag_scan8x8_y[64];
static void fill_scaling_lists(const HEVCContext *h, DXVA_Qmatrix_HEVC *qm)
{
RK_U32 i, j, pos;
const HEVCPPS *pps = (HEVCPPS *)h->pps_list[h->sh.pps_id];
const HEVCSPS *sps = (HEVCSPS *)h->sps_list[pps->sps_id];
const ScalingList *sl = pps->scaling_list_data_present_flag ?
&pps->scaling_list : &sps->scaling_list;
memset(qm, 0, sizeof(*qm));
for (i = 0; i < 6; i++) {
for (j = 0; j < 16; j++) {
pos = 4 * mpp_hevc_diag_scan4x4_y[j] + mpp_hevc_diag_scan4x4_x[j];
qm->ucScalingLists0[i][j] = sl->sl[0][i][pos];
}
for (j = 0; j < 64; j++) {
pos = 8 * mpp_hevc_diag_scan8x8_y[j] + mpp_hevc_diag_scan8x8_x[j];
qm->ucScalingLists1[i][j] = sl->sl[1][i][pos];
qm->ucScalingLists2[i][j] = sl->sl[2][i][pos];
if (i < 2)
qm->ucScalingLists3[i][j] = sl->sl[3][i * 3][pos];
}
qm->ucScalingListDCCoefSizeID2[i] = sl->sl_dc[0][i];
if (i < 2)
qm->ucScalingListDCCoefSizeID3[i] = sl->sl_dc[1][i * 3];
}
}
static void fill_slice_short(DXVA_Slice_HEVC_Short *slice,
unsigned position, unsigned size)
{
memset(slice, 0, sizeof(*slice));
slice->BSNALunitDataLocation = position;
slice->SliceBytesInBuffer = size;
slice->wBadSliceChopping = 0;
}
RK_S32 h265d_parser2_syntax(void *ctx)
{
H265dContext_t *h265dctx = (H265dContext_t *)ctx;
const HEVCContext *h = h265dctx->priv_data;
h265d_dxva2_picture_context_t *ctx_pic = h->hal_pic_private;
/* Fill up DXVA_PicParams_HEVC */
fill_picture_parameters(h, &ctx_pic->pp);
/* Fill up DXVA_Qmatrix_HEVC */
fill_scaling_lists(h, &ctx_pic->qm);
return 0;
}
RK_S32 h265d_syntax_fill_slice(void *ctx, MppBuffer *streambuf)
{
H265dContext_t *h265dctx = (H265dContext_t *)ctx;
const HEVCContext *h = h265dctx->priv_data;
h265d_dxva2_picture_context_t *ctx_pic = h->hal_pic_private;
RK_S32 i, count = 0;
RK_U32 position = 0;
RK_U8 *ptr = (RK_U8 *)mpp_buffer_get_ptr(streambuf);
RK_U8 *current = ptr;
if (current == NULL) {
return MPP_ERR_NULL_PTR;
}
for (i = 0; i < h->nb_nals; i++) {
static const RK_U8 start_code[] = {0, 0, 1 };
static const RK_U32 start_code_size = sizeof(start_code);
GetBitCxt_t gb_cxt, *gb;
RK_S32 value;
RK_U32 nal_type;
mpp_Init_Bits(&gb_cxt, (RK_U8 *)h->nals[i].data,
h->nals[i].size);
gb = &gb_cxt;
READ_BIT1(gb, &value);
if ( value != 0)
return MPP_ERR_STREAM;
READ_BITS(gb, 6, &nal_type);
if (nal_type >= 32) {
continue;
}
memcpy(current, start_code, start_code_size);
current += start_code_size;
position += start_code_size;
memcpy(current, h->nals[i].data, h->nals[i].size);
mpp_err("h->nals[%d].size = %d", i, h->nals[i].size);
fill_slice_short(&ctx_pic->slice_short[i], position, h->nals[i].size);
current += h->nals[i].size;
position += h->nals[i].size;
count++;
}
ctx_pic->slice_count = count;
ctx_pic->bitstream_size = position;
ctx_pic->bitstream = (RK_U8*)ptr;
return MPP_OK;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,450 @@
/*
*
* Copyright 2010 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.
*/
/*
* @file h265_refs.c
* @brief
* @author csy(csy@rock-chips.com)
* @version 1.0.0
* @history
* 2015.7.15 : Create
*/
#define LOG_TAG "H265_PARSER_REF"
#include "h265d_parser.h"
#define HEVC_ALIGN(value, x) ((value + (x-1)) & (~(x-1)))
void mpp_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags)
{
/* frame->frame can be NULL if context init failed */
if (!frame->frame || (frame->slot_index == 0xff))
return;
frame->flags &= ~flags;
if (!frame->flags) {
mpp_free(frame->rpl_buf);
mpp_free(frame->rpl_tab_buf);
frame->rpl_tab = NULL;
frame->refPicList = NULL;
frame->collocated_ref = NULL;
if (frame->slot_index <= 0x7f) {
h265d_dbg(H265D_DBG_REF, "poc %d clr ref index %d", frame->poc, frame->slot_index);
mpp_buf_slot_clr_dpb_ref(s->slots, frame->slot_index);
}
h265d_dbg(H265D_DBG_REF, "unref_frame poc %d frame->slot_index %d \n", frame->poc, frame->slot_index);
frame->poc = INT_MAX;
frame->slot_index = 0xff;
}
}
void mpp_hevc_clear_refs(HEVCContext *s)
{
RK_U32 i;
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
mpp_hevc_unref_frame(s, &s->DPB[i],
HEVC_FRAME_FLAG_SHORT_REF |
HEVC_FRAME_FLAG_LONG_REF);
}
}
void mpp_hevc_flush_dpb(HEVCContext *s)
{
RK_U32 i;
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
mpp_hevc_unref_frame(s, &s->DPB[i], ~0);
}
}
static HEVCFrame *alloc_frame(HEVCContext *s)
{
RK_S32 j;
RK_U32 i;
MPP_RET ret = MPP_OK;
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
HEVCFrame *frame = &s->DPB[i];
if (frame->slot_index != 0xff) {
continue;
}
if (ret != MPP_OK) {
goto fail;
}
mpp_err("width = %d height = %d", s->h265dctx->width, s->h265dctx->height);
mpp_frame_set_width(frame->frame, s->h265dctx->width);
mpp_frame_set_height(frame->frame, s->h265dctx->height);
mpp_frame_set_hor_stride(frame->frame, HEVC_ALIGN(s->h265dctx->coded_width, 256) | 256);
mpp_frame_set_ver_stride(frame->frame, HEVC_ALIGN(s->h265dctx->coded_height, 8));
// frame->frame->color_type = s->h265dctx->pix_fmt;
// if (!frame->frame->sample_aspect_ratio.num)
// frame->frame->sample_aspect_ratio = s->h265dctx->sample_aspect_ratio;
mpp_frame_set_pts(frame->frame, s->pts);
frame->rpl_buf = mpp_calloc(RK_U8, s->nb_nals * sizeof(RefPicListTab));
if (!frame->rpl_buf)
goto fail;
frame->ctb_count = s->sps->ctb_width * s->sps->ctb_height;
frame->rpl_tab_buf = mpp_calloc(RK_U8, frame->ctb_count * sizeof(RefPicListTab));
if (!frame->rpl_tab_buf)
goto fail;
frame->rpl_tab = (RefPicListTab **)frame->rpl_tab_buf;
for (j = 0; j < frame->ctb_count; j++)
frame->rpl_tab[j] = (RefPicListTab *)frame->rpl_buf;
// frame->frame->top_field_first = s->picture_struct;
ret = mpp_buf_slot_get_unused(s->slots, &frame->slot_index);
return frame;
fail:
mpp_hevc_unref_frame(s, frame, ~0);
return NULL;
}
mpp_err( "Error allocating frame, DPB full.\n");
return NULL;
}
int mpp_hevc_set_new_ref(HEVCContext *s, MppFrame *mframe, int poc)
{
HEVCFrame *ref = NULL;
RK_U32 i;
/* check that this POC doesn't already exist */
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
HEVCFrame *frame = &s->DPB[i];
if ((frame->slot_index != 0xff) && frame->sequence == s->seq_decode &&
frame->poc == poc && !s->nuh_layer_id) {
mpp_err( "Duplicate POC in a sequence: %d.\n",
poc);
return MPP_ERR_STREAM;
}
}
ref = alloc_frame(s);
if (!ref)
return MPP_ERR_NOMEM;
*mframe = ref->frame;
s->ref = ref;
ref->poc = poc;
h265d_dbg(H265D_DBG_REF, "alloc frame poc %d slot_index %d", poc, ref->slot_index);
ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF;
mpp_buf_slot_set_dpb_ref(s->slots, ref->slot_index);
mpp_buf_slot_set_hw_dst(s->slots, ref->slot_index, ref->frame);
s->task->output = ref->slot_index;
ref->sequence = s->seq_decode;
ref->window = s->sps->output_window;
return 0;
}
static int init_slice_rpl(HEVCContext *s)
{
HEVCFrame *frame = s->ref;
RK_S32 ctb_count = frame->ctb_count;
RK_S32 ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr];
RK_S32 i;
if (s->slice_idx >= s->nb_nals)
return MPP_ERR_STREAM;
for (i = ctb_addr_ts; i < ctb_count; i++)
frame->rpl_tab[i] = (RefPicListTab *)frame->rpl_buf + s->slice_idx;
frame->refPicList = (RefPicList *)frame->rpl_tab[ctb_addr_ts];
return 0;
}
static HEVCFrame *find_ref_idx(HEVCContext *s, int poc)
{
RK_U32 i;
RK_S32 LtMask = (1 << s->sps->log2_max_poc_lsb) - 1;
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
HEVCFrame *ref = &s->DPB[i];
if ((ref->slot_index != 0xff) && (ref->sequence == s->seq_decode)) {
if ((ref->poc & LtMask) == poc)
return ref;
}
}
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
HEVCFrame *ref = &s->DPB[i];
if ((ref->slot_index != 0xff) && ref->sequence == s->seq_decode) {
if (ref->poc == poc || (ref->poc & LtMask) == poc)
return ref;
}
}
mpp_err(
"Could not find ref with POC %d\n", poc);
return NULL;
}
int mpp_hevc_slice_rpl(HEVCContext *s)
{
SliceHeader *sh = &s->sh;
RK_U8 nb_list = sh->slice_type == B_SLICE ? 2 : 1;
RK_U8 list_idx;
RK_U32 i;
RK_S32 j, ret;
ret = init_slice_rpl(s);
if (ret < 0)
return ret;
if (!(s->rps[ST_CURR_BEF].nb_refs + s->rps[ST_CURR_AFT].nb_refs +
s->rps[LT_CURR].nb_refs)) {
mpp_err( "Zero refs in the frame RPS.\n");
return MPP_ERR_STREAM;
}
for (list_idx = 0; list_idx < nb_list; list_idx++) {
RefPicList rpl_tmp;
memset(&rpl_tmp, 0, sizeof(rpl_tmp));
RefPicList *rpl = &s->ref->refPicList[list_idx];
/* The order of the elements is
* ST_CURR_BEF - ST_CURR_AFT - LT_CURR for the L0 and
* ST_CURR_AFT - ST_CURR_BEF - LT_CURR for the L1 */
RK_S32 cand_lists[3] = { list_idx ? ST_CURR_AFT : ST_CURR_BEF,
list_idx ? ST_CURR_BEF : ST_CURR_AFT,
LT_CURR
};
/* concatenate the candidate lists for the current frame */
while ((RK_U32)rpl_tmp.nb_refs < sh->nb_refs[list_idx]) {
for (i = 0; i < MPP_ARRAY_ELEMS(cand_lists); i++) {
RefPicList *rps = &s->rps[cand_lists[i]];
for (j = 0; j < rps->nb_refs && rpl_tmp.nb_refs < MAX_REFS; j++) {
rpl_tmp.list[rpl_tmp.nb_refs] = rps->list[j];
rpl_tmp.ref[rpl_tmp.nb_refs] = rps->ref[j];
rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = i == 2;
rpl_tmp.nb_refs++;
}
}
}
/* reorder the references if necessary */
if (sh->rpl_modification_flag[list_idx]) {
for (i = 0; i < sh->nb_refs[list_idx]; i++) {
int idx = sh->list_entry_lx[list_idx][i];
if (!s->decoder_id && idx >= rpl_tmp.nb_refs) {
mpp_err( "Invalid reference index.\n");
return MPP_ERR_STREAM;
}
rpl->list[i] = rpl_tmp.list[idx];
rpl->ref[i] = rpl_tmp.ref[idx];
rpl->isLongTerm[i] = rpl_tmp.isLongTerm[idx];
rpl->nb_refs++;
}
} else {
memcpy(rpl, &rpl_tmp, sizeof(*rpl));
rpl->nb_refs = MPP_MIN((RK_U32)rpl->nb_refs, sh->nb_refs[list_idx]);
}
if (sh->collocated_list == list_idx &&
sh->collocated_ref_idx < (RK_U32)rpl->nb_refs)
s->ref->collocated_ref = rpl->ref[sh->collocated_ref_idx];
}
return 0;
}
static void mark_ref(HEVCFrame *frame, int flag)
{
frame->flags &= ~(HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF);
frame->flags |= flag;
}
static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc)
{
HEVCFrame *frame;
mpp_log("generate_missing_ref in \n");
frame = alloc_frame(s);
if (!frame)
return NULL;
#if 0
if (!s->sps->pixel_shift) {
for (i = 0; frame->frame->buf[i]; i++)
memset(frame->frame->buf[i]->data, 1 << (s->sps->bit_depth - 1),
frame->frame->buf[i]->size);
} else {
for (i = 0; frame->frame->data[i]; i++)
for (y = 0; y < (s->sps->height >> s->sps->vshift[i]); y++)
for (x = 0; x < (s->sps->width >> s->sps->hshift[i]); x++) {
AV_WN16(frame->frame->data[i] + y * frame->frame->linesize[i] + 2 * x,
1 << (s->sps->bit_depth - 1));
}
}
#endif
frame->poc = poc;
mpp_err("generate_missing_ref frame poc %d slot_index %d", poc, frame->slot_index);
frame->sequence = s->seq_decode;
frame->flags = 0;
return frame;
}
/* add a reference with the given poc to the list and mark it as used in DPB */
static int add_candidate_ref(HEVCContext *s, RefPicList *list,
int poc, int ref_flag)
{
HEVCFrame *ref = find_ref_idx(s, poc);
if (ref == s->ref)
return MPP_ERR_STREAM;
if (!ref) {
ref = generate_missing_ref(s, poc);
if (!ref)
return MPP_ERR_NOMEM;
}
list->list[list->nb_refs] = ref->poc;
list->ref[list->nb_refs] = ref;
list->nb_refs++;
if (ref_flag) {
h265d_dbg(H265D_DBG_REF, "set ref poc = %d ref->slot_index %d", ref->poc, ref->slot_index);
mpp_buf_slot_set_dpb_ref(s->slots, ref->slot_index);
}
mark_ref(ref, ref_flag);
return 0;
}
RK_S32 mpp_hevc_frame_rps(HEVCContext *s)
{
const ShortTermRPS *short_rps = s->sh.short_term_rps;
const LongTermRPS *long_rps = &s->sh.long_term_rps;
RefPicList *rps = s->rps;
RK_S32 ret;
RK_U32 i;
if (!short_rps) {
rps[0].nb_refs = rps[1].nb_refs = 0;
if (!long_rps)
return 0;
}
/* clear the reference flags on all frames except the current one */
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
HEVCFrame *frame = &s->DPB[i];
if (frame == s->ref)
continue;
mark_ref(frame, 0);
}
for (i = 0; i < NB_RPS_TYPE; i++)
rps[i].nb_refs = 0;
/* add the short refs */
for (i = 0; short_rps && (RK_S32)i < short_rps->num_delta_pocs; i++) {
int poc = s->poc + short_rps->delta_poc[i];
int list;
if (!short_rps->used[i])
list = ST_FOLL;
else if (i < short_rps->num_negative_pics)
list = ST_CURR_BEF;
else
list = ST_CURR_AFT;
ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_SHORT_REF);
if (ret < 0)
return ret;
}
/* add the long refs */
for (i = 0; long_rps && i < long_rps->nb_refs; i++) {
int poc = long_rps->poc[i];
int list = long_rps->used[i] ? LT_CURR : LT_FOLL;
ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_LONG_REF);
if (ret < 0)
return ret;
}
/* release any frames that are now unused */
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
mpp_hevc_unref_frame(s, &s->DPB[i], 0);
}
return 0;
}
int mpp_hevc_compute_poc(HEVCContext *s, int poc_lsb)
{
RK_S32 max_poc_lsb = 1 << s->sps->log2_max_poc_lsb;
RK_S32 prev_poc_lsb = s->pocTid0 % max_poc_lsb;
RK_S32 prev_poc_msb = s->pocTid0 - prev_poc_lsb;
RK_S32 poc_msb;
if (poc_lsb < prev_poc_lsb && prev_poc_lsb - poc_lsb >= max_poc_lsb / 2)
poc_msb = prev_poc_msb + max_poc_lsb;
else if (poc_lsb > prev_poc_lsb && poc_lsb - prev_poc_lsb > max_poc_lsb / 2)
poc_msb = prev_poc_msb - max_poc_lsb;
else
poc_msb = prev_poc_msb;
// For BLA picture types, POCmsb is set to 0.
if (s->nal_unit_type == NAL_BLA_W_LP ||
s->nal_unit_type == NAL_BLA_W_RADL ||
s->nal_unit_type == NAL_BLA_N_LP)
poc_msb = 0;
return poc_msb + poc_lsb;
}
int mpp_hevc_frame_nb_refs(HEVCContext *s)
{
RK_S32 ret = 0;
RK_S32 i;
const ShortTermRPS *rps = s->sh.short_term_rps;
LongTermRPS *long_rps = &s->sh.long_term_rps;
if (s->sh.slice_type == I_SLICE) {
return 0;
}
if (rps) {
for (i = 0; (RK_U32)i < rps->num_negative_pics; i++)
ret += !!rps->used[i];
for (; i < rps->num_delta_pocs; i++)
ret += !!rps->used[i];
}
if (long_rps) {
for (i = 0; i < long_rps->nb_refs; i++)
ret += !!long_rps->used[i];
}
return ret;
}

View File

@@ -0,0 +1,203 @@
/*
*
* Copyright 2010 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.
*/
/*
* @file h265d_sei.c
* @brief
* @author csy(csy@rock-chips.com)
* @version 1.0.0
* @history
* 2015.7.15 : Create
*/
#include "h265d_parser.h"
static RK_S32 decode_nal_sei_decoded_picture_hash(HEVCContext *s)
{
RK_S32 cIdx, i;
RK_U8 hash_type;
//uint16_t picture_crc;
//RK_U32 picture_checksum;
GetBitCxt_t*gb = &s->HEVClc->gb;
READ_BITS(gb, 8, &hash_type);
for (cIdx = 0; cIdx < 3/*((s->sps->chroma_format_idc == 0) ? 1 : 3)*/; cIdx++) {
if (hash_type == 0) {
//s->is_md5 = 1;
for (i = 0; i < 16; i++)
READ_SKIPBITS(gb, 8);
} else if (hash_type == 1) {
READ_SKIPBITS(gb, 16);
} else if (hash_type == 2) {
READ_SKIPBITS(gb, 32);
}
}
return 0;
}
static RK_S32 decode_nal_sei_frame_packing_arrangement(HEVCContext *s)
{
GetBitCxt_t *gb = &s->HEVClc->gb;
RK_S32 value = 0;
READ_UE(gb, &value); // frame_packing_arrangement_id
READ_BIT1(gb, &value);
s->sei_frame_packing_present = !value;
if (s->sei_frame_packing_present) {
READ_BITS(gb, 7, &s->frame_packing_arrangement_type);
READ_BIT1(gb, &s->quincunx_subsampling);
READ_BITS(gb, 6, &s->content_interpretation_type);
// the following skips spatial_flipping_flag frame0_flipped_flag
// field_views_flag current_frame_is_frame0_flag
// frame0_self_contained_flag frame1_self_contained_flag
READ_SKIPBITS(gb, 6);
if (!s->quincunx_subsampling && s->frame_packing_arrangement_type != 5)
READ_SKIPBITS(gb, 16); // frame[01]_grid_position_[xy]
READ_SKIPBITS(gb, 8); // frame_packing_arrangement_reserved_byte
READ_SKIPBITS(gb, 1); // frame_packing_arrangement_persistance_flag
}
READ_SKIPBITS(gb, 1); // upsampled_aspect_ratio_flag
return 0;
}
static RK_S32 decode_pic_timing(HEVCContext *s)
{
GetBitCxt_t *gb = &s->HEVClc->gb;
HEVCSPS *sps;
if (!s->sps_list[s->active_seq_parameter_set_id])
return MPP_ERR_NOMEM;
sps = (HEVCSPS*)s->sps_list[s->active_seq_parameter_set_id];
s->picture_struct = MPP_PICTURE_STRUCTURE_UNKNOWN;
if (sps->vui.frame_field_info_present_flag) {
READ_BITS(gb, 4, &s->picture_struct);
switch (s->picture_struct) {
case 0 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "(progressive) frame \n"); break;
case 1 : s->picture_struct = MPP_PICTURE_STRUCTURE_TOP_FIELD; h265d_dbg(H265D_DBG_SEI, "top field\n"); break;
case 2 : s->picture_struct = MPP_PICTURE_STRUCTURE_BOTTOM_FIELD; h265d_dbg(H265D_DBG_SEI, "bottom field\n"); break;
case 3 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "top field, bottom field, in that order\n"); break;
case 4 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "bottom field, top field, in that order\n"); break;
case 5 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "top field, bottom field, top field repeated, in that order\n"); break;
case 6 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "bottom field, top field, bottom field repeated, in that order\n"); break;
case 7 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "frame doubling\n"); break;
case 8 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "frame tripling\n"); break;
case 9 : s->picture_struct = MPP_PICTURE_STRUCTURE_TOP_FIELD; h265d_dbg(H265D_DBG_SEI, "top field paired with previous bottom field in output order\n"); break;
case 10 : s->picture_struct = MPP_PICTURE_STRUCTURE_BOTTOM_FIELD; h265d_dbg(H265D_DBG_SEI, "bottom field paired with previous top field in output order\n"); break;
case 11 : s->picture_struct = MPP_PICTURE_STRUCTURE_TOP_FIELD; h265d_dbg(H265D_DBG_SEI, "top field paired with next bottom field in output order\n"); break;
case 12 : s->picture_struct = MPP_PICTURE_STRUCTURE_BOTTOM_FIELD; h265d_dbg(H265D_DBG_SEI, "bottom field paired with next top field in output order\n"); break;
}
READ_SKIPBITS(gb, 2); // source_scan_type
READ_SKIPBITS(gb, 1); // duplicate_flag
}
return 1;
}
static RK_S32 active_parameter_sets(HEVCContext *s)
{
GetBitCxt_t *gb = &s->HEVClc->gb;
RK_S32 num_sps_ids_minus1;
RK_S32 i, value;
RK_U32 active_seq_parameter_set_id;
READ_SKIPBITS(gb, 4); // active_video_parameter_set_id
READ_SKIPBITS(gb, 1); // self_contained_cvs_flag
READ_SKIPBITS(gb, 1); // num_sps_ids_minus1
READ_UE(gb, &num_sps_ids_minus1); // num_sps_ids_minus1
READ_UE(gb, &active_seq_parameter_set_id);
if (active_seq_parameter_set_id >= MAX_SPS_COUNT) {
mpp_err( "active_parameter_set_id %d invalid\n", active_seq_parameter_set_id);
return MPP_ERR_STREAM;
}
s->active_seq_parameter_set_id = active_seq_parameter_set_id;
for (i = 1; i <= num_sps_ids_minus1; i++)
READ_UE(gb, &value); // active_seq_parameter_set_id[i]
return 0;
}
static RK_S32 decode_nal_sei_message(HEVCContext *s)
{
GetBitCxt_t *gb = &s->HEVClc->gb;
int payload_type = 0;
int payload_size = 0;
int byte = 0xFF;
h265d_dbg(H265D_DBG_SEI, "Decoding SEI\n");
while (byte == 0xFF) {
READ_BITS(gb, 8, &byte);
payload_type += byte;
}
byte = 0xFF;
while (byte == 0xFF) {
READ_BITS(gb, 8, &byte);
payload_size += byte;
}
if (s->nal_unit_type == NAL_SEI_PREFIX) {
if (payload_type == 256 /*&& s->decode_checksum_sei*/) {
decode_nal_sei_decoded_picture_hash(s);
return 1;
} else if (payload_type == 45) {
decode_nal_sei_frame_packing_arrangement(s);
return 1;
} else if (payload_type == 1) {
int ret = decode_pic_timing(s);
h265d_dbg(H265D_DBG_SEI, "Skipped PREFIX SEI %d\n", payload_type);
READ_SKIPBITS(gb, 8 * payload_size);
return ret;
} else if (payload_type == 129) {
active_parameter_sets(s);
h265d_dbg(H265D_DBG_SEI, "Skipped PREFIX SEI %d\n", payload_type);
return 1;
} else {
h265d_dbg(H265D_DBG_SEI, "Skipped PREFIX SEI %d\n", payload_type);
READ_SKIPBITS(gb, 8 * payload_size);
return 1;
}
} else { /* nal_unit_type == NAL_SEI_SUFFIX */
if (payload_type == 132 /* && s->decode_checksum_sei */)
decode_nal_sei_decoded_picture_hash(s);
else {
h265d_dbg(H265D_DBG_SEI, "Skipped SUFFIX SEI %d\n", payload_type);
READ_SKIPBITS(gb, 8 * payload_size);
}
return 1;
}
}
static RK_S32 more_rbsp_data(GetBitCxt_t *gb)
{
return gb->bytes_left_ > 1 && gb->data_[0] != 0x80;
}
RK_S32 mpp_hevc_decode_nal_sei(HEVCContext *s)
{
RK_S32 ret;
do {
ret = decode_nal_sei_message(s);
if (ret < 0)
return MPP_ERR_NOMEM;
} while (more_rbsp_data(&s->HEVClc->gb));
return 1;
}

View File

@@ -0,0 +1,24 @@
# vim: syntax=cmake
# ----------------------------------------------------------------------------
# codec h265 built-in unit test case
# ----------------------------------------------------------------------------
# log system unit test
option(H265D_TEST "Build codec h265d_parser unit test" ON)
if(H265D_TEST)
add_executable(h265d_parser_test h265d_parser_test.c)
include_directories(.)
link_directories(.)
if(ANDROID)
target_link_libraries(h265d_parser_test m h265d_parser osal h265d_hal mpp_codec mpp vpu)
else()
set(OPENHEVCSO "${CMAKE_SOURCE_DIR}/mpp/codec/dec/h265/test")
add_library(openhevcwrapper SHARED IMPORTED)
set_target_properties(openhevcwrapper PROPERTIES
IMPORTED_LOCATION
"${OPENHEVCSO}/libLibOpenHevcWrapper.so")
target_link_libraries(h265d_parser_test openhevcwrapper m h265d_parser osal h265d_hal mpp_codec mpp)
endif()
endif()

View File

@@ -0,0 +1,520 @@
/*
* Copyright 2010 Rockchip Electronics S.LSI 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.
*/
/*
* @file h265d_parser_test.c
* @brief
* @author csy(csy@rock-chips.com)
* @version 1.0.0
* @history
* 2015.7.15 : Create
*/
#define MODULE_TAG "H265TEST"
#include "h265d_api.h"
#include "hal_h265d_api.h"
#include "mpp_log.h"
#include <string.h>
#include <stdlib.h>
#include "mpp_err.h"
#include "mpp_mem.h"
#include "mpp_frame.h"
#include "openHevcWrapper.h"
#include "mpp_buf_slot.h"
#include "rk_type.h"
#include "mpp_common.h"
#include "mpp_dec.h"
#include "h265d_api.h"
#include "hal_h265d_api.h"
typedef enum VPU_API_DEMO_RET {
PARSER_DEMO_OK = 0,
PARSER_DEMO_PARSE_HELP_OK = 1,
PARSER_DEMO_ERROR_BASE = -100,
ERROR_INVALID_PARAM = PARSER_DEMO_ERROR_BASE - 1,
ERROR_INVALID_STREAM = PARSER_DEMO_ERROR_BASE - 2,
ERROR_IO = PARSER_DEMO_ERROR_BASE - 3,
ERROR_MEMORY = PARSER_DEMO_ERROR_BASE - 4,
ERROR_INIT_VPU = PARSER_DEMO_ERROR_BASE - 5,
ERROR_VPU_DECODE = PARSER_DEMO_ERROR_BASE - 90,
} PARSER_API_DEMO_RET;
typedef struct ParserCmd {
RK_U8* name;
RK_U8* argname;
RK_U8* help;
} ParserCmd_t;
typedef struct parserDemoCmdContext {
RK_U32 width;
RK_U32 height;
RK_U8 input_file[200];
RK_U8 output_file[200];
RK_U8 have_input;
RK_U8 have_output;
RK_U8 disable_debug;
RK_U32 record_frames;
RK_S64 record_start_ms;
} ParserDemoCmdContext_t;
static ParserCmd_t parserCmd[] = {
{(RK_U8*)"i", (RK_U8*)"input_file", (RK_U8*)"input bitstream file"},
{(RK_U8*)"o", (RK_U8*)"output_file", (RK_U8*)"output bitstream file, "},
{(RK_U8*)"w", (RK_U8*)"width", (RK_U8*)"the width of input bitstream"},
{(RK_U8*)"h", (RK_U8*)"height", (RK_U8*)"the height of input bitstream"},
{(RK_U8*)"vframes", (RK_U8*)"number", (RK_U8*)"set the number of video frames to record"},
{(RK_U8*)"ss", (RK_U8*)"time_off", (RK_U8*)"set the start time offset, use Ms as the unit."},
{(RK_U8*)"d", (RK_U8*)"disable", (RK_U8*)"disable the debug output info."},
};
static void show_usage()
{
mpp_log("usage: parserDemo [options] input_file, \n\n");
mpp_log("Getting help:\n");
mpp_log("-help --print options of vpu api demo\n");
}
static RK_S32 show_help()
{
mpp_log("usage: parserDemo [options] input_file, \n\n");
RK_U32 i = 0;
RK_U32 n = sizeof(parserCmd) / sizeof(ParserCmd_t);
for (i = 0; i < n; i++) {
mpp_log("-%s %s\t\t%s\n",
parserCmd[i].name, parserCmd[i].argname, parserCmd[i].help);
}
return 0;
}
static RK_S32 parse_options(int argc, char **argv, ParserDemoCmdContext_t* cmdCxt)
{
const char *opt;
RK_S32 optindex, handleoptions = 1, ret = 0;
if ((argc < 2) || (cmdCxt == NULL)) {
mpp_log("parser demo, input parameter invalid\n");
show_usage();
return MPP_ERR_STREAM;
}
/* parse options */
optindex = 1;
while (optindex < argc) {
opt = (const char*)argv[optindex++];
if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
if (opt[1] == '-') {
if (opt[2] != '\0') {
opt++;
} else {
handleoptions = 0;
continue;
}
}
opt++;
switch (*opt) {
case 'i':
if (argv[optindex]) {
memcpy(cmdCxt->input_file, argv[optindex], strlen(argv[optindex]));
cmdCxt->input_file[strlen(argv[optindex])] = '\0';
cmdCxt->have_input = 1;
} else {
mpp_log("input file is invalid\n");
ret = -1;
goto PARSE_OPINIONS_OUT;
}
break;
case 'o':
if (argv[optindex]) {
memcpy(cmdCxt->output_file, argv[optindex], strlen(argv[optindex]));
cmdCxt->output_file[strlen(argv[optindex])] = '\0';
cmdCxt->have_output = 1;
break;
} else {
mpp_log("out file is invalid\n");
ret = -1;
goto PARSE_OPINIONS_OUT;
}
case 'd':
cmdCxt->disable_debug = 1;
break;
case 'w':
if (argv[optindex]) {
cmdCxt->width = atoi(argv[optindex]);
break;
} else {
mpp_log("input width is invalid\n");
ret = -1;
goto PARSE_OPINIONS_OUT;
}
case 'h':
if ((*(opt + 1) != '\0') && !strncmp(opt, "help", 4)) {
show_help();
ret = PARSER_DEMO_PARSE_HELP_OK;
goto PARSE_OPINIONS_OUT;
} else if (argv[optindex]) {
cmdCxt->height = atoi(argv[optindex]);
} else {
mpp_log("input height is invalid\n");
ret = -1;
goto PARSE_OPINIONS_OUT;
}
break;
default:
if ((*(opt + 1) != '\0') && argv[optindex]) {
if (!strncmp(opt, "vframes", 7)) {
cmdCxt->record_frames = atoi(argv[optindex]);
} else if (!strncmp(opt, "ss", 2)) {
cmdCxt->record_start_ms = atoi(argv[optindex]);
} else {
ret = -1;
goto PARSE_OPINIONS_OUT;
}
} else {
ret = -1;
goto PARSE_OPINIONS_OUT;
}
break;
}
optindex += ret;
}
}
PARSE_OPINIONS_OUT:
if (ret < 0) {
mpp_log("vpu api demo, input parameter invalid\n");
show_usage();
return MPP_ERR_STREAM;
}
return ret;
}
RK_S32 find_start_code (RK_U8 *Buf, RK_S32 zeros_in_startcode)
{
RK_S32 i;
for (i = 0; i < zeros_in_startcode; i++)
if (Buf[i] != 0)
return 0;
return Buf[i];
}
RK_S32 get_next_nal(FILE* inpf, unsigned char* Buf)
{
RK_S32 pos = 0;
RK_S32 StartCodeFound = 0;
RK_S32 info2 = 0;
RK_S32 info3 = 0;
while (!feof(inpf) && (Buf[pos++] = fgetc(inpf)) == 0);
while (pos < 3) Buf[pos++] = fgetc(inpf);
while (!StartCodeFound) {
if (feof (inpf)) {
return pos - 1;
}
Buf[pos++] = fgetc(inpf);
info3 = find_start_code(&Buf[pos - 4], 3);
if (info3 != 1)
info2 = find_start_code(&Buf[pos - 3], 2);
StartCodeFound = (info2 == 1 || info3 == 1);
}
fseek(inpf, - 4 + info2, SEEK_CUR);
return pos - 4 + info2;
}
static RK_S32 poll_task(void *hal, MppBufSlots slots, HalDecTask *dec)
{
HalTask syn;
RK_U32 i;
syn.dec = *dec;
hal_h265d_wait(hal, &syn);
mpp_err("dec->output = %d", dec->output);
mpp_buf_slot_clr_hw_dst(slots, dec->output);
for (i = 0; i < MPP_ARRAY_ELEMS(dec->refer); i++) {
RK_S32 id;
id = dec->refer[i];
if (id >= 0)
mpp_buf_slot_dec_hw_ref(slots, id);
}
return MPP_OK;
}
RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd)
{
FILE* pInFile = NULL;
RK_U8 * buf = NULL;
RK_S32 nal_len = 0;
void *mpp_codex_ctx = NULL;
void *hal = NULL;
// void *openHevcHandle = NULL;
MppBufSlots slots;
ParserCfg parser_cfg;
MppHalCfg hal_cfg;
MppBufferGroup mFrameGroup = NULL;
MppBufferGroup mStreamGroup = NULL;
MppPacket rkpkt = NULL;
MppFrame frame = NULL;
MppBuffer prestrem = NULL;
MppBuffer currentstrem = NULL;
HalDecTask *cutask = NULL;
HalDecTask *pretask = NULL;
FILE * fp = NULL;
RK_U32 wait_task = 0;
MPP_RET ret = MPP_OK;
if (fp == NULL) {
fp = fopen("data/dump.yuv", "wb");
}
if (cmd->width == 0 || cmd->height == 0) {
cmd->width = 4096;
cmd->height = 2160;
}
cutask = mpp_calloc(HalDecTask, 1);
pretask = mpp_calloc(HalDecTask, 1);
mpp_codex_ctx = mpp_calloc(void, api_h265d_parser.ctx_size);
mpp_err("api_h265d_parser.ctx_size = %d", api_h265d_parser.ctx_size);
hal = mpp_calloc(void, hal_api_h265d.ctx_size);
if (cmd->have_input) {
mpp_log("input bitstream w: %d, h: %d, path: %s\n",
cmd->width, cmd->height,
cmd->input_file);
mpp_log("fopen in \n");
pInFile = fopen((const char*)cmd->input_file, "rb");
if (pInFile == NULL) {
mpp_log("input file not exsist\n");
return ERROR_INVALID_PARAM;
}
mpp_log("fopen out \n");
} else {
mpp_log("please set input bitstream file\n");
return -1;
}
mpp_log("mallc in void * value %d \n", sizeof(void *));
buf = mpp_malloc(RK_U8, 2048000);
mpp_buf_slot_init(&slots);
mpp_buf_slot_setup(slots, 20, cmd->width * cmd->height * 2, 0);
if (NULL == slots) {
mpp_err("could not init buffer slot\n");
return MPP_ERR_UNKNOW;
}
if (mFrameGroup == NULL) {
ret = mpp_buffer_group_normal_get(&mFrameGroup, MPP_BUFFER_TYPE_ION);
if (MPP_OK != ret) {
mpp_err("h265d mpp_buffer_group_get failed\n");
return ret;
}
//mpp_buffer_group_limit_config(mFrameGroup,cmd->width*cmd->height*2,20);
}
if (mStreamGroup == NULL) {
ret = mpp_buffer_group_normal_get(&mStreamGroup, MPP_BUFFER_TYPE_ION);
if (MPP_OK != ret) {
mpp_err("h265d mpp_buffer_group_get failed\n");
return ret;
}
}
mpp_buffer_get(mStreamGroup, &currentstrem, 1024 * 1024);
mpp_buffer_get(mStreamGroup, &prestrem, 2 * 1024 * 1024);
parser_cfg.slots = slots;
hal_cfg.slots = slots;
h265d_init(mpp_codex_ctx, &parser_cfg);
hal_h265d_init(hal, &hal_cfg);
mpp_log("mallc out \n");
if (buf == NULL) {
mpp_log("malloc fail for input buf");
}
//buf[0] = 0;
while (!feof(pInFile)) {
nal_len = get_next_nal(pInFile, buf);
RK_U32 index;
RK_U8 *tmpbuf = buf;
void *pos = NULL;
mpp_err("get nal len from file %d", nal_len);
do {
mpp_packet_init(&rkpkt, tmpbuf, nal_len);
memset(cutask, 0, sizeof(HalDecTask));
memset(&cutask->refer, -1, sizeof(cutask->refer));
cutask->stmbuf = currentstrem;
h265d_prepare(mpp_codex_ctx, rkpkt, cutask);
pos = mpp_packet_get_pos(rkpkt);
if (pos < (void*)(tmpbuf + nal_len)) {
tmpbuf = pos;
nal_len = (void*)(tmpbuf + nal_len) - pos;
mpp_err("nal_len = %d", nal_len);
} else {
nal_len = 0;
}
if (cutask->valid) {
if (wait_task) {
poll_task(hal, slots, pretask);
wait_task = 0;
}
cutask->valid = 0;
h265d_parser(mpp_codex_ctx, cutask);
}
if (cutask->valid) {
HalTask syn;
syn.dec = *cutask;
mpp_buf_slot_get_hw_dst(slots, &index);
if (NULL == mpp_buf_slot_get_buffer(slots, index)) {
MppBuffer buffer = NULL;
RK_U32 size = mpp_buf_slot_get_size(slots);
mpp_err("size = %d", size);
mpp_buffer_get(mFrameGroup, &buffer, size);
if (buffer)
mpp_buf_slot_set_buffer(slots, index, buffer);
}
hal_h265d_gen_regs(hal, &syn);
hal_h265d_start(hal, &syn);
{
MppBuffer tmp = NULL;
HalDecTask *task = NULL;
tmp = currentstrem;
currentstrem = prestrem;
prestrem = tmp;
task = cutask;
cutask = pretask;
pretask = task;
}
wait_task = 1;
}
do {
ret = mpp_buf_slot_get_display(slots, &frame);
if (ret == MPP_OK) {
mpp_log("get_display for ");
}
if (frame) {
#if 1//def DUMP
RK_U32 stride_w, stride_h;
void *ptr = NULL;
stride_w = mpp_frame_get_hor_stride(frame);
stride_h = mpp_frame_get_ver_stride(frame);
MppBuffer framebuf = mpp_frame_get_buffer(frame);
ptr = mpp_buffer_get_ptr(framebuf);
fwrite(ptr, 1, stride_w * stride_h * 3 / 2, fp);
fflush(fp);
#endif
mpp_frame_deinit(&frame);
frame = NULL;
}
} while (ret == MPP_OK);
mpp_packet_deinit(&rkpkt);
} while ( nal_len );
}
if (wait_task) {
poll_task(hal, slots, pretask);
wait_task = 0;
}
h265d_flush((void*)mpp_codex_ctx);
do {
ret = mpp_buf_slot_get_display(slots, &frame);
if (ret == MPP_OK) {
mpp_log("get_display for ");
}
if (frame) {
mpp_frame_deinit(&frame);
}
} while (ret == MPP_OK);
if (mpp_codex_ctx != NULL) {
h265d_deinit(mpp_codex_ctx);
mpp_codex_ctx = NULL;
}
if (hal != NULL) {
mpp_err("hal_h265d_deinit in");
hal_h265d_deinit(hal);
}
if (slots != NULL)
mpp_buf_slot_deinit(slots);
if (mFrameGroup != NULL) {
mpp_buffer_group_put(mFrameGroup);
}
if (currentstrem)
mpp_buffer_put(currentstrem);
if (prestrem)
mpp_buffer_put(prestrem);
if (mStreamGroup != NULL) {
mpp_buffer_group_put(mStreamGroup);
}
mpp_free(buf);
mpp_free(mpp_codex_ctx);
mpp_free(hal);
return 0;
}
int main(int argc, char **argv)
{
ParserDemoCmdContext_t demoCmdCtx;
RK_S32 ret = 0;
if (argc == 1) {
show_usage();
mpp_log("vpu api demo complete directly\n");
return 0;
}
//mpp_env_set_u32("buf_slot_debug", 0x10000010, 0);
ParserDemoCmdContext_t* cmd = &demoCmdCtx;
memset((void*)cmd, 0, sizeof(ParserDemoCmdContext_t));
if ((ret = parse_options(argc, argv, cmd)) != 0) {
if (ret == PARSER_DEMO_PARSE_HELP_OK) {
return 0;
}
mpp_log("parse_options fail\n\n");
show_usage();
return 0;
}
hevc_parser_test(cmd);
return 0;
}

View File

@@ -0,0 +1,100 @@
/*
* openhevc.h wrapper to openhevc or ffmpeg
* Copyright (c) 2012-2013 Raulet, Wassim Hamidouche, Gildas Cocherel, Pierre Edouard Lepere
*
* This file is part of openhevc.
*
* openHevc is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* openhevc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with openhevc; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPEN_HEVC_WRAPPER_H
#define OPEN_HEVC_WRAPPER_H
#define NV_VERSION "1.2" ///< Current software version
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
typedef void* OpenHevc_Handle;
typedef struct OpenHevc_Rational {
int num; ///< numerator
int den; ///< denominator
} OpenHevc_Rational;
typedef struct OpenHevc_FrameInfo {
int nYPitch;
int nUPitch;
int nVPitch;
int nBitDepth;
int nWidth;
int nHeight;
int nDisplayWidth;
int nDisplayHeight;
OpenHevc_Rational sample_aspect_ratio;
OpenHevc_Rational frameRate;
int display_picture_number;
int flag; //progressive, interlaced, interlaced top field first, interlaced bottom field first.
int64_t nTimeStamp;
} OpenHevc_FrameInfo;
typedef struct OpenHevc_Frame {
void** pvY;
void** pvU;
void** pvV;
OpenHevc_FrameInfo frameInfo;
} OpenHevc_Frame;
typedef struct OpenHevc_Frame_cpy {
void* pvY;
void* pvU;
void* pvV;
OpenHevc_FrameInfo frameInfo;
} OpenHevc_Frame_cpy;
OpenHevc_Handle libOpenHevcInit(int nb_pthreads, int thread_type);
int libOpenHevcStartDecoder(OpenHevc_Handle openHevcHandle);
int libOpenHevcDecode(OpenHevc_Handle openHevcHandle, const unsigned char *buff, int nal_len, int64_t pts);
void libOpenHevcGetPictureInfo(OpenHevc_Handle openHevcHandle, OpenHevc_FrameInfo *openHevcFrameInfo);
void libOpenHevcCopyExtraData(OpenHevc_Handle openHevcHandle, unsigned char *extra_data, int extra_size_alloc);
void libOpenHevcGetPictureSize2(OpenHevc_Handle openHevcHandle, OpenHevc_FrameInfo *openHevcFrameInfo);
int libOpenHevcGetOutput(OpenHevc_Handle openHevcHandle, int got_picture, OpenHevc_Frame *openHevcFrame);
int libOpenHevcGetOutputCpy(OpenHevc_Handle openHevcHandle, int got_picture, OpenHevc_Frame_cpy *openHevcFrame);
void libOpenHevcSetCheckMD5(OpenHevc_Handle openHevcHandle, int val);
void libOpenHevcSetDebugMode(OpenHevc_Handle openHevcHandle, int val);
void libOpenHevcSetTemporalLayer_id(OpenHevc_Handle openHevcHandle, int val);
void libOpenHevcSetNoCropping(OpenHevc_Handle openHevcHandle, int val);
void libOpenHevcSetActiveDecoders(OpenHevc_Handle openHevcHandle, int val);
void libOpenHevcClose(OpenHevc_Handle openHevcHandle);
void libOpenHevcFlush(OpenHevc_Handle openHevcHandle);
const char *libOpenHevcVersion(OpenHevc_Handle openHevcHandle);
int libOpenHevcControl(OpenHevc_Handle openHevcHandle, int cmd, void* parm);
OpenHevc_Handle libHevcParserInit();
int libHevcParser(OpenHevc_Handle openHevcHandle, void* vpacket, void *vparsepacket);
void libHevcParserClose(OpenHevc_Handle openHevcHandle);
void libHevcParserflush(OpenHevc_Handle openHevcHandle);
void* libOpenHevcGetSliceInfo(OpenHevc_Handle openHevcHandle);
#ifdef __cplusplus
}
#endif
#endif // OPEN_HEVC_WRAPPER_H

View File

@@ -16,7 +16,19 @@
#ifndef __H265D_API_H__ #ifndef __H265D_API_H__
#define __H265D_API_H__ #define __H265D_API_H__
#include "parser_api.h"
extern const ParserApi api_h265d_parser;
MPP_RET h265d_prepare(void *ctx, MppPacket pkt, HalDecTask *task);
MPP_RET h265d_init(void *ctx, ParserCfg *parser_cfg);
MPP_RET h265d_parser(void *ctx, HalDecTask *task);
MPP_RET h265d_deinit(void *ctx);
MPP_RET h265d_flush(void *ctx);
MPP_RET h265d_reset(void *ctx);
MPP_RET h265d_control(void *ctx, RK_S32 cmd, void *param);
RK_S32 mpp_hevc_split_frame(void *sc,
const RK_U8 **poutbuf, RK_S32 *poutbuf_size,
const RK_U8 *buf, RK_S32 buf_size);
#endif /*__H265D_API_H__*/ #endif /*__H265D_API_H__*/

193
mpp/common/h265d_syntax.h Normal file
View File

@@ -0,0 +1,193 @@
/*
*
* Copyright 2010 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.
*/
/*
* @file h265d_syntax.h
* @brief
* @author csy(csy@rock-chips.com)
* @version 1.0.0
* @history
* 2015.7.15 : Create
*/
#ifndef __H265D_SYNTAX__
#define __H265D_SYNTAX__
typedef unsigned long DWORD;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long ULONG;
typedef unsigned short USHORT;
typedef unsigned char UCHAR;
typedef unsigned int UINT;
typedef unsigned int UINT32;
typedef signed int BOOL;
typedef signed int INT;
typedef signed char CHAR;
typedef signed short SHORT;
typedef signed long LONG;
typedef void *PVOID;
/* HEVC Picture Entry structure */
#define MAX_SLICES 600
typedef struct _DXVA_PicEntry_HEVC {
union {
struct {
UCHAR Index7Bits : 7;
UCHAR AssociatedFlag : 1;
};
UCHAR bPicEntry;
};
} DXVA_PicEntry_HEVC, *LPDXVA_PicEntry_HEVC;
/* HEVC Picture Parameter structure */
typedef struct _DXVA_PicParams_HEVC {
USHORT PicWidthInMinCbsY;
USHORT PicHeightInMinCbsY;
union {
struct {
USHORT chroma_format_idc : 2;
USHORT separate_colour_plane_flag : 1;
USHORT bit_depth_luma_minus8 : 3;
USHORT bit_depth_chroma_minus8 : 3;
USHORT log2_max_pic_order_cnt_lsb_minus4 : 4;
USHORT NoPicReorderingFlag : 1;
USHORT NoBiPredFlag : 1;
USHORT ReservedBits1 : 1;
};
USHORT wFormatAndSequenceInfoFlags;
};
DXVA_PicEntry_HEVC CurrPic;
UCHAR sps_max_dec_pic_buffering_minus1;
UCHAR log2_min_luma_coding_block_size_minus3;
UCHAR log2_diff_max_min_luma_coding_block_size;
UCHAR log2_min_transform_block_size_minus2;
UCHAR log2_diff_max_min_transform_block_size;
UCHAR max_transform_hierarchy_depth_inter;
UCHAR max_transform_hierarchy_depth_intra;
UCHAR num_short_term_ref_pic_sets;
UCHAR num_long_term_ref_pics_sps;
UCHAR num_ref_idx_l0_default_active_minus1;
UCHAR num_ref_idx_l1_default_active_minus1;
CHAR init_qp_minus26;
UCHAR ucNumDeltaPocsOfRefRpsIdx;
USHORT wNumBitsForShortTermRPSInSlice;
USHORT ReservedBits2;
union {
struct {
UINT32 scaling_list_enabled_flag : 1;
UINT32 amp_enabled_flag : 1;
UINT32 sample_adaptive_offset_enabled_flag : 1;
UINT32 pcm_enabled_flag : 1;
UINT32 pcm_sample_bit_depth_luma_minus1 : 4;
UINT32 pcm_sample_bit_depth_chroma_minus1 : 4;
UINT32 log2_min_pcm_luma_coding_block_size_minus3 : 2;
UINT32 log2_diff_max_min_pcm_luma_coding_block_size : 2;
UINT32 pcm_loop_filter_disabled_flag : 1;
UINT32 long_term_ref_pics_present_flag : 1;
UINT32 sps_temporal_mvp_enabled_flag : 1;
UINT32 strong_intra_smoothing_enabled_flag : 1;
UINT32 dependent_slice_segments_enabled_flag : 1;
UINT32 output_flag_present_flag : 1;
UINT32 num_extra_slice_header_bits : 3;
UINT32 sign_data_hiding_enabled_flag : 1;
UINT32 cabac_init_present_flag : 1;
UINT32 ReservedBits3 : 5;
};
UINT32 dwCodingParamToolFlags;
};
union {
struct {
UINT32 constrained_intra_pred_flag : 1;
UINT32 transform_skip_enabled_flag : 1;
UINT32 cu_qp_delta_enabled_flag : 1;
UINT32 pps_slice_chroma_qp_offsets_present_flag : 1;
UINT32 weighted_pred_flag : 1;
UINT32 weighted_bipred_flag : 1;
UINT32 transquant_bypass_enabled_flag : 1;
UINT32 tiles_enabled_flag : 1;
UINT32 entropy_coding_sync_enabled_flag : 1;
UINT32 uniform_spacing_flag : 1;
UINT32 loop_filter_across_tiles_enabled_flag : 1;
UINT32 pps_loop_filter_across_slices_enabled_flag : 1;
UINT32 deblocking_filter_override_enabled_flag : 1;
UINT32 pps_deblocking_filter_disabled_flag : 1;
UINT32 lists_modification_present_flag : 1;
UINT32 slice_segment_header_extension_present_flag : 1;
UINT32 IrapPicFlag : 1;
UINT32 IdrPicFlag : 1;
UINT32 IntraPicFlag : 1;
UINT32 ReservedBits4 : 13;
};
UINT32 dwCodingSettingPicturePropertyFlags;
};
CHAR pps_cb_qp_offset;
CHAR pps_cr_qp_offset;
UCHAR num_tile_columns_minus1;
UCHAR num_tile_rows_minus1;
USHORT column_width_minus1[19];
USHORT row_height_minus1[21];
UCHAR diff_cu_qp_delta_depth;
CHAR pps_beta_offset_div2;
CHAR pps_tc_offset_div2;
UCHAR log2_parallel_merge_level_minus2;
INT CurrPicOrderCntVal;
DXVA_PicEntry_HEVC RefPicList[15];
UCHAR ReservedBits5;
INT PicOrderCntValList[15];
UCHAR RefPicSetStCurrBefore[8];
UCHAR RefPicSetStCurrAfter[8];
UCHAR RefPicSetLtCurr[8];
USHORT ReservedBits6;
USHORT ReservedBits7;
UINT StatusReportFeedbackNumber;
UINT32 vps_id;
UINT32 pps_id;
UINT32 sps_id;
UCHAR scaling_list_data_present_flag;
} DXVA_PicParams_HEVC, *LPDXVA_PicParams_HEVC;
/* HEVC Quantizatiuon Matrix structure */
typedef struct _DXVA_Qmatrix_HEVC {
UCHAR ucScalingLists0[6][16];
UCHAR ucScalingLists1[6][64];
UCHAR ucScalingLists2[6][64];
UCHAR ucScalingLists3[2][64];
UCHAR ucScalingListDCCoefSizeID2[6];
UCHAR ucScalingListDCCoefSizeID3[2];
} DXVA_Qmatrix_HEVC, *LPDXVA_Qmatrix_HEVC;
/* HEVC Slice Control Structure */
typedef struct _DXVA_Slice_HEVC_Short {
UINT BSNALunitDataLocation;
UINT SliceBytesInBuffer;
USHORT wBadSliceChopping;
} DXVA_Slice_HEVC_Short, *LPDXVA_Slice_HEVC_Short;
typedef struct h265d_dxva2_picture_context {
DXVA_PicParams_HEVC pp;
DXVA_Qmatrix_HEVC qm;
UINT32 slice_count;
DXVA_Slice_HEVC_Short slice_short[MAX_SLICES];
const UCHAR *bitstream;
UINT32 bitstream_size;
} h265d_dxva2_picture_context_t;
#endif /*__H265D_SYNTAX__*/

View File

@@ -0,0 +1,47 @@
/*
*
* 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 __HAL_H265D_API_H__
#define __HAL_H265D_API_H__
#include "rk_type.h"
#include "mpp_err.h"
#include "mpp_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
extern const MppHalApi hal_api_h265d;
RK_S32 hal_h265d_init(void *hal, MppHalCfg *cfg);
RK_S32 hal_h265d_gen_regs(void *hal, HalTask *syn);
RK_S32 hal_h265d_deinit(void *hal);
MPP_RET hal_h265d_start(void *hal, HalTask *task);
MPP_RET hal_h265d_wait(void *hal, HalTask *task);
MPP_RET hal_h265d_reset(void *hal);
MPP_RET hal_h265d_flush(void *hal);
MPP_RET hal_h265d_control(void *hal, RK_S32 cmd_type, void *param);
#ifdef __cplusplus
}
#endif
#endif /*__HAL_H265D_API_H__*/

View File

@@ -71,6 +71,8 @@ typedef struct HalDecTask_t {
// current tesk protocol syntax information // current tesk protocol syntax information
MppSyntax syntax; MppSyntax syntax;
MppBuffer stmbuf;
// for test purpose // for test purpose
// current tesk output slot index // current tesk output slot index
RK_S32 output; RK_S32 output;

129
mpp/hal/inc/vpu.h Normal file
View File

@@ -0,0 +1,129 @@
/*
*
* Copyright 2010 Rockchip Electronics S.LSI 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 __VPU_H__
#define __VPU_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include "rk_type.h"
#define VPU_SUCCESS (0)
#define VPU_FAILURE (-1)
#define VPU_HW_WAIT_OK VPU_SUCCESS
#define VPU_HW_WAIT_ERROR VPU_FAILURE
#define VPU_HW_WAIT_TIMEOUT 1
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>60 <20><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С 240B
#define VPU_REG_NUM_DEC (60)
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>41 <20><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С 164B
#define VPU_REG_NUM_PP (41)
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӻ<EFBFBD><D3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>101 <20><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С 404B
#define VPU_REG_NUM_DEC_PP (VPU_REG_NUM_DEC+VPU_REG_NUM_PP)
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>96 <20><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С 384B
#define VPU_REG_NUM_ENC (96)
typedef enum
{
VPU_ENC = 0x0,
VPU_DEC = 0x1,
VPU_PP = 0x2,
VPU_DEC_PP = 0x3,
VPU_DEC_HEVC = 0x4,
VPU_TYPE_BUTT ,
} VPU_CLIENT_TYPE;
/* Hardware decoder configuration description */
typedef struct VPUHwDecConfig {
RK_U32 maxDecPicWidth; /* Maximum video decoding width supported */
RK_U32 maxPpOutPicWidth; /* Maximum output width of Post-Processor */
RK_U32 h264Support; /* HW supports h.264 */
RK_U32 jpegSupport; /* HW supports JPEG */
RK_U32 mpeg4Support; /* HW supports MPEG-4 */
RK_U32 customMpeg4Support; /* HW supports custom MPEG-4 features */
RK_U32 vc1Support; /* HW supports VC-1 Simple */
RK_U32 mpeg2Support; /* HW supports MPEG-2 */
RK_U32 ppSupport; /* HW supports post-processor */
RK_U32 ppConfig; /* HW post-processor functions bitmask */
RK_U32 sorensonSparkSupport; /* HW supports Sorenson Spark */
RK_U32 refBufSupport; /* HW supports reference picture buffering */
RK_U32 vp6Support; /* HW supports VP6 */
RK_U32 vp7Support; /* HW supports VP7 */
RK_U32 vp8Support; /* HW supports VP8 */
RK_U32 avsSupport; /* HW supports AVS */
RK_U32 jpegESupport; /* HW supports JPEG extensions */
RK_U32 rvSupport; /* HW supports REAL */
RK_U32 mvcSupport; /* HW supports H264 MVC extension */
} VPUHwDecConfig_t;
/* Hardware encoder configuration description */
typedef struct VPUHwEndConfig {
RK_U32 maxEncodedWidth; /* Maximum supported width for video encoding (not JPEG) */
RK_U32 h264Enabled; /* HW supports H.264 */
RK_U32 jpegEnabled; /* HW supports JPEG */
RK_U32 mpeg4Enabled; /* HW supports MPEG-4 */
RK_U32 vsEnabled; /* HW supports video stabilization */
RK_U32 rgbEnabled; /* HW supports RGB input */
RK_U32 reg_size; /* HW bus type in use */
RK_U32 reserv[2];
} VPUHwEncConfig_t;
typedef enum {
// common command
VPU_CMD_REGISTER ,
VPU_CMD_REGISTER_ACK_OK ,
VPU_CMD_REGISTER_ACK_FAIL ,
VPU_CMD_UNREGISTER ,
VPU_SEND_CONFIG ,
VPU_SEND_CONFIG_ACK_OK , // <20><><EFBFBD><EFBFBD><EFBFBD>óɹ<C3B3><C9B9><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>λ
VPU_SEND_CONFIG_ACK_FAIL , // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD><D8B4><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>λ
VPU_GET_HW_INFO ,
VPU_GET_HW_INFO_ACK_OK ,
VPU_GET_HW_INFO_ACK_FAIL ,
VPU_CMD_BUTT ,
} VPU_CMD_TYPE;
int VPUClientInit(VPU_CLIENT_TYPE type);
RK_S32 VPUClientRelease(int socket);
RK_S32 VPUClientSendReg(int socket, RK_U32 *regs, RK_U32 nregs);
RK_S32 VPUClientWaitResult(int socket, RK_U32 *regs, RK_U32 nregs, VPU_CMD_TYPE *cmd, RK_S32 *len);
RK_S32 VPUClientGetHwCfg(int socket, RK_U32 *cfg, RK_U32 cfg_size);
RK_S32 VPUClientGetIOMMUStatus();
RK_U32 VPUCheckSupportWidth();
void *vpu_service(void *);
#ifdef __cplusplus
}
#endif
#endif /* __VPU_H__ */

View File

@@ -1 +1,23 @@
# vim: syntax=cmake # vim: syntax=cmake
# hal h265 reg
set(HAL_H265D_HDR
hal_h265d_reg.h
cabac.h
../../../common/h265d_syntax.h
)
set(HAL_H265D_SRC
hal_h265d_reg.c
../../../mpp_bitread.c
)
set_target_properties(mpp_hal PROPERTIES FOLDER "mpp/hal")
add_library(h265d_hal STATIC
${HAL_H265D_SRC} ${HAL_H265D_HDR}
)
target_link_libraries(h265d_hal osal)
#add_subdirectory(test)

1751
mpp/hal/rkdec/h265d/cabac.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,131 @@
/*
*
* Copyright 2010 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.
*/
/*
* @file hal_h265d_reg.h
* @brief
* @author csy(csy@rock-chips.com)
* @version 1.0.0
* @history
* 2015.7.15 : Create
*/
#ifndef __HAL_H265D_REG_H__
#define __HAL_H265D_REG_H__
#include "rk_type.h"
#include "mpp_log.h"
extern RK_U32 h265h_debug;
#define H265H_DBG_FUNCTION (0x00000001)
#define H265H_DBG_RPS (0x00000002)
#define H265H_DBG_PPS (0x00000004)
#define H265H_DBG_REG (0x00000008)
#define h265h_dbg(flag, fmt, ...) _mpp_dbg(h265h_debug, flag, fmt, ## __VA_ARGS__)
typedef struct {
struct swreg_id {
RK_U32 minor_ver : 8 ;
RK_U32 major_ver : 8 ;
RK_U32 prod_num : 16 ;
} sw_id;
struct swreg_int {
RK_U32 sw_dec_e : 1 ;
RK_U32 sw_dec_clkgate_e : 1 ;
RK_U32 reserve0 : 2 ;
RK_U32 sw_dec_irq_dis : 1 ;
RK_U32 sw_dec_timeout_e : 1 ;
RK_U32 sw_buf_empty_en : 1 ;
RK_U32 reserve1 : 1 ;
RK_U32 sw_dec_irq : 1 ;
RK_U32 sw_dec_irq_raw : 1 ;
RK_U32 reserve2 : 2 ;
RK_U32 sw_dec_rdy_sta : 1 ;
RK_U32 sw_dec_bus_sta : 1 ;
RK_U32 sw_dec_error_sta : 1 ;
RK_U32 sw_dec_empty_sta : 1 ;
RK_U32 reserve3 : 3 ;
RK_U32 sw_softrst_en_p : 1 ;
RK_U32 sw_force_softreset_valid: 1 ;
RK_U32 sw_softreset_rdy : 1 ;
} sw_interrupt; ///<- zrh: do nothing in C Model
struct swreg_sysctrl {
RK_U32 sw_in_endian : 1 ;
RK_U32 sw_in_swap32_e : 1 ;
RK_U32 sw_in_swap64_e : 1 ;
RK_U32 sw_str_endian : 1 ;
RK_U32 sw_str_swap32_e : 1 ;
RK_U32 sw_str_swap64_e : 1 ;
RK_U32 sw_out_endian : 1 ;
RK_U32 sw_out_swap32_e : 1 ;
RK_U32 sw_out_cbcr_swap : 1 ;
RK_U32 reserve : 1 ;
RK_U32 sw_rlc_mode_direct_write : 1;
RK_U32 sw_rlc_mode : 1 ;
RK_U32 sw_strm_start_bit : 7 ;
} sw_sysctrl; ///<- zrh: do nothing in C Model
struct swreg_pic {
RK_U32 sw_y_hor_virstride : 9 ;
RK_U32 reserve : 3 ;
RK_U32 sw_uv_hor_virstride : 9 ;
RK_U32 sw_slice_num : 8 ;
} sw_picparameter;
RK_U32 sw_strm_rlc_base ;///<- zrh: do nothing in C Model
RK_U32 sw_stream_len ;///<- zrh: do nothing in C Model
RK_U32 sw_cabactbl_base ;///<- zrh: do nothing in C Model
RK_U32 sw_decout_base ;
RK_U32 sw_y_virstride ;
RK_U32 sw_yuv_virstride ;
RK_U32 sw_refer_base[15] ;
RK_S32 sw_refer_poc[15] ;
RK_S32 sw_cur_poc ;
RK_U32 sw_rlcwrite_base ;///<- zrh: do nothing in C Model
RK_U32 sw_pps_base ;///<- zrh: do nothing in C Model
RK_U32 sw_rps_base ;///<- zrh: do nothing in C Model
RK_U32 cabac_error_en ;///<- zrh add
RK_U32 cabac_error_status ;///<- zrh add
struct cabac_error_ctu {
RK_U32 sw_cabac_error_ctu_xoffset : 8;
RK_U32 sw_cabac_error_ctu_yoffset : 8;
RK_U32 sw_streamfifo_space2full : 7;
RK_U32 reversed0 : 9;
} cabac_error_ctu;
struct sao_ctu_position {
RK_U32 sw_saowr_xoffset : 9;
RK_U32 reversed0 : 7;
RK_U32 sw_saowr_yoffset : 10;
RK_U32 reversed1 : 6;
} sao_ctu_position;
RK_U32 sw_ref_valid ; //this is not same with hardware
RK_U32 sw_refframe_index[15];
RK_U32 performance_cycle;
RK_U32 axi_ddr_rdata;
RK_U32 axi_ddr_wdata;
RK_U32 fpgadebug_reset;
} REGS_t;
#endif

View File

@@ -0,0 +1,437 @@
/*
* DXVA2 HEVC HW acceleration.
* Copyright 2010 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.
*/
#include "h265d_parser.h"
#define MAX_SLICES 256
struct hevc_dxva2_picture_context {
DXVA_PicParams_HEVC pp;
DXVA_Qmatrix_HEVC qm;
unsigned slice_count;
DXVA_Slice_HEVC_Short slice_short[MAX_SLICES];
const uint8_t *bitstream;
unsigned bitstream_size;
};
static void fill_picture_entry(DXVA_PicEntry_HEVC *pic,
unsigned index, unsigned flag)
{
av_assert0((index & 0x7f) == index && (flag & 0x01) == flag);
pic->bPicEntry = index | (flag << 7);
}
static int get_refpic_index(const DXVA_PicParams_HEVC *pp, int surface_index)
{
int i;
for (i = 0; i < FF_ARRAY_ELEMS(pp->RefPicList); i++) {
if ((pp->RefPicList[i].bPicEntry & 0x7f) == surface_index)
return i;
}
return 0xff;
}
static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, const HEVCContext *h,
DXVA_PicParams_HEVC *pp)
{
const HEVCFrame *current_picture = h->ref;
const HEVCSPS *sps = h->ps.sps;
const HEVCPPS *pps = h->ps.pps;
int i, j;
memset(pp, 0, sizeof(*pp));
pp->PicWidthInMinCbsY = sps->min_cb_width;
pp->PicHeightInMinCbsY = sps->min_cb_height;
pp->wFormatAndSequenceInfoFlags = (sps->chroma_format_idc << 0) |
(sps->separate_colour_plane_flag << 2) |
((sps->bit_depth - 8) << 3) |
((sps->bit_depth - 8) << 6) |
((sps->log2_max_poc_lsb - 4) << 9) |
(0 << 13) |
(0 << 14) |
(0 << 15);
fill_picture_entry(&pp->CurrPic, ff_dxva2_get_surface_index(avctx, ctx, current_picture->frame), 0);
pp->sps_max_dec_pic_buffering_minus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering - 1;
pp->log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3;
pp->log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_coding_block_size;
pp->log2_min_transform_block_size_minus2 = sps->log2_min_tb_size - 2;
pp->log2_diff_max_min_transform_block_size = sps->log2_max_trafo_size - sps->log2_min_tb_size;
pp->max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter;
pp->max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra;
pp->num_short_term_ref_pic_sets = sps->nb_st_rps;
pp->num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps;
pp->num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1;
pp->num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1;
pp->init_qp_minus26 = pps->pic_init_qp_minus26;
if (h->sh.short_term_ref_pic_set_sps_flag == 0 && h->sh.short_term_rps) {
pp->ucNumDeltaPocsOfRefRpsIdx = h->sh.short_term_rps->rps_idx_num_delta_pocs;
pp->wNumBitsForShortTermRPSInSlice = h->sh.short_term_ref_pic_set_size;
}
pp->dwCodingParamToolFlags = (sps->scaling_list_enable_flag << 0) |
(sps->amp_enabled_flag << 1) |
(sps->sao_enabled << 2) |
(sps->pcm_enabled_flag << 3) |
((sps->pcm_enabled_flag ? (sps->pcm.bit_depth - 1) : 0) << 4) |
((sps->pcm_enabled_flag ? (sps->pcm.bit_depth_chroma - 1) : 0) << 8) |
((sps->pcm_enabled_flag ? (sps->pcm.log2_min_pcm_cb_size - 3) : 0) << 12) |
((sps->pcm_enabled_flag ? (sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size) : 0) << 14) |
(sps->pcm.loop_filter_disable_flag << 16) |
(sps->long_term_ref_pics_present_flag << 17) |
(sps->sps_temporal_mvp_enabled_flag << 18) |
(sps->sps_strong_intra_smoothing_enable_flag << 19) |
(pps->dependent_slice_segments_enabled_flag << 20) |
(pps->output_flag_present_flag << 21) |
(pps->num_extra_slice_header_bits << 22) |
(pps->sign_data_hiding_flag << 25) |
(pps->cabac_init_present_flag << 26) |
(0 << 27);
pp->dwCodingSettingPicturePropertyFlags = (pps->constrained_intra_pred_flag << 0) |
(pps->transform_skip_enabled_flag << 1) |
(pps->cu_qp_delta_enabled_flag << 2) |
(pps->pic_slice_level_chroma_qp_offsets_present_flag << 3) |
(pps->weighted_pred_flag << 4) |
(pps->weighted_bipred_flag << 5) |
(pps->transquant_bypass_enable_flag << 6) |
(pps->tiles_enabled_flag << 7) |
(pps->entropy_coding_sync_enabled_flag << 8) |
(pps->uniform_spacing_flag << 9) |
((pps->tiles_enabled_flag ? pps->loop_filter_across_tiles_enabled_flag : 0) << 10) |
(pps->seq_loop_filter_across_slices_enabled_flag << 11) |
(pps->deblocking_filter_override_enabled_flag << 12) |
(pps->disable_dbf << 13) |
(pps->lists_modification_present_flag << 14) |
(pps->slice_header_extension_present_flag << 15) |
(IS_IRAP(h) << 16) |
(IS_IDR(h) << 17) |
/* IntraPicFlag */
(IS_IRAP(h) << 18) |
(0 << 19);
pp->pps_cb_qp_offset = pps->cb_qp_offset;
pp->pps_cr_qp_offset = pps->cr_qp_offset;
if (pps->tiles_enabled_flag) {
pp->num_tile_columns_minus1 = pps->num_tile_columns - 1;
pp->num_tile_rows_minus1 = pps->num_tile_rows - 1;
if (!pps->uniform_spacing_flag) {
for (i = 0; i < pps->num_tile_columns; i++)
pp->column_width_minus1[i] = pps->column_width[i] - 1;
for (i = 0; i < pps->num_tile_rows; i++)
pp->row_height_minus1[i] = pps->row_height[i] - 1;
}
}
pp->diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth;
pp->pps_beta_offset_div2 = pps->beta_offset / 2;
pp->pps_tc_offset_div2 = pps->tc_offset / 2;
pp->log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2;
pp->CurrPicOrderCntVal = h->poc;
// fill RefPicList from the DPB
for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->RefPicList); i++) {
const HEVCFrame *frame = NULL;
while (!frame && j < FF_ARRAY_ELEMS(h->DPB)) {
if (&h->DPB[j] != current_picture && (h->DPB[j].flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF)))
frame = &h->DPB[j];
j++;
}
if (frame) {
fill_picture_entry(&pp->RefPicList[i], ff_dxva2_get_surface_index(avctx, ctx, frame->frame), !!(frame->flags & HEVC_FRAME_FLAG_LONG_REF));
pp->PicOrderCntValList[i] = frame->poc;
} else {
pp->RefPicList[i].bPicEntry = 0xff;
pp->PicOrderCntValList[i] = 0;
}
}
#define DO_REF_LIST(ref_idx, ref_list) { \
const RefPicList *rpl = &h->rps[ref_idx]; \
for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->ref_list); i++) { \
const HEVCFrame *frame = NULL; \
while (!frame && j < rpl->nb_refs) \
frame = rpl->ref[j++]; \
if (frame) \
pp->ref_list[i] = get_refpic_index(pp, ff_dxva2_get_surface_index(avctx, ctx, frame->frame)); \
else \
pp->ref_list[i] = 0xff; \
} \
}
// Fill short term and long term lists
DO_REF_LIST(ST_CURR_BEF, RefPicSetStCurrBefore);
DO_REF_LIST(ST_CURR_AFT, RefPicSetStCurrAfter);
DO_REF_LIST(LT_CURR, RefPicSetLtCurr);
pp->StatusReportFeedbackNumber = 1 + DXVA_CONTEXT_REPORT_ID(avctx, ctx)++;
}
static void fill_scaling_lists(AVDXVAContext *ctx, const HEVCContext *h, DXVA_Qmatrix_HEVC *qm)
{
unsigned i, j, pos;
const ScalingList *sl = h->ps.pps->scaling_list_data_present_flag ?
&h->ps.pps->scaling_list : &h->ps.sps->scaling_list;
memset(qm, 0, sizeof(*qm));
for (i = 0; i < 6; i++) {
for (j = 0; j < 16; j++) {
pos = 4 * mpp_hevc_diag_scan4x4_y[j] + mpp_hevc_diag_scan4x4_x[j];
qm->ucScalingLists0[i][j] = sl->sl[0][i][pos];
}
for (j = 0; j < 64; j++) {
pos = 8 * mpp_hevc_diag_scan8x8_y[j] + mpp_hevc_diag_scan8x8_x[j];
qm->ucScalingLists1[i][j] = sl->sl[1][i][pos];
qm->ucScalingLists2[i][j] = sl->sl[2][i][pos];
if (i < 2)
qm->ucScalingLists3[i][j] = sl->sl[3][i * 3][pos];
}
qm->ucScalingListDCCoefSizeID2[i] = sl->sl_dc[0][i];
if (i < 2)
qm->ucScalingListDCCoefSizeID3[i] = sl->sl_dc[1][i * 3];
}
}
static void fill_slice_short(DXVA_Slice_HEVC_Short *slice,
unsigned position, unsigned size)
{
memset(slice, 0, sizeof(*slice));
slice->BSNALunitDataLocation = position;
slice->SliceBytesInBuffer = size;
slice->wBadSliceChopping = 0;
}
static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
DECODER_BUFFER_DESC *bs,
DECODER_BUFFER_DESC *sc)
{
const HEVCContext *h = avctx->priv_data;
AVDXVAContext *ctx = avctx->hwaccel_context;
const HEVCFrame *current_picture = h->ref;
struct hevc_dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
DXVA_Slice_HEVC_Short *slice = NULL;
void *dxva_data_ptr;
uint8_t *dxva_data, *current, *end;
unsigned dxva_size;
void *slice_data;
unsigned slice_size;
unsigned padding;
unsigned i;
unsigned type;
/* Create an annex B bitstream buffer with only slice NAL and finalize slice */
#if CONFIG_D3D11VA
if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
D3D11VA_CONTEXT(ctx)->decoder,
type,
&dxva_size, &dxva_data_ptr)))
return -1;
}
#endif
#if CONFIG_DXVA2
if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
type = DXVA2_BitStreamDateBufferType;
if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,
type,
&dxva_data_ptr, &dxva_size)))
return -1;
}
#endif
dxva_data = dxva_data_ptr;
current = dxva_data;
end = dxva_data + dxva_size;
for (i = 0; i < ctx_pic->slice_count; i++) {
static const uint8_t start_code[] = { 0, 0, 1 };
static const unsigned start_code_size = sizeof(start_code);
unsigned position, size;
slice = &ctx_pic->slice_short[i];
position = slice->BSNALunitDataLocation;
size = slice->SliceBytesInBuffer;
if (start_code_size + size > end - current) {
av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
break;
}
slice->BSNALunitDataLocation = current - dxva_data;
slice->SliceBytesInBuffer = start_code_size + size;
memcpy(current, start_code, start_code_size);
current += start_code_size;
memcpy(current, &ctx_pic->bitstream[position], size);
current += size;
}
padding = FFMIN(128 - ((current - dxva_data) & 127), end - current);
if (slice && padding > 0) {
memset(current, 0, padding);
current += padding;
slice->SliceBytesInBuffer += padding;
}
#if CONFIG_D3D11VA
if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type)))
return -1;
#endif
#if CONFIG_DXVA2
if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type)))
return -1;
#endif
if (i < ctx_pic->slice_count)
return -1;
#if CONFIG_D3D11VA
if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
memset(dsc11, 0, sizeof(*dsc11));
dsc11->BufferType = type;
dsc11->DataSize = current - dxva_data;
dsc11->NumMBsInBuffer = 0;
type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
}
#endif
#if CONFIG_DXVA2
if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
DXVA2_DecodeBufferDesc *dsc2 = bs;
memset(dsc2, 0, sizeof(*dsc2));
dsc2->CompressedBufferType = type;
dsc2->DataSize = current - dxva_data;
dsc2->NumMBsInBuffer = 0;
type = DXVA2_SliceControlBufferType;
}
#endif
slice_data = ctx_pic->slice_short;
slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short);
av_assert0(((current - dxva_data) & 127) == 0);
return ff_dxva2_commit_buffer(avctx, ctx, sc,
type,
slice_data, slice_size, 0);
}
static int dxva2_hevc_start_frame(AVCodecContext *avctx,
av_unused const uint8_t *buffer,
av_unused RK_U32 size)
{
const HEVCContext *h = avctx->priv_data;
AVDXVAContext *ctx = avctx->hwaccel_context;
struct hevc_dxva2_picture_context *ctx_pic = h->ref->hwaccel_picture_private;
if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL ||
DXVA_CONTEXT_CFG(avctx, ctx) == NULL ||
DXVA_CONTEXT_COUNT(avctx, ctx) <= 0)
return -1;
av_assert0(ctx_pic);
/* Fill up DXVA_PicParams_HEVC */
fill_picture_parameters(avctx, ctx, h, &ctx_pic->pp);
/* Fill up DXVA_Qmatrix_HEVC */
fill_scaling_lists(ctx, h, &ctx_pic->qm);
ctx_pic->slice_count = 0;
ctx_pic->bitstream_size = 0;
ctx_pic->bitstream = NULL;
return 0;
}
static int dxva2_hevc_decode_slice(AVCodecContext *avctx,
const uint8_t *buffer,
uint32_t size)
{
const HEVCContext *h = avctx->priv_data;
const HEVCFrame *current_picture = h->ref;
struct hevc_dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
unsigned position;
if (ctx_pic->slice_count >= MAX_SLICES)
return -1;
if (!ctx_pic->bitstream)
ctx_pic->bitstream = buffer;
ctx_pic->bitstream_size += size;
position = buffer - ctx_pic->bitstream;
fill_slice_short(&ctx_pic->slice_short[ctx_pic->slice_count], position, size);
ctx_pic->slice_count++;
return 0;
}
static int dxva2_hevc_end_frame(AVCodecContext *avctx)
{
HEVCContext *h = avctx->priv_data;
struct hevc_dxva2_picture_context *ctx_pic = h->ref->hwaccel_picture_private;
int scale = ctx_pic->pp.dwCodingParamToolFlags & 1;
int ret;
if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
return -1;
ret = ff_dxva2_common_end_frame(avctx, h->ref->frame,
&ctx_pic->pp, sizeof(ctx_pic->pp),
scale ? &ctx_pic->qm : NULL, scale ? sizeof(ctx_pic->qm) : 0,
commit_bitstream_and_slice_buffer);
return ret;
}
#if CONFIG_HEVC_DXVA2_HWACCEL
AVHWAccel ff_hevc_dxva2_hwaccel = {
.name = "hevc_dxva2",
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_HEVC,
.pix_fmt = AV_PIX_FMT_DXVA2_VLD,
.start_frame = dxva2_hevc_start_frame,
.decode_slice = dxva2_hevc_decode_slice,
.end_frame = dxva2_hevc_end_frame,
.frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
};
#endif
#if CONFIG_HEVC_D3D11VA_HWACCEL
AVHWAccel ff_hevc_d3d11va_hwaccel = {
.name = "hevc_d3d11va",
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_HEVC,
.pix_fmt = AV_PIX_FMT_D3D11VA_VLD,
.start_frame = dxva2_hevc_start_frame,
.decode_slice = dxva2_hevc_decode_slice,
.end_frame = dxva2_hevc_end_frame,
.frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
};
#endif

193
mpp/mpp_bitread.c Normal file
View File

@@ -0,0 +1,193 @@
#include <stdlib.h>
#include "mpp_mem.h"
#include "mpp_bitread.h"
#include "rk_type.h"
#include <string.h>
static RK_S32 rk_UpdateCurrByte(GetBitCxt_t *pBitCtx)
{
if (pBitCtx->bytes_left_ < 1)
return MPP_ERR_STREAM;
// Emulation prevention three-byte detection.
// If a sequence of 0x000003 is found, skip (ignore) the last byte (0x03).
if (*pBitCtx->data_ == 0x03 && (pBitCtx->prev_two_bytes_ & 0xffff) == 0) {
// Detected 0x000003, skip last byte.
++pBitCtx->data_;
--pBitCtx->bytes_left_;
++pBitCtx->emulation_prevention_bytes_;
// Need another full three bytes before we can detect the sequence again.
pBitCtx->prev_two_bytes_ = 0xffff;
if (pBitCtx->bytes_left_ < 1)
return MPP_ERR_STREAM;
}
// Load a new byte and advance pointers.
pBitCtx->curr_byte_ = *pBitCtx->data_++ & 0xff;
--pBitCtx->bytes_left_;
pBitCtx->num_remaining_bits_in_curr_byte_ = 8;
pBitCtx->prev_two_bytes_ = (pBitCtx->prev_two_bytes_ << 8) | pBitCtx->curr_byte_;
return MPP_OK;
}
// Read |num_bits| (1 to 31 inclusive) from the stream and return them
// in |out|, with first bit in the stream as MSB in |out| at position
// (|num_bits| - 1).
RK_S32 mpp_ReadBits(GetBitCxt_t *pBitCtx, RK_S32 num_bits, RK_S32 *out)
{
RK_S32 bits_left = num_bits;
*out = 0;
if (num_bits > 31) {
// rk_err("%s num bit exceed 32",__function__);
return MPP_ERR_STREAM;
}
while (pBitCtx->num_remaining_bits_in_curr_byte_ < bits_left) {
// Take all that's left in current byte, shift to make space for the rest.
*out |= (pBitCtx->curr_byte_ << (bits_left - pBitCtx->num_remaining_bits_in_curr_byte_));
bits_left -= pBitCtx->num_remaining_bits_in_curr_byte_;
if (rk_UpdateCurrByte(pBitCtx)) {
return MPP_ERR_STREAM;
}
}
*out |= (pBitCtx->curr_byte_ >> (pBitCtx->num_remaining_bits_in_curr_byte_ - bits_left));
*out &= ((1 << num_bits) - 1);
pBitCtx->num_remaining_bits_in_curr_byte_ -= bits_left;
pBitCtx->UsedBits += num_bits;
return MPP_OK;
}
RK_S32 mpp_ReadLongBits(GetBitCxt_t *pBitCtx, RK_S32 num_bits, RK_U32 *out)
{
RK_S32 val = 0, val1 = 0;
if (mpp_ReadBits(pBitCtx, 16, &val)) {
return MPP_ERR_STREAM;
}
if (mpp_ReadBits(pBitCtx, (num_bits - 16), &val1)) {
return MPP_ERR_STREAM;
}
val = val << 16;
*out = (RK_U32)(val | val1);
return MPP_OK;
}
RK_S32 mpp_SkipBits(GetBitCxt_t *pBitCtx, RK_S32 num_bits)
{
RK_S32 bits_left = num_bits;
while (pBitCtx->num_remaining_bits_in_curr_byte_ < bits_left) {
// Take all that's left in current byte, shift to make space for the rest.
bits_left -= pBitCtx->num_remaining_bits_in_curr_byte_;
if (rk_UpdateCurrByte(pBitCtx)) {
return MPP_ERR_STREAM;
}
}
pBitCtx->num_remaining_bits_in_curr_byte_ -= bits_left;
pBitCtx->UsedBits += num_bits;
return MPP_OK;
}
RK_S32 mpp_ReadUE(GetBitCxt_t *pBitCtx, RK_U32 *val)
{
RK_S32 num_bits = -1;
RK_S32 bit;
RK_S32 rest;
// Count the number of contiguous zero bits.
do {
if (mpp_ReadBits(pBitCtx, 1, &bit)) {
return MPP_ERR_STREAM;
}
num_bits++;
} while (bit == 0);
if (num_bits > 31) {
return MPP_ERR_STREAM;
}
// Calculate exp-Golomb code value of size num_bits.
*val = (1 << num_bits) - 1;
if (num_bits > 0) {
if (mpp_ReadBits(pBitCtx, num_bits, &rest)) {
return MPP_ERR_STREAM;
}
*val += rest;
}
return MPP_OK;
}
RK_S32 mpp_ReadSE(GetBitCxt_t *pBitCtx, RK_S32 *val)
{
RK_U32 ue;
if (mpp_ReadUE(pBitCtx, &ue)) {
return MPP_ERR_STREAM;
}
if (ue % 2 == 0) { // odd
*val = -(RK_S32)(ue >> 1);
} else {
*val = (RK_S32)((ue >> 1) + 1);
}
return MPP_OK;
}
RK_S32 mpp_has_more_rbsp_data(GetBitCxt_t *pBitCtx)
{
// Make sure we have more bits, if we are at 0 bits in current byte
// and updating current byte fails, we don't have more data anyway.
if (pBitCtx->num_remaining_bits_in_curr_byte_ == 0 && !rk_UpdateCurrByte(pBitCtx))
return 0;
// On last byte?
if (pBitCtx->bytes_left_)
return 0;
// Last byte, look for stop bit;
// We have more RBSP data if the last non-zero bit we find is not the
// first available bit.
return (pBitCtx->curr_byte_ &
((1 << (pBitCtx->num_remaining_bits_in_curr_byte_ - 1)) - 1)) != 0;
}
void mpp_Init_Bits(GetBitCxt_t *pBitCtx, RK_U8 *data, RK_S32 size)
{
memset(pBitCtx, 0, sizeof(GetBitCxt_t));
pBitCtx->data_ = data;
pBitCtx->bytes_left_ = size;
pBitCtx->num_remaining_bits_in_curr_byte_ = 0;
// Initially set to 0xffff to accept all initial two-byte sequences.
pBitCtx->prev_two_bytes_ = 0xffff;
pBitCtx->emulation_prevention_bytes_ = 0;
// add
pBitCtx->buf = data;
pBitCtx->buf_len = size;
pBitCtx->UsedBits = 0;
}
#if 0
void mpp_Set_Bits_LogContex(GetBitCxt_t *pBitCtx, RK_LOG_CONTEX_t *p_ctx)
{
//pBitCtx->ctx = p_ctx;
}
#endif
void mpp_Reset_UseBits(GetBitCxt_t *pBitCtx)
{
pBitCtx->UsedBits = 0;
}
RK_U8 mpp_get_curdata_value(GetBitCxt_t *pBitCtx)
{
return (*pBitCtx->data_);
}

120
mpp/mpp_bitread.h Normal file
View File

@@ -0,0 +1,120 @@
#ifndef __RK_BIT_READ_H__
#define __RK_BIT_READ_H__
#include <stdio.h>
#include <assert.h>
#include "rk_type.h"
#include "mpp_log.h"
#include "mpp_common.h"
#include "mpp_err.h"
#define READ_BITS(pBitCtx, num_bits, out) \
do { \
RK_S32 _out; \
RK_S32 _ret = 0; \
_ret = mpp_ReadBits(pBitCtx, num_bits, &_out); \
if (!_ret) { *out = _out; } \
else { return MPP_ERR_STREAM; } \
} while (0)
#define READ_SKIPBITS(pBitCtx, num_bits) \
do { \
RK_S32 _ret = 0; \
_ret = mpp_SkipBits(pBitCtx, num_bits); \
if (_ret) {return MPP_ERR_STREAM; } \
} while (0)
#define READ_BIT1(pBitCtx, out) \
do { \
RK_S32 _out; \
RK_S32 _ret = 0; \
_ret = mpp_ReadBits(pBitCtx, 1, &_out); \
if (!_ret) { *out = _out; } \
else { return MPP_ERR_STREAM;} \
} while (0)
#define READ_UE(pBitCtx, out) \
do { \
RK_U32 _out; \
RK_S32 _ret = 0; \
_ret = mpp_ReadUE(pBitCtx, &_out); \
if (!_ret) { *out = _out; } \
else { return MPP_ERR_STREAM; } \
} while (0)
#define READ_SE(pBitCtx, out) \
do { \
RK_S32 _out; \
RK_S32 _ret = 0; \
_ret = mpp_ReadSE(pBitCtx, &_out); \
if (!_ret) { *out = _out; } \
else { return MPP_ERR_STREAM; } \
} while (0)
#define CHECK_RANGE(pBitCtx,val, _min, _max) \
do { \
if ((val) < (_min) || (val) > (_max)) { \
mpp_log("%d[%d,%d]", val, _min, _max); \
return MPP_ERR_STREAM; \
} \
} while (0)
#define CHECK_ERROR(pBitCtx,val) \
do { \
if (!(val)) { \
mpp_log("value false"); \
mpp_assert(0); \
return MPP_ERR_STREAM; \
} \
} while (0)
//=====================================================================
typedef struct {
// 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 preventation bytes (0x000003) we met.
RK_S64 emulation_prevention_bytes_;
// file to debug
// count PPS SPS SEI read bits
RK_S32 UsedBits;
RK_U8 *buf;
RK_S32 buf_len;
} GetBitCxt_t;
#ifdef __cplusplus
extern "C" {
#endif
RK_S32 mpp_ReadBits(GetBitCxt_t *pBitCtx, RK_S32 num_bits, RK_S32 *out);
RK_S32 mpp_ReadLongBits(GetBitCxt_t *pBitCtx, RK_S32 num_bits, RK_U32 *out);
RK_S32 mpp_SkipBits(GetBitCxt_t *pBitCtx, RK_S32 num_bits);
RK_S32 mpp_ReadUE(GetBitCxt_t *pBitCtx, RK_U32* val);
RK_S32 mpp_ReadSE(GetBitCxt_t *pBitCtx, RK_S32* val);
void mpp_Init_Bits(GetBitCxt_t *pBitCtx, RK_U8 *data, RK_S32 size);
RK_S32 mpp_has_more_rbsp_data(GetBitCxt_t * pBitCtx);
//void mpp_Set_Bits_LogContex(GetBitCxt_t *pBitCtx, RK_LOG_CONTEX_t *p_ctx);
void mpp_Reset_UseBits(GetBitCxt_t *pBitCtx);
#ifdef __cplusplus
}
#endif
#endif /* __RK_BIT_READ_H__ */