From: jintao xu Date: Thu, 12 Dec 2019 09:12:52 +0000 (+0800) Subject: video_composer: fix 3 channel crop error [1/1] X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=bd15eb833a0208e349748f7e01daa8797b9f2309;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git video_composer: fix 3 channel crop error [1/1] PD#SWPL-18034 Problem: crop error when hdmi is 4k Solution: fix crop error Verify: Verify on u212 Change-Id: Id7f7599a64ab376e8b84ba891889e0ed38952266 Signed-off-by: jintao xu --- diff --git a/drivers/amlogic/media/video_processor/v4lvideo/v4lvideo.c b/drivers/amlogic/media/video_processor/v4lvideo/v4lvideo.c index a8256244555a..424ad3d24c74 100644 --- a/drivers/amlogic/media/video_processor/v4lvideo/v4lvideo.c +++ b/drivers/amlogic/media/video_processor/v4lvideo/v4lvideo.c @@ -55,6 +55,14 @@ static unsigned int debug; module_param(debug, uint, 0644); MODULE_PARM_DESC(debug, "activates debug info"); +static unsigned int get_count; +module_param(get_count, uint, 0644); +MODULE_PARM_DESC(get_count, "get_count"); + +static unsigned int put_count; +module_param(put_count, uint, 0644); +MODULE_PARM_DESC(put_count, "put_count"); + #define MAX_KEEP_FRAME 64 struct keep_mem_info { @@ -233,7 +241,7 @@ static void video_keeper_free_mem( static void vf_keep(struct file_private_data *file_private_data) { - struct vframe_s *vf_p = file_private_data->vf_p; + struct vframe_s *vf_p; int type = MEM_TYPE_CODEC_MM; int keep_id = 0; int keep_head_id = 0; @@ -242,6 +250,13 @@ static void vf_keep(struct file_private_data *file_private_data) V4LVID_ERR("vf_keep error: file_private_data is NULL"); return; } + vf_p = file_private_data->vf_p; + + if (!vf_p) { + V4LVID_ERR("vf_keep error: vf_p is NULL"); + return; + } + if (vf_p->type & VIDTYPE_SCATTER) type = MEM_TYPE_CODEC_MM_SCATTER; video_keeper_keep_mem( @@ -444,6 +459,10 @@ struct vframe_s *v4lvideo_get_vf(int fd) struct file_private_data *file_private_data; file_vf = fget(fd); + if (!file_vf) { + pr_err("v4lvideo_get_vf file_vf is NULL\n"); + return NULL; + } file_private_data = (struct file_private_data *)file_vf->private_data; vf = &file_private_data->vf; fput(file_vf); @@ -667,7 +686,15 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) dev->v4lvideo_input[p->index] = *p; file_vf = fget(p->m.fd); + if (!file_vf) { + pr_err("v4lvideo: qbuf fget fail\n"); + return 0; + } file_private_data = (struct file_private_data *)(file_vf->private_data); + if (!file_private_data) { + pr_err("v4lvideo: qbuf file_private_data NULL\n"); + return 0; + } vf_p = file_private_data->vf_p; mutex_lock(&dev->mutex_input); @@ -679,6 +706,7 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) file_private_data)) { if (dev->receiver_register) { vf_put(vf_p, dev->vf_receiver_name); + put_count++; } else { vf_free(file_private_data); pr_err("vidioc_qbuf: vfm is unreg\n"); @@ -727,6 +755,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) vf = vf_get(dev->vf_receiver_name); if (!vf) return -EAGAIN; + get_count++; vf->omx_index = dev->frame_num; dev->am_parm.signal_type = vf->signal_type; dev->am_parm.master_display_colour @@ -736,7 +765,17 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) buf = v4l2q_pop(&dev->input_queue); dev->vf_wait_cnt = 0; file_vf = fget(buf->m.fd); + if (!file_vf) { + mutex_unlock(&dev->mutex_input); + pr_err("v4lvideo: dqbuf fget fail\n"); + return -EAGAIN; + } file_private_data = (struct file_private_data *)(file_vf->private_data); + if (!file_private_data) { + mutex_unlock(&dev->mutex_input); + pr_err("v4lvideo: file_private_data NULL\n"); + return -EAGAIN; + } file_private_data->vf = *vf; file_private_data->vf_p = vf; //pr_err("dqbuf: file_private_data=%p, vf=%p\n", file_private_data, vf); @@ -879,6 +918,8 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) dev->frame_num = 0; dev->first_frame = 0; mutex_unlock(&dev->mutex_input); + get_count = 0; + put_count = 0; pr_err("reg:v4lvideo\n"); } else if (type == VFRAME_EVENT_PROVIDER_QUREY_STATE) { if (dev->vf_wait_cnt > 1) diff --git a/drivers/amlogic/media/video_processor/video_composer/vframe_ge2d_composer.c b/drivers/amlogic/media/video_processor/video_composer/vframe_ge2d_composer.c index 715d79dbed9d..0515cec11e05 100644 --- a/drivers/amlogic/media/video_processor/video_composer/vframe_ge2d_composer.c +++ b/drivers/amlogic/media/video_processor/video_composer/vframe_ge2d_composer.c @@ -303,6 +303,7 @@ int fill_vframe_black(struct ge2d_composer_para *ge2d_comp_para) struct canvas_config_s dst_canvas0_config[3]; u32 dst_plane_num; + memset(dst_canvas0_config, 0, sizeof(dst_canvas0_config)); memset(ge2d_comp_para->ge2d_config, 0, sizeof(struct config_para_ex_s)); if (ge2d_comp_para->format == GE2D_FORMAT_S24_YUV444) { @@ -312,7 +313,7 @@ int fill_vframe_black(struct ge2d_composer_para *ge2d_comp_para) dst_canvas0_config[0].block_mode = 0; dst_canvas0_config[0].endian = 0; } - dst_plane_num = 1; + dst_plane_num = ge2d_comp_para->plane_num; if (ge2d_comp_para->canvas0Addr == (u32)-1) { canvas_config_config( @@ -414,7 +415,7 @@ int ge2d_data_composer( dst_canvas0_config[0].block_mode = 0; dst_canvas0_config[0].endian = 0; } - dst_plane_num = 1; + dst_plane_num = ge2d_comp_para->plane_num; if (scr_data->canvas0Addr == (u32)-1) { ret = alloc_src_canvas(ge2d_comp_para); @@ -552,9 +553,13 @@ int ge2d_data_composer( position_width, position_height); if (ge2d_com_debug & 1) - VIDEOCOM_INFO("scr format: %0x, dst format: %0x!\n", + VIDEOCOM_INFO("scr %0x,dst: %0x!,%d, %d, %d, %d\n", ge2d_comp_para->ge2d_config->src_para.format, - ge2d_comp_para->ge2d_config->dst_para.format); + ge2d_comp_para->ge2d_config->dst_para.format, + position_left, + position_top, + position_width, + position_height); return 0; } diff --git a/drivers/amlogic/media/video_processor/video_composer/video_composer.c b/drivers/amlogic/media/video_processor/video_composer/video_composer.c index a4bef7f2f57d..075a08b4c2d4 100644 --- a/drivers/amlogic/media/video_processor/video_composer/video_composer.c +++ b/drivers/amlogic/media/video_processor/video_composer/video_composer.c @@ -116,8 +116,9 @@ static struct class video_composer_class = { #define PRINT_QUEUE_STATUS 0X0001 #define PRINT_FENCE 0X0002 #define PRINT_PERFORMANCE 0X0004 -#define PRINT_OTHER 0X0008 +#define PRINT_AXIS 0X0008 #define PRINT_INDEX_DISP 0X0010 +#define PRINT_OTHER 0X0020 #define to_dst_buf(vf) \ container_of(vf, struct dst_buf_t, frame) @@ -371,7 +372,7 @@ static void display_q_uninit(struct composer_dev *dev) int repeat_count; int i; - vc_print(dev->index, PRINT_OTHER, "vc: unit display_q len=%d\n", + vc_print(dev->index, PRINT_QUEUE_STATUS, "vc: unit display_q len=%d\n", kfifo_len(&dev->display_q)); while (kfifo_len(&dev->display_q) > 0) { @@ -379,7 +380,7 @@ static void display_q_uninit(struct composer_dev *dev) if (dis_vf->flag & VFRAME_FLAG_VIDEO_COMPOSER_BYPASS) { repeat_count = dis_vf->repeat_count[dev->index]; - vc_print(dev->index, PRINT_OTHER, + vc_print(dev->index, PRINT_FENCE, "vc: unit repeat_count=%d\n", repeat_count); for (i = 0; i <= repeat_count; i++) { @@ -399,7 +400,7 @@ static void receive_q_uninit(struct composer_dev *dev) int i = 0; struct received_frames_t *received_frames = NULL; - vc_print(dev->index, PRINT_OTHER, "vc: unit receive_q len=%d\n", + vc_print(dev->index, PRINT_QUEUE_STATUS, "vc: unit receive_q len=%d\n", kfifo_len(&dev->receive_q)); while (kfifo_len(&dev->receive_q) > 0) { if (kfifo_get(&dev->receive_q, &received_frames)) @@ -418,7 +419,7 @@ static void ready_q_uninit(struct composer_dev *dev) int repeat_count; int i; - vc_print(dev->index, PRINT_OTHER, "vc: unit ready_q len=%d\n", + vc_print(dev->index, PRINT_QUEUE_STATUS, "vc: unit ready_q len=%d\n", kfifo_len(&dev->ready_q)); while (kfifo_len(&dev->ready_q) > 0) { @@ -491,14 +492,14 @@ static struct vframe_s *get_dst_vframe_buffer(struct composer_dev *dev) struct vframe_s *dst_vf; if (!kfifo_get(&dev->free_q, &dst_vf)) { - vc_print(dev->index, PRINT_OTHER, "free q is empty\n"); + vc_print(dev->index, PRINT_QUEUE_STATUS, "free q is empty\n"); return NULL; } return dst_vf; } static void check_window_change(struct composer_dev *dev, - struct frames_info_t cur_frame_info) + struct frames_info_t *cur_frame_info) { int last_width, last_height, current_width, current_height; int cur_pos_x, cur_pos_y, cur_pos_w, cur_pos_h; @@ -509,16 +510,16 @@ static void check_window_change(struct composer_dev *dev, int i; last_frame_info = dev->last_frames.frames_info; - if (cur_frame_info.frame_count != last_frame_info.frame_count) { + if (cur_frame_info->frame_count != last_frame_info.frame_count) { window_changed = true; vc_print(dev->index, PRINT_ERROR, "last count=%d, current count=%d\n", last_frame_info.frame_count, - cur_frame_info.frame_count); + cur_frame_info->frame_count); } else { - for (i = 0; i < cur_frame_info.frame_count; i++) { - current_width = cur_frame_info.frame_info[i].crop_w; - current_height = cur_frame_info.frame_info[i].crop_h; + for (i = 0; i < cur_frame_info->frame_count; i++) { + current_width = cur_frame_info->frame_info[i].crop_w; + current_height = cur_frame_info->frame_info[i].crop_h; last_width = last_frame_info.frame_info[i].crop_w; last_height = last_frame_info.frame_info[i].crop_h; @@ -530,10 +531,10 @@ static void check_window_change(struct composer_dev *dev, break; } - cur_pos_x = cur_frame_info.frame_info[i].dst_x; - cur_pos_y = cur_frame_info.frame_info[i].dst_y; - cur_pos_w = cur_frame_info.frame_info[i].dst_w; - cur_pos_h = cur_frame_info.frame_info[i].dst_h; + cur_pos_x = cur_frame_info->frame_info[i].dst_x; + cur_pos_y = cur_frame_info->frame_info[i].dst_y; + cur_pos_w = cur_frame_info->frame_info[i].dst_w; + cur_pos_h = cur_frame_info->frame_info[i].dst_h; last_pos_x = last_frame_info.frame_info[i].dst_x; last_pos_y = last_frame_info.frame_info[i].dst_y; last_pos_w = last_frame_info.frame_info[i].dst_w; @@ -543,16 +544,16 @@ static void check_window_change(struct composer_dev *dev, (cur_pos_y != last_pos_y) || (cur_pos_w != last_pos_w) || (cur_pos_h != last_pos_h)) { - vc_print(dev->index, PRINT_ERROR, + vc_print(dev->index, PRINT_OTHER, "frame axis changed!"); window_changed = true; break; } - cur_zorder = cur_frame_info.frame_info[i].zorder; + cur_zorder = cur_frame_info->frame_info[i].zorder; last_zorder = last_frame_info.frame_info[i].zorder; if (cur_zorder != last_zorder) { - vc_print(dev->index, PRINT_ERROR, + vc_print(dev->index, PRINT_OTHER, "frame zorder changed!"); window_changed = true; break; @@ -652,7 +653,7 @@ static void vframe_composer(struct composer_dev *dev) dst_vf = get_dst_vframe_buffer(dev); } if (IS_ERR_OR_NULL(dst_vf)) { - vc_print(dev->index, PRINT_OTHER, "dst vf is NULL\n"); + vc_print(dev->index, PRINT_ERROR, "dst vf is NULL\n"); return; } memset(dst_vf, 0, sizeof(struct vframe_s)); @@ -666,13 +667,13 @@ static void vframe_composer(struct composer_dev *dev) break; drop_count++; frames_put_file(dev, received_frames); - vc_print(dev->index, PRINT_ERROR, "com: drop frame\n"); + vc_print(dev->index, PRINT_PERFORMANCE, "com: drop frame\n"); atomic_set(&received_frames->on_use, false); } frames_info = &received_frames->frames_info; count = frames_info->frame_count; - check_window_change(dev, received_frames->frames_info); + check_window_change(dev, &received_frames->frames_info); dst_buf = to_dst_buf(dst_vf); dev->ge2d_para.format = GE2D_FORMAT_S24_YUV444; @@ -680,6 +681,7 @@ static void vframe_composer(struct composer_dev *dev) dev->ge2d_para.buffer_w = dst_buf->buf_w; dev->ge2d_para.buffer_h = dst_buf->buf_h; dev->ge2d_para.canvas0Addr = -1; + dev->ge2d_para.plane_num = 1; if (dst_buf->dirty && !close_black) { ret = fill_vframe_black(&dev->ge2d_para); @@ -709,8 +711,6 @@ static void vframe_composer(struct composer_dev *dev) } min_left = vframe_info[0]->dst_x; min_top = vframe_info[0]->dst_y; - max_right = vframe_info[0]->dst_x + vframe_info[0]->dst_w; - max_bottom = vframe_info[0]->dst_y + vframe_info[0]->dst_h; for (i = 0; i < count; i++) { if (vframe_info[vf_dev[i]]->type == 1) { src_data.canvas0Addr = -1; @@ -776,18 +776,6 @@ static void vframe_composer(struct composer_dev *dev) src_data.is_vframe = true; } cur_transform = vframe_info[vf_dev[i]]->transform; - if (min_left > vframe_info[vf_dev[i]]->dst_x) - min_left = vframe_info[vf_dev[i]]->dst_x; - if (min_top > vframe_info[vf_dev[i]]->dst_y) - min_top = vframe_info[vf_dev[i]]->dst_y; - if (max_right < (vframe_info[vf_dev[i]]->dst_x + - vframe_info[vf_dev[i]]->dst_w)) - max_right = vframe_info[vf_dev[i]]->dst_x + - vframe_info[vf_dev[i]]->dst_w; - if (max_bottom < (vframe_info[vf_dev[i]]->dst_y + - vframe_info[vf_dev[i]]->dst_h)) - max_bottom = vframe_info[vf_dev[i]]->dst_y + - vframe_info[vf_dev[i]]->dst_h; dev->ge2d_para.position_left = vframe_info[vf_dev[i]]->dst_x; dev->ge2d_para.position_top = @@ -814,7 +802,16 @@ static void vframe_composer(struct composer_dev *dev) dev->ge2d_para.position_top = dst_axis.top; dev->ge2d_para.position_width = dst_axis.width; dev->ge2d_para.position_height = dst_axis.height; + if (min_left > dst_axis.left) + min_left = dst_axis.left; + if (min_top > dst_axis.top) + min_top = dst_axis.top; + if (max_right < (dst_axis.left + dst_axis.width)) + max_right = dst_axis.left + dst_axis.width; + if (max_bottom < (dst_axis.top + dst_axis.height)) + max_bottom = dst_axis.top + dst_axis.height; } + dev->ge2d_para.plane_num = 1; ret = ge2d_data_composer(&src_data, &dev->ge2d_para); if (ret < 0) @@ -851,6 +848,7 @@ static void vframe_composer(struct composer_dev *dev) dst_vf->crop[1] = min_left; dst_vf->crop[2] = dst_buf->buf_h - max_bottom; dst_vf->crop[3] = dst_buf->buf_w - max_right; + dst_vf->zorder = frames_info->disp_zorder; dst_vf->canvas0_config[0].phy_addr = dst_buf->phy_addr; dst_vf->canvas0Addr = -1; @@ -993,7 +991,11 @@ static void video_composer_task(struct composer_dev *dev) "task: get failed\n"); return; } - + if (vf == NULL) { + vc_print(dev->index, PRINT_ERROR, + "vf is NULL\n"); + return; + } vf->axis[0] = frame_info->dst_x; vf->axis[1] = frame_info->dst_y; vf->axis[2] = frame_info->dst_w + frame_info->dst_x - 1; @@ -1042,31 +1044,31 @@ static void video_composer_task(struct composer_dev *dev) - frame_info->crop_w - frame_info->crop_x; } - vc_print(dev->index, PRINT_OTHER, + vc_print(dev->index, PRINT_AXIS, "axis: %d %d %d %d\ncrop: %d %d %d %d\n", vf->axis[0], vf->axis[1], vf->axis[2], vf->axis[3], vf->crop[0], vf->crop[1], vf->crop[2], vf->crop[3]); - vc_print(dev->index, PRINT_OTHER, + vc_print(dev->index, PRINT_AXIS, "vf_width: %d, vf_height: %d\n", vf->width, vf->height); - vc_print(dev->index, PRINT_OTHER, + vc_print(dev->index, PRINT_AXIS, "=========frame info:==========\n"); - vc_print(dev->index, PRINT_OTHER, + vc_print(dev->index, PRINT_AXIS, "frame aixs x,y,w,h: %d %d %d %d\n", frame_info->dst_x, frame_info->dst_y, frame_info->dst_w, frame_info->dst_h); - vc_print(dev->index, PRINT_OTHER, + vc_print(dev->index, PRINT_AXIS, "frame crop t,l,b,r: %d %d %d %d\n", frame_info->crop_y, frame_info->crop_x, frame_info->crop_h, frame_info->crop_w); - vc_print(dev->index, PRINT_OTHER, + vc_print(dev->index, PRINT_AXIS, "frame buffer Width X Height: %d X %d\n", frame_info->buffer_w, frame_info->buffer_h); - vc_print(dev->index, PRINT_OTHER, + vc_print(dev->index, PRINT_AXIS, "===============================\n"); if (dev->last_file == file_vf && frame_info->type == 0) { vf->repeat_count[dev->index]++; - vc_print(dev->index, PRINT_OTHER, + vc_print(dev->index, PRINT_FENCE, "repeat =%d, omx_index=%d\n", vf->repeat_count[dev->index], vf->omx_index); @@ -1081,7 +1083,7 @@ static void video_composer_task(struct composer_dev *dev) if (ready_count > 1) vc_print(dev->index, PRINT_ERROR, "ready len=%d\n", ready_count); - vc_print(dev->index, PRINT_OTHER, + vc_print(dev->index, PRINT_QUEUE_STATUS, "ready len=%d\n", kfifo_len(&dev->ready_q)); } dev->fake_vf = *vf; @@ -1397,22 +1399,27 @@ static void set_frames_info(struct composer_dev *dev, for (j = 0; j < frames_info->frame_count; j++) { frames_info->frame_info[j].composer_fen_fd = fence_fd; file_vf = fget(frames_info->frame_info[j].fd); + if (!file_vf) { + vc_print(dev->index, PRINT_ERROR, "fget fd fail\n"); + return; + } dev->received_frames[i].file_vf[j] = file_vf; if (frames_info->frame_info[j].type == 0) { file_private_data = (struct file_private_data *)(file_vf->private_data); vf = &file_private_data->vf; - vc_print(dev->index, PRINT_INDEX_DISP, - "received_cnt=%lld,i=%d,z=%d,omx_index=%d, fence_fd=%d, index_disp=%d\n", + vc_print(dev->index, PRINT_FENCE, + "received_cnt=%lld,i=%d,z=%d,omx_index=%d, fence_fd=%d, fc_no=%d, index_disp=%d\n", dev->received_count + 1, i, frames_info->frame_info[j].zorder, vf->omx_index, fence_fd, - vf->index_disp); + dev->cur_streamline_val, + vf->index_disp); ATRACE_COUNTER("video_composer", vf->index_disp); } else if (frames_info->frame_info[j].type == 1) { - vc_print(dev->index, PRINT_OTHER, + vc_print(dev->index, PRINT_FENCE, "received_cnt=%lld,i=%d,z=%d,DMA_fd=%d\n", dev->received_count + 1, i, @@ -1477,12 +1484,14 @@ static struct vframe_s *vc_vf_get(void *op_arg) struct vframe_s *vf = NULL; if (kfifo_get(&dev->ready_q, &vf)) { - if (vf) { - if (!kfifo_put(&dev->display_q, vf)) - vc_print(dev->index, PRINT_ERROR, - "display_q is full!\n"); - get_count[dev->index]++; - } + if (!vf) + return NULL; + + if (!kfifo_put(&dev->display_q, vf)) + vc_print(dev->index, PRINT_ERROR, + "display_q is full!\n"); + get_count[dev->index]++; + vc_print(dev->index, PRINT_OTHER, "get: omx_index=%d\n", vf->omx_index); @@ -1520,7 +1529,7 @@ static void vc_vf_put(struct vframe_s *vf, void *op_arg) return; } - vc_print(dev->index, PRINT_OTHER, + vc_print(dev->index, PRINT_FENCE, "put: repeat_count =%d, omx_index=%d\n", repeat_count, omx_index); @@ -1532,7 +1541,7 @@ static void vc_vf_put(struct vframe_s *vf, void *op_arg) dev->drop_frame_count = 0; } else { dev->drop_frame_count += repeat_count + 1; - vc_print(dev->index, PRINT_ERROR, + vc_print(dev->index, PRINT_PERFORMANCE, "put: drop repeat_count=%d\n", repeat_count); } diff --git a/drivers/amlogic/media/video_processor/video_composer/video_composer.h b/drivers/amlogic/media/video_processor/video_composer/video_composer.h index cbc5136feed6..cf04a8eef868 100644 --- a/drivers/amlogic/media/video_processor/video_composer/video_composer.h +++ b/drivers/amlogic/media/video_processor/video_composer/video_composer.h @@ -56,6 +56,8 @@ #define DMA_BUF_COUNT 4 #define VCOM_MAP_NAME_SIZE 90 +#define VCOM_MAP_STRUCT_SIZE 120 + #define VCOM_PROVIDER_NAME_SIZE 32 enum vc_transform_t { @@ -164,8 +166,8 @@ struct composer_dev { DECLARE_KFIFO(display_q, struct vframe_s *, COMPOSER_READY_POOL_SIZE); DECLARE_KFIFO(dma_free_q, struct vframe_s *, BUFFER_LEN); char vf_provider_name[VCOM_PROVIDER_NAME_SIZE]; - char vfm_map_id[VCOM_MAP_NAME_SIZE]; - char vfm_map_chain[VCOM_MAP_NAME_SIZE]; + char vfm_map_id[VCOM_MAP_STRUCT_SIZE]; + char vfm_map_chain[VCOM_MAP_STRUCT_SIZE]; struct vframe_provider_s vc_vf_prov; void *video_timeline; u32 cur_streamline_val;