mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-11 13:27:06 +09:00
PD#152551: vmh264: fixed the problems of crash and screen flicker when playing.
merged code form kernel 3.14: PD#150863: amports: cherry-pick h264 add_timer patch from customer PD#150199: vmh264: fix fast_output issue PD#147795: vmh264: set hevc frame done when TIMEOUT or EMPTY Change-Id: I9b4fa46b9a7cab50328d941e2f1158d330e393cd Signed-off-by: Nanxin Qin <nanxin.qin@amlogic.com>
This commit is contained in:
@@ -352,6 +352,8 @@ void slice_prepare(struct h264_dpb_stru *p_H264_Dpb,
|
||||
FRAME : p_H264_Dpb->dpb_param.l.data[NEW_PICTURE_STRUCTURE];
|
||||
sps->num_ref_frames = p_H264_Dpb->
|
||||
dpb_param.l.data[MAX_REFERENCE_FRAME_NUM];
|
||||
sps->profile_idc =
|
||||
(p_H264_Dpb->dpb_param.l.data[PROFILE_IDC_MMCO] >> 8) & 0xff;
|
||||
/*sps->max_dpb_size = p_H264_Dpb->dpb_param.l.data[MAX_DPB_SIZE];*/
|
||||
if (pSlice->idr_flag) {
|
||||
pSlice->long_term_reference_flag = mmco_cmd[0] & 1;
|
||||
@@ -2093,6 +2095,10 @@ int output_frames(struct h264_dpb_stru *p_H264_Dpb, unsigned char flush_flag)
|
||||
if ((p_H264_Dpb->fast_output_enable & 0x1) &&
|
||||
(p_Dpb->fs[i]->data_flag & IDR_FLAG))
|
||||
fast_output_flag = 1;
|
||||
if (p_H264_Dpb->fast_output_enable & 0x6
|
||||
&& p_H264_Dpb->poc_even_odd_flag
|
||||
&& p_Dpb->last_output_poc == INT_MIN)
|
||||
fast_output_flag = 1;
|
||||
if ((p_H264_Dpb->fast_output_enable & 0x2) &&
|
||||
((p_Dpb->fs[i]->poc -
|
||||
p_Dpb->last_output_poc)
|
||||
@@ -2124,12 +2130,14 @@ int output_frames(struct h264_dpb_stru *p_H264_Dpb, unsigned char flush_flag)
|
||||
if (prepare_display_buf(p_H264_Dpb->vdec, p_Dpb->fs[pos]) >= 0)
|
||||
p_Dpb->fs[pos]->pre_output = 1;
|
||||
else {
|
||||
dpb_print(p_H264_Dpb->decoder_index, 0,
|
||||
"%s[%d] poc %d last_output_poc %d poc_even_odd_flag %d\n",
|
||||
if (h264_debug_flag & PRINT_FLAG_DPB_DETAIL) {
|
||||
dpb_print(p_H264_Dpb->decoder_index, 0,
|
||||
"%s[%d] poc:%d last_output_poc:%d poc_even_odd_flag:%d\n",
|
||||
__func__, pos, poc,
|
||||
p_Dpb->last_output_poc,
|
||||
p_H264_Dpb->poc_even_odd_flag);
|
||||
dump_dpb(p_Dpb, 1);
|
||||
dump_dpb(p_Dpb, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
|
||||
@@ -5320,7 +5328,10 @@ int is_new_picture(struct StorablePicture *dec_picture,
|
||||
|
||||
#endif
|
||||
|
||||
int remove_picture(struct h264_dpb_stru *p_H264_Dpb,
|
||||
/*
|
||||
* release bufspec and pic for picture not in dpb buf
|
||||
*/
|
||||
int release_picture(struct h264_dpb_stru *p_H264_Dpb,
|
||||
struct StorablePicture *pic)
|
||||
{
|
||||
struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
|
||||
@@ -5336,6 +5347,60 @@ int remove_picture(struct h264_dpb_stru *p_H264_Dpb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ERROR_HANDLE_TEST
|
||||
/*
|
||||
* remove all pictures in dpb and release bufspec/pic of them
|
||||
*/
|
||||
void remove_dpb_pictures(struct h264_dpb_stru *p_H264_Dpb)
|
||||
{
|
||||
/* struct VideoParameters *p_Vid = p_Dpb->p_Vid; */
|
||||
struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
|
||||
struct Slice *currSlice = &p_H264_Dpb->mSlice;
|
||||
unsigned i, j;
|
||||
|
||||
dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
|
||||
"%s\n", __func__);
|
||||
|
||||
if (!p_Dpb->init_done)
|
||||
return;
|
||||
|
||||
for (i = 0; i < p_Dpb->used_size; i++) {
|
||||
if (p_Dpb->fs[i]->colocated_buf_index >= 0) {
|
||||
dpb_print(p_H264_Dpb->decoder_index,
|
||||
PRINT_FLAG_DPB_DETAIL,
|
||||
"release_colocate_buf[%d] for fs[%d]\n",
|
||||
p_Dpb->fs[i]->colocated_buf_index, i);
|
||||
|
||||
release_colocate_buf(p_H264_Dpb,
|
||||
p_Dpb->fs[i]->colocated_buf_index); /* rain */
|
||||
p_Dpb->fs[i]->colocated_buf_index = -1;
|
||||
}
|
||||
if (!p_Dpb->fs[i]->pre_output) {
|
||||
release_buf_spec_num(p_H264_Dpb->vdec,
|
||||
p_Dpb->fs[i]->buf_spec_num);
|
||||
p_Dpb->fs[i]->buf_spec_num = -1;
|
||||
}
|
||||
remove_frame_from_dpb(p_H264_Dpb, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < p_Dpb->used_size; i++) {
|
||||
p_Dpb->fs_ref[i] = NULL;
|
||||
p_Dpb->fs_ltref[i] = NULL;
|
||||
p_Dpb->fs_list0[i] = NULL;
|
||||
p_Dpb->fs_list1[i] = NULL;
|
||||
p_Dpb->fs_listlt[i] = NULL;
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
currSlice->listXsize[i] = 0;
|
||||
for (j = 0; j < (MAX_LIST_SIZE * 2); j++)
|
||||
currSlice->listX[i][j] = NULL;
|
||||
}
|
||||
p_Dpb->ref_frames_in_buffer = 0;
|
||||
p_Dpb->ltref_frames_in_buffer = 0;
|
||||
p_Dpb->last_output_poc = INT_MIN;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void check_frame_store_same_pic_num(struct DecodedPictureBuffer *p_Dpb,
|
||||
struct StorablePicture *p, struct Slice *currSlice)
|
||||
{
|
||||
@@ -5563,6 +5628,8 @@ int dpb_check_ref_list_error(
|
||||
currSlice->listX[0][j]->pic_num)
|
||||
return 1;
|
||||
}*/
|
||||
if (currSlice->listX[0][i] == NULL)
|
||||
return 5;
|
||||
if (!is_pic_in_dpb(p_H264_Dpb,
|
||||
currSlice->listX[0][i]))
|
||||
return 1;
|
||||
@@ -5584,7 +5651,8 @@ int dpb_check_ref_list_error(
|
||||
currSlice->listX[0][j]->pic_num)
|
||||
return 3;
|
||||
}*/
|
||||
|
||||
if (currSlice->listX[1][i] == NULL)
|
||||
return 6;
|
||||
if (!is_pic_in_dpb(p_H264_Dpb,
|
||||
currSlice->listX[1][i]))
|
||||
return 2;
|
||||
|
||||
@@ -382,7 +382,21 @@ enum SliceType {
|
||||
NUM_SLICE_TYPES = 5
|
||||
};
|
||||
|
||||
enum ProfileIDC {
|
||||
FREXT_CAVLC444 = 44, /*!< YUV 4:4:4/14 "CAVLC 4:4:4"*/
|
||||
BASELINE = 66, /*!< YUV 4:2:0/8 "Baseline"*/
|
||||
MAIN = 77, /*!< YUV 4:2:0/8 "Main"*/
|
||||
EXTENDED = 88, /*!< YUV 4:2:0/8 "Extended"*/
|
||||
FREXT_HP = 100, /*!< YUV 4:2:0/8 "High"*/
|
||||
FREXT_Hi10P = 110, /*!< YUV 4:2:0/10 "High 10"*/
|
||||
FREXT_Hi422 = 122, /*!< YUV 4:2:2/10 "High 4:2:2"*/
|
||||
FREXT_Hi444 = 244, /*!< YUV 4:4:4/14 "High 4:4:4"*/
|
||||
MVC_HIGH = 118, /*!< YUV 4:2:0/8 "Multiview High"*/
|
||||
STEREO_HIGH = 128 /*!< YUV 4:2:0/8 "Stereo High"*/
|
||||
};
|
||||
|
||||
struct SPSParameters {
|
||||
unsigned int profile_idc;
|
||||
int pic_order_cnt_type;
|
||||
int log2_max_pic_order_cnt_lsb_minus4;
|
||||
int num_ref_frames_in_pic_order_cnt_cycle;
|
||||
@@ -806,9 +820,11 @@ int get_free_buf_idx(struct vdec_s *vdec);
|
||||
void store_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb,
|
||||
struct StorablePicture *p, unsigned char data_flag);
|
||||
|
||||
int remove_picture(struct h264_dpb_stru *p_H264_Dpb,
|
||||
int release_picture(struct h264_dpb_stru *p_H264_Dpb,
|
||||
struct StorablePicture *pic);
|
||||
|
||||
void remove_dpb_pictures(struct h264_dpb_stru *p_H264_Dpb);
|
||||
|
||||
void bufmgr_post(struct h264_dpb_stru *p_H264_Dpb);
|
||||
|
||||
int get_long_term_flag_by_buf_spec_num(struct h264_dpb_stru *p_H264_Dpb,
|
||||
|
||||
@@ -165,6 +165,8 @@ static u32 udebug_pause_val;
|
||||
|
||||
static u32 udebug_pause_decode_idx;
|
||||
|
||||
static unsigned int disp_vframe_valve_level;
|
||||
|
||||
static unsigned int max_decode_instance_num = H264_DEV_NUM;
|
||||
static unsigned int decode_frame_count[H264_DEV_NUM];
|
||||
static unsigned int display_frame_count[H264_DEV_NUM];
|
||||
@@ -218,7 +220,7 @@ static unsigned int i_only_flag;
|
||||
|
||||
bit[12] i_only when error happen
|
||||
*/
|
||||
static unsigned int error_proc_policy = 0x1f14; /*0xc;*/
|
||||
static unsigned int error_proc_policy = 0x1f94; /*0x1f14*/
|
||||
|
||||
/*
|
||||
error_skip_count:
|
||||
@@ -246,7 +248,7 @@ static unsigned int first_i_policy = (15 << 8) | 2;
|
||||
bit [2], if even poc only, output frame ifthe cuurent poc
|
||||
is 2 big than the previous poc
|
||||
*/
|
||||
static unsigned int fast_output_enable;
|
||||
static unsigned int fast_output_enable = 4;
|
||||
|
||||
static unsigned int enable_itu_t35 = 1;
|
||||
|
||||
@@ -639,7 +641,7 @@ struct vdec_h264_hw_s {
|
||||
/* timeout handle */
|
||||
unsigned long int start_process_time;
|
||||
unsigned last_mby_mbx;
|
||||
unsigned last_ucode_watchdog_reg_val;
|
||||
unsigned last_vld_level;
|
||||
unsigned decode_timeout_count;
|
||||
unsigned timeout_num;
|
||||
unsigned search_dataempty_num;
|
||||
@@ -681,6 +683,7 @@ struct vdec_h264_hw_s {
|
||||
u32 cfg_param2;
|
||||
u32 cfg_param3;
|
||||
u32 cfg_param4;
|
||||
int valve_count;
|
||||
struct firmware_s *fw;
|
||||
};
|
||||
|
||||
@@ -695,6 +698,9 @@ static void set_frame_info(struct vdec_h264_hw_s *hw, struct vframe_s *vf,
|
||||
u32 index);
|
||||
static void release_aux_data(struct vdec_h264_hw_s *hw,
|
||||
int buf_spec_num);
|
||||
#ifdef ERROR_HANDLE_TEST
|
||||
static void h264_clear_dpb(struct vdec_h264_hw_s *hw);
|
||||
#endif
|
||||
|
||||
#define H265_PUT_SAO_4K_SET 0x03
|
||||
#define H265_ABORT_SAO_4K_SET 0x04
|
||||
@@ -1158,6 +1164,18 @@ static void hevc_set_frame_done(struct vdec_h264_hw_s *hw)
|
||||
return;
|
||||
}
|
||||
|
||||
static void release_cur_decoding_buf(struct vdec_h264_hw_s *hw)
|
||||
{
|
||||
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
|
||||
if (p_H264_Dpb->mVideo.dec_picture) {
|
||||
release_picture(p_H264_Dpb,
|
||||
p_H264_Dpb->mVideo.dec_picture);
|
||||
p_H264_Dpb->mVideo.dec_picture = NULL;
|
||||
if (mmu_enable)
|
||||
hevc_set_frame_done(hw);
|
||||
}
|
||||
}
|
||||
|
||||
static void hevc_sao_wait_done(struct vdec_h264_hw_s *hw)
|
||||
{
|
||||
ulong timeout = jiffies + HZ;
|
||||
@@ -3463,11 +3481,11 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec)
|
||||
(p_H264_Dpb->dpb_param.l.data[SLICE_TYPE]
|
||||
== I_Slice)
|
||||
? 1 : 0;
|
||||
|
||||
unsigned char is_idr =
|
||||
((p_H264_Dpb->dpb_param.dpb.NAL_info_mmco & 0x1f)
|
||||
== 5);
|
||||
if ((first_i_policy & 0x3) == 0x3)
|
||||
is_i_slice =
|
||||
(p_H264_Dpb->dpb_param.dpb.NAL_info_mmco & 0x1f)
|
||||
== 5 ? 1 : 0;
|
||||
is_i_slice = is_idr;
|
||||
if (!is_i_slice) {
|
||||
if (hw->has_i_frame == 0) {
|
||||
hw->dec_result = DEC_RESULT_DONE;
|
||||
@@ -3478,15 +3496,13 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
} else {
|
||||
if (hw->skip_frame_count < 0) {
|
||||
if (hw->skip_frame_count < 0 || is_idr) {
|
||||
/* second I */
|
||||
hw->dec_flag &= (~NODISP_FLAG);
|
||||
hw->skip_frame_count = 0;
|
||||
}
|
||||
if (hw->has_i_frame == 0 &&
|
||||
(p_H264_Dpb->
|
||||
dpb_param.dpb.NAL_info_mmco & 0x1f)
|
||||
!= 5) {
|
||||
(!is_idr)) {
|
||||
int skip_count =
|
||||
(first_i_policy >> 8) & 0xff;
|
||||
/* first I (not IDR) */
|
||||
@@ -3524,6 +3540,12 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec)
|
||||
schedule_work(&hw->user_data_work);
|
||||
}
|
||||
if (slice_header_process_status == 1) {
|
||||
/* for baseline , set fast_output mode */
|
||||
if (p_H264_Dpb->mSPS.profile_idc == BASELINE)
|
||||
p_H264_Dpb->fast_output_enable = 4;
|
||||
else
|
||||
p_H264_Dpb->fast_output_enable
|
||||
= fast_output_enable;
|
||||
hw->data_flag =
|
||||
(p_H264_Dpb->
|
||||
dpb_param.l.data[SLICE_TYPE]
|
||||
@@ -3548,9 +3570,15 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec)
|
||||
int ret = dpb_check_ref_list_error(p_H264_Dpb);
|
||||
if (ret != 0) {
|
||||
dpb_print(DECODE_ID(hw), 0,
|
||||
"reference list error %d\n",
|
||||
ret);
|
||||
"reference list error %d frame count %d to skip %d\n",
|
||||
ret,
|
||||
hw->decode_pic_count+1,
|
||||
hw->skip_frame_count);
|
||||
hw->data_flag |= ERROR_FLAG;
|
||||
if ((error_proc_policy & 0x80)
|
||||
&& ((hw->dec_flag &
|
||||
NODISP_FLAG) == 0))
|
||||
hw->reset_bufmgr_flag = 1;
|
||||
}
|
||||
}
|
||||
if ((error_proc_policy & 0x800)
|
||||
@@ -3559,6 +3587,9 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec)
|
||||
"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))
|
||||
hw->reset_bufmgr_flag = 1;
|
||||
}
|
||||
|
||||
cfg_ret = config_decode_buf(hw,
|
||||
@@ -3568,9 +3599,7 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec)
|
||||
"config_decode_buf fail (%d)\n",
|
||||
cfg_ret);
|
||||
if (error_proc_policy & 0x2) {
|
||||
remove_picture(p_H264_Dpb,
|
||||
p_H264_Dpb->mVideo.dec_picture);
|
||||
p_H264_Dpb->mVideo.dec_picture = NULL;
|
||||
release_cur_decoding_buf(hw);
|
||||
/*hw->data_flag |= ERROR_FLAG;*/
|
||||
hw->dec_result = DEC_RESULT_DONE;
|
||||
vdec_schedule_work(&hw->work);
|
||||
@@ -3585,7 +3614,7 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec)
|
||||
else
|
||||
WRITE_VREG(DPB_STATUS_REG, H264_ACTION_DECODE_SLICE);
|
||||
hw->last_mby_mbx = 0;
|
||||
hw->last_ucode_watchdog_reg_val = 0;
|
||||
hw->last_vld_level = 0;
|
||||
start_process_time(hw);
|
||||
} else if (dec_dpb_status == H264_PIC_DATA_DONE) {
|
||||
pic_done_proc:
|
||||
@@ -3630,10 +3659,22 @@ pic_done_proc:
|
||||
}
|
||||
}
|
||||
check_decoded_pic_error(hw);
|
||||
|
||||
store_picture_in_dpb(p_H264_Dpb,
|
||||
p_H264_Dpb->mVideo.dec_picture,
|
||||
hw->data_flag | hw->dec_flag);
|
||||
#ifdef ERROR_HANDLE_TEST
|
||||
if ((hw->data_flag & ERROR_FLAG)
|
||||
&& (error_proc_policy & 0x80)) {
|
||||
release_cur_decoding_buf(hw);
|
||||
h264_clear_dpb(hw);
|
||||
hw->dec_flag = 0;
|
||||
hw->data_flag = 0;
|
||||
hw->skip_frame_count = 0;
|
||||
hw->has_i_frame = 0;
|
||||
hw->no_error_count = 0xfff;
|
||||
hw->no_error_i_count = 0xf;
|
||||
} else
|
||||
#endif
|
||||
store_picture_in_dpb(p_H264_Dpb,
|
||||
p_H264_Dpb->mVideo.dec_picture,
|
||||
hw->data_flag | hw->dec_flag);
|
||||
if (hw->data_flag & ERROR_FLAG) {
|
||||
hw->no_error_count = 0;
|
||||
hw->no_error_i_count = 0;
|
||||
@@ -3732,7 +3773,7 @@ pic_done_proc:
|
||||
PRINT_FLAG_DPB_DETAIL))
|
||||
dump_aux_buf(hw);
|
||||
#ifdef CONFIG_AM_VDEC_DV
|
||||
if (dolby_meta_with_el || vdec->slave) {
|
||||
if (vdec->dolby_meta_with_el || vdec->slave) {
|
||||
if (hw->last_dec_picture)
|
||||
set_aux_data(hw, hw->last_dec_picture,
|
||||
0, 0, NULL);
|
||||
@@ -3769,11 +3810,8 @@ pic_done_proc:
|
||||
(dec_dpb_status == H264_DECODE_TIMEOUT)) {
|
||||
empty_proc:
|
||||
reset_process_time(hw);
|
||||
if (p_H264_Dpb->mVideo.dec_picture) {
|
||||
remove_picture(p_H264_Dpb,
|
||||
p_H264_Dpb->mVideo.dec_picture);
|
||||
p_H264_Dpb->mVideo.dec_picture = NULL;
|
||||
}
|
||||
|
||||
release_cur_decoding_buf(hw);
|
||||
|
||||
if (input_frame_based(vdec) ||
|
||||
(READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0x200)) {
|
||||
@@ -3832,13 +3870,16 @@ send_again:
|
||||
} else
|
||||
goto empty_proc;
|
||||
} else if (dec_dpb_status == H264_DECODE_OVER_SIZE) {
|
||||
dpb_print(DECODE_ID(hw), 0,
|
||||
"vmh264 decode oversize !!\n");
|
||||
hw->data_flag |= ERROR_FLAG;
|
||||
hw->stat |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
|
||||
reset_process_time(hw);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
dpb_print(DECODE_ID(hw), 0,
|
||||
"vmh264 decode oversize !!\n");
|
||||
release_cur_decoding_buf(hw);
|
||||
hw->data_flag |= ERROR_FLAG;
|
||||
hw->stat |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
|
||||
reset_process_time(hw);
|
||||
hw->dec_result = DEC_RESULT_DONE;
|
||||
vdec_schedule_work(&hw->work);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (READ_VREG(AV_SCRATCH_G) == 1) {
|
||||
hw->sei_itu_data_len =
|
||||
@@ -3992,6 +4033,7 @@ static void timeout_process(struct vdec_h264_hw_s *hw)
|
||||
amvdec_stop();
|
||||
dpb_print(DECODE_ID(hw),
|
||||
PRINT_FLAG_ERROR, "%s decoder timeout\n", __func__);
|
||||
release_cur_decoding_buf(hw);
|
||||
hw->dec_result = DEC_RESULT_DONE;
|
||||
hw->data_flag |= ERROR_FLAG;
|
||||
reset_process_time(hw);
|
||||
@@ -4162,6 +4204,8 @@ static void check_timer_func(unsigned long arg)
|
||||
}
|
||||
if ((h264_debug_cmd & 0x200) != 0 &&
|
||||
DECODE_ID(hw) == (h264_debug_cmd & 0xff)) {
|
||||
pr_debug("vdec %d is forced to reset bufmgr\n",
|
||||
h264_debug_cmd & 0xff);
|
||||
hw->reset_bufmgr_flag = 1;
|
||||
h264_debug_cmd = 0;
|
||||
return;
|
||||
@@ -4204,16 +4248,16 @@ static void check_timer_func(unsigned long arg)
|
||||
} else
|
||||
start_process_time(hw);
|
||||
} else if (is_in_parsing_state(dpb_status)) {
|
||||
if (hw->last_ucode_watchdog_reg_val ==
|
||||
READ_VREG(UCODE_WATCHDOG_REG)) {
|
||||
if (hw->last_vld_level ==
|
||||
READ_VREG(VLD_MEM_VIFIFO_LEVEL)) {
|
||||
if (hw->decode_timeout_count > 0)
|
||||
hw->decode_timeout_count--;
|
||||
if (hw->decode_timeout_count == 0)
|
||||
timeout_process(hw);
|
||||
}
|
||||
}
|
||||
hw->last_ucode_watchdog_reg_val =
|
||||
READ_VREG(UCODE_WATCHDOG_REG);
|
||||
hw->last_vld_level =
|
||||
READ_VREG(VLD_MEM_VIFIFO_LEVEL);
|
||||
hw->last_mby_mbx = mby_mbx;
|
||||
}
|
||||
|
||||
@@ -4224,9 +4268,7 @@ static void check_timer_func(unsigned long arg)
|
||||
WRITE_VREG(DEBUG_REG1, 0);
|
||||
}
|
||||
|
||||
hw->check_timer.expires = jiffies + CHECK_INTERVAL;
|
||||
|
||||
add_timer(&hw->check_timer);
|
||||
mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
|
||||
}
|
||||
|
||||
static int dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
|
||||
@@ -4341,7 +4383,7 @@ static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw)
|
||||
|
||||
WRITE_VREG(FRAME_COUNTER_REG, hw->decode_pic_count);
|
||||
WRITE_VREG(AV_SCRATCH_8, hw->buf_offset);
|
||||
if (!tee_enabled())
|
||||
if (!is_secload_get())
|
||||
WRITE_VREG(AV_SCRATCH_G, hw->mc_dma_handle);
|
||||
|
||||
/* hw->error_recovery_mode = (error_recovery_mode != 0) ?
|
||||
@@ -4384,12 +4426,17 @@ static void vh264_local_init(struct vdec_h264_hw_s *hw)
|
||||
int i;
|
||||
hw->init_flag = 0;
|
||||
hw->eos = 0;
|
||||
hw->valve_count = 0;
|
||||
hw->config_bufmgr_done = 0;
|
||||
hw->start_process_time = 0;
|
||||
hw->has_i_frame = 0;
|
||||
hw->no_error_count = 0xfff;
|
||||
hw->no_error_i_count = 0xf;
|
||||
|
||||
hw->dec_flag = 0;
|
||||
hw->data_flag = 0;
|
||||
hw->skip_frame_count = 0;
|
||||
|
||||
hw->decode_timeout_count = 0;
|
||||
|
||||
hw->vh264_ratio = hw->vh264_amstream_dec_info.ratio;
|
||||
@@ -4494,7 +4541,7 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw)
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
if (tee_enabled() && !firmwareloaded) {
|
||||
if (is_secload_get() && !firmwareloaded) {
|
||||
pr_info("VMH264 start load sec firmware ...\n");
|
||||
if (tee_load_video_fw((u32)VIDEO_DEC_H264_MULTI)
|
||||
!= 0) {
|
||||
@@ -4570,6 +4617,8 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw)
|
||||
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
|
||||
"264 load orignal firmware error.\n");
|
||||
amvdec_disable();
|
||||
if (mmu_enable)
|
||||
amhevc_disable();
|
||||
if (hw->mc_cpu_addr) {
|
||||
dma_free_coherent(amports_get_dma_device(),
|
||||
MC_TOTAL_SIZE, hw->mc_cpu_addr,
|
||||
@@ -4965,6 +5014,16 @@ static bool run_ready(struct vdec_s *vdec)
|
||||
if (hw->eos)
|
||||
return 0;
|
||||
|
||||
if (disp_vframe_valve_level &&
|
||||
kfifo_len(&hw->display_q) >=
|
||||
disp_vframe_valve_level) {
|
||||
hw->valve_count--;
|
||||
if (hw->valve_count <= 0)
|
||||
hw->valve_count = 2;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (h264_debug_flag & 0x20000000) {
|
||||
/* pr_info("%s, a\n", __func__); */
|
||||
ret = 1;
|
||||
@@ -5093,7 +5152,8 @@ static void run(struct vdec_s *vdec,
|
||||
size);
|
||||
|
||||
start_process_time(hw);
|
||||
if (tee_enabled()) {
|
||||
|
||||
if (is_secload_get()) {
|
||||
if (tee_load_video_fw((u32)VIDEO_DEC_H264_MULTI)
|
||||
!= 0) {
|
||||
amvdec_enable_flag = false;
|
||||
@@ -5137,7 +5197,7 @@ static void run(struct vdec_s *vdec,
|
||||
WRITE_VREG(NAL_SEARCH_CTL, READ_VREG(NAL_SEARCH_CTL) | 0x2);
|
||||
if (udebug_flag)
|
||||
WRITE_VREG(AV_SCRATCH_K, udebug_flag);
|
||||
add_timer(&hw->check_timer);
|
||||
mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
|
||||
|
||||
amvdec_start();
|
||||
|
||||
@@ -5195,6 +5255,24 @@ static void h264_reconfig(struct vdec_h264_hw_s *hw)
|
||||
|
||||
}
|
||||
|
||||
#ifdef ERROR_HANDLE_TEST
|
||||
static void h264_clear_dpb(struct vdec_h264_hw_s *hw)
|
||||
{
|
||||
int i;
|
||||
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
|
||||
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
|
||||
"%s\n", __func__);
|
||||
remove_dpb_pictures(p_H264_Dpb);
|
||||
for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
|
||||
/*make sure buffers not put back to bufmgr when
|
||||
vf_put is called*/
|
||||
if (hw->buffer_spec[i].used == 2)
|
||||
hw->buffer_spec[i].used = 5;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw)
|
||||
{
|
||||
int i;
|
||||
@@ -5250,7 +5328,9 @@ static void h264_reset_bufmgr(struct vdec_h264_hw_s *hw)
|
||||
hw->has_i_frame = 0;
|
||||
#else
|
||||
dpb_print(DECODE_ID(hw), 0,
|
||||
"%s\n", __func__);
|
||||
"%s frame count %d to skip %d\n\n",
|
||||
__func__, hw->decode_pic_count+1,
|
||||
hw->skip_frame_count);
|
||||
|
||||
for (i = 0; i < VF_POOL_SIZE; i++)
|
||||
hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */
|
||||
@@ -5730,6 +5810,9 @@ module_param_array(max_get_frame_interval, uint,
|
||||
|
||||
module_param_array(step, uint, &max_decode_instance_num, 0664);
|
||||
|
||||
module_param(disp_vframe_valve_level, uint, 0664);
|
||||
MODULE_PARM_DESC(disp_vframe_valve_level, "\n disp_vframe_valve_level\n");
|
||||
|
||||
module_init(ammvdec_h264_driver_init_module);
|
||||
module_exit(ammvdec_h264_driver_remove_module);
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ static unsigned int clk_config;
|
||||
static int hevc_max_reset_count;
|
||||
#define MAX_INSTANCE_MUN 9
|
||||
|
||||
|
||||
static int no_powerdown;
|
||||
static DEFINE_SPINLOCK(vdec_spin_lock);
|
||||
|
||||
#define HEVC_TEST_LIMIT 100
|
||||
@@ -231,6 +231,20 @@ int vdec_set_isreset(struct vdec_s *vdec, int isreset)
|
||||
}
|
||||
EXPORT_SYMBOL(vdec_set_isreset);
|
||||
|
||||
int vdec_set_dv_metawithel(struct vdec_s *vdec, int isdvmetawithel)
|
||||
{
|
||||
vdec->dolby_meta_with_el = isdvmetawithel;
|
||||
pr_info("isdvmetawithel=%d\n", isdvmetawithel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vdec_set_no_powerdown(int flag)
|
||||
{
|
||||
no_powerdown = flag;
|
||||
pr_info("no_powerdown=%d\n", no_powerdown);
|
||||
return;
|
||||
}
|
||||
|
||||
void vdec_count_info(struct vdec_info *vs, unsigned int err,
|
||||
unsigned int offset)
|
||||
{
|
||||
@@ -1479,6 +1493,7 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k)
|
||||
}
|
||||
}
|
||||
|
||||
p->dolby_meta_with_el = 0;
|
||||
pr_debug("vdec_init, vf_provider_name = %s\n", p->vf_provider_name);
|
||||
vdec_input_prepare_bufs(/*prepared buffer for fast playing.*/
|
||||
&vdec->input,
|
||||
@@ -1714,7 +1729,8 @@ static inline bool vdec_ready_to_run(struct vdec_s *vdec)
|
||||
vdec->input.total_rd_count) < 2)) {
|
||||
vdec->need_more_data |= VDEC_NEED_MORE_DATA;
|
||||
return false;
|
||||
}
|
||||
} else if (level > input->prepare_level)
|
||||
vdec->need_more_data &= ~VDEC_NEED_MORE_DATA;
|
||||
}
|
||||
|
||||
if (step_mode) {
|
||||
@@ -2227,8 +2243,9 @@ void vdec_poweroff(enum vdec_type_e core)
|
||||
}
|
||||
} else if (core == VDEC_HEVC) {
|
||||
if (has_hevc_vdec()) {
|
||||
/* enable hevc isolation */
|
||||
WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
|
||||
if (no_powerdown == 0) {
|
||||
/* enable hevc isolation */
|
||||
WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
|
||||
READ_AOREG(AO_RTI_GEN_PWR_ISO0) |
|
||||
0xc00);
|
||||
/* power off hevc memories */
|
||||
@@ -2239,6 +2256,11 @@ void vdec_poweroff(enum vdec_type_e core)
|
||||
WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
|
||||
READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) |
|
||||
0xc0);
|
||||
} else {
|
||||
pr_info("!!!!!!!!not power down\n");
|
||||
hevc_reset_core(NULL);
|
||||
no_powerdown = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
mutex_unlock(&vdec_mutex);
|
||||
@@ -2386,7 +2408,7 @@ void hevc_reset_core(struct vdec_s *vdec)
|
||||
& (1 << 4)))
|
||||
;
|
||||
|
||||
if (input_frame_based(vdec))
|
||||
if (vdec == NULL || input_frame_based(vdec))
|
||||
WRITE_VREG(HEVC_STREAM_CONTROL, 0);
|
||||
|
||||
/*
|
||||
|
||||
@@ -194,6 +194,7 @@ struct vdec_s {
|
||||
char config[PAGE_SIZE];
|
||||
int config_len;
|
||||
bool is_reset;
|
||||
bool dolby_meta_with_el;
|
||||
|
||||
/* canvas */
|
||||
int (*get_canvas)(unsigned int index, unsigned int base);
|
||||
|
||||
Reference in New Issue
Block a user