mirror of
https://gitee.com/Vancouver2017/luban-lite.git
synced 2025-12-29 01:06:56 +00:00
V1.0.6
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user