From 5b104d75edc08d932f2614ffcf21c4ed3aeb3543 Mon Sep 17 00:00:00 2001 From: Nanxin Qin Date: Tue, 17 Oct 2017 14:17:48 +0800 Subject: [PATCH] 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 --- .../decoder/h264_multi/h264_dpb.c | 78 +++++++- .../decoder/h264_multi/h264_dpb.h | 18 +- .../decoder/h264_multi/vmh264.c | 175 +++++++++++++----- .../frame_provider/decoder/utils/vdec.c | 32 +++- .../frame_provider/decoder/utils/vdec.h | 1 + 5 files changed, 247 insertions(+), 57 deletions(-) diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.c index a18fa79cf7ee..11c3a6468add 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.c @@ -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; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.h b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.h index c76a26a43f85..4edb79108d17 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.h +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/h264_dpb.h @@ -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, diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c index eb4982cbfa64..04ccd480bb24 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c @@ -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); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c index 3fd7ef4d148a..dd5973115182 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c @@ -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); /* diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.h b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.h index 98c5f43aa2c2..b540ebf500b1 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.h +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.h @@ -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);