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:
Nanxin Qin
2017-10-17 14:17:48 +08:00
committed by Dongjin Kim
parent 72bb68f1f5
commit 5b104d75ed
5 changed files with 247 additions and 57 deletions

View File

@@ -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;

View File

@@ -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,

View File

@@ -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);

View File

@@ -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);
/*

View File

@@ -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);