-rw-r--r-- | drivers/amvdec_ports/aml_vcodec_adapt.c | 2 | ||||
-rw-r--r-- | drivers/amvdec_ports/aml_vcodec_dec.c | 27 | ||||
-rw-r--r-- | drivers/amvdec_ports/aml_vcodec_dec.h | 2 | ||||
-rw-r--r-- | drivers/amvdec_ports/aml_vcodec_dec_drv.c | 30 | ||||
-rw-r--r-- | drivers/amvdec_ports/aml_vcodec_drv.h | 19 | ||||
-rw-r--r-- | drivers/amvdec_ports/decoder/vdec_h264_if.c | 1 | ||||
-rw-r--r-- | drivers/amvdec_ports/decoder/vdec_hevc_if.c | 1 | ||||
-rw-r--r-- | drivers/amvdec_ports/decoder/vdec_vp9_if.c | 1 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/h264_multi/vmh264.c | 12 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/h265/vh265.c | 183 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/utils/vdec.c | 2 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/vp9/vvp9.c | 94 |
12 files changed, 288 insertions, 86 deletions
diff --git a/drivers/frame_provider/decoder/h265/vh265.c b/drivers/frame_provider/decoder/h265/vh265.c index 714ae42..320457d 100644 --- a/drivers/frame_provider/decoder/h265/vh265.c +++ b/drivers/frame_provider/decoder/h265/vh265.c @@ -47,6 +47,7 @@ #include "../utils/firmware.h" #include "../../../common/chips/decoder_cpu_ver_info.h" #include "../utils/vdec_v4l2_buffer_ops.h" +#include <media/v4l2-mem2mem.h> #define CONSTRAIN_MAX_BUF_NUM @@ -183,6 +184,8 @@ static int start_decode_buf_level = 0x8000; static unsigned int decode_timeout_val = 200; +static u32 run_ready_min_buf_num = 2; + /*data_resend_policy: bit 0, stream base resend data when decoding buf empty */ @@ -2150,7 +2153,7 @@ static void hevc_init_stru(struct hevc_state_s *hevc, for (i = 0; i < MAX_REF_PIC_NUM; i++) { if (hevc->m_PIC[i] != NULL) { memset(hevc->m_PIC[i], 0 ,sizeof(struct PIC_s)); - hevc->m_PIC[i]->index = -1; + hevc->m_PIC[i]->index = i; } } } @@ -3051,10 +3054,10 @@ static int cal_current_buf_size(struct hevc_state_s *hevc, return buf_size; } -static int v4l_alloc_buf(struct hevc_state_s *hevc) +static int v4l_alloc_buf(struct hevc_state_s *hevc, struct PIC_s *pic) { - int i; int ret = -1; + int i = pic->index; struct vdec_v4l2_buffer *fb = NULL; if (hevc->fatal_error & DECODER_FATAL_ERROR_NO_MEM) @@ -3067,10 +3070,6 @@ static int v4l_alloc_buf(struct hevc_state_s *hevc) return ret; } - for (i = 0; i < BUF_POOL_SIZE; i++) - if (hevc->m_BUF[i].start_adr == 0) - break; - if (hevc->mmu_enable) { if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && (IS_8K_SIZE(hevc->pic_w, hevc->pic_h))) @@ -3091,8 +3090,9 @@ static int v4l_alloc_buf(struct hevc_state_s *hevc) } } - hevc->m_BUF[i].used_flag = 0; - hevc->m_BUF[i].v4l_ref_buf_addr = (ulong)fb; + hevc->m_BUF[i].used_flag = 0; + hevc->m_BUF[i].v4l_ref_buf_addr = (ulong)fb; + 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; @@ -3316,20 +3316,9 @@ static int get_alloc_pic_count(struct hevc_state_s *hevc) static int v4l_config_pic(struct hevc_state_s *hevc, struct PIC_s *pic) { - int i; + int i = pic->index; int dw_mode = get_double_write_mode(hevc); - for (i = 0; i < BUF_POOL_SIZE; i++) { - if (hevc->m_BUF[i].start_adr != 0 && - hevc->m_BUF[i].used_flag == 0) { - hevc->m_BUF[i].used_flag = 1; - break; - } - } - - if (i >= BUF_POOL_SIZE) - return -1; - if (hevc->mmu_enable) pic->header_adr = hevc->m_BUF[i].header_addr; @@ -5580,20 +5569,14 @@ static struct PIC_s *get_new_pic(struct hevc_state_s *hevc, return NULL; if (new_pic->BUF_index < 0) { - ret = hevc->is_used_v4l ? - v4l_alloc_buf(hevc) : - alloc_buf(hevc); - if (ret < 0) - return NULL; - - ret = hevc->is_used_v4l ? - v4l_config_pic(hevc, new_pic) : - config_pic(hevc, new_pic); - if (ret < 0) { - dealloc_pic_buf(hevc, new_pic); + if (alloc_buf(hevc) < 0) return NULL; + else { + if (config_pic(hevc, new_pic) < 0) { + dealloc_pic_buf(hevc, new_pic); + return NULL; + } } - new_pic->width = hevc->pic_w; new_pic->height = hevc->pic_h; set_canvas(hevc, new_pic); @@ -5682,6 +5665,124 @@ static struct PIC_s *get_new_pic(struct hevc_state_s *hevc, return new_pic; } +static struct PIC_s *v4l_get_new_pic(struct hevc_state_s *hevc, + union param_u *rpm_param) +{ + int ret; + int used_buf_num = get_work_pic_num(hevc); + struct aml_vcodec_ctx * v4l = hevc->v4l2_ctx; + struct PIC_s *new_pic = NULL; + struct PIC_s *pic = NULL; + int i; + + for (i = 0; i < used_buf_num; ++i) { + struct v4l_buff_pool *pool = &v4l->cap_pool; + u32 state = (pool->seq[i] >> 16); + u32 index = (pool->seq[i] & 0xffff); + + switch (state) { + case V4L_CAP_BUFF_IN_DEC: + pic = hevc->m_PIC[i]; + if (pic && (pic->index != -1) && + (pic->output_mark == 0) && + (pic->referenced == 0) && + (pic->output_ready == 0) && + (pic->width == hevc->pic_w) && + (pic->height == hevc->pic_h) && + pic->cma_alloc_addr) { + new_pic = pic; + } + break; + case V4L_CAP_BUFF_IN_M2M: + pic = hevc->m_PIC[index]; + pic->width = hevc->pic_w; + pic->height = hevc->pic_h; + if ((pic->index != -1) && + !v4l_alloc_buf(hevc, pic)) { + v4l_config_pic(hevc, pic); + init_pic_list_hw(hevc); + new_pic = pic; + } + break; + default: + pr_err("v4l buffer state err %d.\n", state); + break; + } + + if (new_pic) + break; + } + + if (new_pic == NULL) + return NULL; + + new_pic->double_write_mode = get_double_write_mode(hevc); + if (new_pic->double_write_mode) + set_canvas(hevc, new_pic); + + if (get_mv_buf(hevc, new_pic) < 0) + return NULL; + + if (hevc->mmu_enable) { + ret = H265_alloc_mmu(hevc, new_pic, + rpm_param->p.bit_depth, + hevc->frame_mmu_map_addr); + if (ret != 0) { + put_mv_buf(hevc, new_pic); + hevc_print(hevc, 0, + "can't alloc need mmu1,idx %d ret =%d\n", + new_pic->decode_idx, ret); + return NULL; + } + } + + new_pic->referenced = 1; + new_pic->decode_idx = hevc->decode_idx; + new_pic->slice_idx = 0; + new_pic->referenced = 1; + new_pic->output_mark = 0; + new_pic->recon_mark = 0; + new_pic->error_mark = 0; + 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->losless_comp_body_size = hevc->losless_comp_body_size; + new_pic->POC = hevc->curr_POC; + new_pic->pic_struct = hevc->curr_pic_struct; + + if (new_pic->aux_data_buf) + release_aux_data(hevc, new_pic); + new_pic->mem_saving_mode = + hevc->mem_saving_mode; + new_pic->bit_depth_luma = + hevc->bit_depth_luma; + new_pic->bit_depth_chroma = + hevc->bit_depth_chroma; + new_pic->video_signal_type = + hevc->video_signal_type; + + new_pic->conformance_window_flag = + hevc->param.p.conformance_window_flag; + new_pic->conf_win_left_offset = + hevc->param.p.conf_win_left_offset; + new_pic->conf_win_right_offset = + hevc->param.p.conf_win_right_offset; + new_pic->conf_win_top_offset = + hevc->param.p.conf_win_top_offset; + new_pic->conf_win_bottom_offset = + hevc->param.p.conf_win_bottom_offset; + new_pic->chroma_format_idc = + hevc->param.p.chroma_format_idc; + + hevc_print(hevc, H265_DEBUG_BUFMGR_MORE, + "%s: index %d, buf_idx %d, decode_idx %d, POC %d\n", + __func__, new_pic->index, + new_pic->BUF_index, new_pic->decode_idx, + new_pic->POC); + + return new_pic; +} + static int get_display_pic_num(struct hevc_state_s *hevc) { int i; @@ -6918,7 +7019,9 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, set_aux_data(hevc, hevc->cur_pic, 1, 0); #endif /* new pic */ - hevc->cur_pic = get_new_pic(hevc, rpm_param); + hevc->cur_pic = hevc->is_used_v4l ? + v4l_get_new_pic(hevc, rpm_param) : + get_new_pic(hevc, rpm_param); if (hevc->cur_pic == NULL) { if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) dump_pic_list(hevc); @@ -6979,7 +7082,9 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, } else { if (hevc->wait_buf == 1) { pic_list_process(hevc); - hevc->cur_pic = get_new_pic(hevc, rpm_param); + hevc->cur_pic = hevc->is_used_v4l ? + v4l_get_new_pic(hevc, rpm_param) : + get_new_pic(hevc, rpm_param); if (hevc->cur_pic == NULL) return -1; @@ -12147,8 +12252,11 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) !ctx->v4l_codec_ready && hevc->v4l_params_parsed) { ret = 0; /*the params has parsed.*/ - } else if (!ctx->v4l_codec_dpb_ready) - ret = 0; + } else if (!ctx->v4l_codec_dpb_ready) { + if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < + run_ready_min_buf_num) + ret = 0; + } } if (ret) @@ -12357,7 +12465,6 @@ static void aml_free_canvas(struct vdec_s *vdec) static void reset(struct vdec_s *vdec) { - struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; int i; |