This commit is contained in:
刘可亮
2024-09-03 11:16:08 +08:00
parent cf270df8d6
commit 803cac77d5
2931 changed files with 614364 additions and 31222 deletions

View File

@@ -1,10 +1,12 @@
/*
* Copyright (C) 2020-2022 Artinchip Technology Co. Ltd
*
* author: <qi.xu@artinchip.com>
* Desc: h264 decoder interface
*
*/
* Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* author: <qi.xu@artinchip.com>
* Desc: h264 decoder interface
*
*/
#define LOG_TAG "h264_decoder"
#include <stdlib.h>
@@ -55,7 +57,7 @@ static int find_startcode(unsigned char* buf, int len)
* @len: [in] length of input buffer
* return: remove bytes number
*/
static int remove_eptb(unsigned char* dst, int* offset, unsigned char* src, int len )
static int remove_eptb(unsigned char* dst, int* offset, unsigned char* src, int len)
{
int si = 0;
int di = 0;
@@ -159,8 +161,7 @@ static int procese_nalu(struct h264_dec_ctx *s, unsigned char* buf, int len, int
s->idr_pic_flag = 0;
switch(s->nal_unit_type) {
case NAL_TYPE_IDR:
{
case NAL_TYPE_IDR: {
logd("idr frame");
s->idr_pic_flag = 1;
s->prev_frame_num = s->prev_frame_num_offset = 0;
@@ -174,8 +175,7 @@ static int procese_nalu(struct h264_dec_ctx *s, unsigned char* buf, int len, int
for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
s->frame_info.last_pocs[i] = INT_MIN;
}
case NAL_TYPE_SLICE:
{
case NAL_TYPE_SLICE: {
logd("decode slice");
ret = h264_decode_slice_header(s);
if (ret) {
@@ -183,7 +183,7 @@ static int procese_nalu(struct h264_dec_ctx *s, unsigned char* buf, int len, int
}
ret = decode_slice(s);
if(ret) {
if (ret) {
loge("decode_slice error, ret: %d", ret);
error_flag = 1;
ret = DEC_ERR_NOT_SUPPORT;
@@ -192,18 +192,22 @@ static int procese_nalu(struct h264_dec_ctx *s, unsigned char* buf, int len, int
*use_len = len;
break;
}
case NAL_TYPE_SPS:
{
case NAL_TYPE_SPS: {
logd("sps");
ret = h264_decode_sps(s);
if (ret) {
s->error = H264_DECODER_ERROR_SPS;
}
*use_len = read_bits_count(&s->gb) / 8 +
s->sc_byte_offset + s->remove_bytes;
break;
}
case NAL_TYPE_PPS:
{
case NAL_TYPE_PPS: {
logd("pps");
ret = h264_decode_pps(s);
if (ret) {
s->error = H264_DECODER_ERROR_PPS;
}
*use_len = read_bits_count(&s->gb) / 8 +
s->sc_byte_offset + s->remove_bytes;
break;
@@ -215,14 +219,17 @@ static int procese_nalu(struct h264_dec_ctx *s, unsigned char* buf, int len, int
return 0;
}
if(s->nal_unit_type != NAL_TYPE_IDR && s->nal_unit_type != NAL_TYPE_SLICE)
if(s->nal_unit_type != NAL_TYPE_IDR && s->nal_unit_type != NAL_TYPE_SLICE) {
return ret;
}
s->prev_poc_lsb = s->sh.poc_lsb;
s->prev_poc_msb = s->sh.poc_msb;
s->prev_frame_num = s->sh.frame_num;
s->prev_frame_num_offset = s->frame_num_offset;
s->nal_ref_idc_pre = s->nal_ref_idc;
if ((s->decode_mb_num >= s->mbs_in_pic || error_flag) && s->nal_ref_idc) {
// execute_ref_pic
execute_ref_pic_marking(s);
@@ -274,16 +281,16 @@ int __h264_decode_frame(struct mpp_decoder *ctx)
struct h264_dec_ctx *s = (struct h264_dec_ctx*)ctx;
s->slice_offset = 0;
//* 1. get a packet data
// 1. get a packet data
s->curr_packet = pm_dequeue_ready_packet(s->decoder.pm);
if(s->curr_packet == NULL) {
loge("pm_dequeue_ready_packet error, ready_packet num: %d", pm_get_ready_packet_num(s->decoder.pm));
return DEC_NO_READY_PACKET;
}
s->error = H264_DECODER_ERROR_NONE;
s->eos = s->curr_packet->flag & PACKET_FLAG_EOS;
//* 2. process extra data
// 2. process extra data
if(s->curr_packet->flag & PACKET_FLAG_EXTRA_DATA) {
s->avcc = 1;
ret = process_extradata(s, s->curr_packet->data, s->curr_packet->size);
@@ -291,18 +298,14 @@ int __h264_decode_frame(struct mpp_decoder *ctx)
return ret;
}
//* 3. process this packet
// 3. process this packet
while (s->slice_offset+4 < s->curr_packet->size) {
int use_len = 0;
unsigned char* pos = s->curr_packet->data + s->slice_offset;
ret = procese_nalu(s, s->curr_packet->data + s->slice_offset,
s->curr_packet->size - s->slice_offset, &use_len);
if(ret) {
if(ret == DEC_NO_EMPTY_FRAME)
pm_reclaim_ready_packet(s->decoder.pm, s->curr_packet);
else
pm_enqueue_empty_packet(s->decoder.pm, s->curr_packet);
return ret;
if (ret) {
break;
}
if (s->avcc)
@@ -313,14 +316,20 @@ int __h264_decode_frame(struct mpp_decoder *ctx)
logi("offset: %d 0x%x", s->slice_offset, s->slice_offset);
}
pm_enqueue_empty_packet(s->decoder.pm, s->curr_packet);
if(s->curr_packet->flag & PACKET_FLAG_EOS) {
render_all_delayed_frame(s);
}
if (s->error == H264_DECODER_ERROR_NOEMPTYFRAME) {
pm_reclaim_ready_packet(s->decoder.pm, s->curr_packet);
} else {
pm_enqueue_empty_packet(s->decoder.pm, s->curr_packet);
}
logd("__h264_decode_frame end");
return 0;
return ret;
}
int __h264_decode_destroy(struct mpp_decoder *ctx)
@@ -370,6 +379,10 @@ int __h264_decode_reset(struct mpp_decoder *ctx)
render_all_delayed_frame(s);
// refresh reference frame
reference_refresh(s);
//force reclaim all frame used by decoder avoid frame lost
fm_decoder_reclaim_all_used_frame(s->decoder.fm);
s->next_output_poc = INT_MIN;
for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
s->frame_info.last_pocs[i] = INT_MIN;

View File

@@ -1,10 +1,12 @@
/*
* Copyright (C) 2020-2022 Artinchip Technology Co. Ltd
*
* author: <qi.xu@artinchip.com>
* Desc: h264 decoder contxet
*
*/
* 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_
@@ -36,6 +38,25 @@
// 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.
*/
@@ -76,127 +97,127 @@ enum NAL_TYPE
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)
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;
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];
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)
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)
// 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 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)
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
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 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;
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
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
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
};
/*
@@ -204,31 +225,31 @@ 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
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
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
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
@@ -236,78 +257,81 @@ struct h264_frame_info {
#define RBSP_BYTES 128
struct h264_dec_ctx
{
struct mpp_decoder decoder;
unsigned long regs_base;
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;
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;
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 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;
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_unit_type;
int idr_pic_flag; // IDR nalu
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 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 frame_num; // for ref_mark
int avc_start; // for hw reset
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
// 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 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 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 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 bit_offset; // bit offset of slice data this NALU
int slice_offset; // slice offset in packet, in byte unit
int slice_offset; // slice offset in packet, in byte unit
FILE* fp_reg;
FILE* fp_reg;
int error;
};
/**************** h264_refs *********************/
//* init ref list
// init ref list
int init_ref_list(struct h264_dec_ctx *s);
//* ref list reordering
// ref list reordering
int ref_pic_list_reordering(struct h264_dec_ctx *s);
int execute_ref_pic_marking(struct h264_dec_ctx *s);

View File

@@ -1,10 +1,12 @@
/*
* Copyright (C) 2020-2022 Artinchip Technology Co. Ltd
*
* author: <qi.xu@artinchip.com>
* Desc: h264 register config
*
*/
* Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* author: <qi.xu@artinchip.com>
* Desc: h264 register config
*
*/
#include <stdlib.h>
#include <string.h>
@@ -439,8 +441,8 @@ static void config_refrence_frame_info(struct h264_dec_ctx *s)
int cur_frame_idx = s->frame_info.cur_pic_ptr->buf_idx;
memset(frame_info, 0, 32*sizeof(struct frame_info));
//* 1. find the corresponding top/bottom field,
//* then save the info to frame_info
// 1. find the corresponding top/bottom field,
// then save the info to frame_info
logd("list_count: %d, num_ref: %d", s->sh.list_count, s->sh.num_ref_idx[0]);
for(list=0; list<s->sh.list_count; list++) {
for(i=0; i<s->sh.num_ref_idx[list]; i++) {
@@ -452,7 +454,7 @@ static void config_refrence_frame_info(struct h264_dec_ctx *s)
frame_info[buf_idx].buf_idx = buf_idx;
if(pic->refrence == PICT_FRAME) {
//* current picture is used for refrence
// current picture is used for refrence
frame_info[buf_idx].field_poc[0] = pic->field_poc[0];
frame_info[buf_idx].field_poc[1] = pic->field_poc[1];
frame_info[buf_idx].frame_stucture = 1;
@@ -491,7 +493,7 @@ static void config_refrence_frame_info(struct h264_dec_ctx *s)
}
logd("valid_frame_num: %d", valid_frame_num);
//* config reference frame info register
// config reference frame info register
for(i=0; i<valid_frame_num; i++) {
j = valid_frame[i];
// top poc ( select 0 )
@@ -560,10 +562,10 @@ static void config_framebuffer_info(struct h264_dec_ctx *s)
if(s->fp_reg)
fprintf(s->fp_reg, "// config framebuffer info\n");
//* config currrent frame info
// config currrent frame info
config_frame_info(s, s->frame_info.cur_pic_ptr);
//* config reference frame info
// config reference frame info
config_refrence_frame_info(s);
}
@@ -595,7 +597,7 @@ static void config_picture_info(struct h264_dec_ctx *s)
+ s->decoder.output_x;
if ((s->pix_format == MPP_FMT_NV12) || (s->pix_format == MPP_FMT_NV21)) {
phy_addr_offset[1] = s->decoder.output_y * cur_pic->frame->mpp_frame.buf.stride[1] /2
+ s->decoder.output_x ;
+ s->decoder.output_x;
} else {
phy_addr_offset[1] = s->decoder.output_y * cur_pic->frame->mpp_frame.buf.stride[1] /2
+ s->decoder.output_x / 2;
@@ -783,11 +785,11 @@ int decode_slice(struct h264_dec_ctx *s)
goto error;
}
if(s->sh.slice_type == H264_SLICE_P){
if (s->sh.slice_type == H264_SLICE_P) {
logi("%p, %s slice, cycle: %d", s,"P", read_reg(s->regs_base + CYCLES_REG));
}else if(s->sh.slice_type == H264_SLICE_B){
} else if (s->sh.slice_type == H264_SLICE_B) {
logi("%p, %s slice, cycle: %d", s,"B", read_reg(s->regs_base + CYCLES_REG));
}else if(s->sh.slice_type == H264_SLICE_I){
} else if (s->sh.slice_type == H264_SLICE_I) {
logi("%p, %s slice, cycle: %d", s,"I", read_reg(s->regs_base + CYCLES_REG));
}
@@ -819,5 +821,6 @@ error:
cur_pic->frame->mpp_frame.flags |= FRAME_FLAG_ERROR;
ve_put_client();
s->avc_start = 1;
s->error = H264_DECODER_ERROR_HARD;
return ret;
}

View File

@@ -1,10 +1,12 @@
/*
* Copyright (C) 2020-2022 Artinchip Technology Co. Ltd
*
* author: <qi.xu@artinchip.com>
* Desc: h264 sps/pps parse
*
*/
* Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* author: <qi.xu@artinchip.com>
* Desc: h264 sps/pps parse
*
*/
#include <stdlib.h>
#include <string.h>
#include "h264_decoder.h"
@@ -392,6 +394,11 @@ int h264_decode_sps(struct h264_dec_ctx *s)
int level_idc = read_bits(&s->gb, 8);
int sps_id = read_ue_golomb(&s->gb);
if (sps_id > SPS_MAX_NUM - 1) {
loge("sps_id:%d\n",sps_id);
return -1;
}
// if currenct sps is not exist before, alloc buffer for it
if(s->sps_buffers[sps_id] == NULL) {
s->sps_buffers[sps_id] = (struct h264_sps_info*)mpp_alloc(sizeof(struct h264_sps_info));
@@ -519,6 +526,11 @@ int h264_decode_pps(struct h264_dec_ctx *s)
logd("pps_id: %d", pps_id);
logd("gb index: %d", read_bits_count(&s->gb));
if (pps_id > PPS_MAX_NUM - 1) {
loge("pps_id:%d\n",pps_id);
return -1;
}
if(s->pps_buffers[pps_id] == NULL) {
s->pps_buffers[pps_id] = (struct h264_pps_info*)mpp_alloc(sizeof(struct h264_pps_info));
if(s->pps_buffers[pps_id] == NULL) {
@@ -794,18 +806,20 @@ static void set_error_from_ref_list(struct h264_dec_ctx *s)
static void set_frame_info(struct h264_dec_ctx *s)
{
struct h264_sps_info* cur_sps = s->sps_buffers[s->active_sps_id];
struct frame* f = s->frame_info.cur_pic_ptr->frame;
int crop_unit_y = 2 - cur_sps->frame_mbs_only_flag;
struct h264_sps_info* cur_sps = s->sps_buffers[s->active_sps_id];
struct frame* f = s->frame_info.cur_pic_ptr->frame;
int sub = (cur_sps->chroma_format_idc == 1) ? 1 : 0;
int crop_unit_y = (2 - cur_sps->frame_mbs_only_flag) << sub;
int crop_unit_x = 1 << sub;
f->mpp_frame.pts = s->curr_packet->pts;
f->mpp_frame.buf.crop_en = 1;
f->mpp_frame.buf.crop.x = cur_sps->frame_cropping_rect_left_offset;
f->mpp_frame.buf.crop.y = crop_unit_y * cur_sps->frame_cropping_rect_top_offset;
f->mpp_frame.buf.crop.height = s->height - crop_unit_y * cur_sps->frame_cropping_rect_bottom_offset
- crop_unit_y * cur_sps->frame_cropping_rect_top_offset;
f->mpp_frame.buf.crop.width = s->width - cur_sps->frame_cropping_rect_left_offset
- cur_sps->frame_cropping_rect_right_offset;
f->mpp_frame.pts = s->curr_packet->pts;
f->mpp_frame.buf.crop_en = 1;
f->mpp_frame.buf.crop.x = cur_sps->frame_cropping_rect_left_offset * crop_unit_x;
f->mpp_frame.buf.crop.y = crop_unit_y * cur_sps->frame_cropping_rect_top_offset;
f->mpp_frame.buf.crop.height = s->height - crop_unit_y * cur_sps->frame_cropping_rect_bottom_offset
- crop_unit_y * cur_sps->frame_cropping_rect_top_offset;
f->mpp_frame.buf.crop.width = s->width - crop_unit_x * cur_sps->frame_cropping_rect_right_offset
- crop_unit_x * cur_sps->frame_cropping_rect_left_offset;
}
// check whether last frame is error
@@ -826,8 +840,9 @@ static int check_last_frame(struct h264_dec_ctx *s)
cur_pic->frame->mpp_frame.flags |= FRAME_FLAG_ERROR;
loge("last picture error, decoded_mb: %d, total_mbs: %d",
s->decode_mb_num, s->mbs_in_pic);
execute_ref_pic_marking(s);
if (s->nal_ref_idc_pre) {
execute_ref_pic_marking(s);
}
select_output_frame(s);
s->frame_info.cur_pic_ptr = NULL;
}
@@ -859,6 +874,8 @@ int h264_decode_slice_header(struct h264_dec_ctx *s)
if(sh->first_mb_in_slice == 0) {
s->cur_slice_num = 0;
} else if(s->cur_slice_num == 0) {
s->error = H264_DECODER_ERROR_SLICENUM;
loge("first_mb_in_slice:%d,cur_slice_num:%d\n", sh->first_mb_in_slice,s->cur_slice_num);
return -1;
}
@@ -867,15 +884,25 @@ int h264_decode_slice_header(struct h264_dec_ctx *s)
sh->slice_type = read_ue_golomb(&s->gb);
if(sh->slice_type > 9) {
loge("slice type(%d) error", sh->slice_type);
s->error = H264_DECODER_ERROR_SLICETYPE;
return -1;
}
sh->slice_type = (sh->slice_type > 4) ? sh->slice_type-5 : sh->slice_type;
sh->pps_id = read_ue_golomb(&s->gb);
if(sh->pps_id > 255 || s->pps_buffers[sh->pps_id] == NULL) {
if(sh->pps_id > 255) {
s->error = H264_DECODER_ERROR_PPS;
loge("slice header pps id(%d) error", sh->pps_id);
return -1;
}
if(s->pps_buffers[sh->pps_id] == NULL) {
s->error = H264_DECODER_ERROR_PPS;
loge("slice header pps id:%d,pps_buffers==NULL", sh->pps_id);
return -1;
}
logi("SH: slice_type: %d, pps_id: %d, bit offset: %d", sh->slice_type, sh->pps_id, read_bits_count(&s->gb));
s->active_pps_id = sh->pps_id;
@@ -939,6 +966,7 @@ int h264_decode_slice_header(struct h264_dec_ctx *s)
// last field not match
if(s->picture_structure == PICT_FRAME || s->picture_structure == last_pic_structure) {
s->first_field = 0;
s->error = H264_DECODER_ERROR_PICTURESTRUCTUTE;
loge("picture struct error");
return -1;
} else {
@@ -959,9 +987,26 @@ int h264_decode_slice_header(struct h264_dec_ctx *s)
s->picture_structure = last_pic_structure;
s->first_field = last_first_field;
//pm_reclaim_ready_packet(s->decoder.pm, s->curr_packet);
s->error = H264_DECODER_ERROR_NOEMPTYFRAME;
return DEC_NO_EMPTY_FRAME;
}
// top_field_col_addr & top_field_col_addr are fixed addr.
// s->frame_info.picture[f->mpp_frame.id].top_field_col_addr = 0;
// s->frame_info.picture[f->mpp_frame.id].bot_field_col_addr = 0;
s->frame_info.picture[f->mpp_frame.id].mbaff_frame = 0;
s->frame_info.picture[f->mpp_frame.id].nal_ref_idc[0] = 0;
s->frame_info.picture[f->mpp_frame.id].nal_ref_idc[1] = 0;
s->frame_info.picture[f->mpp_frame.id].picture_structure = 0;
s->frame_info.picture[f->mpp_frame.id].displayed_flag = 0;
s->frame_info.picture[f->mpp_frame.id].field_poc[0] = 0;
s->frame_info.picture[f->mpp_frame.id].field_poc[1] = 0;
s->frame_info.picture[f->mpp_frame.id].poc = 0;
s->frame_info.picture[f->mpp_frame.id].frame_num = 0;
s->frame_info.picture[f->mpp_frame.id].pic_id = 0;
s->frame_info.picture[f->mpp_frame.id].long_ref = 0;
s->frame_info.picture[f->mpp_frame.id].ref_count[0] = 0;
s->frame_info.picture[f->mpp_frame.id].ref_count[1] = 0;
f->mpp_frame.flags = 0;
s->frame_info.picture[f->mpp_frame.id].frame = f;
s->frame_info.picture[f->mpp_frame.id].refrence = 0;
s->frame_info.picture[f->mpp_frame.id].buf_idx = f->mpp_frame.id;
@@ -1062,7 +1107,7 @@ int h264_decode_slice_header(struct h264_dec_ctx *s)
if(s->nal_ref_idc) {
if(dec_ref_pic_marking(s) < 0) {
loge("dec_ref_pic_marking error");
return -1;
s->error = H264_DECODER_ERROR_REFPICMARKING;
}
}
@@ -1089,8 +1134,8 @@ int h264_decode_slice_header(struct h264_dec_ctx *s)
if(cur_pps->deblocking_filter_control_present_flag) {
sh->deblocking_filter = read_ue_golomb(&s->gb);
if(sh->deblocking_filter > 2) {
s->error = H264_DECODER_ERROR_DEBLOCKINGFILTER;
loge("deblocking_filter(%d) out of range", sh->deblocking_filter);
return -1;
}
if(sh->deblocking_filter != 1) {