media_module: sync 3.14 decoder code

PD#166988: sync decoder code with 3.14-dev

1)  fix multi-instace stability issue ( crash. searial no-respense)
2)  add vmh264 & h265 error handle code
3)  add  h265 dolby vision corner case process
4)  add h265 fast output process
5)  add vp9 mmu mem alloc optimization

Change-Id: I02548af673660bd088528c23da21dcd37aad801e
This commit is contained in:
Hui Zhang
2018-05-23 18:22:19 +08:00
committed by Dongjin Kim
parent 704b9a2719
commit 1fb35a30c3
8 changed files with 556 additions and 116 deletions

View File

@@ -1091,6 +1091,7 @@ static struct StorablePicture *get_new_pic(struct h264_dpb_stru *p_H264_Dpb,
s->is_output = 0;
s->pre_output = 0;
s->max_slice_id = 0;
s->data_flag &= ~(ERROR_FLAG | NODISP_FLAG | MAYBE_ERROR_FLAG);
#if (MVC_EXTENSION_ENABLE)
s->view_id = -1;
#endif

View File

@@ -9,6 +9,7 @@
#define PRINT_FLAG_VDEC_STATUS 0X0001
#define PRINT_FLAG_UCODE_EVT 0x0002
#define PRINT_FLAG_MMU_DETAIL 0x0004
#define PRINT_FLAG_ERRORFLAG_DBG 0x0008
#define PRINT_FLAG_DPB_DETAIL 0x0010
#define PRINT_FLAG_DEC_DETAIL 0x0020
#define PRINT_FLAG_VDEC_DETAIL 0x0040
@@ -17,6 +18,7 @@
#define PRINT_FLAG_DEBUG_POC 0x0200
#define RRINT_FLAG_RPM 0x0400
#define DEBUG_DISABLE_RUNREADY_RMBUF 0x0800
#define PRINT_FLAG_DUMP_BUFSPEC 0x1000
#define DISABLE_ERROR_HANDLE 0x10000
#define DEBUG_DUMP_STAT 0x80000
@@ -685,6 +687,7 @@ struct FrameStore {
#define IDR_FLAG 0x02
#define ERROR_FLAG 0x10
#define NULL_FLAG 0x20
#define MAYBE_ERROR_FLAG 0x40
#define NODISP_FLAG 0x80
unsigned char data_flag;
#endif

View File

@@ -137,8 +137,14 @@ static unsigned int max_alloc_buf_count;
static unsigned int decode_timeout_val = 100;
static unsigned int errordata_timeout_val = 50;
static unsigned int get_data_timeout_val = 2000;
#if 1
/* H264_DATA_REQUEST does not work, disable it,
decode has error for data in none continuous address
*/
static unsigned int frame_max_data_packet;
#else
static unsigned int frame_max_data_packet = 8;
#endif
static unsigned int radr;
static unsigned int rval;
static u32 endian = 0xff0;
@@ -603,6 +609,10 @@ struct vdec_h264_hw_s {
u32 max_reference_size;
u32 decode_pic_count;
int start_search_pos;
u32 reg_iqidct_control;
u32 reg_vcop_ctrl_reg;
u32 reg_rv_ai_mb_count;
u32 vld_dec_control;
struct vframe_s vframe_dummy;
unsigned char buffer_empty_flag;
@@ -742,6 +752,8 @@ struct vdec_h264_hw_s {
u32 cfg_param3;
u32 cfg_param4;
int valve_count;
u8 next_again_flag;
u32 pre_parser_wr_ptr;
struct firmware_s *fw;
struct firmware_s *fw_mmu;
#ifdef MH264_USERDATA_ENABLE
@@ -755,9 +767,12 @@ struct vdec_h264_hw_s {
#endif
};
static u32 again_threshold = 0x40;
static void dump_bufspec(struct vdec_h264_hw_s *hw,
const char *caller);
static void h264_reconfig(struct vdec_h264_hw_s *hw);
static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw);
static void h264_reset_bufmgr(struct vdec_s *vdec);
static void vh264_local_init(struct vdec_h264_hw_s *hw);
static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw);
static int vh264_stop(struct vdec_h264_hw_s *hw);
@@ -1395,6 +1410,7 @@ static void release_cur_decoding_buf(struct vdec_h264_hw_s *hw)
if (p_H264_Dpb->mVideo.dec_picture) {
release_picture(p_H264_Dpb,
p_H264_Dpb->mVideo.dec_picture);
p_H264_Dpb->mVideo.dec_picture->data_flag &= ~ERROR_FLAG;
p_H264_Dpb->mVideo.dec_picture = NULL;
if (hw->mmu_enable)
hevc_set_frame_done(hw);
@@ -1444,6 +1460,9 @@ static void buf_spec_init(struct vdec_h264_hw_s *hw)
hw->buffer_spec[i].used = -1;
hw->buffer_spec[i].canvas_pos = -1;
}
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_DUMP_BUFSPEC))
dump_bufspec(hw, __func__);
spin_unlock_irqrestore(&hw->bufspec_lock, flags);
}
@@ -1636,6 +1655,10 @@ int get_free_buf_idx(struct vdec_s *vdec)
"%s fail\n", __func__);
vmh264_dump_state(vdec);
}
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_DUMP_BUFSPEC))
dump_bufspec(hw, __func__);
return index;
}
@@ -1655,11 +1678,16 @@ int release_buf_spec_num(struct vdec_s *vdec, int buf_spec_num)
hw->buffer_spec[buf_spec_num].used = 0;
spin_unlock_irqrestore(&hw->bufspec_lock, flags);
if (hw->mmu_enable) {
cur_buf_idx = buf_spec_num&0xff;
WRITE_VREG(CURR_CANVAS_CTRL, buf_spec_num<<24);
cur_buf_idx = READ_VREG(CURR_CANVAS_CTRL);
cur_buf_idx = cur_buf_idx&0xff;
decoder_mmu_box_free_idx(hw->mmu_box, cur_buf_idx);
}
release_aux_data(hw, buf_spec_num);
}
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_DUMP_BUFSPEC))
dump_bufspec(hw, __func__);
return 0;
}
@@ -1726,9 +1754,11 @@ static void dealloc_buf_specs(struct vdec_h264_hw_s *hw,
{
int i;
unsigned long flags;
unsigned char dealloc_flag = 0;
for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
if (hw->buffer_spec[i].used == 4 ||
release_all) {
dealloc_flag = 1;
dpb_print(DECODE_ID(hw),
PRINT_FLAG_DPB_DETAIL,
"%s buf_spec_num %d\n",
@@ -1769,6 +1799,10 @@ static void dealloc_buf_specs(struct vdec_h264_hw_s *hw,
}
}
}
if (dealloc_flag &&
dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_DUMP_BUFSPEC))
dump_bufspec(hw, __func__);
return;
}
@@ -1909,15 +1943,22 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
&& (!(frame->data_flag & I_FLAG)))
frame->data_flag |= ERROR_FLAG;
}
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG,
"%s, buffer_index 0x%x frame_error %x poc %d hw error %x error_proc_policy %x\n",
__func__, buffer_index, frame->data_flag & ERROR_FLAG,
frame->poc, hw->data_flag & ERROR_FLAG,
error_proc_policy);
if ((frame->data_flag & NODISP_FLAG) ||
(frame->data_flag & NULL_FLAG) ||
(frame->data_flag & ERROR_FLAG) ||
((!hw->send_error_frame_flag) &&
(frame->data_flag & ERROR_FLAG)) ||
((hw->i_only & 0x1) &&
(!(frame->data_flag & I_FLAG)))
) {
set_frame_output_flag(&hw->dpb, frame->index);
return -1;
return 0; /*do not return -1,
otherwise flush_dpb() will not flush all dbp frames*/
}
display_frame_count[DECODE_ID(hw)]++;
@@ -2058,6 +2099,9 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
}
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_DUMP_BUFSPEC))
dump_bufspec(hw, __func__);
return 0;
}
@@ -2137,7 +2181,7 @@ static void set_aux_data(struct vdec_h264_hw_s *hw,
unsigned aux_count = 0;
int aux_size = 0;
struct vdec_h264_hw_s *hw_buf = hw_b ? hw_b : hw;
if (pic->buf_spec_num < 0 || pic->buf_spec_num >= BUFSPEC_POOL_SIZE
if (pic == NULL || pic->buf_spec_num < 0 || pic->buf_spec_num >= BUFSPEC_POOL_SIZE
|| (!is_buf_spec_in_use(hw, pic->buf_spec_num)))
return;
@@ -2504,10 +2548,15 @@ int config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic)
#ifdef ERROR_CHECK
if (ref == NULL) {
hw->data_flag |= ERROR_FLAG;
pic->data_flag |= ERROR_FLAG;
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref list0 NULL\n");
return -1;
}
if (ref->data_flag & ERROR_FLAG)
if (ref->data_flag & ERROR_FLAG) {
hw->data_flag |= ERROR_FLAG;
pic->data_flag |= ERROR_FLAG;
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref error mark1 \n");
}
if (ref->data_flag & NULL_FLAG)
hw->data_flag |= NULL_FLAG;
#endif
@@ -2567,10 +2616,15 @@ int config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic)
#ifdef ERROR_CHECK
if (ref == NULL) {
hw->data_flag |= ERROR_FLAG;
pic->data_flag |= ERROR_FLAG;
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref error list1 NULL\n");
return -2;
}
if (ref->data_flag & ERROR_FLAG)
if (ref->data_flag & ERROR_FLAG) {
pic->data_flag |= ERROR_FLAG;
hw->data_flag |= ERROR_FLAG;
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref error mark2\n");
}
if (ref->data_flag & NULL_FLAG)
hw->data_flag |= NULL_FLAG;
#endif
@@ -2704,10 +2758,15 @@ int config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic)
#ifdef ERROR_CHECK
if (colocate_pic == NULL) {
hw->data_flag |= ERROR_FLAG;
pic->data_flag |= ERROR_FLAG;
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " colocate error pic NULL\n");
return -5;
}
if (colocate_pic->data_flag & ERROR_FLAG)
if (colocate_pic->data_flag & ERROR_FLAG) {
pic->data_flag |= ERROR_FLAG;
hw->data_flag |= ERROR_FLAG;
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " colocare ref error mark\n");
}
if (colocate_pic->data_flag & NULL_FLAG)
hw->data_flag |= NULL_FLAG;
#endif
@@ -2970,14 +3029,21 @@ static struct vframe_s *vh264_vf_get(void *op_arg)
1000*(time - hw->last_frame_time)/HZ;
struct vframe_s *next_vf;
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_VDEC_STATUS)) {
PRINT_FLAG_VDEC_DETAIL)) {
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
int frame_index = FRAME_INDEX(vf->index);
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s buf_spec_num %d vf %p poc %d dur %d pts %d interval %dms\n",
__func__, BUFSPEC_INDEX(vf->index), vf,
p_H264_Dpb->mFrameStore[frame_index].poc,
vf->duration, vf->pts, frame_interval);
if (frame_index < 0 ||
frame_index >= DPB_SIZE_MAX) {
dpb_print(DECODE_ID(hw), 0,
"%s vf index 0x%x error\r\n",
__func__, vf->index);
} else {
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL,
"%s buf_spec_num %d vf %p poc %d dur %d pts %d interval %dms\n",
__func__, BUFSPEC_INDEX(vf->index), vf,
p_H264_Dpb->mFrameStore[frame_index].poc,
vf->duration, vf->pts, frame_interval);
}
}
if (hw->last_frame_time > 0) {
if (frame_interval >
@@ -3053,6 +3119,10 @@ static void vh264_vf_put(struct vframe_s *vf, void *op_arg)
hw->buffer_spec[buf_spec_num].used = 0;
}
spin_unlock_irqrestore(&hw->bufspec_lock, flags);
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_DUMP_BUFSPEC))
dump_bufspec(hw, __func__);
}
hw->vf_put_count++;
@@ -3434,6 +3504,9 @@ static int vh264_set_params(struct vdec_h264_hw_s *hw,
hevc_mcr_config_canv2axitbl(hw, 0);
}
mutex_unlock(&vmh264_mutex);
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_DUMP_BUFSPEC))
dump_bufspec(hw, __func__);
#ifdef ONE_COLOCATE_BUF_PER_DECODE_BUF
buf_size = PAGE_ALIGN(
@@ -3773,6 +3846,9 @@ static bool is_buffer_available(struct vdec_s *vdec)
bufmgr_recover(hw);
else
bufmgr_h264_remove_unused_frame(p_H264_Dpb, 1);
if (hw->reset_bufmgr_flag == 1)
buffer_available = 1;
}
return buffer_available;
@@ -3781,23 +3857,31 @@ static bool is_buffer_available(struct vdec_s *vdec)
static void check_decoded_pic_error(struct vdec_h264_hw_s *hw)
{
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
struct StorablePicture *p = p_H264_Dpb->mVideo.dec_picture;
unsigned mby_mbx = READ_VREG(MBY_MBX);
unsigned mb_total = (hw->seq_info2 >> 8) & 0xffff;
unsigned decode_mb_count =
(((mby_mbx & 0xff) + 1) *
(((mby_mbx >> 8) & 0xff) + 1));
if (mby_mbx == 0)
return;
if (get_cur_slice_picture_struct(p_H264_Dpb) != FRAME)
mb_total /= 2;
if ((error_proc_policy & 0x100) &&
decode_mb_count != mb_total)
hw->data_flag |= ERROR_FLAG;
if (error_proc_policy & 0x100) {
if (decode_mb_count != mb_total)
p->data_flag |= ERROR_FLAG;
else if (p->data_flag & MAYBE_ERROR_FLAG)
p->data_flag &= ~ERROR_FLAG;
p->data_flag &= ~MAYBE_ERROR_FLAG;
}
if ((error_proc_policy & 0x200) &&
READ_VREG(ERROR_STATUS_REG) != 0)
hw->data_flag |= ERROR_FLAG;
READ_VREG(ERROR_STATUS_REG) != 0) {
p->data_flag |= ERROR_FLAG;
}
if (hw->data_flag & ERROR_FLAG) {
dpb_print(DECODE_ID(hw), 0,
if (p->data_flag & ERROR_FLAG) {
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG,
"%s: decode error, seq_info2 0x%x, mby_mbx 0x%x, mb_total %d decoded mb_count %d ERROR_STATUS_REG 0x%x\n",
__func__,
hw->seq_info2,
@@ -3835,6 +3919,10 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
unsigned short *p = (unsigned short *)hw->lmem_addr;
reset_process_time(hw);
hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL);
hw->reg_vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG);
hw->reg_rv_ai_mb_count = READ_VREG(RV_AI_MB_COUNT);
hw->vld_dec_control = READ_VREG(VLD_DECODE_CONTROL);
if (input_frame_based(vdec) &&
frmbase_cont_bitlevel2 != 0 &&
READ_VREG(VIFF_BIT_CNT) <
@@ -3983,7 +4071,10 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
}
if (slice_header_process_status == 1) {
/* for baseline , set fast_output mode */
if (p_H264_Dpb->mSPS.profile_idc == BASELINE)
if ((p_H264_Dpb->mSPS.profile_idc == BASELINE)
|| ((((unsigned long)
hw->vh264_amstream_dec_info.param) & 0x8)
&& (!hw->i_only)))
p_H264_Dpb->fast_output_enable = 4;
else
p_H264_Dpb->fast_output_enable
@@ -3994,7 +4085,9 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
== I_Slice)
? I_FLAG : 0;
if ((hw->i_only & 0x2) &&
(!(hw->data_flag & I_FLAG))) {
(!(hw->data_flag & I_FLAG)) &&
(p_H264_Dpb->mSlice.structure
== FRAME)) {
hw->data_flag = NULL_FLAG;
goto pic_done_proc;
}
@@ -4007,7 +4100,32 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
"==================> frame count %d to skip %d\n",
hw->decode_pic_count+1,
hw->skip_frame_count);
}
} else {
struct StorablePicture *p =
p_H264_Dpb->mVideo.dec_picture;
unsigned mby_mbx = READ_VREG(MBY_MBX);
unsigned decode_mb_count =
(((mby_mbx & 0xff) + 1) *
(((mby_mbx >> 8) & 0xff) + 1));
if ((error_proc_policy & 0x100) &&
p_H264_Dpb->dpb_param.l.
data[FIRST_MB_IN_SLICE]
< decode_mb_count) {
dpb_print(DECODE_ID(hw),
PRINT_FLAG_VDEC_STATUS,
"Error detect! first_mb 0x%x mby_mbx 0x%x decode_mb 0x%x\n",
p_H264_Dpb->dpb_param.l.
data[FIRST_MB_IN_SLICE],
READ_VREG(MBY_MBX),
decode_mb_count);
if (!p_H264_Dpb->dpb_param.l.
data[FIRST_MB_IN_SLICE]) {
p->data_flag |= ERROR_FLAG;
goto pic_done_proc;
} else
p->data_flag |= MAYBE_ERROR_FLAG;
}
}
if (error_proc_policy & 0x400) {
int ret = dpb_check_ref_list_error(p_H264_Dpb);
if (ret != 0) {
@@ -4017,10 +4135,17 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
hw->decode_pic_count+1,
hw->skip_frame_count);
hw->data_flag |= ERROR_FLAG;
p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG;
if ((error_proc_policy & 0x80)
&& ((hw->dec_flag &
NODISP_FLAG) == 0))
NODISP_FLAG) == 0)) {
hw->reset_bufmgr_flag = 1;
amvdec_stop();
hw->dec_result
= DEC_RESULT_DONE;
vdec_schedule_work(&hw->work);
return IRQ_HANDLED;
}
}
}
if ((error_proc_policy & 0x800)
@@ -4029,9 +4154,15 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
"dpb error %d\n",
p_H264_Dpb->dpb_error_flag);
hw->data_flag |= ERROR_FLAG;
if ((error_proc_policy & 0x80)
&& ((hw->dec_flag & NODISP_FLAG) == 0))
p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG;
if ((error_proc_policy & 0x80) &&
((hw->dec_flag & NODISP_FLAG) == 0)) {
hw->reset_bufmgr_flag = 1;
amvdec_stop();
hw->dec_result = DEC_RESULT_DONE;
vdec_schedule_work(&hw->work);
return IRQ_HANDLED;
}
}
cfg_ret = config_decode_buf(hw,
@@ -4048,6 +4179,7 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
return IRQ_HANDLED;
} else
hw->data_flag |= ERROR_FLAG;
p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG;
}
}
@@ -4133,7 +4265,11 @@ pic_done_proc:
#endif
ret = store_picture_in_dpb(p_H264_Dpb,
p_H264_Dpb->mVideo.dec_picture,
hw->data_flag | hw->dec_flag);
hw->data_flag | hw->dec_flag |
p_H264_Dpb->mVideo.dec_picture->data_flag);
if (ret == -1) {
release_cur_decoding_buf(hw);
bufmgr_force_recover(p_H264_Dpb);
@@ -4200,7 +4336,7 @@ pic_done_proc:
"H264_FIND_NEXT_PIC_NAL" : "H264_FIND_NEXT_DVEL_NAL",
hw->decode_pic_count);
/* WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD); */
hw->dec_result = DEC_RESULT_DONE;
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
if (vdec->slave &&
dec_dpb_status == H264_FIND_NEXT_DVEL_NAL) {
@@ -4434,7 +4570,7 @@ send_again:
else
WRITE_VREG(DEBUG_REG1, 0);
} else if (debug_tag != 0) {
dpb_print(DECODE_ID(hw), 0,
dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT,
"dbg%x: %x\n", debug_tag,
READ_VREG(DEBUG_REG2));
if (((udebug_pause_pos & 0xffff)
@@ -4513,12 +4649,38 @@ static void timeout_process(struct vdec_h264_hw_s *hw)
vdec_schedule_work(&hw->work);
}
static void dump_bufspec(struct vdec_h264_hw_s *hw,
const char *caller)
{
int i;
dpb_print(DECODE_ID(hw), 0,
"%s in %s:\n", __func__, caller);
for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
if (hw->buffer_spec[i].used == -1)
continue;
dpb_print(DECODE_ID(hw), 0,
"bufspec (%d): used %d adr 0x%x canvas(%d) vf_ref(%d) ",
i, hw->buffer_spec[i].used,
hw->buffer_spec[i].buf_adr,
hw->buffer_spec[i].canvas_pos,
hw->buffer_spec[i].vf_ref
);
#ifdef CONFIG_AM_VDEC_DV
dpb_print_cont(DECODE_ID(hw), 0,
"dv_el_exist %d",
hw->buffer_spec[i].dv_enhance_exist
);
#endif
dpb_print_cont(DECODE_ID(hw), 0, "\n");
}
}
static void vmh264_dump_state(struct vdec_s *vdec)
{
struct vdec_h264_hw_s *hw =
(struct vdec_h264_hw_s *)(vdec->private);
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
int i;
dpb_print(DECODE_ID(hw), 0,
"====== %s\n", __func__);
dpb_print(DECODE_ID(hw), 0,
@@ -4573,24 +4735,7 @@ static void vmh264_dump_state(struct vdec_s *vdec)
dump_dpb(&p_H264_Dpb->mDPB, 1);
dump_pic(p_H264_Dpb);
for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
if (hw->buffer_spec[i].used == -1)
continue;
dpb_print(DECODE_ID(hw), 0,
"bufspec (%d): used %d adr 0x%x canvas(%d) vf_ref(%d) ",
i, hw->buffer_spec[i].used,
hw->buffer_spec[i].buf_adr,
hw->buffer_spec[i].canvas_pos,
hw->buffer_spec[i].vf_ref
);
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
dpb_print_cont(DECODE_ID(hw), 0,
"dv_el_exist %d",
hw->buffer_spec[i].dv_enhance_exist
);
#endif
dpb_print_cont(DECODE_ID(hw), 0, "\n");
}
dump_bufspec(hw, __func__);
dpb_print(DECODE_ID(hw), 0,
"DPB_STATUS_REG=0x%x\n",
@@ -4702,7 +4847,7 @@ static void check_timer_func(unsigned long arg)
}
if ((input_frame_based(vdec) ||
(READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0x100)) &&
(READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0xb0)) &&
((h264_debug_flag & DISABLE_ERROR_HANDLE) == 0) &&
(timeout_val > 0) &&
(hw->start_process_time > 0) &&
@@ -4895,6 +5040,13 @@ static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw)
WRITE_VREG(DEBUG_REG1, 0);
WRITE_VREG(DEBUG_REG2, 0);
if (hw->reg_iqidct_control)
WRITE_VREG(IQIDCT_CONTROL, hw->reg_iqidct_control);
if (hw->reg_vcop_ctrl_reg)
WRITE_VREG(VCOP_CTRL_REG, hw->reg_vcop_ctrl_reg);
if (hw->vld_dec_control)
WRITE_VREG(VLD_DECODE_CONTROL, hw->vld_dec_control);
return 0;
}
@@ -4927,7 +5079,10 @@ static void vh264_local_init(struct vdec_h264_hw_s *hw)
hw->dec_flag = 0;
hw->data_flag = 0;
hw->skip_frame_count = 0;
hw->reg_iqidct_control = 0;
hw->reg_vcop_ctrl_reg = 0;
hw->reg_rv_ai_mb_count = 0;
hw->vld_dec_control = 0;
hw->decode_timeout_count = 0;
hw->vh264_ratio = hw->vh264_amstream_dec_info.ratio;
@@ -5228,6 +5383,11 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw)
static int vh264_stop(struct vdec_h264_hw_s *hw)
{
if (hw->stat & STAT_VDEC_RUN) {
amvdec_stop();
hw->stat &= ~STAT_VDEC_RUN;
}
cancel_work_sync(&hw->work);
cancel_work_sync(&hw->notify_work);
cancel_work_sync(&hw->user_data_work);
@@ -6140,7 +6300,7 @@ result_done:
vdec_schedule_work(&hw->work);
return;
}
hw->next_again_flag = 1;
} else if (hw->dec_result == DEC_RESULT_EOS) {
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
@@ -6160,6 +6320,7 @@ result_done:
if (hw->mmu_enable)
amhevc_stop();
if (hw->stat & STAT_ISR_REG) {
WRITE_VREG(ASSIST_MBOX1_MASK, 0);
vdec_free_irq(VDEC_IRQ_1, (void *)hw);
hw->stat &= ~STAT_ISR_REG;
}
@@ -6226,6 +6387,15 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
else
return 0;
}
if (hw->next_again_flag &&
(!vdec_frame_based(vdec))) {
u32 parser_wr_ptr =
READ_PARSER_REG(PARSER_VIDEO_WP);
if (parser_wr_ptr >= hw->pre_parser_wr_ptr &&
(parser_wr_ptr - hw->pre_parser_wr_ptr) <
again_threshold)
return 0;
}
if (h264_debug_flag & 0x20000000) {
/* pr_info("%s, a\n", __func__); */
@@ -6273,10 +6443,14 @@ static void run(struct vdec_s *vdec, unsigned long mask,
kfifo_len(&hw->display_q));
}
hw->pre_parser_wr_ptr =
READ_PARSER_REG(PARSER_VIDEO_WP);
hw->next_again_flag = 0;
if (hw->reset_bufmgr_flag ||
((error_proc_policy & 0x40) &&
p_H264_Dpb->buf_alloc_fail)) {
h264_reset_bufmgr(hw);
h264_reset_bufmgr(vdec);
hw->reset_bufmgr_flag = 0;
}
@@ -6368,8 +6542,7 @@ static void run(struct vdec_s *vdec, unsigned long mask,
if (tee_load_video_fw(VIDEO_DEC_H264_MULTI, 0) != 0) {
amvdec_enable_flag = false;
amvdec_disable();
pr_err("id: %d, %s: Error amvdec_vdec_loadmc fail\n",
DECODE_ID(hw), __func__);
dpb_print(DECODE_ID(hw), 0, "%s: Error amvdec_vdec_loadmc fail\n", __func__);
return;
}
if (hw->mmu_enable) {
@@ -6377,7 +6550,7 @@ static void run(struct vdec_s *vdec, unsigned long mask,
OPTEE_VDEC_HEVC) < 0) {
amvdec_enable_flag = false;
amhevc_disable();
pr_debug("tee mmu fw load fail\n");
dpb_print(DECODE_ID(hw), 0, "tee mmu fw load fail\n");
return;
}
}
@@ -6386,8 +6559,7 @@ static void run(struct vdec_s *vdec, unsigned long mask,
if (amvdec_vdec_loadmc_ex(vdec, NULL, hw->fw->data) < 0) {
amvdec_enable_flag = false;
amvdec_disable();
pr_err("id: %d, %s: Error amvdec_vdec_loadmc fail\n",
DECODE_ID(hw), __func__);
dpb_print(DECODE_ID(hw), 0, "%s: Error amvdec_vdec_loadmc fail\n", __func__);
return;
}
if (hw->mmu_enable) {
@@ -6395,7 +6567,7 @@ static void run(struct vdec_s *vdec, unsigned long mask,
NULL, hw->fw_mmu->data) < 0) {
amvdec_enable_flag = false;
amhevc_disable();
pr_debug("mmu fw load fail\n");
dpb_print(DECODE_ID(hw), 0, "mmu fw load fail\n");
return;
}
}
@@ -6472,6 +6644,10 @@ static void h264_reconfig(struct vdec_h264_hw_s *hw)
all buffers are in display queue (used == 2),
or free (used == 0)
*/
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_DUMP_BUFSPEC))
dump_bufspec(hw, "pre h264_reconfig");
flush_dpb(p_H264_Dpb);
bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0);
@@ -6501,6 +6677,10 @@ static void h264_reconfig(struct vdec_h264_hw_s *hw)
hw->has_i_frame = 0;
hw->config_bufmgr_done = 0;
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_DUMP_BUFSPEC))
dump_bufspec(hw, "after h264_reconfig");
}
#ifdef ERROR_HANDLE_TEST
@@ -6521,9 +6701,10 @@ static void h264_clear_dpb(struct vdec_h264_hw_s *hw)
}
#endif
static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw)
static void h264_reset_bufmgr(struct vdec_s *vdec)
{
int i;
struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
#if 0
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
int actual_dpb_size, max_reference_size;
@@ -6587,6 +6768,10 @@ static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw)
if (hw->cur_pool >= VF_POOL_NUM)
hw->cur_pool = 0;
for (i = 0; i < VF_POOL_SIZE; i++)
hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */
if (hw->collocate_cma_alloc_addr) {
decoder_bmmu_box_free_idx(
hw->bmmu_box,
@@ -6595,6 +6780,7 @@ static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw)
hw->dpb.colocated_mv_addr_start = 0;
hw->dpb.colocated_mv_addr_end = 0;
}
vf_notify_receiver(vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_RESET, NULL);
dealloc_buf_specs(hw, 1);
buf_spec_init(hw);
@@ -7096,6 +7282,10 @@ MODULE_PARM_DESC(mmu_enable, "\n mmu_enable\n");
module_param(force_enable_mmu, uint, 0664);
MODULE_PARM_DESC(force_enable_mmu, "\n force_enable_mmu\n");
module_param(again_threshold, uint, 0664);
MODULE_PARM_DESC(again_threshold, "\n again_threshold\n");
/*
module_param(trigger_task, uint, 0664);
MODULE_PARM_DESC(trigger_task, "\n amvdec_h264 trigger_task\n");

View File

@@ -45,7 +45,7 @@
#include "../utils/decoder_bmmu_box.h"
#include "../utils/config_parser.h"
#include "../utils/firmware.h"
#define AGAIN_HAS_THRESHOLD
/*#define TEST_NO_BUF*/
/*#define HEVC_PIC_STRUCT_SUPPORT*/
#define MULTI_INSTANCE_SUPPORT
@@ -237,15 +237,16 @@ static u32 pts_unstable;
#define H265_DEBUG_NO_DISPLAY 0x200
#define H265_DEBUG_DISCARD_NAL 0x400
#define H265_DEBUG_OUT_PTS 0x800
#define H265_DEBUG_DUMP_PIC_LIST 0x1000
#define H265_DEBUG_PRINT_SEI 0x2000
#define H265_DEBUG_PIC_STRUCT 0x4000
#define H265_DEBUG_DIS_LOC_ERROR_PROC 0x10000
#define H265_DEBUG_DIS_SYS_ERROR_PROC 0x20000
#define H265_DEBUG_DUMP_PIC_LIST 0x40000
#define H265_NO_CHANG_DEBUG_FLAG_IN_CODE 0x40000
#define H265_DEBUG_TRIG_SLICE_SEGMENT_PROC 0x80000
#define H265_DEBUG_HW_RESET 0x100000
#define H265_CFG_CANVAS_IN_DECODE 0x200000
#define H265_DEBUG_ERROR_TRIG 0x400000
#define H265_DEBUG_DV 0x400000
#define H265_DEBUG_NO_EOS_SEARCH_DONE 0x800000
#define H265_DEBUG_NOT_USE_LAST_DISPBUF 0x1000000
#define H265_DEBUG_IGNORE_CONFORMANCE_WINDOW 0x2000000
@@ -363,9 +364,14 @@ static u32 nal_skip_policy = 2;
static u32 i_only_flag;
/*
*use_cma: 1, use both reserver memory and cma for buffers
*2, only use cma for buffers
*/
bit 0, fast output first I picture
*/
static u32 fast_output_enable = 1;
/*
use_cma: 1, use both reserver memory and cma for buffers
2, only use cma for buffers
*/
static u32 use_cma = 2;
#define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf))
@@ -414,6 +420,7 @@ static u32 parser_sei_enable;
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
static u32 parser_dolby_vision_enable = 1;
static u32 dolby_meta_with_el;
static u32 dolby_el_flush_th = 2;
#endif
/* this is only for h265 mmu enable */
@@ -464,7 +471,7 @@ static u32 dv_debug;
DEFINE_SPINLOCK(lock);
struct task_struct *h265_task = NULL;
#define DEBUG_REG
#undef DEBUG_REG
#ifdef DEBUG_REG
void WRITE_VREG_DBG(unsigned adr, unsigned val)
{
@@ -685,8 +692,8 @@ static unsigned short parser_cmd[PARSER_CMD_NUMBER] = {
#define HEVC_SPS_BUFFER HEVC_ASSIST_SCRATCH_4
#define HEVC_PPS_BUFFER HEVC_ASSIST_SCRATCH_5
#define HEVC_SAO_UP HEVC_ASSIST_SCRATCH_6
#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7
#define HEVC_STREAM_SWAP_BUFFER2 HEVC_ASSIST_SCRATCH_8
/*#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7
#define HEVC_STREAM_SWAP_BUFFER2 HEVC_ASSIST_SCRATCH_8*/
#define HEVC_sao_mem_unit HEVC_ASSIST_SCRATCH_9
#define HEVC_SAO_ABV HEVC_ASSIST_SCRATCH_A
#define HEVC_sao_vb_size HEVC_ASSIST_SCRATCH_B
@@ -1344,6 +1351,7 @@ struct hevc_state_s {
unsigned int timeout_num;
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
unsigned char switch_dvlayer_flag;
unsigned char no_switch_dvlayer_count;
#endif
unsigned char start_parser_type;
/*start_decoding_flag:
@@ -1352,6 +1360,7 @@ struct hevc_state_s {
unsigned char rps_set_id;
unsigned char eos;
int pic_decoded_lcu_idx;
u8 over_decode;
#endif
struct vframe_s vframe_dummy;
char *provider_name;
@@ -1571,8 +1580,15 @@ struct hevc_state_s {
u8 head_error_flag;
int valve_count;
struct firmware_s *fw;
#ifdef AGAIN_HAS_THRESHOLD
u8 next_again_flag;
u32 pre_parser_wr_ptr;
#endif
} /*hevc_stru_t */;
#ifdef AGAIN_HAS_THRESHOLD
u32 again_threshold = 0x40;
#endif
#ifdef SEND_LMEM_WITH_RPM
#define get_lmem_params(hevc, ladr) \
hevc->lmem_ptr[ladr - (ladr & 0x3) + 3 - (ladr & 0x3)]
@@ -1858,8 +1874,12 @@ static void backup_decode_state(struct hevc_state_s *hevc)
static void restore_decode_state(struct hevc_state_s *hevc)
{
struct vdec_s *vdec = hw_to_vdec(hevc);
if (!vdec_has_more_input(vdec))
if (!vdec_has_more_input(vdec)) {
hevc->pic_decoded_lcu_idx =
READ_VREG(HEVC_PARSER_LCU_START)
& 0xffffff;
return;
}
hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
"%s: discard pic index 0x%x\n",
__func__, hevc->decoding_pic ?
@@ -1975,6 +1995,7 @@ static void hevc_init_stru(struct hevc_state_s *hevc,
hevc->timeout_num = 0;
hevc->eos = 0;
hevc->pic_decoded_lcu_idx = -1;
hevc->over_decode = 0;
hevc->used_4k_num = -1;
hevc->start_decoding_flag = 0;
hevc->rps_set_id = 0;
@@ -2821,6 +2842,21 @@ static void dump_pic_list(struct hevc_state_s *hevc)
}
}
static void clear_referenced_flag(struct hevc_state_s *hevc)
{
int i;
struct PIC_s *pic;
for (i = 0; i < MAX_REF_PIC_NUM; i++) {
pic = hevc->m_PIC[i];
if (pic == NULL || pic->index == -1)
continue;
if (pic->referenced) {
pic->referenced = 0;
put_mv_buf(hevc, pic);
}
}
}
static struct PIC_s *output_pic(struct hevc_state_s *hevc,
unsigned char flush_flag)
{
@@ -2865,6 +2901,13 @@ static struct PIC_s *output_pic(struct hevc_state_s *hevc,
continue;
if (pic->output_mark)
num_pic_not_yet_display++;
if (pic->slice_type == 2 &&
hevc->vf_pre_count == 0 &&
fast_output_enable & 0x1) {
/*fast output for first I picture*/
pic->num_reorder_pic = 0;
hevc_print(hevc, 0, "VH265: output first frame\n");
}
}
for (i = 0; i < MAX_REF_PIC_NUM; i++) {
@@ -3503,10 +3546,10 @@ static void hevc_config_work_space_hw(struct hevc_state_s *hevc)
"write HEVC_ASSIST_MMU_MAP_ADDR\n");
} else
WRITE_VREG(H265_MMU_MAP_BUFFER, hevc->frame_mmu_map_phy_addr);
} else
} /*else
WRITE_VREG(HEVC_STREAM_SWAP_BUFFER,
buf_spec->swap_buf.buf_start);
WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start);
WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start);*/
WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start);
/* cfg_p_addr */
WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start);
@@ -4677,6 +4720,7 @@ static void flush_output(struct hevc_state_s *hevc, struct PIC_s *pic)
}
}
} while (pic_display);
clear_referenced_flag(hevc);
}
/*
@@ -5062,6 +5106,13 @@ static void check_pic_decoded_error(struct hevc_state_s *hevc,
"head has error, set error_mark\n");
}
if ((error_handle_policy & 0x80) == 0) {
if (hevc->over_decode && hevc->cur_pic) {
hevc_print(hevc, 0,
"over decode, set error_mark\n");
hevc->cur_pic->error_mark = 1;
}
}
}
static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
@@ -5141,14 +5192,27 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
}
if (OVER_SIZE(hevc->pic_w, hevc->pic_h)) {
pr_info("over size : %u x %u.\n",
hevc_print(hevc, 0, "over size : %u x %u.\n",
hevc->pic_w, hevc->pic_h);
if (!hevc->m_ins_flag)
if ((!hevc->m_ins_flag) &&
((debug &
H265_NO_CHANG_DEBUG_FLAG_IN_CODE) == 0))
debug |= (H265_DEBUG_DIS_LOC_ERROR_PROC |
H265_DEBUG_DIS_SYS_ERROR_PROC);
hevc->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
return 3;
}
if (hevc->bit_depth_chroma > 10 ||
hevc->bit_depth_luma > 10) {
hevc_print(hevc, 0, "unsupport bitdepth : %u,%u\n",
hevc->bit_depth_chroma,
hevc->bit_depth_luma);
if (!hevc->m_ins_flag)
debug |= (H265_DEBUG_DIS_LOC_ERROR_PROC |
H265_DEBUG_DIS_SYS_ERROR_PROC);
hevc->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
return 4;
}
/* it will cause divide 0 error */
if (hevc->pic_w == 0 || hevc->pic_h == 0) {
@@ -5330,8 +5394,12 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
struct hevc_state_s *hevc_ba =
(struct hevc_state_s *)
vdec->master->private;
if (hevc_ba->cur_pic != NULL)
if (hevc_ba->cur_pic != NULL) {
hevc_ba->cur_pic->dv_enhance_exist = 1;
hevc_print(hevc, H265_DEBUG_DV,
"To decode el (poc %d) => set bl (poc %d) dv_enhance_exist flag\n",
hevc->curr_POC, hevc_ba->cur_pic->POC);
}
}
if (vdec->master == NULL &&
vdec->slave == NULL)
@@ -5352,6 +5420,10 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
#endif
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
hevc->cur_pic->dv_enhance_exist = 0;
if (vdec->slave)
hevc_print(hevc, H265_DEBUG_DV,
"Clear bl (poc %d) dv_enhance_exist flag\n",
hevc->curr_POC);
if (vdec->master == NULL &&
vdec->slave == NULL)
set_aux_data(hevc, hevc->cur_pic, 0, 0);
@@ -5470,7 +5542,8 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
(hevc->pic_w +
hevc->lcu_size -
1) / hevc->lcu_size);
if (hevc->tile_y_x != (hevc->tile_x | (hevc->tile_y << 8))) {
if ((hevc->tile_y_x != (hevc->tile_x | (hevc->tile_y << 8)))
&& (hevc->tile_y_x != -1)) {
hevc->new_tile = 1;
hevc->tile_x = hevc->tile_y_x & 0xff;
hevc->tile_y = (hevc->tile_y_x >> 8) & 0xff;
@@ -5485,6 +5558,10 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
} else
hevc->new_tile = 0;
if ((hevc->tile_x > (MAX_TILE_COL_NUM - 1))
|| (hevc->tile_y > (MAX_TILE_ROW_NUM - 1)))
hevc->new_tile = 0;
if (hevc->new_tile) {
hevc->tile_start_lcu_x =
hevc->m_tile[hevc->tile_y][hevc->tile_x].start_cu_x;
@@ -5665,6 +5742,13 @@ static int H265_alloc_mmu(struct hevc_state_s *hevc, struct PIC_s *new_pic,
decoder_mmu_box_free_idx(hevc->mmu_box, new_pic->index);
new_pic->scatter_alloc = 0;
}
if (cur_mmu_4k_number > MAX_FRAME_4K_NUM) {
hevc_print(hevc, 0, "over max !! 0x%x width %d height %d\n",
cur_mmu_4k_number,
new_pic->width,
new_pic->height);
return -1;
}
ret = decoder_mmu_box_alloc_idx(
hevc->mmu_box,
cur_buf_idx,
@@ -5969,7 +6053,8 @@ static int init_buf_spec(struct hevc_state_s *hevc)
return 0;
}
static int parse_sei(struct hevc_state_s *hevc, char *sei_buf, uint32_t size)
static int parse_sei(struct hevc_state_s *hevc,
struct PIC_s *pic, char *sei_buf, uint32_t size)
{
char *p = sei_buf;
char *p_sei;
@@ -5992,6 +6077,17 @@ static int parse_sei(struct hevc_state_s *hevc, char *sei_buf, uint32_t size)
payload_size = *p++;
if (p+payload_size <= sei_buf+size) {
switch (payload_type) {
case SEI_PicTiming:
p_sei = p;
hevc->curr_pic_struct = (*p_sei >> 4)&0x0f;
pic->pic_struct = hevc->curr_pic_struct;
if (get_dbg_flag(hevc) &
H265_DEBUG_PIC_STRUCT) {
hevc_print(hevc, 0,
"parse result pic_struct = %d\n",
hevc->curr_pic_struct);
}
break;
case SEI_MasteringDisplayColorVolume:
/*hevc_print(hevc, 0,
"sei type: primary display color volume %d, size %d\n",
@@ -6193,7 +6289,7 @@ static void set_frame_info(struct hevc_state_s *hevc, struct vframe_s *vf,
if (type == 0x02000000) {
/* hevc_print(hevc, 0,
"sei(%d)\n", size); */
parse_sei(hevc, p, size);
parse_sei(hevc, pic, p, size);
}
p += size;
}
@@ -6489,6 +6585,9 @@ static int vh265_event_cb(int type, void *data, void *op_arg)
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
req->dv_enhance_exist =
hevc->m_PIC[index]->dv_enhance_exist;
hevc_print(hevc, H265_DEBUG_DV,
"query dv_enhance_exist for pic (poc %d) flag => %d\n",
hevc->m_PIC[index]->POC, req->dv_enhance_exist);
#else
req->dv_enhance_exist = 0;
#endif
@@ -6848,10 +6947,8 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
/* hevc_print(hevc, 0,
"aaa: %d/%d, %d/%d\n",
vf->width,vf->height, pic->width, pic->height); */
vf->width = pic->width /
get_double_write_ratio(hevc, pic->double_write_mode);
vf->height = pic->height /
get_double_write_ratio(hevc, pic->double_write_mode);
vf->width = pic->width;
vf->height = pic->height;
if (force_w_h != 0) {
vf->width = (force_w_h >> 16) & 0xffff;
@@ -6918,6 +7015,10 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
vf->width, vf->height, vf->compWidth, vf->compHeight);
}
vf->width = vf->width /
get_double_write_ratio(hevc, pic->double_write_mode);
vf->height = vf->height /
get_double_write_ratio(hevc, pic->double_write_mode);
#ifdef HEVC_PIC_STRUCT_SUPPORT
if (pic->pic_struct == 3 || pic->pic_struct == 4) {
struct vframe_s *vf2;
@@ -7659,8 +7760,14 @@ pic_done:
(struct hevc_state_s *)
vdec->slave->private;
hevc->switch_dvlayer_flag = 1;
hevc->no_switch_dvlayer_count = 0;
hevc_el->start_parser_type =
next_parser_type;
hevc_print(hevc, H265_DEBUG_DV,
"switch (poc %d) to el\n",
hevc->cur_pic ?
hevc->cur_pic->POC :
INVALID_POC);
} else if (vdec->master &&
dec_status == HEVC_FIND_NEXT_PIC_NAL) {
/*cur is enhance, found base*/
@@ -7668,12 +7775,46 @@ pic_done:
(struct hevc_state_s *)
vdec->master->private;
hevc->switch_dvlayer_flag = 1;
hevc->no_switch_dvlayer_count = 0;
hevc_ba->start_parser_type =
next_parser_type;
hevc_print(hevc, H265_DEBUG_DV,
"switch (poc %d) to bl\n",
hevc->cur_pic ?
hevc->cur_pic->POC :
INVALID_POC);
} else {
hevc->switch_dvlayer_flag = 0;
hevc->start_parser_type =
next_parser_type;
hevc->no_switch_dvlayer_count++;
hevc_print(hevc, H265_DEBUG_DV,
"%s: no_switch_dvlayer_count = %d\n",
vdec->master ? "el" : "bl",
hevc->no_switch_dvlayer_count);
if (vdec->slave &&
dolby_el_flush_th != 0 &&
hevc->no_switch_dvlayer_count >
dolby_el_flush_th) {
struct hevc_state_s *hevc_el =
(struct hevc_state_s *)
vdec->slave->private;
struct PIC_s *el_pic;
check_pic_decoded_error(hevc_el,
hevc_el->pic_decoded_lcu_idx);
el_pic = get_pic_by_POC(hevc_el,
hevc_el->curr_POC);
hevc_el->curr_POC = INVALID_POC;
hevc_el->m_pocRandomAccess = MAX_INT;
flush_output(hevc_el, el_pic);
hevc_el->decoded_poc = INVALID_POC; /*
already call flush_output*/
hevc_el->decoding_pic = NULL;
hevc->no_switch_dvlayer_count = 0;
if (get_dbg_flag(hevc) & H265_DEBUG_DV)
hevc_print(hevc, 0,
"no el anymore, flush_output el\n");
}
}
hevc->decoded_poc = hevc->curr_POC;
hevc->decoding_pic = NULL;
@@ -8204,16 +8345,18 @@ static irqreturn_t vh265_isr(int irq, void *data)
hevc->dec_status = dec_status;
if (is_log_enable(hevc))
add_log(hevc,
"isr: status = 0x%x dec info 0x%x lcu 0x%x shiftbyte 0x%x",
"isr: status = 0x%x dec info 0x%x lcu 0x%x shiftbyte 0x%x shiftstatus 0x%x",
dec_status, READ_HREG(HEVC_DECODE_INFO),
READ_VREG(HEVC_MPRED_CURR_LCU),
READ_VREG(HEVC_SHIFT_BYTE_COUNT));
READ_VREG(HEVC_SHIFT_BYTE_COUNT),
READ_VREG(HEVC_SHIFT_STATUS));
if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
hevc_print(hevc, 0,
"265 isr dec status = 0x%x dec info 0x%x shiftbyte 0x%x\n",
"265 isr dec status = 0x%x dec info 0x%x shiftbyte 0x%x shiftstatus 0x%x\n",
dec_status, READ_HREG(HEVC_DECODE_INFO),
READ_VREG(HEVC_SHIFT_BYTE_COUNT));
READ_VREG(HEVC_SHIFT_BYTE_COUNT),
READ_VREG(HEVC_SHIFT_STATUS));
debug_tag = READ_HREG(DEBUG_REG1);
if (debug_tag & 0x10000) {
@@ -8259,9 +8402,11 @@ static irqreturn_t vh265_isr(int irq, void *data)
WRITE_HREG(DEBUG_REG1, 0);
} else if (debug_tag != 0) {
hevc_print(hevc, 0,
"dbg%x: %x lcu %x\n", READ_HREG(DEBUG_REG1),
"dbg%x: %x l/w/r %x %x %x\n", READ_HREG(DEBUG_REG1),
READ_HREG(DEBUG_REG2),
READ_VREG(HEVC_PARSER_LCU_START));
READ_VREG(HEVC_STREAM_LEVEL),
READ_VREG(HEVC_STREAM_WR_PTR),
READ_VREG(HEVC_STREAM_RD_PTR));
if (((udebug_pause_pos & 0xffff)
== (debug_tag & 0xffff)) &&
(udebug_pause_decode_idx == 0 ||
@@ -8441,8 +8586,7 @@ static void vh265_check_timer_func(unsigned long arg)
"H265 dec fatal error watchdog.\n");
hevc->
error_system_watchdog_count = 0;
hevc->fatal_error =
DECODER_FATAL_ERROR_UNKNOWN;
hevc->fatal_error |= DECODER_FATAL_ERROR_UNKNOWN;
}
}
} else {
@@ -8585,7 +8729,12 @@ int vh265_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
int vh265_dec_status(struct vdec_info *vstatus)
#endif
{
#ifdef MULTI_INSTANCE_SUPPORT
struct hevc_state_s *hevc =
(struct hevc_state_s *)vdec->private;
#else
struct hevc_state_s *hevc = &gHevc;
#endif
vstatus->frame_width = hevc->frame_width;
vstatus->frame_height = hevc->frame_height;
if (hevc->frame_dur != 0)
@@ -9172,18 +9321,18 @@ static unsigned char is_new_pic_available(struct hevc_state_s *hevc)
static int vmh265_stop(struct hevc_state_s *hevc)
{
if (hevc->stat & STAT_TIMER_ARM) {
del_timer_sync(&hevc->timer);
hevc->stat &= ~STAT_TIMER_ARM;
}
if (hevc->stat & STAT_VDEC_RUN) {
amhevc_stop();
hevc->stat &= ~STAT_VDEC_RUN;
}
if (hevc->stat & STAT_ISR_REG) {
vdec_free_irq(VDEC_IRQ_1, (void *)hevc);
vdec_free_irq(VDEC_IRQ_0, (void *)hevc);
hevc->stat &= ~STAT_ISR_REG;
}
if (hevc->stat & STAT_TIMER_ARM) {
del_timer_sync(&hevc->timer);
hevc->stat &= ~STAT_TIMER_ARM;
}
if (hevc->stat & STAT_VF_HOOK) {
if (fr_hint_status == VDEC_HINTED)
@@ -9454,6 +9603,11 @@ static void vh265_work(struct work_struct *work)
hevc->pic_decoded_lcu_idx =
READ_VREG(HEVC_PARSER_LCU_START)
& 0xffffff;
hevc->over_decode =
(READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1;
if (hevc->over_decode)
hevc_print(hevc, 0,
"!!!Over decode\n");
if (is_log_enable(hevc))
add_log(hevc,
@@ -9543,7 +9697,9 @@ static void vh265_work(struct work_struct *work)
vdec_schedule_work(&hevc->work);
return;
}
#ifdef AGAIN_HAS_THRESHOLD
hevc->next_again_flag = 1;
#endif
} else if (hevc->dec_result == DEC_RESULT_EOS) {
struct PIC_s *pic;
hevc->eos = 1;
@@ -9594,6 +9750,8 @@ static void vh265_work(struct work_struct *work)
vdec_free_irq(VDEC_IRQ_0, (void *)hevc);
hevc->stat &= ~STAT_ISR_REG;
}
hevc_print(hevc, 0, "%s: force exit end\n",
__func__);
}
if (hevc->stat & STAT_VDEC_RUN) {
@@ -9644,6 +9802,17 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
if (hevc->eos)
return 0;
#ifdef AGAIN_HAS_THRESHOLD
if (hevc->next_again_flag &&
(!vdec_frame_based(vdec))) {
u32 parser_wr_ptr =
READ_PARSER_REG(PARSER_VIDEO_WP);
if (parser_wr_ptr >= hevc->pre_parser_wr_ptr &&
(parser_wr_ptr - hevc->pre_parser_wr_ptr) <
again_threshold)
return 0;
}
#endif
if (disp_vframe_valve_level &&
kfifo_len(&hevc->display_q) >=
@@ -9682,6 +9851,11 @@ static void run(struct vdec_s *vdec, unsigned long mask,
hevc_reset_core(vdec);
#ifdef AGAIN_HAS_THRESHOLD
hevc->pre_parser_wr_ptr =
READ_PARSER_REG(PARSER_VIDEO_WP);
hevc->next_again_flag = 0;
#endif
r = vdec_prepare_input(vdec, &hevc->chunk);
if (r < 0) {
input_empty[hevc->index]++;
@@ -9832,7 +10006,9 @@ static int amvdec_h265_probe(struct platform_device *pdev)
#endif
struct hevc_state_s *hevc = &gHevc;
int ret;
if ((debug & H265_NO_CHANG_DEBUG_FLAG_IN_CODE) == 0)
debug &= (~(H265_DEBUG_DIS_LOC_ERROR_PROC |
H265_DEBUG_DIS_SYS_ERROR_PROC));
memset(hevc, 0, sizeof(struct hevc_state_s));
if (get_dbg_flag(hevc))
hevc_print(hevc, 0, "%s\r\n", __func__);
@@ -10232,7 +10408,8 @@ static int ammvdec_h265_probe(struct platform_device *pdev)
"\n 265 mmu init failed!\n");
mutex_unlock(&vh265_mutex);
/* devm_kfree(&pdev->dev, (void *)hevc);*/
vfree((void *)hevc);
if (hevc)
vfree((void *)hevc);
return -EFAULT;
}
#if 0
@@ -10246,7 +10423,8 @@ static int ammvdec_h265_probe(struct platform_device *pdev)
if (ret < 0) {
uninit_mmu_buffers(hevc);
/* devm_kfree(&pdev->dev, (void *)hevc); */
vfree((void *)hevc);
if (hevc)
vfree((void *)hevc);
mutex_unlock(&vh265_mutex);
return ret;
}
@@ -10265,7 +10443,8 @@ static int ammvdec_h265_probe(struct platform_device *pdev)
"\namvdec_h265 memory resource undefined.\n");
uninit_mmu_buffers(hevc);
/* devm_kfree(&pdev->dev, (void *)hevc); */
vfree((void *)hevc);
if (hevc)
vfree((void *)hevc);
return -EFAULT;
}
/*
@@ -10294,7 +10473,8 @@ static int ammvdec_h265_probe(struct platform_device *pdev)
hevc_local_uninit(hevc);
uninit_mmu_buffers(hevc);
/* devm_kfree(&pdev->dev, (void *)hevc); */
vfree((void *)hevc);
if (hevc)
vfree((void *)hevc);
return -ENODEV;
}
@@ -10326,8 +10506,8 @@ static int ammvdec_h265_remove(struct platform_device *pdev)
vdec_core_release(hw_to_vdec(hevc), CORE_MASK_HEVC);
vdec_set_status(hw_to_vdec(hevc), VDEC_STATUS_DISCONNECTED);
vfree((void *)hevc);
if (hevc)
vfree((void *)hevc);
return 0;
}
@@ -10538,6 +10718,9 @@ MODULE_PARM_DESC(nal_skip_policy, "\n amvdec_h265 nal_skip_policy\n");
module_param(i_only_flag, uint, 0664);
MODULE_PARM_DESC(i_only_flag, "\n amvdec_h265 i_only_flag\n");
module_param(fast_output_enable, uint, 0664);
MODULE_PARM_DESC(fast_output_enable, "\n amvdec_h265 fast_output_enable\n");
module_param(error_handle_policy, uint, 0664);
MODULE_PARM_DESC(error_handle_policy, "\n amvdec_h265 error_handle_policy\n");
@@ -10631,6 +10814,10 @@ MODULE_PARM_DESC(parser_dolby_vision_enable,
module_param(dolby_meta_with_el, uint, 0664);
MODULE_PARM_DESC(dolby_meta_with_el,
"\n dolby_meta_with_el\n");
module_param(dolby_el_flush_th, uint, 0664);
MODULE_PARM_DESC(dolby_el_flush_th,
"\n dolby_el_flush_th\n");
#endif
module_param(mmu_enable, uint, 0664);
MODULE_PARM_DESC(mmu_enable, "\n mmu_enable\n");
@@ -10680,6 +10867,11 @@ module_param(dv_debug, uint, 0664);
MODULE_PARM_DESC(dv_debug, "\n dv_debug\n");
#endif
#ifdef AGAIN_HAS_THRESHOLD
module_param(again_threshold, uint, 0664);
MODULE_PARM_DESC(again_threshold, "\n again_threshold\n");
#endif
module_param(force_disp_pic_index, int, 0664);
MODULE_PARM_DESC(force_disp_pic_index,
"\n amvdec_h265 force_disp_pic_index\n");
@@ -10696,6 +10888,9 @@ MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n");
module_param(udebug_pause_decode_idx, uint, 0664);
MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n");
module_param(disp_vframe_valve_level, uint, 0664);
MODULE_PARM_DESC(disp_vframe_valve_level, "\n disp_vframe_valve_level\n");
module_init(amvdec_h265_driver_init_module);
module_exit(amvdec_h265_driver_remove_module);

View File

@@ -74,6 +74,7 @@ static DEFINE_MUTEX(vdec_mutex);
#define CMA_ALLOC_SIZE SZ_64M
#define MEM_NAME "vdec_prealloc"
static int inited_vcodec_num;
#define jiffies_ms div64_u64(get_jiffies_64() * 1000, HZ)
static int poweron_clock_level;
static int keep_vdec_mem;
static unsigned int debug_trace_num = 16 * 20;
@@ -218,7 +219,7 @@ static int get_canvas(unsigned int index, unsigned int base)
int vdec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
{
if (vdec->dec_status)
if (vdec && vdec->dec_status)
return vdec->dec_status(vdec, vstatus);
return -1;
@@ -235,6 +236,7 @@ int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
if ((r == 0) && (vdec->slave) && (vdec->slave->set_trickmode))
r = vdec->slave->set_trickmode(vdec->slave,
trickmode);
return r;
}
return -1;
@@ -1108,6 +1110,20 @@ bool vdec_need_more_data(struct vdec_s *vdec)
}
EXPORT_SYMBOL(vdec_need_more_data);
void hevc_wait_ddr(void)
{
unsigned long flags;
spin_lock_irqsave(&vdec_spin_lock, flags);
codec_dmcbus_write(DMC_REQ_CTRL,
codec_dmcbus_read(DMC_REQ_CTRL) & (~(1 << 4)));
spin_unlock_irqrestore(&vdec_spin_lock, flags);
while (!(codec_dmcbus_read(DMC_CHAN_STS)
& (1 << 4)))
;
}
void vdec_save_input_context(struct vdec_s *vdec)
{
struct vdec_input_s *input = &vdec->input;
@@ -1169,6 +1185,8 @@ void vdec_save_input_context(struct vdec_s *vdec)
/* pr_info("master->input.last_swap_slave = %d\n",
master->input.last_swap_slave); */
}
hevc_wait_ddr();
}
}
EXPORT_SYMBOL(vdec_save_input_context);
@@ -1813,7 +1831,7 @@ static irqreturn_t vdec_isr(int irq, void *dev_id)
{
struct vdec_isr_context_s *c =
(struct vdec_isr_context_s *)dev_id;
struct vdec_s *vdec = c->vdec;
struct vdec_s *vdec = vdec_core->active_vdec;
irqreturn_t ret = IRQ_HANDLED;
if (vdec)
atomic_set(&vdec->inirq_flag, 1);
@@ -1857,7 +1875,7 @@ static irqreturn_t vdec_thread_isr(int irq, void *dev_id)
{
struct vdec_isr_context_s *c =
(struct vdec_isr_context_s *)dev_id;
struct vdec_s *vdec = c->vdec;
struct vdec_s *vdec = vdec_core->active_vdec;
irqreturn_t ret = IRQ_HANDLED;
if (vdec)
atomic_set(&vdec->inirq_thread_flag, 1);
@@ -3148,7 +3166,8 @@ static ssize_t show_debug(struct class *class,
list_for_each_entry(vdec,
&core->connected_vdec_list, list) {
enum vdec_type_e type;
if ((vdec->status == VDEC_STATUS_CONNECTED
|| vdec->status == VDEC_STATUS_ACTIVE)) {
for (type = VDEC_1; type < VDEC_MAX; type++) {
if (vdec->core_mask & (1 << type)) {
pbuf += sprintf(pbuf, "%s(%d):",
@@ -3168,6 +3187,7 @@ static ssize_t show_debug(struct class *class,
/ vdec->total_clk[type]));
}
}
}
}
vdec_core_unlock(vdec_core, flags);

View File

@@ -410,6 +410,9 @@ int vdec_wakeup_userdata_poll(struct vdec_s *vdec);
void vdec_reset_userdata_fifo(struct vdec_s *vdec, int bInit);
#ifdef VDEC_DEBUG_SUPPORT
extern void vdec_set_step_mode(void);
#endif
int vdec_get_debug_flags(void);
unsigned char is_mult_inc(unsigned int);

View File

@@ -278,7 +278,7 @@ static u32 bit_depth_chroma;
static u32 frame_width;
static u32 frame_height;
static u32 video_signal_type;
static u32 pts_unstable;
static u32 on_no_keyframe_skiped;
#define PROB_SIZE (496 * 2 * 4)
@@ -1563,10 +1563,14 @@ static int get_double_write_mode(struct VP9Decoder_s *pbi)
u32 dw;
if (valid_dw_mode == 0x100) {
struct VP9_Common_s *cm = &pbi->common;
struct PIC_BUFFER_CONFIG_s *cur_pic_config
= &cm->cur_frame->buf;
int w = cur_pic_config->y_crop_width;
int h = cur_pic_config->y_crop_width;
struct PIC_BUFFER_CONFIG_s *cur_pic_config;
int w, h;
if (!cm->cur_frame)
return 1;/*no valid frame,*/
cur_pic_config = &cm->cur_frame->buf;
w = cur_pic_config->y_crop_width;
h = cur_pic_config->y_crop_width;
if (w > 1920 && h > 1088)
dw = 0x4; /*1:2*/
else
@@ -1622,7 +1626,15 @@ int vp9_alloc_mmu(
int bit_depth_10 = (bit_depth == VPX_BITS_10);
int picture_size;
int cur_mmu_4k_number;
if (!pbi->mmu_box) {
pr_err("error no mmu box!\n");
return -1;
}
if (bit_depth >= VPX_BITS_12) {
pbi->fatal_error = DECODER_FATAL_ERROR_SIZE_OVERFLOW;
pr_err("fatal_error, un support bit depth 12!\n\n");
return -1;
}
picture_size = compute_losless_comp_body_size(pic_width, pic_height,
bit_depth_10);
cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12);
@@ -5119,7 +5131,7 @@ static void config_sao_hw(struct VP9Decoder_s *pbi, union param_u *params)
/*set them all 0 for H265_NV21 (no down-scale)*/
data32 &= ~(0xff << 16);
WRITE_VREG(HEVC_SAO_CTRL5, data32);
ata32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
data32 &= (~0x30);
/*[5:4] address_format 00:linear 01:32x32 10:64x32*/
data32 |= (MEM_MAP_MODE << 4);
@@ -6218,7 +6230,7 @@ static int vp9_local_init(struct VP9Decoder_s *pbi)
#endif
init_pic_list(pbi);
pts_unstable = ((unsigned long)(pbi->vvp9_amstream_dec_info.param)
pbi->pts_unstable = ((unsigned long)(pbi->vvp9_amstream_dec_info.param)
& 0x40) >> 6;
if ((debug & VP9_DEBUG_SEND_PARAM_WITH_REG) == 0) {
@@ -8193,6 +8205,14 @@ static int vmvp9_stop(struct VP9Decoder_s *pbi)
{
pbi->init_flag = 0;
if (pbi->stat & STAT_VDEC_RUN) {
amhevc_stop();
pbi->stat &= ~STAT_VDEC_RUN;
}
if (pbi->stat & STAT_ISR_REG) {
vdec_free_irq(VDEC_IRQ_0, (void *)pbi);
pbi->stat &= ~STAT_ISR_REG;
}
if (pbi->stat & STAT_TIMER_ARM) {
del_timer_sync(&pbi->timer);
pbi->stat &= ~STAT_TIMER_ARM;
@@ -8284,8 +8304,12 @@ static int amvdec_vp9_mmu_init(struct VP9Decoder_s *pbi)
#ifdef VP9_10B_MMU
int buf_size = 48;
if ((pbi->max_pic_w * pbi->max_pic_h) > 0 && (pbi->max_pic_w * pbi->max_pic_h) <= 1920*1088) {
if ((pbi->max_pic_w * pbi->max_pic_h > 1280*736) &&
(pbi->max_pic_w * pbi->max_pic_h <= 1920*1088)) {
buf_size = 12;
} else if ((pbi->max_pic_w * pbi->max_pic_h > 0) &&
(pbi->max_pic_w * pbi->max_pic_h <= 1280*736)) {
buf_size = 4;
}
pbi->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
pbi->index, FRAME_BUFFERS + STAGE_MAX_BUFFERS,
@@ -8667,6 +8691,10 @@ static void vp9_work(struct work_struct *work)
pbi->stat &= ~STAT_ISR_REG;
}
}
if (pbi->stat & STAT_VDEC_RUN) {
amhevc_stop();
pbi->stat &= ~STAT_VDEC_RUN;
}
if (pbi->stat & STAT_TIMER_ARM) {
del_timer_sync(&pbi->timer);

BIN
firmware/video/video_ucode.bin Normal file → Executable file

Binary file not shown.