mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-14 18:38:55 +00:00
359 lines
10 KiB
C
359 lines
10 KiB
C
/*
|
|
* Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* author: <qi.xu@artinchip.com>
|
|
* Desc: h264 decoder contxet
|
|
*
|
|
*/
|
|
#ifndef _H264_DECODER_H_
|
|
#define _H264_DECODER_H_
|
|
|
|
#include "mpp_codec.h"
|
|
#include "ve_buffer.h"
|
|
#include "mpp_dec_type.h"
|
|
#include "read_bits.h"
|
|
|
|
// #define SAVE_REG
|
|
|
|
// slice_type
|
|
#define H264_SLICE_P 0 // Predicted
|
|
#define H264_SLICE_B 1 // Bi-dir predicted
|
|
#define H264_SLICE_I 2 // Intra
|
|
#define H264_SLICE_SP 3 // Switching Predicted
|
|
#define H264_SLICE_SI 4 // Switching Intra
|
|
|
|
/* picture type */
|
|
#define PICT_TOP_FIELD 1
|
|
#define PICT_BOTTOM_FIELD 2
|
|
#define PICT_FRAME 3
|
|
|
|
#define DELAYED_PIC_REF 4
|
|
|
|
#define MAX_DELAYED_PIC_COUNT 16
|
|
|
|
#define MAX_MMCO_COUNT 66
|
|
|
|
// extra frames for picture reorder
|
|
#define MAX_B_FRAMES 2
|
|
|
|
/*
|
|
planing to perform appropriate error handling base on error indicators
|
|
*/
|
|
enum h264_decoder_error{
|
|
H264_DECODER_ERROR_NONE = 0,
|
|
H264_DECODER_ERROR_SLICETYPE,
|
|
H264_DECODER_ERROR_SLICENUM,
|
|
H264_DECODER_ERROR_SPS,
|
|
H264_DECODER_ERROR_PPS,
|
|
H264_DECODER_ERROR_PICTURESTRUCTUTE,
|
|
H264_DECODER_ERROR_NOEMPTYFRAME,
|
|
H264_DECODER_ERROR_REFPICMARKING,
|
|
H264_DECODER_ERROR_DEBLOCKINGFILTER,
|
|
H264_DECODER_ERROR_HARD,
|
|
H264_DECODER_ERROR_REFLISTREORDERING,
|
|
H264_DECODER_ERROR_CHECKLASTFRAME,
|
|
};
|
|
|
|
|
|
/**
|
|
* Memory management control operation opcode.
|
|
*/
|
|
enum mmco_opcode {
|
|
MMCO_END = 0,
|
|
MMCO_SHORT2UNUSED,
|
|
MMCO_LONG2UNUSED,
|
|
MMCO_SHORT2LONG,
|
|
MMCO_SET_MAX_LONG,
|
|
MMCO_RESET,
|
|
MMCO_LONG,
|
|
};
|
|
|
|
/**
|
|
* Memory management control operation.
|
|
*/
|
|
struct mmco {
|
|
enum mmco_opcode opcode;
|
|
int short_pic_num; ///< pic_num without wrapping (pic_num & max_pic_num)
|
|
int long_arg; ///< index, pic_num, or num long refs depending on opcode
|
|
};
|
|
|
|
enum NAL_TYPE
|
|
{
|
|
NAL_TYPE_SLICE = 1,
|
|
NAL_TYPE_DPA = 2,
|
|
NAL_TYPE_DPB = 3,
|
|
NAL_TYPE_DPC = 4,
|
|
NAL_TYPE_IDR = 5,
|
|
NAL_TYPE_SEI = 6,
|
|
NAL_TYPE_SPS = 7,
|
|
NAL_TYPE_PPS = 8,
|
|
NAL_TYPE_AUD = 9,
|
|
NAL_TYPE_EOSEQ = 10,
|
|
NAL_TYPE_EOSTREAM = 11,
|
|
NAL_TYPE_FILL = 12,
|
|
};
|
|
|
|
struct pred_weight_table
|
|
{
|
|
int luma_log2_weight_denom;
|
|
int chroma_log2_weight_denom;
|
|
int wp_weight[2][32][3]; // [list][index][component], range(-128~127)
|
|
int wp_offset[2][32][3]; // [list][index][component], range(-128~127)
|
|
};
|
|
|
|
struct h264_sps_info
|
|
{
|
|
u8 mbaff;
|
|
u8 frame_mbs_only_flag;
|
|
u8 direct_8x8_inference_flag;
|
|
u8 scaling_matrix_present_flag; // u(1)
|
|
u32 level_idc;
|
|
u32 profile_idc;
|
|
u32 constraint_set_flags;
|
|
u32 chroma_format_idc; // use(v)
|
|
u8 scaling_matrix4[6][16];
|
|
u8 scaling_matrix8[2][64];
|
|
int log2_max_frm_num; // ue(v), log2_max_frm_num_minus4 + 4
|
|
int poc_type;
|
|
// poc_type == 0
|
|
int log2_max_poc_lsb; // ue(v), log2_max_pic_order_cnt_lsb_minus4 + 4
|
|
// poc_type == 1
|
|
int delta_pic_order_always_zero_flag; // u(1)
|
|
int offset_for_non_ref_pic; // se(v)
|
|
int offset_for_top_to_bottom_field; // se(v)
|
|
int num_ref_frames_in_poc_cycle; // ue(v) (0~255)
|
|
u16 offset_for_ref_frame[256];
|
|
int max_num_ref_frames; // ue(v)
|
|
int gaps_in_frame_num_value_allowed_flag;
|
|
int pic_mb_width;
|
|
int pic_mb_height;
|
|
int frame_cropping_rect_left_offset;
|
|
int frame_cropping_rect_right_offset;
|
|
int frame_cropping_rect_top_offset;
|
|
int frame_cropping_rect_bottom_offset;
|
|
};
|
|
|
|
struct h264_pps_info
|
|
{
|
|
u8 deblocking_filter_control_present_flag;
|
|
u8 transform_8x8_mode_flag;
|
|
u8 constrained_intra_pred_flag;
|
|
u8 entropy_coding_flag; // 0: cavlc; 1: cabac
|
|
u8 bottom_field_pic_order_in_frame_flag;
|
|
u8 weighted_pred_flag;
|
|
u8 weighted_bipred_flag;
|
|
u8 redundant_pic_cnt_present_flag;
|
|
u32 sps_id;
|
|
int num_ref_idx[2]; // num_ref_idx_l0/l1_active_minus1 +1
|
|
u32 pic_init_qp; // pic_init_qp_minus26 + 26
|
|
int chroma_qp_index_offset[2];
|
|
u8 scaling_matrix4[6][16];
|
|
u8 scaling_matrix8[2][64];
|
|
};
|
|
|
|
struct h264_slice_header
|
|
{
|
|
u8 field_pic_flag; // u(1)
|
|
u8 bottom_field_flag; // u(1)
|
|
u8 mbaff_frame;
|
|
u32 first_mb_in_slice; // ue(v)
|
|
u32 slice_type; // ue(v)
|
|
u32 pps_id; // ue(v)
|
|
int frame_num; // u(v)
|
|
u32 idr_pic_id; // ue(v)
|
|
|
|
// poc type == 0
|
|
int poc_lsb; // u(v)
|
|
int poc_msb;
|
|
int delta_poc_bottom; // se(v)
|
|
// poc_type == 1 && !delta_pic_order_always_zero_flag
|
|
int delta_poc[2]; // se(v)
|
|
|
|
int num_ref_idx[2];
|
|
int direct_spatial_mv_pred;
|
|
int num_ref_idx_active_override;
|
|
|
|
int list_count; // count of ref lists(I:0, P:1, B:2)
|
|
|
|
struct mmco mmco[MAX_MMCO_COUNT];
|
|
int nb_mmco;
|
|
int explicit_ref_marking; // adaptive_ref_pic_marking_mode_flag
|
|
|
|
int cur_pic_num;
|
|
int max_pic_num;
|
|
struct pred_weight_table pwt;
|
|
int cabac_init_idc;
|
|
int qp_y;
|
|
|
|
int deblocking_filter;
|
|
int slice_alpha_c0_offset_div2;
|
|
int slice_beta_offset_div2;
|
|
};
|
|
|
|
/*
|
|
picture infomation
|
|
*/
|
|
struct h264_picture {
|
|
u8 mbaff_frame; ///< 1 -> MBAFF frame 0-> not MBAFF
|
|
u8 nal_ref_idc[2];
|
|
u8 refrence; // 0: not used for refrence; PICT_FRAME: the frame used by refrence;
|
|
// PICT_TOP/PICT_BOT: one field of this frame used by refrence
|
|
// DELAYED_PIC_REF: not used by refrence, and not send to render (need renorder)
|
|
u8 key_frame;
|
|
u8 mmco_reset;
|
|
u8 picture_structure;
|
|
u8 displayed_flag; // this picture is displayed
|
|
int field_poc[2]; // h264 top/bottom POC
|
|
int poc; // h264 frame POC
|
|
int frame_num; // h264 frame_num (raw frame_num from slice header)
|
|
int pic_id; // h264 pic_num (short -> no wrap version of pic_num,
|
|
//pic_num & max_pic_num; long -> long_pic_num)
|
|
int long_ref; // 1->long term nReference 0->short term nReference
|
|
int ref_poc[2][16]; // h264 POCs of the frames used as nReference
|
|
int ref_count[2]; // number of entries in ref_nPoc
|
|
|
|
u32 buf_idx;
|
|
u32 top_field_col_addr; // phy addr for top field col buf, it is a part of col_buf in struct h264_frame_info
|
|
u32 bot_field_col_addr; // phy addr for bot field col buf
|
|
struct frame* frame; // frame ptr get from frame manager
|
|
};
|
|
|
|
/*
|
|
the refrence field/frame context.
|
|
if it is one field of picture, the variable refrence is set PICT_TOP/PICT_FIELD
|
|
*/
|
|
struct h264_ref {
|
|
int refrence; // refrence type of current field/frame
|
|
int poc; // poc of current field/frame
|
|
int pic_id;
|
|
struct h264_picture* parent; // pointer to picture in struct h264_frame_info
|
|
};
|
|
|
|
struct h264_frame_info {
|
|
int max_valid_frame_num; // total frame number in frame_manager
|
|
struct ve_buffer* col_buf; // col buf for all frames, used by ve
|
|
struct ve_buffer* dblk_y_buf; // y data buffer for deblk, used by ve
|
|
struct ve_buffer* dblk_c_buf; // c data buffer for deblk, used by ve
|
|
struct ve_buffer* intrap_buf; // intra-pred buffer, used by ve
|
|
struct ve_buffer* mb_info_buf; // mb info buffer, used by ve
|
|
struct ve_buffer* mb_col_info_buf; // mb co-located info
|
|
|
|
struct h264_picture picture[32];
|
|
struct h264_picture* long_ref[32];
|
|
struct h264_picture* short_ref[32];
|
|
struct h264_ref def_ref_list[2][32];
|
|
struct h264_ref ref_list[2][48];
|
|
struct h264_picture* delayed_output_pic;
|
|
struct h264_picture* delayed_pic[MAX_DELAYED_PIC_COUNT + 2]; // render delayed picture in decoder, for reorder
|
|
int delay_pic_num;
|
|
int last_pocs[MAX_DELAYED_PIC_COUNT];
|
|
struct h264_picture* cur_pic_ptr; // current decoding picture
|
|
};
|
|
|
|
#define SPS_MAX_NUM 32
|
|
#define PPS_MAX_NUM 256
|
|
#define RBSP_BYTES 128
|
|
struct h264_dec_ctx
|
|
{
|
|
struct mpp_decoder decoder;
|
|
unsigned long regs_base;
|
|
|
|
int active_pps_id; // the pps_buffers id
|
|
int active_sps_id; // the sps_buffers id
|
|
struct h264_pps_info* pps_buffers[PPS_MAX_NUM]; // we need malloc buffer if we get a new pps
|
|
struct h264_sps_info* sps_buffers[SPS_MAX_NUM]; // we need malloc buffer if we get a new pps
|
|
struct h264_slice_header sh;
|
|
struct h264_frame_info frame_info;
|
|
int extra_frame_num;
|
|
|
|
struct ve_buffer_allocator* ve_buf_handle;
|
|
struct packet* curr_packet;
|
|
struct frame* curr_frame;
|
|
enum mpp_pixel_format pix_format; // output pixel format
|
|
int eos;
|
|
|
|
int avcc; // nalu_size + nalu, like mov
|
|
|
|
int sc_byte_offset; // byte offset of startcode
|
|
int remove_bytes; // remove 0x03 bytes
|
|
int first_eptb_offset; // offste of first 0x03 byte in eptb
|
|
unsigned char rbsp_buffer[RBSP_BYTES]; // rbsp buffer (remove eptb)
|
|
int rbsp_len;
|
|
|
|
struct read_bit_context gb;
|
|
int nal_ref_idc;
|
|
int nal_ref_idc_pre;
|
|
int nal_unit_type;
|
|
int idr_pic_flag; // IDR nalu
|
|
|
|
int width;
|
|
int height;
|
|
int cur_slice_num;
|
|
int first_field;
|
|
int picture_structure;
|
|
int decode_mb_num; // current decode mb number
|
|
int mbs_in_pic; // total mb number in a picture
|
|
|
|
int frame_num; // for ref_mark
|
|
|
|
int avc_start; // for hw reset
|
|
|
|
// for poc, ffmpeg s->poc
|
|
int prev_poc_msb; // poc_msb of the last reference pic for POC type 0
|
|
int prev_poc_lsb; // poc_lsb of the last reference pic for POC type 0
|
|
int frame_num_offset; // for POC type 2
|
|
int prev_frame_num_offset; // for POC type 2
|
|
int prev_frame_num; // frame_num of the last pic for POC type 1/2
|
|
|
|
int min_display_poc; // last displayed poc, for reorder display picture
|
|
int poc_delta; // poc delta between two pictures
|
|
int next_output_poc; // next poc, for reorder display picture
|
|
|
|
int has_b_frames; //
|
|
int b_frames_max_num;
|
|
|
|
int long_ref_count; // number of actual long term references
|
|
int short_ref_count; // number of actual short term references
|
|
|
|
int bit_offset; // bit offset of slice data this NALU
|
|
|
|
int slice_offset; // slice offset in packet, in byte unit
|
|
|
|
FILE* fp_reg;
|
|
|
|
int error;
|
|
};
|
|
|
|
|
|
/**************** h264_refs *********************/
|
|
// init ref list
|
|
int init_ref_list(struct h264_dec_ctx *s);
|
|
|
|
// ref list reordering
|
|
int ref_pic_list_reordering(struct h264_dec_ctx *s);
|
|
|
|
int execute_ref_pic_marking(struct h264_dec_ctx *s);
|
|
|
|
void select_output_frame(struct h264_dec_ctx *s);
|
|
|
|
/*
|
|
flush all the delay picture, if decoder reset
|
|
*/
|
|
void flush_all_delay_picture(struct h264_dec_ctx *s);
|
|
|
|
/*
|
|
put all the frame in delayed list to render, used in 2 cases:
|
|
1) IDR
|
|
2) eos
|
|
*/
|
|
int render_all_delayed_frame(struct h264_dec_ctx *s);
|
|
|
|
void reference_refresh(struct h264_dec_ctx *s);
|
|
|
|
/***************** h264_hal ********************/
|
|
int decode_slice(struct h264_dec_ctx *s);
|
|
|
|
#endif
|