vpp: fix display blurred in lowlatency mode [1/1]

PD#SWPL-132411

Problem:
video buffer put back when in lowlatency proc

Solution:
only put video buffer in vsync_isr

Verify:
ohm

Change-Id: If78ef47a58fa93d44303d49c84c4079a1b1e321c
Signed-off-by: Pengcheng Chen <pengcheng.chen@amlogic.com>
This commit is contained in:
Pengcheng Chen
2023-08-16 17:47:27 +08:00
committed by gerrit autosubmit
parent b41991ebf3
commit bd1bc39010
12 changed files with 119 additions and 36 deletions
@@ -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);
@@ -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 */
@@ -23,8 +23,8 @@
#include <linux/amlogic/media/video_sink/video.h>
#endif
#include <linux/amlogic/media/registers/cpu_version.h>
#include <linux/amlogic/media/video_processor/video_pp_common.h>
#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,
+3
View File
@@ -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 <linux/amlogic/media/amprime_sl/prime_sl.h>
#endif
#include <linux/amlogic/media/video_processor/video_pp_common.h>
#include <linux/math64.h>
#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++;
+7
View File
@@ -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);
+3
View File
@@ -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
+26 -10
View File
@@ -68,6 +68,7 @@
#ifdef CONFIG_AMLOGIC_MEDIA_FRC
#include <linux/amlogic/media/frc/frc_common.h>
#endif
#include <linux/amlogic/media/video_processor/video_pp_common.h>
#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",
+1 -1
View File
@@ -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*/
+22 -17
View File
@@ -64,10 +64,12 @@ MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_DEFAULT_LEVEL_DESC, LOG_MASK_DESC);
#include <uapi/amlogic/msync.h>
#endif
#include <linux/amlogic/gki_module.h>
#include <linux/amlogic/media/video_processor/video_pp_common.h>
#include <linux/math64.h>
#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",
+38 -3
View File
@@ -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);
@@ -19,9 +19,12 @@
#ifndef VIDEO_RECEIVER_HEADER_HH
#define VIDEO_RECEIVER_HEADER_HH
#include <linux/kfifo.h>
#include <linux/amlogic/media/vfm/vframe.h>
#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;
@@ -22,6 +22,8 @@
#include <linux/amlogic/media/vfm/vframe.h>
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 */