ppmgr: add keep last frame in ppmgr. [5/6]

PD#SWPL-9350

Problem:
freeze frame fail among two vertical videos switching.

Solution:
add keep last frame in ppmgr

Verify:
on U212

Change-Id: I7192c69725ce08a546af3f2252e743224ad19ec3
Signed-off-by: renjiang.han <renjiang.han@amlogic.com>
This commit is contained in:
renjiang.han
2019-06-04 19:13:04 +08:00
committed by Gongwei Chen
parent 307be27f2a
commit 74a6fddf48
3 changed files with 115 additions and 69 deletions

View File

@@ -2238,7 +2238,7 @@ static void process_vf_rotate(struct vframe_s *vf,
#endif
ppmgr_vf_put_dec(vf);
new_vf->source_type = VFRAME_SOURCE_TYPE_PPMGR;
vfq_push(&q_ready, new_vf);
#ifdef DDD

View File

@@ -112,13 +112,6 @@ static int video_pause_global = 1;
static u32 cur_omx_index;
#ifdef CONFIG_GE2D_KEEP_FRAME
/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
/* #include <mach/mod_gate.h> */
/* #endif */
/* #include "mach/meson-secure.h" */
#endif
#if 1
/*TODO for logo*/
struct platform_resource_s {
@@ -8666,27 +8659,13 @@ static void video_vf_unreg_provider(void)
try_free_keep_video(1);
}
#ifdef CONFIG_GE2D_KEEP_FRAME
if (cur_dispbuf) {
/* TODO: mod gate */
/* switch_mod_gate_by_name("ge2d", 1); */
keeped = vf_keep_current(cur_dispbuf, el_vf);
/* TODO: mod gate */
/* switch_mod_gate_by_name("ge2d", 0); */
}
if ((hdmi_in_onvideo == 0) && (video_start_post)) {
tsync_avevent(VIDEO_STOP, 0);
video_start_post = false;
}
#else
/* if (!trickmode_fffb) */
if (cur_dispbuf)
keeped = vf_keep_current(cur_dispbuf, el_vf);
if ((hdmi_in_onvideo == 0) && (video_start_post)) {
tsync_avevent(VIDEO_STOP, 0);
video_start_post = false;
}
#endif
if (keeped < 0) {/*keep failed.*/
pr_info("video keep failed, disable video now!\n");
safe_disble_videolayer();

View File

@@ -45,7 +45,7 @@
#include <linux/amlogic/media/canvas/canvas_mgr.h>
#include <linux/dma-mapping.h>
#include <linux/dma-contiguous.h>
#ifdef CONFIG_GE2D_KEEP_FRAME
#ifdef CONFIG_AMLOGIC_MEDIA_GE2D
#include <linux/amlogic/media/ge2d/ge2d.h>
#include <linux/amlogic/media/canvas/canvas_mgr.h>
#endif
@@ -74,7 +74,7 @@ static int keep_el_head_id;
static int keep_pip_el_id;
static int keep_pip_el_head_id;
#define Y_BUFFER_SIZE 0x400000 /* for 1920*1088 */
#define Y_BUFFER_SIZE 0x600000 /* for 1920*1088 */
#define U_BUFFER_SIZE 0x100000 /* compatible with NV21 */
#define V_BUFFER_SIZE 0x80000
@@ -85,7 +85,7 @@ static inline ulong keep_phy_addr(unsigned long addr)
return addr;
}
#ifdef CONFIG_GE2D_KEEP_FRAME
#ifdef CONFIG_AMLOGIC_MEDIA_GE2D
static int display_canvas_y_dup;
static int display_canvas_u_dup;
static int display_canvas_v_dup;
@@ -131,6 +131,80 @@ static int ge2d_videotask_release(void)
return 0;
}
static int ge2d_store_frame_S_YUV444(u32 cur_index)
{
u32 y_index, des_index, src_index;
struct canvas_s cs, cd;
ulong yaddr;
u32 ydupindex;
struct config_para_ex_s ge2d_config;
memset(&ge2d_config, 0, sizeof(struct config_para_ex_s));
ydupindex = display_canvas_y_dup;
pr_info("ge2d_store_frame_S_YUV444 cur_index:s:0x%x\n", cur_index);
/* pr_info("ge2d_store_frame cur_index:d:0x%x\n", canvas_tab[0]); */
y_index = cur_index & 0xff;
canvas_read(y_index, &cs);
yaddr = keep_phy_addr(keep_y_addr);
canvas_config(ydupindex,
(ulong) yaddr,
cs.width, cs.height, CANVAS_ADDR_NOWRAP, cs.blkmode);
canvas_read(ydupindex, &cd);
src_index = y_index;
des_index = ydupindex;
pr_info("ge2d_canvas_dup ADDR srcy[0x%lx] des[0x%lx] des_index[0x%x]\n",
cs.addr, cd.addr, des_index);
ge2d_config.alu_const_color = 0;
ge2d_config.bitmask_en = 0;
ge2d_config.src1_gb_alpha = 0;
ge2d_config.src_planes[0].addr = cs.addr;
ge2d_config.src_planes[0].w = cs.width;
ge2d_config.src_planes[0].h = cs.height;
ge2d_config.dst_planes[0].addr = cd.addr;
ge2d_config.dst_planes[0].w = cd.width;
ge2d_config.dst_planes[0].h = cd.height;
ge2d_config.src_para.canvas_index = src_index;
ge2d_config.src_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config.src_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config.src_para.fill_color_en = 0;
ge2d_config.src_para.fill_mode = 0;
ge2d_config.src_para.color = 0;
ge2d_config.src_para.top = 0;
ge2d_config.src_para.left = 0;
ge2d_config.src_para.width = cs.width;
ge2d_config.src_para.height = cs.height;
ge2d_config.src2_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config.dst_para.canvas_index = des_index;
ge2d_config.dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config.dst_para.format = GE2D_FORMAT_S24_YUV444;
ge2d_config.dst_para.fill_color_en = 0;
ge2d_config.dst_para.fill_mode = 0;
ge2d_config.dst_para.color = 0;
ge2d_config.dst_para.top = 0;
ge2d_config.dst_para.left = 0;
ge2d_config.dst_para.width = cs.width;
ge2d_config.dst_para.height = cs.height;
if (ge2d_context_config_ex(ge2d_video_context, &ge2d_config) < 0) {
pr_info("ge2d_context_config_ex failed\n");
return -1;
}
stretchblt_noalpha(ge2d_video_context, 0, 0, cs.width, cs.height,
0, 0, cs.width, cs.height);
return 0;
}
static int ge2d_store_frame_YUV444(u32 cur_index)
{
u32 y_index, des_index, src_index;
@@ -540,13 +614,13 @@ static int ge2d_store_frame_YUV420(u32 cur_index)
static void ge2d_keeplastframe_block(int cur_index, int format)
{
u32 y_index, u_index, v_index;
#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
#if 0 /*def CONFIG_VSYNC_RDMA*/
u32 y_index2, u_index2, v_index2;
#endif
video_module_lock();
#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
#if 0 /*def CONFIG_VSYNC_RDMA*/
y_index = disp_canvas_index[0][0];
y_index2 = disp_canvas_index[1][0];
u_index = disp_canvas_index[0][1];
@@ -564,41 +638,50 @@ static void ge2d_keeplastframe_block(int cur_index, int format)
#endif
switch (format) {
case GE2D_FORMAT_S24_YUV444:
pr_info("GE2D_FORMAT_S24_YUV444\n");
ge2d_store_frame_S_YUV444(cur_index);
canvas_update_addr(y_index, keep_phy_addr(keep_y_addr));
break;
case GE2D_FORMAT_M24_YUV444:
pr_info("GE2D_FORMAT_M24_YUV444\n");
ge2d_store_frame_YUV444(cur_index);
canvas_update_addr(y_index, keep_phy_addr(keep_y_addr));
#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
#if 0 /*def CONFIG_VSYNC_RDMA*/
canvas_update_addr(y_index2, keep_phy_addr(keep_y_addr));
#endif
break;
case GE2D_FORMAT_M24_NV21:
pr_info("GE2D_FORMAT_M24_NV21\n");
ge2d_store_frame_NV21(cur_index);
canvas_update_addr(y_index, keep_phy_addr(keep_y_addr));
canvas_update_addr(u_index, keep_phy_addr(keep_u_addr));
#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
#if 0 /*def CONFIG_VSYNC_RDMA*/
canvas_update_addr(y_index2, keep_phy_addr(keep_y_addr));
canvas_update_addr(u_index2, keep_phy_addr(keep_u_addr));
#endif
break;
case GE2D_FORMAT_M24_YUV420:
pr_info("GE2D_FORMAT_M24_YUV420\n");
ge2d_store_frame_YUV420(cur_index);
canvas_update_addr(y_index, keep_phy_addr(keep_y_addr));
canvas_update_addr(u_index, keep_phy_addr(keep_u_addr));
canvas_update_addr(v_index, keep_phy_addr(keep_v_addr));
#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
#if 0 /*def CONFIG_VSYNC_RDMA*/
canvas_update_addr(y_index2, keep_phy_addr(keep_y_addr));
canvas_update_addr(u_index2, keep_phy_addr(keep_u_addr));
canvas_update_addr(v_index2, keep_phy_addr(keep_v_addr));
#endif
break;
default:
pr_info("default\n");
break;
}
video_module_unlock();
}
#endif
#ifndef CONFIG_AMLOGIC_MEDIA_GE2D
#define FETCHBUF_SIZE (64*1024) /*DEBUG_TMP*/
static int canvas_dup(ulong dst, ulong src_paddr, ulong size)
{
@@ -617,7 +700,7 @@ static int canvas_dup(ulong dst, ulong src_paddr, ulong size)
return 0;
}
#endif
#ifdef RESERVE_CLR_FRAME
static int free_alloced_keep_buffer(void)
{
@@ -645,7 +728,7 @@ static int alloc_keep_buffer(void)
{
int flags = CODEC_MM_FLAGS_DMA |
CODEC_MM_FLAGS_FOR_VDECODER;
#ifndef CONFIG_GE2D_KEEP_FRAME
#ifndef CONFIG_AMLOGIC_MEDIA_GE2D
/*
* if not used ge2d.
* need CPU access.
@@ -916,8 +999,12 @@ static unsigned int vf_keep_current_locked(
return 0;
}
if (get_video_debug_flags() &
DEBUG_FLAG_TOGGLE_SKIP_KEEP_CURRENT) {
if (cur_dispbuf->source_type == VFRAME_SOURCE_TYPE_OSD) {
pr_info("keep exit is osd\n");
return 0;
}
if (get_video_debug_flags() & DEBUG_FLAG_TOGGLE_SKIP_KEEP_CURRENT) {
pr_info("keep exit is skip current\n");
return 0;
}
@@ -936,6 +1023,11 @@ static unsigned int vf_keep_current_locked(
return 0;
}
if (cur_dispbuf->source_type == VFRAME_SOURCE_TYPE_PPMGR) {
pr_info("use ge2d keep frame!\n");
goto GE2D_KEEP_FRAME;
}
ret = video_keeper_frame_keep_locked(
cur_dispbuf,
cur_dispbuf_el);
@@ -944,6 +1036,7 @@ static unsigned int vf_keep_current_locked(
keep_video_on = 1;
return 1;
}
GE2D_KEEP_FRAME:
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
if (codec_mm_video_tvp_enabled()) {
pr_info("keep exit is TVP\n");
@@ -963,7 +1056,7 @@ static unsigned int vf_keep_current_locked(
v_index = (cur_index >> 16) & 0xff;
canvas_read(y_index, &cd);
if ((cd.width * cd.height) <= 2048 * 1088
if ((cd.width * cd.height) <= 1920 * 1088 * 3
&& !keep_y_addr) {
alloc_keep_buffer();
}
@@ -983,32 +1076,6 @@ static unsigned int vf_keep_current_locked(
if ((cur_dispbuf->type & VIDTYPE_VIU_422) == VIDTYPE_VIU_422) {
return -1;
/* no VIDTYPE_VIU_422 type frame need keep,avoid memcpy crash*/
/*
if ((Y_BUFFER_SIZE < (cd.width * cd.height))) {
pr_info("[%s::%d]data > buf size: %x,%x,%x, %x,%x\n",
__func__, __LINE__, Y_BUFFER_SIZE,
U_BUFFER_SIZE, V_BUFFER_SIZE,
cd.width, cd.height);
return -1;
}
if (keep_phy_addr(keep_y_addr) != canvas_get_addr(y_index) &&
canvas_dup(keep_phy_addr(keep_y_addr),
canvas_get_addr(y_index),
(cd.width) * (cd.height))) {
#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
canvas_update_addr(disp_canvas_index[0][0],
keep_phy_addr(keep_y_addr));
canvas_update_addr(disp_canvas_index[1][0],
keep_phy_addr(keep_y_addr));
#else
canvas_update_addr(y_index,
keep_phy_addr(keep_y_addr));
#endif
if (get_video_debug_flags() & DEBUG_FLAG_BLACKOUT)
pr_info("%s: VIDTYPE_VIU_422\n", __func__);
}
*/
} else if ((cur_dispbuf->type & VIDTYPE_VIU_444) == VIDTYPE_VIU_444) {
if ((Y_BUFFER_SIZE < (cd.width * cd.height))) {
pr_info
@@ -1018,8 +1085,8 @@ static unsigned int vf_keep_current_locked(
cd.width, cd.height);
return -1;
}
#ifdef CONFIG_GE2D_KEEP_FRAME
ge2d_keeplastframe_block(cur_index, GE2D_FORMAT_M24_YUV444);
#ifdef CONFIG_AMLOGIC_MEDIA_GE2D
ge2d_keeplastframe_block(cur_index, GE2D_FORMAT_S24_YUV444);
#else
if (keep_phy_addr(keep_y_addr) != canvas_get_addr(y_index) &&
canvas_dup(keep_phy_addr(keep_y_addr),
@@ -1047,7 +1114,7 @@ static unsigned int vf_keep_current_locked(
__func__, __LINE__);
return -1;
}
#ifdef CONFIG_GE2D_KEEP_FRAME
#ifdef CONFIG_AMLOGIC_MEDIA_GE2D
ge2d_keeplastframe_block(cur_index, GE2D_FORMAT_M24_NV21);
#else
if (keep_phy_addr(keep_y_addr) != canvas_get_addr(y_index) &&
@@ -1091,7 +1158,7 @@ static unsigned int vf_keep_current_locked(
cs2.height);
return -1;
}
#ifdef CONFIG_GE2D_KEEP_FRAME
#ifdef CONFIG_AMLOGIC_MEDIA_GE2D
ge2d_keeplastframe_block(cur_index, GE2D_FORMAT_M24_YUV420);
#else
if (keep_phy_addr(keep_y_addr) != canvas_get_addr(y_index) &&
@@ -1197,7 +1264,7 @@ unsigned int vf_keep_current(
int __init video_keeper_init(void)
{
#ifdef CONFIG_GE2D_KEEP_FRAME
#ifdef CONFIG_AMLOGIC_MEDIA_GE2D
/* video_frame_getmem(); */
ge2d_videotask_init();
#endif
@@ -1205,7 +1272,7 @@ int __init video_keeper_init(void)
}
void __exit video_keeper_exit(void)
{
#ifdef CONFIG_GE2D_KEEP_FRAME
#ifdef CONFIG_AMLOGIC_MEDIA_GE2D
ge2d_videotask_release();
#endif
}