From b9ff72330f14078663592bcb8566458402d171e2 Mon Sep 17 00:00:00 2001 From: Nanxin Qin Date: Sat, 07 Dec 2019 13:46:08 +0000 Subject: v4l: fixed the issue of mosaic shows when seeking. [1/1] PD#SWPL-18134 Problem: playback youtube 4k videos, the automatically switched resolution or seek operation,Display abnormal. Solution: fixed the issue of mosaic shows when seeking or resolution change. Verify: u212 Change-Id: I9654fdbba7711c76dfcee4b999f63ee8ed12899d Signed-off-by: Nanxin Qin --- diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.c b/drivers/amvdec_ports/aml_vcodec_adapt.c index f7293f6..9e4658b 100644 --- a/drivers/amvdec_ports/aml_vcodec_adapt.c +++ b/drivers/amvdec_ports/aml_vcodec_adapt.c @@ -669,7 +669,7 @@ bool vdec_input_full(struct aml_vdec_adapt *ada_ctx) { struct vdec_s *vdec = ada_ctx->vdec; - return (vdec->input.have_frame_num > 60) ? true : false; + return (vdec->input.have_frame_num > 600) ? true : false; } int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx, diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c index 6989153..f773031 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec.c +++ b/drivers/amvdec_ports/aml_vcodec_dec.c @@ -337,7 +337,7 @@ int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_ pfb->mem_type = VDEC_SCATTER_MEMORY_TYPE; pfb->status = FB_ST_NORMAL; } else if (dst_buf->num_planes == 1) { - pfb = &dst_buf_info->frame_buffer; + pfb = &dst_buf_info->frame_buffer; pfb->m.mem[0].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); pfb->m.mem[0].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr); pfb->m.mem[0].size = ctx->picinfo.y_len_sz + ctx->picinfo.c_len_sz; @@ -399,6 +399,8 @@ int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_ info = container_of(pfb, struct aml_video_dec_buf, frame_buffer); + ctx->cap_pool.seq[ctx->cap_pool.out++] = + (V4L_CAP_BUFF_IN_DEC << 16 | dst_buf->index); v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); aml_vcodec_ctx_unlock(ctx, flags); @@ -511,6 +513,7 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *f /* make the run to stanby until new buffs to enque. */ ctx->v4l_codec_dpb_ready = false; + ctx->reset_flag = V4L_RESET_MODE_LIGHT; /* * After all buffers containing decoded frames from @@ -1179,8 +1182,7 @@ static int vidioc_vdec_dqbuf(struct file *file, void *priv, aml_buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb); file = fget(vb2_v4l2->private); - if (is_v4l2_buf_file(file) && - !aml_buf->is_install_privdata) { + if (is_v4l2_buf_file(file)) { dmabuf_fd_install_data(vb2_v4l2->private, (void*)&aml_buf->privdata, sizeof(struct file_private_data)); @@ -1720,15 +1722,23 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) __func__, __LINE__, buf->frame_buffer.m.mem[0].addr, buf->frame_buffer.vf_handle, buf->frame_buffer.status); + if (vb->index >= ctx->dpb_size) { + aml_v4l2_debug(2, "[%d] enque capture buf idx %d is invalid.", + ctx->id, vb->index); + return; + } + if (!buf->que_in_m2m) { - aml_v4l2_debug(2, "[%d] enque capture buf idx %d, %p", - ctx->id, vb->index, vb); + aml_v4l2_debug(2, "[%d] enque capture buf idx %d, vf: %p", + ctx->id, vb->index, v4l_get_vf_handle(vb2_v4l2->private)); v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2); buf->que_in_m2m = true; buf->queued_in_vb2 = true; buf->queued_in_v4l2 = true; buf->ready_to_display = false; + ctx->cap_pool.seq[ctx->cap_pool.in++] = + (V4L_CAP_BUFF_IN_M2M << 16 | vb->index); /* check dpb ready */ aml_check_dpb_ready(ctx); @@ -1950,12 +1960,15 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q) while ((vb2_v4l2 = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR); } else { + /* stop decoder. */ + wait_vcodec_ending(ctx); + for (i = 0; i < q->num_buffers; ++i) { vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]); buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb); buf->frame_buffer.status = FB_ST_NORMAL; buf->que_in_m2m = false; - buf->is_install_privdata = false; + ctx->cap_pool.seq[i] = 0; if (vb2_v4l2->vb2_buf.state == VB2_BUF_STATE_ACTIVE) v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR); @@ -1965,6 +1978,8 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q) } } ctx->buf_used_count = 0; + ctx->cap_pool.in = 0; + ctx->cap_pool.out = 0; } static void m2mops_vdec_device_run(void *priv) diff --git a/drivers/amvdec_ports/aml_vcodec_dec.h b/drivers/amvdec_ports/aml_vcodec_dec.h index 765b788..68f878a 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec.h +++ b/drivers/amvdec_ports/aml_vcodec_dec.h @@ -94,7 +94,6 @@ struct aml_video_dec_buf { bool queued_in_v4l2; bool lastframe; bool error; - bool is_install_privdata; }; extern const struct v4l2_ioctl_ops aml_vdec_ioctl_ops; @@ -123,5 +122,6 @@ void aml_thread_stop(struct aml_vcodec_ctx *ctx); void wait_vcodec_ending(struct aml_vcodec_ctx *ctx); void vdec_frame_buffer_release(void *data); void aml_vdec_dispatch_event(struct aml_vcodec_ctx *ctx, u32 changes); +void* v4l_get_vf_handle(int fd); #endif /* _AML_VCODEC_DEC_H_ */ diff --git a/drivers/amvdec_ports/aml_vcodec_dec_drv.c b/drivers/amvdec_ports/aml_vcodec_dec_drv.c index d35d738..43ff0c5 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec_drv.c +++ b/drivers/amvdec_ports/aml_vcodec_dec_drv.c @@ -269,6 +269,36 @@ int dmabuf_fd_install_data(int fd, void* data, u32 size) return 0; } +void* v4l_get_vf_handle(int fd) +{ + struct file *file; + struct file_private_data *data = NULL; + void *vf_handle = 0; + + file = fget(fd); + + if (!file) { + pr_err("%s: fget fd %d fail!, comm %s, pid %d\n", + __func__, fd, current->comm, current->pid); + return NULL; + } + + if (!is_v4l2_buf_file(file)) { + fput(file); + pr_err("%s the buf file checked fail!\n", __func__); + return NULL; + } + + data = (struct file_private_data*) file->private_data; + if (data) + vf_handle = &data->vf; + + fput(file); + + return vf_handle; +} + + static long v4l2_vcodec_ioctl(struct file *file, unsigned int cmd, ulong arg) diff --git a/drivers/amvdec_ports/aml_vcodec_drv.h b/drivers/amvdec_ports/aml_vcodec_drv.h index eff017f..1baec44 100644 --- a/drivers/amvdec_ports/aml_vcodec_drv.h +++ b/drivers/amvdec_ports/aml_vcodec_drv.h @@ -58,7 +58,15 @@ #define V4L2_EVENT_REQUEST_RESET (1 << 8) #define V4L2_EVENT_REQUEST_EXIT (1 << 9) +/* v4l buffer pool */ +#define V4L_CAP_BUFF_MAX (32) +#define V4L_CAP_BUFF_INVALID (0) +#define V4L_CAP_BUFF_IN_M2M (1) +#define V4L_CAP_BUFF_IN_DEC (2) +/* v4l reset mode */ +#define V4L_RESET_MODE_NORMAL (1 << 0) /* reset vdec_input and decoder. */ +#define V4L_RESET_MODE_LIGHT (1 << 1) /* just only reset decoder. */ /** * enum aml_hw_reg_idx - AML hw register base index @@ -330,6 +338,15 @@ struct v4l2_config_parm { u8 buf[4096]; }; +struct v4l_buff_pool { + /* + * bit 31-16: buffer state + * bit 15- 0: buffer index + */ + u32 seq[V4L_CAP_BUFF_MAX]; + u32 in, out; +}; + enum aml_thread_type { AML_THREAD_OUTPUT, AML_THREAD_CAPTURE, @@ -445,6 +462,8 @@ struct aml_vcodec_ctx { bool is_stream_off; int reset_flag; int stop_cmd; + u32 display_count; + struct v4l_buff_pool cap_pool; }; /** diff --git a/drivers/amvdec_ports/decoder/vdec_h264_if.c b/drivers/amvdec_ports/decoder/vdec_h264_if.c index 8a740c5..eada4ea 100644 --- a/drivers/amvdec_ports/decoder/vdec_h264_if.c +++ b/drivers/amvdec_ports/decoder/vdec_h264_if.c @@ -279,6 +279,7 @@ static void vdec_parser_parms(struct vdec_h264_inst *inst) ctx->config.length = pbuf - ctx->config.buf; } else { ctx->config.parm.dec.cfg.double_write_mode = 16; + ctx->config.parm.dec.cfg.ref_buf_margin = 7; ctx->config.length = vdec_config_default_parms(ctx->config.buf); } diff --git a/drivers/amvdec_ports/decoder/vdec_hevc_if.c b/drivers/amvdec_ports/decoder/vdec_hevc_if.c index 3d7e76e..cd4d361 100644 --- a/drivers/amvdec_ports/decoder/vdec_hevc_if.c +++ b/drivers/amvdec_ports/decoder/vdec_hevc_if.c @@ -185,6 +185,7 @@ static void vdec_parser_parms(struct vdec_hevc_inst *inst) ctx->config.length = pbuf - ctx->config.buf; } else { ctx->config.parm.dec.cfg.double_write_mode = 16; + ctx->config.parm.dec.cfg.ref_buf_margin = 7; ctx->config.length = vdec_config_default_parms(ctx->config.buf); } diff --git a/drivers/amvdec_ports/decoder/vdec_vp9_if.c b/drivers/amvdec_ports/decoder/vdec_vp9_if.c index 106dc5e..950894f 100644 --- a/drivers/amvdec_ports/decoder/vdec_vp9_if.c +++ b/drivers/amvdec_ports/decoder/vdec_vp9_if.c @@ -202,6 +202,7 @@ static void vdec_parser_parms(struct vdec_vp9_inst *inst) ctx->config.length = pbuf - ctx->config.buf; } else { ctx->config.parm.dec.cfg.double_write_mode = 16; + ctx->config.parm.dec.cfg.ref_buf_margin = 7; ctx->config.length = vdec_config_default_parms(ctx->config.buf); } diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c index 144cd9f..1038076 100644 --- a/drivers/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c @@ -61,6 +61,7 @@ #include "../../../common/chips/decoder_cpu_ver_info.h" #include "../utils/vdec_v4l2_buffer_ops.h" #include +#include #undef pr_info #define pr_info printk @@ -159,6 +160,8 @@ static u32 run_ready_display_q_num; static u32 run_ready_max_buf_num = 0xff; #endif +static u32 run_ready_min_buf_num = 2; + #define VDEC_ASSIST_CANVAS_BLK32 0x5 @@ -8210,10 +8213,11 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) !ctx->v4l_codec_ready && hw->v4l_params_parsed) { ret = 0; /*the params has parsed.*/ - } else if (!ctx->v4l_codec_dpb_ready) - ret = 0; - else if (hw->wait_reset_done_flag) - 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) 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 #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; diff --git a/drivers/frame_provider/decoder/utils/vdec.c b/drivers/frame_provider/decoder/utils/vdec.c index d987eb3..f5acd6a 100644 --- a/drivers/frame_provider/decoder/utils/vdec.c +++ b/drivers/frame_provider/decoder/utils/vdec.c @@ -2512,6 +2512,8 @@ int vdec_v4l2_reset(struct vdec_s *vdec, int flag) vdec_connect(vdec); + vdec_frame_check_init(vdec); + return 0; } EXPORT_SYMBOL(vdec_v4l2_reset); diff --git a/drivers/frame_provider/decoder/vp9/vvp9.c b/drivers/frame_provider/decoder/vp9/vvp9.c index 171706f..8c302c7 100644 --- a/drivers/frame_provider/decoder/vp9/vvp9.c +++ b/drivers/frame_provider/decoder/vp9/vvp9.c @@ -1243,26 +1243,6 @@ static void resize_context_buffers(struct VP9Decoder_s *pbi, } pr_info("%s (%d,%d)=>(%d,%d)\r\n", __func__, cm->width, cm->height, width, height); - - if (pbi->is_used_v4l) { - struct PIC_BUFFER_CONFIG_s *pic = &cm->cur_frame->buf; - - /* resolution change happend need to reconfig buffs if true. */ - if (pic->y_crop_width != width || pic->y_crop_height != height) { - int i; - for (i = 0; i < pbi->used_buf_num; i++) { - pic = &cm->buffer_pool->frame_bufs[i].buf; - pic->y_crop_width = width; - pic->y_crop_height = height; - if (!v4l_alloc_and_config_pic(pbi, pic)) - set_canvas(pbi, pic); - else - vp9_print(pbi, 0, - "v4l: reconfig buff fail.\n"); - } - } - } - cm->width = width; cm->height = height; } @@ -2156,7 +2136,6 @@ static int get_free_fb(struct VP9Decoder_s *pbi) { struct VP9_Common_s *const cm = &pbi->common; struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; - struct PIC_BUFFER_CONFIG_s *pic = NULL; int i; unsigned long flags; @@ -2170,21 +2149,11 @@ static int get_free_fb(struct VP9Decoder_s *pbi) } } for (i = 0; i < pbi->used_buf_num; ++i) { - pic = &frame_bufs[i].buf; if ((frame_bufs[i].ref_count == 0) && - (pic->vf_ref == 0) && (pic->index != -1)) { - if (pbi->is_used_v4l && !pic->cma_alloc_addr) { - pic->y_crop_width = pbi->frame_width; - pic->y_crop_height = pbi->frame_height; - if (!v4l_alloc_and_config_pic(pbi, pic)) { - set_canvas(pbi, pic); - init_pic_list_hw(pbi); - } else - i = pbi->used_buf_num; - } - + (frame_bufs[i].buf.vf_ref == 0) && + (frame_bufs[i].buf.index != -1) + ) break; - } } if (i != pbi->used_buf_num) { frame_bufs[i].ref_count = 1; @@ -2200,6 +2169,58 @@ static int get_free_fb(struct VP9Decoder_s *pbi) return i; } +static int v4l_get_free_fb(struct VP9Decoder_s *pbi) +{ + struct VP9_Common_s *const cm = &pbi->common; + struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; + struct aml_vcodec_ctx * v4l = pbi->v4l2_ctx; + struct PIC_BUFFER_CONFIG_s *pic = NULL; + int i, idx = INVALID_IDX; + ulong flags; + + lock_buffer_pool(cm->buffer_pool, flags); + + for (i = 0; i < pbi->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 = &frame_bufs[i].buf; + if ((frame_bufs[i].ref_count == 0) && + (pic->vf_ref == 0) && + (pic->index != -1) && + pic->cma_alloc_addr) { + idx = i; + } + break; + case V4L_CAP_BUFF_IN_M2M: + pic = &frame_bufs[index].buf; + pic->y_crop_width = pbi->frame_width; + pic->y_crop_height = pbi->frame_height; + if (!v4l_alloc_and_config_pic(pbi, pic)) { + set_canvas(pbi, pic); + init_pic_list_hw(pbi); + idx = index; + } + break; + default: + pr_err("v4l buffer state err %d.\n", state); + break; + } + + if (idx != INVALID_IDX) { + frame_bufs[idx].ref_count = 1; + break; + } + } + + unlock_buffer_pool(cm->buffer_pool, flags); + + return idx; +} + static int get_free_buf_count(struct VP9Decoder_s *pbi) { struct VP9_Common_s *const cm = &pbi->common; @@ -2361,7 +2382,9 @@ int vp9_bufmgr_process(struct VP9Decoder_s *pbi, union param_u *params) if (debug & VP9_DEBUG_BUFMGR_DETAIL) dump_pic_list(pbi); #endif - cm->new_fb_idx = get_free_fb(pbi); + cm->new_fb_idx = pbi->is_used_v4l ? + v4l_get_free_fb(pbi) : + get_free_fb(pbi); if (cm->new_fb_idx == INVALID_IDX) { pr_info("get_free_fb error\r\n"); return -1; @@ -10126,7 +10149,6 @@ static void init_frame_bufs(struct VP9Decoder_s *pbi) static void reset(struct vdec_s *vdec) { - struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)vdec->private; -- cgit