116 files changed, 25845 insertions, 36303 deletions
diff --git a/drivers/frame_provider/decoder/h265/vh265.c b/drivers/frame_provider/decoder/h265/vh265.c index 8d4e0f3..53aeb10 100644 --- a/drivers/frame_provider/decoder/h265/vh265.c +++ b/drivers/frame_provider/decoder/h265/vh265.c @@ -49,6 +49,8 @@ #include "../utils/vdec_v4l2_buffer_ops.h" #include <media/v4l2-mem2mem.h> +#define HEVC_8K_LFTOFFSET_FIX + #define CONSTRAIN_MAX_BUF_NUM #define SWAP_HEVC_UCODE @@ -185,7 +187,7 @@ static int start_decode_buf_level = 0x8000; static unsigned int decode_timeout_val = 200; static u32 run_ready_min_buf_num = 2; - +static u32 disable_ip_mode; /*data_resend_policy: bit 0, stream base resend data when decoding buf empty */ @@ -473,8 +475,11 @@ static unsigned int force_disp_pic_index; static unsigned int disp_vframe_valve_level; static int pre_decode_buf_level = 0x1000; static unsigned int pic_list_debug; - - +#ifdef HEVC_8K_LFTOFFSET_FIX + /* performance_profile: bit 0, multi slice in ucode + */ +static unsigned int performance_profile = 1; +#endif #ifdef MULTI_INSTANCE_SUPPORT static unsigned int max_decode_instance_num = MAX_DECODE_INSTANCE_NUM; @@ -532,12 +537,13 @@ void WRITE_VREG_DBG(unsigned adr, unsigned val) #undef WRITE_VREG #define WRITE_VREG WRITE_VREG_DBG #endif +extern u32 trickmode_i; static DEFINE_MUTEX(vh265_mutex); static DEFINE_MUTEX(vh265_log_mutex); -static struct vdec_info *gvs; +//static struct vdec_info *gvs; static u32 without_display_mode; @@ -822,7 +828,7 @@ union param_u { unsigned short tiles_enabled_flag; unsigned short num_tile_columns_minus1; unsigned short num_tile_rows_minus1; - unsigned short tile_width[8]; + unsigned short tile_width[12]; unsigned short tile_height[8]; unsigned short misc_flag0; unsigned short pps_beta_offset_div2; @@ -1312,6 +1318,8 @@ struct BUF_s { u32 header_size; int used_flag; ulong v4l_ref_buf_addr; + ulong chroma_addr; + u32 chroma_size; } /*BUF_t */; /* level 6, 6.1 maximum slice number is 800; other is 200 */ @@ -1403,7 +1411,10 @@ struct PIC_s { int min_mv; int avg_mv; + u32 hw_decode_time; + u32 frame_size; // For frame base mode bool vframe_bound; + bool ip_mode; } /*PIC_t */; #define MAX_TILE_COL_NUM 10 @@ -1736,6 +1747,10 @@ struct hevc_state_s { void *v4l2_ctx; bool v4l_params_parsed; u32 mem_map_mode; + u32 performance_profile; + struct vdec_info *gvs; + unsigned int res_ch_flag; + bool ip_mode; } /*hevc_stru_t */; #ifdef AGAIN_HAS_THRESHOLD @@ -1947,6 +1962,31 @@ static int get_double_write_mode(struct hevc_state_s *hevc) return dw; } +static int v4l_parser_get_double_write_mode(struct hevc_state_s *hevc, int w, int h) +{ + u32 valid_dw_mode = get_valid_double_write_mode(hevc); + u32 dw = 0x1; /*1:1*/ + switch (valid_dw_mode) { + case 0x100: + if (w > 1920 && h > 1088) + dw = 0x4; /*1:2*/ + break; + case 0x200: + if (w > 1920 && h > 1088) + dw = 0x2; /*1:4*/ + break; + case 0x300: + if (w > 1280 && h > 720) + dw = 0x4; /*1:2*/ + break; + default: + dw = valid_dw_mode; + break; + } + return dw; +} + + static int get_double_write_ratio(struct hevc_state_s *hevc, int dw_mode) { @@ -3096,15 +3136,21 @@ static int v4l_alloc_buf(struct hevc_state_s *hevc, struct PIC_s *pic) pic->cma_alloc_addr = hevc->m_BUF[i].v4l_ref_buf_addr; if (fb->num_planes == 1) { hevc->m_BUF[i].start_adr = fb->m.mem[0].addr; - hevc->m_BUF[i].size = fb->m.mem[0].size; hevc->m_BUF[i].luma_size = fb->m.mem[0].offset; + hevc->m_BUF[i].size = fb->m.mem[0].size; fb->m.mem[0].bytes_used = fb->m.mem[0].size; + pic->dw_y_adr = hevc->m_BUF[i].start_adr; + pic->dw_u_v_adr = pic->dw_y_adr + hevc->m_BUF[i].luma_size; } else if (fb->num_planes == 2) { hevc->m_BUF[i].start_adr = fb->m.mem[0].addr; - hevc->m_BUF[i].size = fb->m.mem[0].size + fb->m.mem[1].size; hevc->m_BUF[i].luma_size = fb->m.mem[0].size; + hevc->m_BUF[i].chroma_addr = fb->m.mem[1].addr; + hevc->m_BUF[i].chroma_size = fb->m.mem[1].size; + hevc->m_BUF[i].size = fb->m.mem[0].size + fb->m.mem[1].size; fb->m.mem[0].bytes_used = fb->m.mem[0].size; fb->m.mem[1].bytes_used = fb->m.mem[1].size; + pic->dw_y_adr = hevc->m_BUF[i].start_adr; + pic->dw_u_v_adr = hevc->m_BUF[i].chroma_addr; } return ret; @@ -3297,11 +3343,68 @@ static int get_work_pic_num(struct hevc_state_s *hevc) used_buf_num += 1; } + if (hevc->is_used_v4l) { + /* for eos add more buffer to flush.*/ + used_buf_num++; + } + if (used_buf_num > MAX_BUF_NUM) used_buf_num = MAX_BUF_NUM; return used_buf_num; } +static int v4l_parser_work_pic_num(struct hevc_state_s *hevc) +{ + int used_buf_num = 0; + int sps_pic_buf_diff = 0; + pr_debug("margin = %d, sps_max_dec_pic_buffering_minus1_0 = %d, sps_num_reorder_pics_0 = %d\n", + get_dynamic_buf_num_margin(hevc), + hevc->param.p.sps_max_dec_pic_buffering_minus1_0, + hevc->param.p.sps_num_reorder_pics_0); + if (get_dynamic_buf_num_margin(hevc) > 0) { + if ((!hevc->param.p.sps_num_reorder_pics_0) && + (hevc->param.p.sps_max_dec_pic_buffering_minus1_0)) { + /* the range of sps_num_reorder_pics_0 is in + [0, sps_max_dec_pic_buffering_minus1_0] */ + used_buf_num = get_dynamic_buf_num_margin(hevc) + + hevc->param.p.sps_max_dec_pic_buffering_minus1_0; + } else + used_buf_num = hevc->param.p.sps_num_reorder_pics_0 + + get_dynamic_buf_num_margin(hevc); + + sps_pic_buf_diff = hevc->param.p.sps_max_dec_pic_buffering_minus1_0 + - hevc->param.p.sps_num_reorder_pics_0; +#ifdef MULTI_INSTANCE_SUPPORT + /* + need one more for multi instance, as + apply_ref_pic_set() has no chanch to run to + to clear referenced flag in some case + */ + if (hevc->m_ins_flag) + used_buf_num++; +#endif + } else + used_buf_num = max_buf_num; + + if (hevc->save_buffer_mode) + hevc_print(hevc, 0, + "save buf _mode : dynamic_buf_num_margin %d ----> %d \n", + dynamic_buf_num_margin, hevc->dynamic_buf_num_margin); + + if (sps_pic_buf_diff >= 4) + { + used_buf_num += 1; + } + + /* for eos add more buffer to flush.*/ + used_buf_num++; + + if (used_buf_num > MAX_BUF_NUM) + used_buf_num = MAX_BUF_NUM; + return used_buf_num; +} + + static int get_alloc_pic_count(struct hevc_state_s *hevc) { int alloc_pic_count = 0; @@ -3329,16 +3432,10 @@ static int v4l_config_pic(struct hevc_state_s *hevc, struct PIC_s *pic) pic->mc_canvas_u_v = pic->index; if (dw_mode & 0x10) { - pic->mc_y_adr = hevc->m_BUF[i].start_adr; - pic->mc_u_v_adr = pic->mc_y_adr + hevc->m_BUF[i].luma_size; pic->mc_canvas_y = (pic->index << 1); pic->mc_canvas_u_v = (pic->index << 1) + 1; - - pic->dw_y_adr = pic->mc_y_adr; - pic->dw_u_v_adr = pic->mc_u_v_adr; - } else if (dw_mode) { - pic->dw_y_adr = hevc->m_BUF[i].start_adr; - pic->dw_u_v_adr = pic->dw_y_adr + hevc->m_BUF[i].luma_size; + pic->mc_y_adr = pic->dw_y_adr; + pic->mc_u_v_adr = pic->dw_u_v_adr; } return 0; @@ -3493,30 +3590,6 @@ static void init_pic_list(struct hevc_state_s *hevc) set_canvas(hevc, pic); } } - - for (; i < MAX_REF_PIC_NUM; i++) { - struct PIC_s *pic = hevc->m_PIC[i]; - - if (!pic) { - pic = vmalloc(sizeof(struct PIC_s)); - if (pic == NULL) { - hevc_print(hevc, 0, - "%s: alloc pic %d fail!!!\n", - __func__, i); - break; - } - hevc->m_PIC[i] = pic; - } - memset(pic, 0, sizeof(struct PIC_s)); - - pic->index = -1; - pic->BUF_index = -1; - if (vdec->parallel_dec == 1) { - pic->y_canvas_index = -1; - pic->uv_canvas_index = -1; - } - } - } static void uninit_pic_list(struct hevc_state_s *hevc) @@ -3644,31 +3717,6 @@ static void init_pic_list_hw(struct hevc_state_s *hevc) } if (cur_pic_num == 0) return; - for (; i < MAX_REF_PIC_NUM; i++) { - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) { - if (hevc->mmu_enable && ((dw_mode & 0x10) == 0)) - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, - hevc->m_PIC[cur_pic_num-1]->header_adr>>5); - else - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, - hevc->m_PIC[cur_pic_num-1]->mc_y_adr >> 5); -#ifndef LOSLESS_COMPRESS_MODE - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, - hevc->m_PIC[cur_pic_num-1]->mc_u_v_adr >> 5); -#endif - } else { - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, - hevc->m_PIC[cur_pic_num-1]->mc_y_adr| - (hevc->m_PIC[cur_pic_num-1]->mc_canvas_y<<8) - | 0x1); -#ifndef LOSLESS_COMPRESS_MODE - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, - hevc->m_PIC[cur_pic_num-1]->mc_u_v_adr| - (hevc->m_PIC[cur_pic_num-1]->mc_canvas_u_v<<8) - | 0x1); -#endif - } - } WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1); @@ -3748,7 +3796,7 @@ static struct PIC_s *output_pic(struct hevc_state_s *hevc, unsigned char flush_flag) { int num_pic_not_yet_display = 0; - int i; + int i, fisrt_pic_flag = 0; struct PIC_s *pic; struct PIC_s *pic_display = NULL; struct vdec_s *vdec = hw_to_vdec(hevc); @@ -3796,6 +3844,7 @@ static struct PIC_s *output_pic(struct hevc_state_s *hevc, pic->num_reorder_pic = 0; if (vdec->master || vdec->slave) pic_display = pic; + fisrt_pic_flag = 1; hevc_print(hevc, 0, "VH265: output first frame\n"); } } @@ -3817,10 +3866,21 @@ static struct PIC_s *output_pic(struct hevc_state_s *hevc, decode_idx)) pic_display = pic; + } else pic_display = pic; + } } + /* dv wait cur_pic all data get, + some data may get after picture output */ + if ((vdec->master || vdec->slave) + && (pic_display == hevc->cur_pic) && + (!flush_flag) && + (hevc->bypass_dvenl && !dolby_meta_with_el) + && (!fisrt_pic_flag)) + pic_display = NULL; + if (pic_display) { if ((num_pic_not_yet_display > pic_display->num_reorder_pic) @@ -3841,7 +3901,8 @@ static struct PIC_s *output_pic(struct hevc_state_s *hevc, } } - if (pic_display && (hevc->vf_pre_count == 1) && (hevc->first_pic_flag == 1)) { + if (pic_display && hevc->sps_num_reorder_pics_0 && + (hevc->vf_pre_count == 1) && (hevc->first_pic_flag == 1)) { pic_display = NULL; hevc->first_pic_flag = 0; } @@ -4473,6 +4534,13 @@ static void hevc_config_work_space_hw(struct hevc_state_s *hevc) buf_spec->swap_buf.buf_start); WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start);*/ WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start); +#ifdef HEVC_8K_LFTOFFSET_FIX + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { + WRITE_VREG(HEVC_DBLK_CFG3, 0x808020); /*offset should x2 if 8k*/ + hevc_print(hevc, H265_DEBUG_BUFMGR_MORE, + "write HEVC_DBLK_CFG3\n"); + } +#endif /* cfg_p_addr */ WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start); /* cfg_d_addr */ @@ -5312,8 +5380,8 @@ static void config_sao_hw(struct hevc_state_s *hevc, union param_u *params) /* swap uv */ if (hevc->is_used_v4l) { - if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) || - (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M)) + if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21) || + (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21M)) data32 &= ~(1 << 8); /* NV21 */ else data32 |= (1 << 8); /* NV12 */ @@ -5355,8 +5423,8 @@ static void config_sao_hw(struct hevc_state_s *hevc, union param_u *params) /* swap uv */ if (hevc->is_used_v4l) { - if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) || - (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M)) + if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21) || + (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21M)) data32 |= (1 << 12); /* NV21 */ else data32 &= ~(1 << 12); /* NV12 */ @@ -5625,6 +5693,7 @@ static struct PIC_s *get_new_pic(struct hevc_state_s *hevc, new_pic->dis_mark = 0; /* new_pic->output_ready = 0; */ new_pic->num_reorder_pic = rpm_param->p.sps_num_reorder_pics_0; + new_pic->ip_mode = (!new_pic->num_reorder_pic && !disable_ip_mode) ? true : false; new_pic->losless_comp_body_size = hevc->losless_comp_body_size; new_pic->POC = hevc->curr_POC; new_pic->pic_struct = hevc->curr_pic_struct; @@ -5748,6 +5817,7 @@ static struct PIC_s *v4l_get_new_pic(struct hevc_state_s *hevc, new_pic->dis_mark = 0; /* new_pic->output_ready = 0; */ new_pic->num_reorder_pic = rpm_param->p.sps_num_reorder_pics_0; + new_pic->ip_mode = (!new_pic->num_reorder_pic && !disable_ip_mode) ? true : false; new_pic->losless_comp_body_size = hevc->losless_comp_body_size; new_pic->POC = hevc->curr_POC; new_pic->pic_struct = hevc->curr_pic_struct; @@ -5821,11 +5891,8 @@ static void flush_output(struct hevc_state_s *hevc, struct PIC_s *pic) hevc->ignore_bufmgr_error |= 0x2; } } - /**/ - if (pic->POC != INVALID_POC) { + if (pic->POC != INVALID_POC && !pic->ip_mode) pic->output_mark = 1; - pic->recon_mark = 1; - } pic->recon_mark = 1; } do { @@ -5851,6 +5918,14 @@ static void flush_output(struct hevc_state_s *hevc, struct PIC_s *pic) hevc_print_cont(hevc, 0, "Debug mode or error, recycle it\n"); } + /* + * Here the pic/frame error_mark is 1, + * and it won't be displayed, so increase + * the drop count + */ + hevc->gvs->drop_frame_count++; + /* error frame count also need increase */ + hevc->gvs->error_frame_count++; } else { if (hevc->i_only & 0x1 && pic_display->slice_type != 2) { @@ -5936,7 +6011,7 @@ static void set_aux_data(struct hevc_state_s *hevc, } } new_size = pic->aux_data_size + aux_count + heads_size; - new_buf = vmalloc(new_size); + new_buf = vzalloc(new_size); if (new_buf) { unsigned char valid_tag = 0; unsigned char *h = @@ -5945,10 +6020,13 @@ static void set_aux_data(struct hevc_state_s *hevc, unsigned char *p = h + 8; int len = 0; int padding_len = 0; - memcpy(new_buf, pic->aux_data_buf, pic->aux_data_size); - if (pic->aux_data_buf) + + if (pic->aux_data_buf) { + memcpy(new_buf, pic->aux_data_buf, pic->aux_data_size); vfree(pic->aux_data_buf); + } pic->aux_data_buf = new_buf; + for (i = 0; i < aux_count; i += 4) { int ii; unsigned char tag = aux_adr[i + 3] >> 8; @@ -6066,6 +6144,8 @@ static inline void hevc_pre_pic(struct hevc_state_s *hevc, pic = get_pic_by_POC(hevc, decoded_poc); if (pic && (pic->POC != INVALID_POC)) { + struct vdec_s *vdec = hw_to_vdec(hevc); + /*PB skip control */ if (pic->error_mark == 0 && hevc->PB_skip_mode == 1) { @@ -6110,10 +6190,14 @@ static inline void hevc_pre_pic(struct hevc_state_s *hevc, hevc->used_4k_num = -1; } } - - pic->output_mark = 1; + if (!pic->ip_mode) + pic->output_mark = 1; pic->recon_mark = 1; pic->dis_mark = 1; + if (vdec->mvfrm) { + pic->frame_size = vdec->mvfrm->frame_size; + pic->hw_decode_time = (u32)vdec->mvfrm->hw_decode_time; + } } do { pic_display = output_pic(hevc, 0); @@ -6139,6 +6223,14 @@ static inline void hevc_pre_pic(struct hevc_state_s *hevc, hevc_print_cont(hevc, 0, "Debug or err,recycle it\n"); } + /* + * Here the pic/frame error_mark is 1, + * and it won't be displayed, so increase + * the drop count + */ + hevc->gvs->drop_frame_count++; + /* error frame count also need increase */ + hevc->gvs->error_frame_count++; } else { if (hevc->i_only & 0x1 && pic_display-> @@ -6652,55 +6744,55 @@ static void get_picture_qos_info(struct hevc_state_s *hevc) #endif picture->min_mv = mv_lo; +#ifdef DEBUG_QOS /* {mvy_L0_max, mvy_L0_min} */ rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS hevc_print(hevc, 0, "[Picture %d Quality] MVY_L0 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + hevc_print(hevc, 0, "[Picture %d Quality] MVY_L0 MIN : %d\n", pic_number, mv_lo); -#endif + /* {mvx_L1_max, mvx_L1_min} */ rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS + hevc_print(hevc, 0, "[Picture %d Quality] MVX_L1 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + hevc_print(hevc, 0, "[Picture %d Quality] MVX_L1 MIN : %d\n", pic_number, mv_lo); -#endif + /* {mvy_L1_max, mvy_L1_min} */ rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS + hevc_print(hevc, 0, "[Picture %d Quality] MVY_L1 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + hevc_print(hevc, 0, "[Picture %d Quality] MVY_L1 MIN : %d\n", pic_number, mv_lo); #endif @@ -6728,10 +6820,16 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, int lcu_y_num_div; int Col_ref; int dbg_skip_flag = 0; + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hevc->v4l2_ctx); + + if (hevc->is_used_v4l && ctx->param_sets_from_ucode) + hevc->res_ch_flag = 0; if (hevc->wait_buf == 0) { hevc->sps_num_reorder_pics_0 = rpm_param->p.sps_num_reorder_pics_0; + hevc->ip_mode = (!hevc->sps_num_reorder_pics_0 && !disable_ip_mode) ? true : false; hevc->m_temporalId = rpm_param->p.m_temporalId; hevc->m_nalUnitType = rpm_param->p.m_nalUnitType; hevc->interlace_flag = @@ -6743,7 +6841,8 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, (rpm_param->p.sei_frame_field_info >> 8) & 0x1; } - if (interlace_enable == 0 || hevc->m_ins_flag) + /* if (interlace_enable == 0 || hevc->m_ins_flag) */ + if (interlace_enable == 0) hevc->interlace_flag = 0; if (interlace_enable & 0x100) hevc->interlace_flag = interlace_enable & 0x1; @@ -7299,11 +7398,11 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, if (hevc->cur_pic->error_mark && ((hevc->ignore_bufmgr_error & 0x1) == 0)) { -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC /*count info*/ - vdec_count_info(gvs, hevc->cur_pic->error_mark, + vdec_count_info(hevc->gvs, hevc->cur_pic->error_mark, hevc->cur_pic->stream_offset); -#endif + if (hevc->PB_skip_mode == 2) + hevc->gvs->drop_frame_count++; } if (is_skip_decoding(hevc, @@ -7331,11 +7430,11 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, hevc_print(hevc, 0, "Discard this picture index %d\n", hevc->cur_pic->index); -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC /*count info*/ - vdec_count_info(gvs, hevc->cur_pic->error_mark, + vdec_count_info(hevc->gvs, hevc->cur_pic->error_mark, hevc->cur_pic->stream_offset); -#endif + if (hevc->PB_skip_mode == 2) + hevc->gvs->drop_frame_count++; return 2; } #ifdef MCRCC_ENABLE @@ -7363,7 +7462,7 @@ static int H265_alloc_mmu(struct hevc_state_s *hevc, struct PIC_s *new_pic, picture_size = compute_losless_comp_body_size(hevc, new_pic->width, new_pic->height, !bit_depth_10); cur_mmu_4k_number = ((picture_size+(1<<12)-1) >> 12); - if (hevc->double_write_mode & 0x10) + if (get_double_write_mode(hevc) == 0x10) return 0; /*hevc_print(hevc, 0, "alloc_mmu cur_idx : %d picture_size : %d mmu_4k_number : %d\r\n", @@ -7471,8 +7570,7 @@ static void hevc_local_uninit(struct hevc_state_s *hevc) hevc->frame_mmu_map_addr = NULL; } - kfree(gvs); - gvs = NULL; + //pr_err("[%s line %d] hevc->gvs=0x%p operation\n",__func__, __LINE__, hevc->gvs); } static int hevc_local_init(struct hevc_state_s *hevc) @@ -7928,6 +8026,7 @@ static void set_frame_info(struct hevc_state_s *hevc, struct vframe_s *vf, pic->height), DISP_RATIO_ASPECT_RATIO_MAX); vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT); + vf->ratio_control <<= hevc->interlace_flag; } hevc->ratio_control = vf->ratio_control; if (pic->aux_data_buf @@ -8221,6 +8320,8 @@ static void vh265_vf_put(struct vframe_s *vf, void *op_arg) return; if (vf == (&hevc->vframe_dummy)) return; + if (!vf) + return; index_top = vf->index & 0xff; index_bot = (vf->index >> 8) & 0xff; if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) @@ -8517,7 +8618,10 @@ static void fill_frame_info(struct hevc_state_s *hevc, /* #define SHOW_QOS_INFO */ - vframe_qos->size = framesize; + if (input_frame_based(hw_to_vdec(hevc))) + vframe_qos->size = pic->frame_size; + else + vframe_qos->size = framesize; vframe_qos->pts = pts; #ifdef SHOW_QOS_INFO hevc_print(hevc, 0, "slice:%d, poc:%d\n", pic->slice_type, pic->POC); @@ -8556,19 +8660,44 @@ static void fill_frame_info(struct hevc_state_s *hevc, vframe_qos->num++; - if (hevc->frameinfo_enable) - vdec_fill_frame_info(vframe_qos, 1); +} + +static inline void hevc_update_gvs(struct hevc_state_s *hevc) +{ + if (hevc->gvs->frame_height != hevc->frame_height) { + hevc->gvs->frame_width = hevc->frame_width; + hevc->gvs->frame_height = hevc->frame_height; + } + if (hevc->gvs->frame_dur != hevc->frame_dur) { + hevc->gvs->frame_dur = hevc->frame_dur; + if (hevc->frame_dur != 0) + hevc->gvs->frame_rate = 96000 / hevc->frame_dur; + else + hevc->gvs->frame_rate = -1; + } + hevc->gvs->error_count = hevc->gvs->error_frame_count; + hevc->gvs->status = hevc->stat | hevc->fatal_error; + if (hevc->gvs->ratio_control != hevc->ratio_control) + hevc->gvs->ratio_control = hevc->ratio_control; } static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) { -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION struct vdec_s *vdec = hw_to_vdec(hevc); -#endif struct vframe_s *vf = NULL; int stream_offset = pic->stream_offset; unsigned short slice_type = pic->slice_type; - u32 frame_size; + ulong nv_order = VIDTYPE_VIU_NV21; + u32 frame_size = 0; + struct vdec_info tmp4x; + struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx; + + /* swap uv */ + if (hevc->is_used_v4l) { + if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || + (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M)) + nv_order = VIDTYPE_VIU_NV12; + } if (force_disp_pic_index & 0x100) { /*recycle directly*/ @@ -8598,7 +8727,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) } #ifdef MULTI_INSTANCE_SUPPORT - if (vdec_frame_based(hw_to_vdec(hevc))) { + if (vdec_frame_based(vdec)) { vf->pts = pic->pts; vf->pts_us64 = pic->pts64; vf->timestamp = pic->timestamp; @@ -8728,7 +8857,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) } if (pic->double_write_mode) { vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - vf->type |= VIDTYPE_VIU_NV21; + vf->type |= nv_order; if ((pic->double_write_mode == 3) && (!(IS_8K_SIZE(pic->width, pic->height)))) { @@ -8794,7 +8923,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) vf->bitdepth |= BITDEPTH_SAVING_MODE; #else vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - vf->type |= VIDTYPE_VIU_NV21; + vf->type |= nv_order; vf->canvas0Addr = vf->canvas1Addr = spec2canvas(pic); #endif set_frame_info(hevc, vf, pic); @@ -8895,17 +9024,17 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) if (pic->pic_struct == 3) { vf->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; + | nv_order; vf2->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; + | nv_order; } else { vf->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; + | nv_order; vf2->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; + | nv_order; } hevc->vf_pre_count++; - decoder_do_frame_check(hw_to_vdec(hevc), vf); + decoder_do_frame_check(vdec, vf); kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -8940,21 +9069,21 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) if (pic->pic_struct == 5) { vf->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; + | nv_order; vf2->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; + | nv_order; vf3->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; + | nv_order; } else { vf->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; + | nv_order; vf2->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; + | nv_order; vf3->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; + | nv_order; } hevc->vf_pre_count++; - decoder_do_frame_check(hw_to_vdec(hevc), vf); + decoder_do_frame_check(vdec, vf); kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -8980,19 +9109,19 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) process_pending_vframe(hevc, pic, (pic->pic_struct == 9)); - decoder_do_frame_check(hw_to_vdec(hevc), vf); + decoder_do_frame_check(vdec, vf); /* process current vf */ kfifo_put(&hevc->pending_q, (const struct vframe_s *)vf); vf->height <<= 1; if (pic->pic_struct == 9) { vf->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; + | nv_order | VIDTYPE_VIU_FIELD; process_pending_vframe(hevc, hevc->pre_bot_pic, 0); } else { vf->type = VIDTYPE_INTERLACE_BOTTOM | - VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; + nv_order | VIDTYPE_VIU_FIELD; vf->index = (pic->index << 8) | 0xff; process_pending_vframe(hevc, hevc->pre_top_pic, 1); @@ -9023,13 +9152,13 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) vf->height <<= 1; if (pic->pic_struct == 11) vf->type = VIDTYPE_INTERLACE_TOP | - VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; + nv_order | VIDTYPE_VIU_FIELD; else { vf->type = VIDTYPE_INTERLACE_BOTTOM | - VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; + nv_order | VIDTYPE_VIU_FIELD; vf->index = (pic->index << 8) | 0xff; } - decoder_do_frame_check(hw_to_vdec(hevc), vf); + decoder_do_frame_check(vdec, vf); kfifo_put(&hevc->pending_q, (const struct vframe_s *)vf); if (hevc->vf_pre_count == 0) @@ -9060,21 +9189,21 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) case 1: vf->height <<= 1; vf->type = VIDTYPE_INTERLACE_TOP | - VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; + nv_order | VIDTYPE_VIU_FIELD; process_pending_vframe(hevc, pic, 1); hevc->pre_top_pic = pic; break; case 2: vf->height <<= 1; vf->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21 + | nv_order | VIDTYPE_VIU_FIELD; process_pending_vframe(hevc, pic, 0); hevc->pre_bot_pic = pic; break; } hevc->vf_pre_count++; - decoder_do_frame_check(hw_to_vdec(hevc), vf); + decoder_do_frame_check(vdec, vf); kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -9083,23 +9212,26 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) vf->type_original = vf->type; pic->vf_ref = 1; hevc->vf_pre_count++; - decoder_do_frame_check(hw_to_vdec(hevc), vf); + decoder_do_frame_check(vdec, vf); kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); - - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "%s(type %d index 0x%x poc %d/%d) pts(%d,%d) dur %d\n", - __func__, vf->type, vf->index, - get_pic_poc(hevc, vf->index & 0xff), - get_pic_poc(hevc, (vf->index >> 8) & 0xff), - vf->pts, vf->pts_us64, - vf->duration); #endif -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC /*count info*/ - vdec_count_info(gvs, 0, stream_offset); -#endif + vdec_count_info(hevc->gvs, 0, stream_offset); + hevc_update_gvs(hevc); + memcpy(&tmp4x, hevc->gvs, sizeof(struct vdec_info)); + tmp4x.bit_depth_luma = hevc->bit_depth_luma; + tmp4x.bit_depth_chroma = hevc->bit_depth_chroma; + tmp4x.double_write_mode = get_double_write_mode(hevc); + vdec_fill_vdec_frame(vdec, &hevc->vframe_qos, &tmp4x, vf, pic->hw_decode_time); + vdec->vdec_fps_detec(vdec->id); + hevc_print(hevc, H265_DEBUG_BUFMGR, + "%s(type %d index 0x%x poc %d/%d) pts(%d,%d) dur %d\n", + __func__, vf->type, vf->index, + get_pic_poc(hevc, vf->index & 0xff), + get_pic_poc(hevc, (vf->index >> 8) & 0xff), + vf->pts, vf->pts_us64, + vf->duration); hw_to_vdec(hevc)->vdec_fps_detec(hw_to_vdec(hevc)->id); if (without_display_mode == 0) { vf_notify_receiver(hevc->provider_name, @@ -9485,6 +9617,59 @@ static void read_decode_info(struct hevc_state_s *hevc) hevc->rps_set_id = (decode_info >> 8) & 0xff; } +static int vh265_get_ps_info(struct hevc_state_s *hevc, int width, int height, struct aml_vdec_ps_infos *ps) +{ + int dw_mode = v4l_parser_get_double_write_mode(hevc, width, height); + + ps->visible_width = width / get_double_write_ratio(hevc, dw_mode); + ps->visible_height = height / get_double_write_ratio(hevc, dw_mode); + ps->coded_width = ALIGN(width, 32) / get_double_write_ratio(hevc, dw_mode); + ps->coded_height = ALIGN(height, 32) / get_double_write_ratio(hevc, dw_mode); + ps->dpb_size = v4l_parser_work_pic_num(hevc); + + return 0; +} + +static int v4l_res_change(struct hevc_state_s *hevc, union param_u *rpm_param) +{ + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hevc->v4l2_ctx); + int ret = 0; + + if (ctx->param_sets_from_ucode && + hevc->res_ch_flag == 0) { + struct aml_vdec_ps_infos ps; + int width = rpm_param->p.pic_width_in_luma_samples; + int height = rpm_param->p.pic_height_in_luma_samples; + if ((hevc->pic_w != 0 && + hevc->pic_h != 0) && + (hevc->pic_w != width || + hevc->pic_h != height)) { + hevc_print(hevc, 0, + "v4l_res_change Pic Width/Height Change (%d,%d)=>(%d,%d), interlace %d\n", + hevc->pic_w, hevc->pic_h, + width, + height, + hevc->interlace_flag); + + vh265_get_ps_info(hevc, width, height, &ps); + vdec_v4l_set_ps_infos(ctx, &ps); + vdec_v4l_res_ch_event(ctx); + hevc->v4l_params_parsed = false; + hevc->res_ch_flag = 1; + hevc->eos = 1; + flush_output(hevc, NULL); + //del_timer_sync(&hevc->timer); + notify_v4l_eos(hw_to_vdec(hevc)); + + ret = 1; + } + } + + return ret; +} + + static irqreturn_t vh265_isr_thread_fn(int irq, void *data) { struct hevc_state_s *hevc = (struct hevc_state_s *) data; @@ -9662,6 +9847,10 @@ static irqreturn_t vh265_isr_thread_fn(int irq, void *data) struct PIC_s *pic; struct PIC_s *pic_display; int decoded_poc; + + if (vdec->mvfrm) + vdec->mvfrm->hw_decode_time = + local_clock() - vdec->mvfrm->hw_decode_start; #ifdef DETREFILL_ENABLE if (hevc->is_swap && get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM) { @@ -9707,7 +9896,7 @@ pic_done: reset_process_time(hevc); - if (hevc->vf_pre_count == 0) { + if (hevc->vf_pre_count == 0 || hevc->ip_mode) { decoded_poc = hevc->curr_POC; pic = get_pic_by_POC(hevc, decoded_poc); if (pic && (pic->POC != INVALID_POC)) { @@ -9757,6 +9946,12 @@ pic_done: pic->output_mark = 1; pic->recon_mark = 1; + if (vdec->mvfrm) { + pic->frame_size = + vdec->mvfrm->frame_size; + pic->hw_decode_time = + (u32)vdec->mvfrm->hw_decode_time; + } } check_pic_decoded_error(hevc, READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff); @@ -9788,8 +9983,8 @@ force_output: "Debug or err,recycle it\n"); } } else { - if (pic_display-> - slice_type != 2) { + if ((pic_display-> + slice_type != 2) && !pic_display->ip_mode) { pic_display->output_ready = 0; } else { prepare_display_buf @@ -10156,20 +10351,33 @@ force_output: if (hevc->is_used_v4l) { struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hevc->v4l2_ctx); + if (!v4l_res_change(hevc, &hevc->param)) { + if (ctx->param_sets_from_ucode && !hevc->v4l_params_parsed) { + struct aml_vdec_ps_infos ps; + int width = hevc->param.p.pic_width_in_luma_samples; + int height = hevc->param.p.pic_height_in_luma_samples; + + pr_debug("set ucode parse\n"); + vh265_get_ps_info(hevc, width, height, &ps); + /*notice the v4l2 codec.*/ + vdec_v4l_set_ps_infos(ctx, &ps); + hevc->v4l_params_parsed = true; + hevc->dec_result = DEC_RESULT_AGAIN; + amhevc_stop(); + restore_decode_state(hevc); + reset_process_time(hevc); + vdec_schedule_work(&hevc->work); + return IRQ_HANDLED; + } + }else { + pr_debug("resolution change\n"); + hevc->dec_result = DEC_RESULT_AGAIN; + amhevc_stop(); + restore_decode_state(hevc); + reset_process_time(hevc); + vdec_schedule_work(&hevc->work); + return IRQ_HANDLED; - if (ctx->param_sets_from_ucode && !hevc->v4l_params_parsed) { - struct aml_vdec_ps_infos ps; - - hevc->frame_width = hevc->param.p.pic_width_in_luma_samples; - hevc->frame_height = hevc->param.p.pic_height_in_luma_samples; - ps.visible_width = hevc->frame_width; - ps.visible_height = hevc->frame_height; - ps.coded_width = ALIGN(hevc->frame_width, 32); - ps.coded_height = ALIGN(hevc->frame_height, 32); - ps.dpb_size = get_work_pic_num(hevc); - hevc->v4l_params_parsed = true; - /*notice the v4l2 codec.*/ - vdec_v4l_set_ps_infos(ctx, &ps); } } @@ -10236,9 +10444,7 @@ force_output: &hevc->notify_work); hevc->get_frame_dur = true; -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC - gvs->frame_dur = hevc->frame_dur; -#endif + //hevc->gvs->frame_dur = hevc->frame_dur; } if (hevc->video_signal_type != @@ -10285,6 +10491,11 @@ force_output: hevc->pic_h = hevc->param.p.pic_height_in_luma_samples; hevc->lcu_size = 1 << (log + 3 + log_s); hevc->lcu_size_log2 = log2i(hevc->lcu_size); + if (performance_profile &&( (!is_oversize(hevc->pic_w, hevc->pic_h)) && IS_8K_SIZE(hevc->pic_w,hevc->pic_h))) + hevc->performance_profile = 1; + else + hevc->performance_profile = 0; + hevc_print(hevc, 0, "hevc->performance_profile %d\n", hevc->performance_profile); if (hevc->pic_w == 0 || hevc->pic_h == 0 || hevc->lcu_size == 0 || is_oversize(hevc->pic_w, hevc->pic_h) @@ -10307,7 +10518,19 @@ force_output: } else { hevc->sps_num_reorder_pics_0 = hevc->param.p.sps_num_reorder_pics_0; + hevc->ip_mode = (!hevc->sps_num_reorder_pics_0 && !disable_ip_mode) ? true : false; hevc->pic_list_init_flag = 1; + if ((!IS_4K_SIZE(hevc->pic_w, hevc->pic_h)) && + ((hevc->param.p.profile_etc & 0xc) == 0x4) + && (interlace_enable != 0)) { + hevc->double_write_mode = 1; + hevc->interlace_flag = 1; + hevc->frame_ar = (hevc->pic_h * 0x100 / hevc->pic_w) * 2; + hevc_print(hevc, 0, + "interlace (%d, %d), profile_etc %x, ar 0x%x, dw %d\n", + hevc->pic_w, hevc->pic_h, hevc->param.p.profile_etc, hevc->frame_ar, + get_double_write_mode(hevc)); + } #ifdef MULTI_INSTANCE_SUPPORT if (hevc->m_ins_flag) { vdec_schedule_work(&hevc->work); @@ -10379,9 +10602,7 @@ force_output: #endif } else { /* skip, search next start code */ -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC - gvs->drop_frame_count++; -#endif + hevc->gvs->drop_frame_count++; WRITE_VREG(HEVC_WAIT_FLAG, READ_VREG(HEVC_WAIT_FLAG) & (~0x2)); hevc->skip_flag = 1; WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); @@ -10550,7 +10771,8 @@ static void vh265_check_timer_func(unsigned long arg) (get_dbg_flag(hevc) & H265_DEBUG_WAIT_DECODE_DONE_WHEN_STOP) == 0 && hw_to_vdec(hevc)->next_status == - VDEC_STATUS_DISCONNECTED) { + VDEC_STATUS_DISCONNECTED && + !hevc->is_used_v4l) { hevc->dec_result = DEC_RESULT_FORCE_EXIT; vdec_schedule_work(&hevc->work); hevc_print(hevc, @@ -10559,9 +10781,7 @@ static void vh265_check_timer_func(unsigned long arg) } if (hevc->m_ins_flag) { - if ((input_frame_based(hw_to_vdec(hevc)) || - (READ_VREG(HEVC_STREAM_LEVEL) > 0xb0)) && - ((get_dbg_flag(hevc) & + if (((get_dbg_flag(hevc) & H265_DEBUG_DIS_LOC_ERROR_PROC) == 0) && (decode_timeout_val > 0) && (hevc->start_process_time > 0) && @@ -10825,30 +11045,30 @@ int vh265_dec_status(struct vdec_info *vstatus) return -1; vstatus->frame_width = hevc->frame_width; - vstatus->frame_height = hevc->frame_height; + /* for hevc interlace for disp height x2 */ + vstatus->frame_height = + (hevc->frame_height << hevc->interlace_flag); if (hevc->frame_dur != 0) vstatus->frame_rate = 96000 / hevc->frame_dur; else vstatus->frame_rate = -1; - vstatus->error_count = 0; + vstatus->error_count = hevc->gvs->error_frame_count; vstatus->status = hevc->stat | hevc->fatal_error; -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC - vstatus->bit_rate = gvs->bit_rate; + vstatus->bit_rate = hevc->gvs->bit_rate; vstatus->frame_dur = hevc->frame_dur; - if (gvs) { - vstatus->bit_rate = gvs->bit_rate; - vstatus->frame_data = gvs->frame_data; - vstatus->total_data = gvs->total_data; - vstatus->frame_count = gvs->frame_count; - vstatus->error_frame_count = gvs->error_frame_count; - vstatus->drop_frame_count = gvs->drop_frame_count; - vstatus->total_data = gvs->total_data; - vstatus->samp_cnt = gvs->samp_cnt; - vstatus->offset = gvs->offset; + if (hevc->gvs) { + vstatus->bit_rate = hevc->gvs->bit_rate; + vstatus->frame_data = hevc->gvs->frame_data; + vstatus->total_data = hevc->gvs->total_data; + vstatus->frame_count = hevc->gvs->frame_count; + vstatus->error_frame_count = hevc->gvs->error_frame_count; + vstatus->drop_frame_count = hevc->gvs->drop_frame_count; + vstatus->samp_cnt = hevc->gvs->samp_cnt; + vstatus->offset = hevc->gvs->offset; } + snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name), "%s", DRIVER_NAME); -#endif vstatus->ratio_control = hevc->ratio_control; return 0; } @@ -10859,13 +11079,15 @@ int vh265_set_isreset(struct vdec_s *vdec, int isreset) return 0; } -static int vh265_vdec_info_init(void) +static int vh265_vdec_info_init(struct hevc_state_s *hevc) { - gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL); - if (NULL == gvs) { + hevc->gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL); + //pr_err("[%s line %d] hevc->gvs=0x%p operation\n",__func__, __LINE__, hevc->gvs); + if (NULL == hevc->gvs) { pr_info("the struct of vdec status malloc failed.\n"); return -ENOMEM; } + vdec_set_vframe_comm(hw_to_vdec(hevc), DRIVER_NAME); return 0; } @@ -10890,12 +11112,43 @@ static void H265_DECODE_INIT(void) } #endif +int vh265_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) +{ + struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; + hevc_print(hevc, 0, "[%s %d] trickmode:%lu\n", __func__, __LINE__, trickmode); + + if (trickmode == TRICKMODE_I) { + trickmode_i = 1; + i_only_flag = 0x1; + } else if (trickmode == TRICKMODE_NONE) { + trickmode_i = 0; + i_only_flag = 0x0; + } else if (trickmode == 0x02) { + trickmode_i = 0; + i_only_flag = 0x02; + } else if (trickmode == 0x03) { + trickmode_i = 1; + i_only_flag = 0x03; + } else if (trickmode == 0x07) { + trickmode_i = 1; + i_only_flag = 0x07; + } + //hevc_print(hevc, 0, "i_only_flag: %d trickmode_i:%d\n", i_only_flag, trickmode_i); + + return 0; +} + static void config_decode_mode(struct hevc_state_s *hevc) { #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION struct vdec_s *vdec = hw_to_vdec(hevc); #endif unsigned decode_mode; +#ifdef HEVC_8K_LFTOFFSET_FIX + if (hevc->performance_profile) + WRITE_VREG(NAL_SEARCH_CTL, + READ_VREG(NAL_SEARCH_CTL) | (1 << 21)); +#endif if (!hevc->m_ins_flag) decode_mode = DECODE_MODE_SINGLE; else if (vdec_frame_based(hw_to_vdec(hevc))) @@ -11050,9 +11303,7 @@ static int vh265_local_init(struct hevc_state_s *hevc) hevc->frame_dur = (hevc->vh265_amstream_dec_info.rate == 0) ? 3600 : hevc->vh265_amstream_dec_info.rate; -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC - gvs->frame_dur = hevc->frame_dur; -#endif + //hevc->gvs->frame_dur = hevc->frame_dur; if (hevc->frame_width && hevc->frame_height) hevc->frame_ar = hevc->frame_height * 0x100 / hevc->frame_width; @@ -11193,6 +11444,7 @@ static s32 vh265_init(struct hevc_state_s *hevc) hevc->timer.expires = jiffies + PUT_INTERVAL; hevc->fw = fw; + hevc->init_flag = 1; return 0; } @@ -11427,8 +11679,10 @@ static int vh265_stop(struct hevc_state_s *hevc) uninit_mmu_buffers(hevc); amhevc_disable(); - kfree(gvs); - gvs = NULL; + //pr_err("[%s line %d] hevc->gvs=0x%p operation\n",__func__, __LINE__, hevc->gvs); + if (hevc->gvs) + kfree(hevc->gvs); + hevc->gvs = NULL; return 0; } @@ -11626,13 +11880,9 @@ static int vmh265_stop(struct hevc_state_s *hevc) hevc_local_uninit(hevc); - hevc->init_flag = 0; - hevc->first_sc_checked = 0; - cancel_work_sync(&hevc->notify_work); - cancel_work_sync(&hevc->set_clk_work); - cancel_work_sync(&hevc->timeout_work); - - uninit_mmu_buffers(hevc); + if (hevc->gvs) + kfree(hevc->gvs); + hevc->gvs = NULL; if (use_cma) { hevc->uninit_list = 1; @@ -11649,7 +11899,13 @@ static int vmh265_stop(struct hevc_state_s *hevc) msleep(20); #endif } + hevc->init_flag = 0; + hevc->first_sc_checked = 0; + cancel_work_sync(&hevc->notify_work); + cancel_work_sync(&hevc->set_clk_work); + cancel_work_sync(&hevc->timeout_work); cancel_work_sync(&hevc->work); + uninit_mmu_buffers(hevc); vfree(hevc->fw); hevc->fw = NULL; @@ -11720,7 +11976,6 @@ static void vh265_work_implement(struct hevc_state_s *hevc, if (hevc->dec_result == DEC_RESULT_FREE_CANVAS) { /*USE_BUF_BLOCK*/ uninit_pic_list(hevc); - hevc_print(hevc, 0, "uninit list\n"); hevc->uninit_list = 0; #ifdef USE_UNINIT_SEMA up(&hevc->h265_uninit_done_sema); @@ -12263,10 +12518,18 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hevc->v4l2_ctx); - if (ctx->param_sets_from_ucode && - !ctx->v4l_codec_ready && - hevc->v4l_params_parsed) { - ret = 0; /*the params has parsed.*/ + if (ctx->param_sets_from_ucode) { + if (hevc->v4l_params_parsed) { + if (!ctx->v4l_codec_dpb_ready && + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < + run_ready_min_buf_num) + ret = 0; + } else { + if ((hevc->res_ch_flag == 1) && + ((ctx->state <= AML_STATE_INIT) || + (ctx->state >= AML_STATE_FLUSHING))) + ret = 0; + } } else if (!ctx->v4l_codec_dpb_ready) { if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < run_ready_min_buf_num) @@ -12435,6 +12698,8 @@ static void run(struct vdec_s *vdec, unsigned long mask, r = hevc->chunk->size + (hevc->chunk->offset & (VDEC_FIFO_ALIGN - 1)); hevc->decode_size = r; + if (vdec->mvfrm) + vdec->mvfrm->frame_size = hevc->chunk->size; } #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION else { @@ -12456,6 +12721,8 @@ static void run(struct vdec_s *vdec, unsigned long mask, mod_timer(&hevc->timer, jiffies); hevc->stat |= STAT_TIMER_ARM; hevc->stat |= STAT_ISR_REG; + if (vdec->mvfrm) + vdec->mvfrm->hw_decode_start = local_clock(); amhevc_start(); hevc->stat |= STAT_VDEC_RUN; } @@ -12497,7 +12764,6 @@ static void reset(struct vdec_s *vdec) } hevc->dec_result = DEC_RESULT_NONE; reset_process_time(hevc); - hevc->init_flag = 0; hevc->pic_list_init_flag = 0; dealloc_mv_bufs(hevc); aml_free_canvas(vdec); @@ -12646,11 +12912,12 @@ static int amvdec_h265_probe(struct platform_device *pdev) workaround_enable &= ~3; #endif hevc->cma_dev = pdata->cma_dev; - vh265_vdec_info_init(); + vh265_vdec_info_init(hevc); #ifdef MULTI_INSTANCE_SUPPORT pdata->private = hevc; pdata->dec_status = vh265_dec_status; + pdata->set_trickmode = vh265_set_trickmode; pdata->set_isreset = vh265_set_isreset; is_reset = 0; if (vh265_init(pdata) < 0) { @@ -12660,6 +12927,9 @@ static int amvdec_h265_probe(struct platform_device *pdev) hevc_print(hevc, 0, "\namvdec_h265 init failed.\n"); hevc_local_uninit(hevc); + if (hevc->gvs) + kfree(hevc->gvs); + hevc->gvs = NULL; uninit_mmu_buffers(hevc); vfree(hevc); pdata->dec_status = NULL; @@ -12742,10 +13012,11 @@ static void vh265_dump_state(struct vdec_s *vdec) "====== %s\n", __func__); hevc_print(hevc, 0, - "width/height (%d/%d), reorder_pic_num %d buf count(bufspec size) %d, video_signal_type 0x%x, is_swap %d\n", + "width/height (%d/%d), reorder_pic_num %d ip_mode %d buf count(bufspec size) %d, video_signal_type 0x%x, is_swap %d\n", hevc->frame_width, hevc->frame_height, hevc->sps_num_reorder_pics_0, + hevc->ip_mode, get_work_pic_num(hevc), hevc->video_signal_type_debug, hevc->is_swap @@ -12901,6 +13172,7 @@ static int ammvdec_h265_probe(struct platform_device *pdev) #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC int config_val; #endif + //pr_err("[%s pid=%d tgid=%d] \n",__func__, current->pid, current->tgid); if (pdata == NULL) { pr_info("\nammvdec_h265 memory resource undefined.\n"); return -EFAULT; @@ -12920,7 +13192,7 @@ static int ammvdec_h265_probe(struct platform_device *pdev) pdata->private = hevc; pdata->dec_status = vh265_dec_status; - /* pdata->set_trickmode = set_trickmode; */ + pdata->set_trickmode = vh265_set_trickmode; pdata->run_ready = run_ready; pdata->run = run; pdata->reset = reset; @@ -13028,6 +13300,9 @@ static int ammvdec_h265_probe(struct platform_device *pdev) } hevc->double_write_mode = double_write_mode; } + /* get valid double write from configure or node */ + hevc->double_write_mode = get_double_write_mode(hevc); + if (!hevc->is_used_v4l) { if (hevc->save_buffer_mode && dynamic_buf_num_margin > 2) hevc->dynamic_buf_num_margin = dynamic_buf_num_margin -2; @@ -13101,11 +13376,15 @@ static int ammvdec_h265_probe(struct platform_device *pdev) hevc->double_write_mode); hevc->cma_dev = pdata->cma_dev; + vh265_vdec_info_init(hevc); if (vh265_init(pdata) < 0) { hevc_print(hevc, 0, "\namvdec_h265 init failed.\n"); hevc_local_uninit(hevc); + if (hevc->gvs) + kfree(hevc->gvs); + hevc->gvs = NULL; uninit_mmu_buffers(hevc); /* devm_kfree(&pdev->dev, (void *)hevc); */ if (hevc) @@ -13133,11 +13412,13 @@ static int ammvdec_h265_remove(struct platform_device *pdev) struct hevc_state_s *hevc = (struct hevc_state_s *) (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); - struct vdec_s *vdec = hw_to_vdec(hevc); + struct vdec_s *vdec; if (hevc == NULL) return 0; + vdec = hw_to_vdec(hevc); + //pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid); if (get_dbg_flag(hevc)) hevc_print(hevc, 0, "%s\r\n", __func__); @@ -13152,6 +13433,7 @@ static int ammvdec_h265_remove(struct platform_device *pdev) vdec_set_status(hw_to_vdec(hevc), VDEC_STATUS_DISCONNECTED); vfree((void *)hevc); + return 0; } @@ -13578,6 +13860,13 @@ MODULE_PARM_DESC(pic_list_debug, "\n pic_list_debug\n"); module_param(without_display_mode, uint, 0664); MODULE_PARM_DESC(without_display_mode, "\n amvdec_h265 without_display_mode\n"); +#ifdef HEVC_8K_LFTOFFSET_FIX +module_param(performance_profile, uint, 0664); +MODULE_PARM_DESC(performance_profile, "\n amvdec_h265 performance_profile\n"); +#endif +module_param(disable_ip_mode, uint, 0664); +MODULE_PARM_DESC(disable_ip_mode, "\n amvdec_h265 disable ip_mode\n"); + module_init(amvdec_h265_driver_init_module); module_exit(amvdec_h265_driver_remove_module); |