diff --git a/drivers/media/video_processor/video_composer/video_composer.c b/drivers/media/video_processor/video_composer/video_composer.c index ff217128a..3dc2d03b7 100644 --- a/drivers/media/video_processor/video_composer/video_composer.c +++ b/drivers/media/video_processor/video_composer/video_composer.c @@ -3073,6 +3073,12 @@ static bool check_vf_has_afbc(struct composer_dev *dev, struct file *file_vf) return false; } +bool get_lowlatency_mode(void) +{ + return use_low_latency; +} +EXPORT_SYMBOL(get_lowlatency_mode); + static bool check_mosaic_22(struct composer_dev *dev, struct received_frames_t *received_frames) { struct vinfo_s *video_composer_vinfo; @@ -4168,7 +4174,7 @@ static void set_frames_info(struct composer_dev *dev, vf->source_type == VFRAME_SOURCE_TYPE_CVBS) tv_fence_creat_count++; vc_print(dev->index, PRINT_FENCE | PRINT_PATTERN, - "received_cnt=%lld,new_cnt=%lld,i=%d,z=%d,omx_index=%d, fence_fd=%d, fc_no=%d, index_disp=%d,pts=%lld\n", + "received_cnt=%lld,new_cnt=%lld,i=%d,z=%d,omx_index=%d, fence_fd=%d, fc_no=%d, index_disp=%d,pts=%lld,vf=%p\n", dev->received_count + 1, dev->received_new_count, i, @@ -4177,7 +4183,8 @@ static void set_frames_info(struct composer_dev *dev, fence_fd, dev->cur_streamline_val, vf->index_disp, - vf->pts_us64); + vf->pts_us64, + vf); #if IS_ENABLED(CONFIG_AMLOGIC_DEBUG_ATRACE) ATRACE_COUNTER("video_composer_sf_omx_index", vf->omx_index); ATRACE_COUNTER("video_composer_sf_omx_index", 0); diff --git a/drivers/media/video_processor/video_composer/video_composer.h b/drivers/media/video_processor/video_composer/video_composer.h index dc46a811f..729a0c942 100644 --- a/drivers/media/video_processor/video_composer/video_composer.h +++ b/drivers/media/video_processor/video_composer/video_composer.h @@ -314,5 +314,4 @@ void vc_private_q_init(struct composer_dev *dev); void vc_private_q_recycle(struct composer_dev *dev, struct video_composer_private *vc_private); struct video_composer_private *vc_private_q_pop(struct composer_dev *dev); - #endif /* VIDEO_COMPOSER_H */ diff --git a/drivers/media/video_processor/video_composer/videodisplay.c b/drivers/media/video_processor/video_composer/videodisplay.c index 6a8a4e2d2..7c3739156 100644 --- a/drivers/media/video_processor/video_composer/videodisplay.c +++ b/drivers/media/video_processor/video_composer/videodisplay.c @@ -23,8 +23,8 @@ #include #endif #include +#include #include "videodisplay.h" -#include "video_composer.h" static struct timeval vsync_time[MAX_VD_LAYERS]; static DEFINE_MUTEX(video_display_mutex); @@ -617,6 +617,8 @@ static struct vframe_s *vc_vf_peek(void *op_arg) time2 = vsync_time[dev->index]; if (kfifo_peek(&dev->ready_q, &vf)) { + if (get_lowlatency_mode()) + return vf; if (vf->vc_private && vd_set_frame_delay[dev->index] > 0) { vsync_index = vf->vc_private->vsync_index; vc_print(dev->index, PRINT_OTHER, diff --git a/drivers/media/video_sink/video.c b/drivers/media/video_sink/video.c index f762e5b7b..54571d649 100644 --- a/drivers/media/video_sink/video.c +++ b/drivers/media/video_sink/video.c @@ -122,6 +122,7 @@ MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_DEFAULT_LEVEL_DESC, LOG_MASK_DESC); #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_PRIME_SL #include #endif +#include #include #include "video_receiver.h" @@ -5300,6 +5301,8 @@ static irqreturn_t vsync_isr(int irq, void *dev_id) { irqreturn_t ret; + if (get_lowlatency_mode()) + put_buffer_proc(); lowlatency_vsync_count++; if (atomic_inc_return(&video_proc_lock) > 1) { vsync_proc_drop++; diff --git a/drivers/media/video_sink/video_common.c b/drivers/media/video_sink/video_common.c index 7bebabda0..37f736b67 100644 --- a/drivers/media/video_sink/video_common.c +++ b/drivers/media/video_sink/video_common.c @@ -1415,6 +1415,13 @@ bool is_aisr_enable(struct video_layer_s *layer) return ret; } +#ifndef CONFIG_AMLOGIC_VIDEO_COMPOSER +bool get_lowlatency_mode(void) +{ + return 0; +} +#endif + MODULE_PARM_DESC(debug_common_flag, "\n debug_common_flag\n"); module_param(debug_common_flag, uint, 0664); diff --git a/drivers/media/video_sink/video_common.h b/drivers/media/video_sink/video_common.h index d87ce6953..91ef1fc58 100644 --- a/drivers/media/video_sink/video_common.h +++ b/drivers/media/video_sink/video_common.h @@ -46,4 +46,7 @@ bool frc_n2m_worked(void); bool frc_n2m_1st_frame_worked(struct video_layer_s *layer); bool check_aisr_need_disable(struct video_layer_s *layer); bool is_aisr_enable(struct video_layer_s *layer); +#ifndef CONFIG_AMLOGIC_VIDEO_COMPOSER +bool get_lowlatency_mode(void); +#endif #endif diff --git a/drivers/media/video_sink/video_func.c b/drivers/media/video_sink/video_func.c index 3142b3961..66e82ef89 100644 --- a/drivers/media/video_sink/video_func.c +++ b/drivers/media/video_sink/video_func.c @@ -68,6 +68,7 @@ #ifdef CONFIG_AMLOGIC_MEDIA_FRC #include #endif +#include #include "video_common.h" #include "video_hw_s5.h" #include "vpp_post_s5.h" @@ -2695,18 +2696,29 @@ static void vd_dispbuf_init(u8 layer_id) } } +void put_buffer_proc(void) +{ + int i; + + for (i = 0; i < 3; i++) { + if (gvideo_recv[i]) + gvideo_recv[i]->func->early_proc(gvideo_recv[i], 0); + } +} + static inline int recvx_early_proc(u8 path_index) { if (atomic_read(&video_unreg_flag)) return -1; check_src_fmt_change(); - if (gvideo_recv[path_index]) { - /* normal mode: true; lowlatency mode: false */ - gvideo_recv[path_index]->irq_mode = true; - //gvideo_recv[layer_id]->irq_mode = get_irq_mode(); - gvideo_recv[path_index]->func->early_proc(gvideo_recv[path_index], - over_field ? 1 : 0); + if (!get_lowlatency_mode()) { + if (gvideo_recv[path_index]) { + /* normal mode: true; lowlatency mode: false */ + gvideo_recv[path_index]->irq_mode = true; + gvideo_recv[path_index]->func->early_proc(gvideo_recv[path_index], + over_field ? 1 : 0); + } } return 0; } @@ -4825,7 +4837,8 @@ void post_vsync_process(void) } if (debug_flag & DEBUG_FLAG_PRINT_DISBUF_PER_VSYNC) - pr_info("VID: path id: %d, %d; new_frame:%p, %p, %p, %p, %p, %p cur:%p, %p, %p, %p; vd dispbuf:%p, %p; vf_ext:%p, %p; local:%p, %p, %p, %p\n", + pr_info("VID(%s): path id: %d, %d; new_frame:%p, %p, %p, %p, %p, %p cur:%p, %p, %p, %p; vd dispbuf:%p, %p; vf_ext:%p, %p; local:%p, %p, %p, %p\n", + __func__, vd_path_id[0], vd_path_id[1], path_new_frame[0], path_new_frame[1], path_new_frame[2], path_new_frame[3], @@ -4855,7 +4868,8 @@ void post_vsync_process(void) cur_vd_path_id[i], &path_new_frame[0]); if (debug_flag & DEBUG_FLAG_PRINT_DISBUF_PER_VSYNC) - pr_info("VID: layer enable status: VD1:e:%d,e_save:%d,g:%d,d:%d,f:%s; VD2:e:%d,e_save:%d,g:%d,d:%d,f:%s;", + pr_info("VID(%s): layer enable status: VD1:e:%d,e_save:%d,g:%d,d:%d,f:%s; VD2:e:%d,e_save:%d,g:%d,d:%d,f:%s;", + __func__, vd_layer[0].enabled, vd_layer[0].enabled_status_saved, vd_layer[0].global_output, vd_layer[0].disable_video, vd_layer[0].force_disable ? "true" : "false", @@ -4894,7 +4908,8 @@ void post_vsync_process(void) } if (debug_flag & DEBUG_FLAG_PRINT_DISBUF_PER_VSYNC) - pr_info("VID: path id: %d, %d, %d; new_frame:%p, %p, %p, %p, %p, %p cur:%p, %p, %p, %p, %p, %p; vd dispbuf:%p, %p, %p; vf_ext:%p, %p, %p; local:%p, %p, %p, %p, %p, %p\n", + pr_info("VID(%s): path id: %d, %d, %d; new_frame:%p, %p, %p, %p, %p, %p cur:%p, %p, %p, %p, %p, %p; vd dispbuf:%p, %p, %p; vf_ext:%p, %p, %p; local:%p, %p, %p, %p, %p, %p\n", + __func__, vd_path_id[0], vd_path_id[1], vd_path_id[2], path_new_frame[0], path_new_frame[1], path_new_frame[2], path_new_frame[3], @@ -4928,7 +4943,8 @@ void post_vsync_process(void) cur_vd_path_id[i], &path_new_frame[0]); if (debug_flag & DEBUG_FLAG_PRINT_DISBUF_PER_VSYNC) - pr_info("VID: layer enable status: VD1:e:%d,e_save:%d,g:%d,d:%d,f:%s; VD2:e:%d,e_save:%d,g:%d,d:%d,f:%s; VD3:e:%d,e_save:%d,g:%d,d:%d,f:%s", + pr_info("(%s)VID: layer enable status: VD1:e:%d,e_save:%d,g:%d,d:%d,f:%s; VD2:e:%d,e_save:%d,g:%d,d:%d,f:%s; VD3:e:%d,e_save:%d,g:%d,d:%d,f:%s", + __func__, vd_layer[0].enabled, vd_layer[0].enabled_status_saved, vd_layer[0].global_output, vd_layer[0].disable_video, vd_layer[0].force_disable ? "true" : "false", diff --git a/drivers/media/video_sink/video_func.h b/drivers/media/video_sink/video_func.h index d342e50b7..83b7b072a 100644 --- a/drivers/media/video_sink/video_func.h +++ b/drivers/media/video_sink/video_func.h @@ -170,6 +170,6 @@ void pre_vsync_process(void); ssize_t blend_conflict_show(struct class *cla, struct class_attribute *attr, char *buf); - +void put_buffer_proc(void); #endif /*VIDEO_FUNC_HEADER_HH*/ diff --git a/drivers/media/video_sink/video_low_latency.c b/drivers/media/video_sink/video_low_latency.c index 55c1d0669..2a1a58d43 100644 --- a/drivers/media/video_sink/video_low_latency.c +++ b/drivers/media/video_sink/video_low_latency.c @@ -64,10 +64,12 @@ MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_DEFAULT_LEVEL_DESC, LOG_MASK_DESC); #include #endif #include +#include #include #include "video_receiver.h" #include "video_low_latency.h" +#include "video_common.h" static u32 lowlatency_proc_drop; static u32 lowlatency_err_drop; @@ -235,21 +237,22 @@ static int lowlatency_vsync(u8 instance_id) vd_layer[2].next_canvas_id = 1; } #endif - - if (gvideo_recv[0]) { - gvideo_recv[0]->irq_mode = false; - gvideo_recv[0]->func->early_proc(gvideo_recv[0], - over_field ? 1 : 0); - } - if (gvideo_recv[1]) { - gvideo_recv[1]->irq_mode = false; - gvideo_recv[1]->func->early_proc(gvideo_recv[1], - over_field ? 1 : 0); - } - if (gvideo_recv[2]) { - gvideo_recv[2]->irq_mode = false; - gvideo_recv[2]->func->early_proc(gvideo_recv[2], - over_field ? 1 : 0); + if (!get_lowlatency_mode()) { + if (gvideo_recv[0]) { + gvideo_recv[0]->irq_mode = false; + gvideo_recv[0]->func->early_proc(gvideo_recv[0], + over_field ? 1 : 0); + } + if (gvideo_recv[1]) { + gvideo_recv[1]->irq_mode = false; + gvideo_recv[1]->func->early_proc(gvideo_recv[1], + over_field ? 1 : 0); + } + if (gvideo_recv[2]) { + gvideo_recv[2]->irq_mode = false; + gvideo_recv[2]->func->early_proc(gvideo_recv[2], + over_field ? 1 : 0); + } } /* video_render.0 toggle frame */ @@ -499,7 +502,8 @@ static int lowlatency_vsync(u8 instance_id) blackout[0], blackout[1], blackout[2], force_blackout); } if (debug_flag & DEBUG_FLAG_PRINT_DISBUF_PER_VSYNC) - pr_info("VID: path id: %d, %d, %d; new_frame:%p, %p, %p, %p, %p, %p cur:%p, %p, %p, %p, %p, %p; vd dispbuf:%p, %p, %p; vf_ext:%p, %p, %p; local:%p, %p, %p, %p, %p, %p\n", + pr_info("VID(%s): path id: %d, %d, %d; new_frame:%p, %p, %p, %p, %p, %p cur:%p, %p, %p, %p, %p, %p; vd dispbuf:%p, %p, %p; vf_ext:%p, %p, %p; local:%p, %p, %p, %p, %p, %p\n", + __func__, vd1_path_id, vd2_path_id, vd2_path_id, path0_new_frame, path1_new_frame, path2_new_frame, path3_new_frame, @@ -740,7 +744,8 @@ static int lowlatency_vsync(u8 instance_id) } if (debug_flag & DEBUG_FLAG_PRINT_DISBUF_PER_VSYNC) - pr_info("VID: layer enable status: VD1:e:%d,e_save:%d,g:%d,d:%d,f:%s; VD2:e:%d,e_save:%d,g:%d,d:%d,f:%s; VD3:e:%d,e_save:%d,g:%d,d:%d,f:%s", + pr_info("VID(%s): layer enable status: VD1:e:%d,e_save:%d,g:%d,d:%d,f:%s; VD2:e:%d,e_save:%d,g:%d,d:%d,f:%s; VD3:e:%d,e_save:%d,g:%d,d:%d,f:%s", + __func__, vd_layer[0].enabled, vd_layer[0].enabled_status_saved, vd_layer[0].global_output, vd_layer[0].disable_video, vd_layer[0].force_disable ? "true" : "false", diff --git a/drivers/media/video_sink/video_receiver.c b/drivers/media/video_sink/video_receiver.c index d6c6f9fbf..32e10f8a9 100644 --- a/drivers/media/video_sink/video_receiver.c +++ b/drivers/media/video_sink/video_receiver.c @@ -87,6 +87,12 @@ static inline struct vframe_s *common_vf_get(struct video_recv_s *ins) vf->index_disp, ktime_to_us(ktime_get())); if (vf) { + if (debug_flag & DEBUG_FLAG_PRINT_FRAME_DETAIL) + pr_info("%s:vf=%p, vf->type=0x%x, vf->flag=0x%x,canvas adr:0x%lx, canvas0:%x, pnum:%d, afbc:0x%lx-0x%lx,\n", + __func__, + vf, vf->type, vf->flag, + vf->canvas0_config[0].phy_addr, vf->canvas0Addr, vf->plane_num, + vf->compHeadAddr, vf->compBodyAddr); vpp_trace_vframe("common_vf_get", (void *)vf, vf->type, vf->flag, ins->vpp_id, vsync_cnt[ins->vpp_id]); @@ -137,6 +143,12 @@ static inline void common_vf_put(struct video_recv_s *ins, (void *)vf, vf->type, vf->flag, ins->vpp_id, vsync_cnt[ins->vpp_id]); vf_put(vf, ins->recv_name); + if (debug_flag & DEBUG_FLAG_PRINT_FRAME_DETAIL) + pr_info("%s:vf=%p, vf->type=0x%x, vf->flag=0x%x,canvas adr:0x%lx, canvas0:%x, pnum:%d, afbc:0x%lx-0x%lx,\n", + __func__, + vf, vf->type, vf->flag, + vf->canvas0_config[0].phy_addr, vf->canvas0Addr, vf->plane_num, + vf->compHeadAddr, vf->compBodyAddr); #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION if ((glayer_info[0].display_path_id == ins->path_id || is_multi_dv_mode()) && is_amdv_enable()) @@ -146,6 +158,12 @@ static inline void common_vf_put(struct video_recv_s *ins, } } +static void init_receiver_buffer_q(struct video_recv_s *ins) +{ + INIT_KFIFO(ins->put_q); + kfifo_reset(&ins->put_q); +} + /* TODO: need add keep frame function */ static void common_vf_unreg_provider(struct video_recv_s *ins) { @@ -189,6 +207,7 @@ static void common_vf_unreg_provider(struct video_recv_s *ins) ins->buf_to_put_num = 0; for (i = 0; i < DISPBUF_TO_PUT_MAX; i++) ins->buf_to_put[i] = NULL; + init_receiver_buffer_q(ins); ins->rdma_buf = NULL; ins->original_vf = NULL; ins->switch_vf = false; @@ -384,6 +403,7 @@ static void common_vf_light_unreg_provider(struct video_recv_s *ins) ins->buf_to_put_num = 0; for (i = 0; i < DISPBUF_TO_PUT_MAX; i++) ins->buf_to_put[i] = NULL; + init_receiver_buffer_q(ins); ins->rdma_buf = NULL; if (ins->cur_buf) { @@ -498,6 +518,20 @@ static bool is_vsync_vppx_rdma_enable(u8 vpp_index) return enable; } +void put_receiver_buffer_q(struct video_recv_s *ins) +{ + struct vframe_s *vf = NULL; + + while (kfifo_len(&ins->put_q) > 0) { + if (kfifo_get(&ins->put_q, &vf)) { + if (debug_flag & DEBUG_FLAG_PRINT_FRAME_DETAIL) + pr_info("%s, put vf=0x%p\n", + __func__, vf); + common_vf_put(ins, vf); + } + } +} + static void common_toggle_frame(struct video_recv_s *ins, struct vframe_s *vf) { @@ -523,10 +557,10 @@ static void common_toggle_frame(struct video_recv_s *ins, ins->original_vf; ins->buf_to_put_num++; } else { - common_vf_put(ins, ins->original_vf); + kfifo_put(&ins->put_q, ins->original_vf); } } else { - common_vf_put(ins, ins->original_vf); + kfifo_put(&ins->put_q, ins->original_vf); } } else { for (i = 0; i < ins->buf_to_put_num; i++) { @@ -566,6 +600,7 @@ static s32 recv_common_early_process(struct video_recv_s *ins, u32 op) /* not over vsync */ if (!op) { + put_receiver_buffer_q(ins); for (i = 0; i < ins->buf_to_put_num; i++) { if (ins->buf_to_put[i]) { ins->buf_to_put[i]->rendered = true; @@ -734,7 +769,7 @@ static struct vframe_s *recv_common_dequeue_frame(struct video_recv_s *ins, } else { vf = common_vf_get(ins); if (vf) - common_vf_put(ins, vf); + kfifo_put(&ins->put_q, vf); } drop_count++; vf = common_vf_peek(ins); diff --git a/drivers/media/video_sink/video_receiver.h b/drivers/media/video_sink/video_receiver.h index b2c95b725..ae3f7cdbd 100644 --- a/drivers/media/video_sink/video_receiver.h +++ b/drivers/media/video_sink/video_receiver.h @@ -19,9 +19,12 @@ #ifndef VIDEO_RECEIVER_HEADER_HH #define VIDEO_RECEIVER_HEADER_HH +#include #include #include "video_priv.h" +#define RECEIVER_BUFFER_POOL_SIZE 4 + struct video_layer_s; struct recv_func_s { @@ -43,6 +46,7 @@ struct video_recv_s { struct vframe_s *rdma_buf; struct vframe_s *buf_to_put[DISPBUF_TO_PUT_MAX]; struct vframe_s *original_vf; + DECLARE_KFIFO(put_q, struct vframe_s *, RECEIVER_BUFFER_POOL_SIZE); bool switch_vf; bool last_switch_state; diff --git a/include/linux/amlogic/media/video_processor/video_pp_common.h b/include/linux/amlogic/media/video_processor/video_pp_common.h index a571745c7..d28837346 100644 --- a/include/linux/amlogic/media/video_processor/video_pp_common.h +++ b/include/linux/amlogic/media/video_processor/video_pp_common.h @@ -22,6 +22,8 @@ #include int get_ge2d_input_format(struct vframe_s *vf); - +#ifdef CONFIG_AMLOGIC_VIDEO_COMPOSER +bool get_lowlatency_mode(void); +#endif #endif /* VIDEO_PP_COMMON_H */