mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-11 05:17:10 +09:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
BIN
firmware/video/video_ucode.bin
Normal file → Executable file
Binary file not shown.
Reference in New Issue
Block a user