From 1fb35a30c39f2a3b3089bf5f48831e75f1cf35ae Mon Sep 17 00:00:00 2001 From: Hui Zhang Date: Wed, 23 May 2018 18:22:19 +0800 Subject: [PATCH] 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 --- .../decoder/h264_multi/h264_dpb.c | 1 + .../decoder/h264_multi/h264_dpb.h | 3 + .../decoder/h264_multi/vmh264.c | 310 ++++++++++++++---- .../frame_provider/decoder/h265/vh265.c | 281 +++++++++++++--- .../frame_provider/decoder/utils/vdec.c | 28 +- .../frame_provider/decoder/utils/vdec.h | 3 + .../frame_provider/decoder/vp9/vvp9.c | 46 ++- firmware/video/video_ucode.bin | Bin 768768 -> 768768 bytes 8 files changed, 556 insertions(+), 116 deletions(-) mode change 100644 => 100755 firmware/video/video_ucode.bin 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 de23924f6546..3ec89d64509d 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 @@ -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 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 32f36d6c8fc4..dc3824f451a5 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 @@ -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 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 7ee7a7cda9f0..650d483a656f 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 @@ -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"); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c index 3f73b76030d5..ebf67817d166 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c @@ -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); 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 e5b889374aff..e7fb7514ea55 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c @@ -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); 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 21bb8ae48512..90158f300eae 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.h +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.h @@ -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); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c b/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c index cfca5817f7bc..bd249ac5e506 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c @@ -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); diff --git a/firmware/video/video_ucode.bin b/firmware/video/video_ucode.bin old mode 100644 new mode 100755 index e5cfacd945b4fd00525ba3737e2844265c9a40c0..24b752810f2856f26f21ff13edd52ae594ad8628 GIT binary patch delta 7028 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 U&&TRWNp2Nory5XJKG3h=|06g#NdN!<