ppmgr: modify first frame garbage. [1/1]

PD#SWPL-9350

Problem:
ppmgr first frame garbage for afbc.

Solution:
alloc canvas.

Verify:
on u212

Change-Id: Ifd8d865240fee07f37d8ed47b224a39f24eac3d4
Signed-off-by: renjiang.han <renjiang.han@amlogic.com>
This commit is contained in:
renjiang.han
2019-06-15 23:16:39 +08:00
committed by Chris KIM
parent 9888fd0eb5
commit b3499b7872
4 changed files with 425 additions and 242 deletions

View File

@@ -73,6 +73,9 @@ struct ppmgr_device_t {
void __iomem *vir_addr;
struct platform_device *pdev;
unsigned int ppmgr_debug;
unsigned int debug_first_frame;
unsigned int debug_10bit_frame;
char dump_path[32];
};
struct ppmgr_dev_reg_s {

View File

@@ -458,6 +458,54 @@ static ssize_t ppmgr_debug_write(struct class *cla,
return count;
}
static ssize_t debug_first_frame_read(struct class *cla,
struct class_attribute *attr, char *buf)
{
return snprintf(buf,
80,
"current debug_first_frame is %d\n",
ppmgr_device.debug_first_frame);
}
static ssize_t debug_first_frame_write(struct class *cla,
struct class_attribute *attr, const char *buf, size_t count)
{
long tmp;
int ret = kstrtol(buf, 0, &tmp);
if (ret != 0) {
PPMGRDRV_ERR("ERROR converting %s to long int!\n", buf);
return ret;
}
ppmgr_device.debug_first_frame = tmp;
return count;
}
static ssize_t debug_10bit_frame_read(struct class *cla,
struct class_attribute *attr, char *buf)
{
return snprintf(buf,
80,
"current debug_10bit_frame is %d\n",
ppmgr_device.debug_10bit_frame);
}
static ssize_t debug_10bit_frame_write(struct class *cla,
struct class_attribute *attr, const char *buf, size_t count)
{
long tmp;
int ret = kstrtol(buf, 0, &tmp);
if (ret != 0) {
PPMGRDRV_ERR("ERROR converting %s to long int!\n", buf);
return ret;
}
ppmgr_device.debug_10bit_frame = tmp;
return count;
}
static ssize_t rect_read(struct class *cla, struct class_attribute *attr,
char *buf)
{
@@ -520,6 +568,26 @@ static ssize_t rect_write(struct class *cla, struct class_attribute *attr,
return count;
}
static ssize_t dump_path_read(struct class *cla, struct class_attribute *attr,
char *buf)
{
return snprintf(buf, 80,
"ppmgr dump path is: %s\n",
ppmgr_device.dump_path);
}
static ssize_t dump_path_write(struct class *cla, struct class_attribute *attr,
const char *buf, size_t count)
{
char *tmp;
tmp = kstrdup(buf, GFP_KERNEL);
strcpy(ppmgr_device.dump_path, tmp);
return count;
}
static ssize_t disp_read(struct class *cla, struct class_attribute *attr,
char *buf)
{
@@ -1292,6 +1360,20 @@ __ATTR(ppmgr_debug,
0644,
ppmgr_debug_read,
ppmgr_debug_write),
__ATTR(debug_first_frame,
0644,
debug_first_frame_read,
debug_first_frame_write),
__ATTR(debug_10bit_frame,
0644,
debug_10bit_frame_read,
debug_10bit_frame_write),
__ATTR(dump_path,
0644,
dump_path_read,
dump_path_write),
__ATTR(disp,
0644,
@@ -1623,6 +1705,8 @@ int init_ppmgr_device(void)
ppmgr_device.tb_detect_buf_len = 8;
ppmgr_device.tb_detect_init_mute = 0;
ppmgr_device.ppmgr_debug = 0;
ppmgr_device.debug_first_frame = 0;
ppmgr_device.debug_10bit_frame = 0;
PPMGRDRV_INFO("ppmgr_dev major:%d\n", ret);
ppmgr_device.cla = init_ppmgr_cls();

View File

@@ -168,7 +168,7 @@ static u8 tb_detect_last_flag;
static u32 tb_buff_wptr;
static u32 tb_buff_rptr;
static s32 tb_canvas = -1;
static u32 tb_src_canvas;
static s32 tb_src_canvas[3] = {-1, -1, -1};
static s8 tb_buffer_status;
static u32 tb_buffer_start;
static u32 tb_buffer_size;
@@ -183,6 +183,10 @@ static struct TB_DetectFuncPtr *gfunc;
static int tb_buffer_init(void);
static int tb_buffer_uninit(void);
#endif
static s32 ppmgr_src_canvas[3] = {-1, -1, -1};
static int dumpfirstframe;
static int count_scr;
static int count_dst;
const struct vframe_receiver_op_s *vf_ppmgr_reg_provider(void);
@@ -216,8 +220,6 @@ u32 index2canvas(u32 index)
return ppmgr_canvas_tab[index];
}
#define PPMGR2_CANVAS_INDEX_SRC (PPMGR_CANVAS_INDEX + 8)
/************************************************
*
* ppmgr as a frame provider
@@ -339,12 +341,14 @@ static int get_source_type(struct vframe_s *vf)
if ((vf->source_type == VFRAME_SOURCE_TYPE_HDMI)
|| (vf->source_type == VFRAME_SOURCE_TYPE_CVBS)) {
if ((vf->bitdepth & BITDEPTH_Y10)
&& (!(vf->type & VIDTYPE_COMPRESS))
&& (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL))
ret = VDIN_10BIT_NORMAL;
else
ret = VDIN_8BIT_NORMAL;
} else {
if ((vf->bitdepth & BITDEPTH_Y10)
&& (!(vf->type & VIDTYPE_COMPRESS))
&& (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL)) {
if (interlace_mode == VIDTYPE_INTERLACE_TOP)
ret = DECODER_10BIT_TOP;
@@ -650,6 +654,12 @@ static const struct vframe_provider_s *dec_vfp;
const struct vframe_receiver_op_s *vf_ppmgr_reg_provider(void)
{
const struct vframe_receiver_op_s *r = NULL;
if (ppmgr_device.debug_first_frame == 1) {
dumpfirstframe = 1;
count_scr = 0;
count_dst = 0;
PPMGRVPP_INFO("need dump first frame!\n");
}
mutex_lock(&ppmgr_mutex);
@@ -797,10 +807,12 @@ static void vf_rotate_adjust(struct vframe_s *vf, struct vframe_s *new_vf,
input_height = vf->height * 2;
else
input_height = vf->height;
if (ppmgr_device.ppmgr_debug)
if (ppmgr_device.ppmgr_debug) {
PPMGRVPP_INFO("disp_width: %d, disp_height: %d\n",
disp_w, disp_h);
PPMGRVPP_INFO("input_width: %d, input_height: %d\n",
input_width, input_height);
}
if (angle & 1) {
int ar = (vf->ratio_control
>> DISP_RATIO_ASPECT_RATIO_BIT) & 0x3ff;
@@ -992,21 +1004,21 @@ static int process_vf_tb_detect(struct vframe_s *vf,
if (vf->canvas0Addr == (u32)-1) {
canvas_config_config(
tb_src_canvas & 0xff,
tb_src_canvas[0] & 0xff,
&src_vf.canvas0_config[0]);
if (src_vf.plane_num == 2) {
canvas_config_config(
(tb_src_canvas >> 8) & 0xff,
tb_src_canvas[1] & 0xff,
&src_vf.canvas0_config[1]);
} else if (src_vf.plane_num == 3) {
canvas_config_config(
(tb_src_canvas >> 16) & 0xff,
tb_src_canvas[2] & 0xff,
&src_vf.canvas0_config[2]);
}
src_vf.canvas0Addr =
(tb_src_canvas & 0xff)
| (((tb_src_canvas >> 8) & 0xff) << 8)
| (((tb_src_canvas >> 16) & 0xff) << 16);
(tb_src_canvas[0] & 0xff)
| ((tb_src_canvas[1] & 0xff) << 8)
| ((tb_src_canvas[2] & 0xff) << 16);
canvas_read(
src_vf.canvas0Addr & 0xff, &cs0);
@@ -1089,6 +1101,38 @@ static int process_vf_tb_detect(struct vframe_s *vf,
}
#endif
static int copy_phybuf_to_file(ulong phys, u32 size,
struct file *fp, loff_t pos)
{
u32 span = SZ_1M;
u8 *p;
int remain_size = 0;
ssize_t ret;
remain_size = size;
while (remain_size > 0) {
if (remain_size < span)
span = remain_size;
p = codec_mm_vmap(phys, PAGE_ALIGN(span));
if (!p) {
PPMGRVPP_INFO("vmap failed\n");
return -1;
}
codec_mm_dma_flush(p, span, DMA_FROM_DEVICE);
ret = vfs_write(fp, (char *)p,
span, &pos);
if (ret <= 0)
PPMGRVPP_INFO("vfs write failed!\n");
phys += span;
codec_mm_unmap_phyaddr(p);
remain_size -= span;
PPMGRVPP_INFO("pos: %lld, phys: %lx, remain_size: %d\n",
pos, phys, remain_size);
}
return 0;
}
static void process_vf_rotate(struct vframe_s *vf,
struct ge2d_context_s *context,
struct config_para_ex_s *ge2d_config)
@@ -1100,6 +1144,13 @@ static void process_vf_rotate(struct vframe_s *vf,
int ret = 0;
unsigned int cur_angle = 0;
int interlace_mode;
struct file *filp_scr = NULL;
struct file *filp_dst = NULL;
char source_path[64];
char dst_path[64];
int count;
int result = 0;
mm_segment_t old_fs;
#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER_3D_PROCESS
enum platform_type_t platform_type;
#endif
@@ -1166,35 +1217,47 @@ static void process_vf_rotate(struct vframe_s *vf,
pp_vf->dec_frame = vf;
if (vf->type & VIDTYPE_COMPRESS) {
if ((vf->bitdepth == (
BITDEPTH_Y10 |
BITDEPTH_U10 |
BITDEPTH_V10))
&& (!ppmgr_device.debug_10bit_frame))
pp_vf->dec_frame = vf;
if (vf->canvas0Addr != (u32)-1) {
canvas_copy(vf->canvas0Addr & 0xff,
PPMGR2_CANVAS_INDEX_SRC);
ppmgr_src_canvas[0]);
canvas_copy((vf->canvas0Addr >> 8) & 0xff,
PPMGR2_CANVAS_INDEX_SRC + 1);
ppmgr_src_canvas[1]);
canvas_copy((vf->canvas0Addr >> 16) & 0xff,
PPMGR2_CANVAS_INDEX_SRC + 2);
ppmgr_src_canvas[2]);
if (dumpfirstframe)
PPMGRVPP_INFO("compress canvas copy!\n");
} else if (vf->plane_num > 0) {
canvas_config_config(PPMGR2_CANVAS_INDEX_SRC,
canvas_config_config(ppmgr_src_canvas[0],
&vf->canvas0_config[0]);
if (vf->plane_num == 2) {
canvas_config_config(
PPMGR2_CANVAS_INDEX_SRC + 1,
ppmgr_src_canvas[1],
&vf->canvas0_config[1]);
} else if (vf->plane_num == 3) {
canvas_config_config(
PPMGR2_CANVAS_INDEX_SRC + 2,
ppmgr_src_canvas[2],
&vf->canvas0_config[2]);
}
vf->canvas0Addr =
(PPMGR2_CANVAS_INDEX_SRC)
| ((PPMGR2_CANVAS_INDEX_SRC + 1) << 8)
| ((PPMGR2_CANVAS_INDEX_SRC + 2) << 16);
ppmgr_src_canvas[0]
| (ppmgr_src_canvas[1] << 8)
| (ppmgr_src_canvas[2] << 16);
if (dumpfirstframe)
PPMGRVPP_INFO("compress canvas config\n");
} else {
pp_vf->dec_frame = vf;
if (ppmgr_device.ppmgr_debug)
PPMGRVPP_INFO("vframe is compress!\n");
}
if (dumpfirstframe == 1)
dumpfirstframe = 2;
}
if (pp_vf->dec_frame) {
/* bypass mode */
@@ -1386,21 +1449,21 @@ static void process_vf_rotate(struct vframe_s *vf,
src_vf = *vf;
if (vf->canvas0Addr == (u32)-1) {
canvas_config_config(PPMGR2_CANVAS_INDEX_SRC,
canvas_config_config(ppmgr_src_canvas[0],
&src_vf.canvas0_config[0]);
if (src_vf.plane_num == 2) {
canvas_config_config(
PPMGR2_CANVAS_INDEX_SRC + 1,
ppmgr_src_canvas[1],
&src_vf.canvas0_config[1]);
} else if (src_vf.plane_num == 3) {
canvas_config_config(
PPMGR2_CANVAS_INDEX_SRC + 2,
ppmgr_src_canvas[2],
&src_vf.canvas0_config[2]);
}
src_vf.canvas0Addr =
(PPMGR2_CANVAS_INDEX_SRC)
| ((PPMGR2_CANVAS_INDEX_SRC + 1) << 8)
| ((PPMGR2_CANVAS_INDEX_SRC + 2) << 16);
ppmgr_src_canvas[0]
| (ppmgr_src_canvas[1] << 8)
| (ppmgr_src_canvas[2] << 16);
ge2d_config->src_planes[0].addr =
src_vf.canvas0_config[0].phy_addr;
@@ -1413,14 +1476,14 @@ static void process_vf_rotate(struct vframe_s *vf,
ge2d_config->src_planes[1].w =
src_vf.canvas0_config[1].width;
ge2d_config->src_planes[1].h =
src_vf.canvas0_config[1].height << 1;
src_vf.canvas0_config[1].height >> 1;
if (src_vf.plane_num == 3) {
ge2d_config->src_planes[2].addr =
src_vf.canvas0_config[2].phy_addr;
ge2d_config->src_planes[2].w =
src_vf.canvas0_config[2].width;
ge2d_config->src_planes[2].h =
src_vf.canvas0_config[2].height << 1;
src_vf.canvas0_config[2].height >> 1;
}
} else {
canvas_read(vf->canvas0Addr & 0xff, &cs0);
@@ -1514,22 +1577,21 @@ static void process_vf_rotate(struct vframe_s *vf,
src_vf = *vf;
if (vf->canvas0Addr == (u32)-1) {
canvas_config_config(PPMGR2_CANVAS_INDEX_SRC,
canvas_config_config(ppmgr_src_canvas[0],
&src_vf.canvas0_config[0]);
if (src_vf.plane_num == 2) {
canvas_config_config(
PPMGR2_CANVAS_INDEX_SRC + 1,
ppmgr_src_canvas[1],
&src_vf.canvas0_config[1]);
} else if (src_vf.plane_num == 3) {
canvas_config_config(
PPMGR2_CANVAS_INDEX_SRC + 2,
&src_vf.canvas0_config[2]);
ppmgr_src_canvas[2],
&src_vf.canvas0_config[2]);
}
src_vf.canvas0Addr =
(PPMGR2_CANVAS_INDEX_SRC)
| ((PPMGR2_CANVAS_INDEX_SRC + 1) << 8)
| ((PPMGR2_CANVAS_INDEX_SRC + 2) << 16);
ppmgr_src_canvas[0]
| (ppmgr_src_canvas[1] << 8)
| (ppmgr_src_canvas[2] << 16);
ge2d_config->src_planes[0].addr =
src_vf.canvas0_config[0].phy_addr;
@@ -1542,14 +1604,14 @@ static void process_vf_rotate(struct vframe_s *vf,
ge2d_config->src_planes[1].w =
src_vf.canvas0_config[1].width;
ge2d_config->src_planes[1].h =
src_vf.canvas0_config[1].height << 1;
src_vf.canvas0_config[1].height >> 1;
if (src_vf.plane_num == 3) {
ge2d_config->src_planes[2].addr =
src_vf.canvas0_config[2].phy_addr;
ge2d_config->src_planes[2].w =
src_vf.canvas0_config[2].width;
ge2d_config->src_planes[2].h =
src_vf.canvas0_config[2].height << 1;
src_vf.canvas0_config[2].height >> 1;
}
ge2d_config->src_para.canvas_index = src_vf.canvas0Addr;
} else {
@@ -1713,9 +1775,68 @@ static void process_vf_rotate(struct vframe_s *vf,
0, 0, new_vf->width, new_vf->height);
#endif
if (strstr(ppmgr_device.dump_path, "scr")
&& (dumpfirstframe == 2)) {
old_fs = get_fs();
set_fs(KERNEL_DS);
count = strlen(ppmgr_device.dump_path);
ppmgr_device.dump_path[count] = count_scr;
sprintf(source_path, "%s_scr", ppmgr_device.dump_path);
count_scr++;
filp_scr = filp_open(source_path, O_RDWR | O_CREAT, 0666);
if (IS_ERR(filp_scr))
PPMGRVPP_INFO("open %s failed\n", source_path);
else {
result = copy_phybuf_to_file(
vf->canvas0_config[0].phy_addr,
(vf->canvas0_config[0].width)
* (vf->canvas0_config[0].height),
filp_scr, 0);
if (result < 0)
PPMGRVPP_INFO("write %s failed\n", source_path);
PPMGRVPP_INFO("scr addr: %0x, width: %d, height: %d\n",
vf->canvas0_config[0].phy_addr,
vf->canvas0_config[0].width,
vf->canvas0_config[0].height);
PPMGRVPP_INFO("dump source type: %d\n",
get_input_format(vf));
vfs_fsync(filp_scr, 0);
filp_close(filp_scr, NULL);
set_fs(old_fs);
}
}
ppmgr_vf_put_dec(vf);
new_vf->source_type = VFRAME_SOURCE_TYPE_PPMGR;
vfq_push(&q_ready, new_vf);
if (dumpfirstframe != 2)
vfq_push(&q_ready, new_vf);
if (strstr(ppmgr_device.dump_path, "dst")
&& (dumpfirstframe == 2)) {
old_fs = get_fs();
set_fs(KERNEL_DS);
count = strlen(ppmgr_device.dump_path);
ppmgr_device.dump_path[count] = count_dst;
sprintf(dst_path, "%s_dst", ppmgr_device.dump_path);
count_dst++;
filp_dst = filp_open(dst_path, O_RDWR | O_CREAT, 0666);
if (IS_ERR(filp_dst))
PPMGRVPP_INFO("open %s failed\n", dst_path);
else {
result = copy_phybuf_to_file(cd.addr,
cd.width * cd.height,
filp_dst, 0);
if (result < 0)
PPMGRVPP_INFO("write %s failed\n", dst_path);
PPMGRVPP_INFO("dst addr: %lx, width: %d, height: %d\n",
cd.addr, cd.width, cd.height);
PPMGRVPP_INFO("dump dst type: %d\n",
get_input_format(new_vf));
vfs_fsync(filp_dst, 0);
filp_close(filp_dst, NULL);
set_fs(old_fs);
}
if (count_dst >= ppmgr_device.ppmgr_debug)
dumpfirstframe = 0;
}
#ifdef DDD
PPMGRVPP_WARN("rotate avail=%d, free=%d\n",
@@ -2832,6 +2953,19 @@ int ppmgr_buffer_uninit(void)
ppmgr_device.buffer_start = 0;
ppmgr_device.buffer_size = 0;
}
if (ppmgr_src_canvas[0] >= 0)
canvas_pool_map_free_canvas(ppmgr_src_canvas[0]);
ppmgr_src_canvas[0] = -1;
if (ppmgr_src_canvas[1] >= 0)
canvas_pool_map_free_canvas(ppmgr_src_canvas[1]);
ppmgr_src_canvas[1] = -1;
if (ppmgr_src_canvas[2] >= 0)
canvas_pool_map_free_canvas(ppmgr_src_canvas[2]);
ppmgr_src_canvas[2] = -1;
ppmgr_buffer_status = 0;
return 0;
}
@@ -2846,6 +2980,7 @@ int ppmgr_buffer_init(int vout_mode)
struct vinfo_s vinfo = {.width = 1280, .height = 720, };
/* int flags = CODEC_MM_FLAGS_DMA; */
int flags = CODEC_MM_FLAGS_DMA | CODEC_MM_FLAGS_CMA_CLEAR;
const char *keep_owner = "ppmgr_scr";
switch (ppmgr_buffer_status) {
case 0:/*not config*/
@@ -2879,6 +3014,31 @@ int ppmgr_buffer_init(int vout_mode)
return -1;
}
}
if (ppmgr_src_canvas[0] < 0)
ppmgr_src_canvas[0] = canvas_pool_map_alloc_canvas(keep_owner);
if (ppmgr_src_canvas[0] < 0) {
PPMGRVPP_INFO("tb_detect tb_src_canvas[0] alloc failed\n");
return -1;
}
if (ppmgr_src_canvas[1] < 0)
ppmgr_src_canvas[1] = canvas_pool_map_alloc_canvas(keep_owner);
if (ppmgr_src_canvas[1] < 0) {
PPMGRVPP_INFO("tb_detect tb_src_canvas[1] alloc failed\n");
return -1;
}
if (ppmgr_src_canvas[2] < 0)
ppmgr_src_canvas[2] = canvas_pool_map_alloc_canvas(keep_owner);
if (ppmgr_src_canvas[2] < 0) {
PPMGRVPP_INFO("tb_detect tb_src_canvas[2] alloc failed\n");
return -1;
}
ppmgr_buffer_status = 1;
get_ppmgr_buf_info(&buf_start, &buf_size);
#ifdef CONFIG_V4L_AMLOGIC_VIDEO
@@ -3147,22 +3307,33 @@ static int tb_buffer_init(void)
int i;
//int flags = CODEC_MM_FLAGS_DMA_CPU | CODEC_MM_FLAGS_CMA_CLEAR;
int flags = 0;
const char *keep_owner = "tb_detect";
if (tb_buffer_status)
return tb_buffer_status;
if (tb_src_canvas == 0) {
if (canvas_pool_alloc_canvas_table(
"tb_detect_src",
&tb_src_canvas, 1,
CANVAS_MAP_TYPE_YUV)) {
pr_err(
"%s alloc tb src canvas error.\n",
__func__);
return -1;
}
pr_info("alloc tb src canvas 0x%x.\n",
tb_src_canvas);
if (tb_src_canvas[0] < 0)
tb_src_canvas[0] = canvas_pool_map_alloc_canvas(keep_owner);
if (tb_src_canvas[0] < 0) {
PPMGRVPP_INFO("tb_detect tb_src_canvas[0] alloc failed\n");
return -1;
}
if (tb_src_canvas[1] < 0)
tb_src_canvas[1] = canvas_pool_map_alloc_canvas(keep_owner);
if (tb_src_canvas[1] < 0) {
PPMGRVPP_INFO("tb_detect tb_src_canvas[1] alloc failed\n");
return -1;
}
if (tb_src_canvas[2] < 0)
tb_src_canvas[2] = canvas_pool_map_alloc_canvas(keep_owner);
if (tb_src_canvas[2] < 0) {
PPMGRVPP_INFO("tb_detect tb_src_canvas[2] alloc failed\n");
return -1;
}
if (tb_canvas < 0)
@@ -3213,18 +3384,18 @@ static int tb_buffer_init(void)
static int tb_buffer_uninit(void)
{
int i;
if (tb_src_canvas) {
if (tb_src_canvas & 0xff)
canvas_pool_map_free_canvas(
tb_src_canvas & 0xff);
if ((tb_src_canvas >> 8) & 0xff)
canvas_pool_map_free_canvas(
(tb_src_canvas >> 8) & 0xff);
if ((tb_src_canvas >> 16) & 0xff)
canvas_pool_map_free_canvas(
(tb_src_canvas >> 16) & 0xff);
}
tb_src_canvas = 0;
if (tb_src_canvas[0] >= 0)
canvas_pool_map_free_canvas(tb_src_canvas[0]);
tb_src_canvas[0] = -1;
if (tb_src_canvas[1] >= 0)
canvas_pool_map_free_canvas(tb_src_canvas[1]);
tb_src_canvas[1] = -1;
if (tb_src_canvas[2] >= 0)
canvas_pool_map_free_canvas(tb_src_canvas[2]);
tb_src_canvas[2] = -1;
if (tb_canvas >= 0)
canvas_pool_map_free_canvas(tb_canvas);

View File

@@ -984,14 +984,101 @@ void video_pip_keeper_new_frame_notify(void)
}
#ifdef CONFIG_AMLOGIC_MEDIA_GE2D
static unsigned int vf_ge2d_keep_frame_locked(struct vframe_s *cur_dispbuf)
{
u32 cur_index;
u32 y_index, u_index, v_index;
struct canvas_s cs0, cs1, cs2, cd;
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
if (codec_mm_video_tvp_enabled()) {
pr_info("keep exit is TVP\n");
return 0;
}
#endif
if (cur_dispbuf->type & VIDTYPE_COMPRESS) {
/* todo: duplicate compressed video frame */
pr_info("keep exit is skip VIDTYPE_COMPRESS\n");
return 0;
}
cur_index = READ_VCBUS_REG(VD1_IF0_CANVAS0 +
get_video_cur_dev()->viu_off);
y_index = cur_index & 0xff;
u_index = (cur_index >> 8) & 0xff;
v_index = (cur_index >> 16) & 0xff;
canvas_read(y_index, &cd);
if ((cd.width * cd.height) <= 1920 * 1088 * 3
&& !keep_y_addr) {
alloc_keep_buffer();
}
if (!keep_y_addr) {
pr_info("%s:alloc keep buffer failed, keep_y_addr is NULL!\n",
__func__);
return 0;
}
if (get_video_debug_flags() & DEBUG_FLAG_BLACKOUT) {
pr_info("%s keep_y_addr=%p %x\n",
__func__, (void *)keep_y_addr,
canvas_get_addr(y_index));
}
if ((cur_dispbuf->type & VIDTYPE_VIU_422) == VIDTYPE_VIU_422) {
pr_info("%s:no support VIDTYPE_VIU_422\n", __func__);
return 0;
} else if ((cur_dispbuf->type & VIDTYPE_VIU_444) == VIDTYPE_VIU_444) {
if ((Y_BUFFER_SIZE < (cd.width * cd.height))) {
pr_info
("[%s::%d] error: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 0;
}
ge2d_keeplastframe_block(cur_index, GE2D_FORMAT_S24_YUV444);
if (get_video_debug_flags() & DEBUG_FLAG_BLACKOUT)
pr_info("%s: VIDTYPE_VIU_444\n", __func__);
} else if ((cur_dispbuf->type & VIDTYPE_VIU_NV21) == VIDTYPE_VIU_NV21) {
canvas_read(y_index, &cs0);
canvas_read(u_index, &cs1);
if ((Y_BUFFER_SIZE < (cs0.width * cs0.height))
|| (U_BUFFER_SIZE < (cs1.width * cs1.height))) {
pr_info("## [%s::%d] error: yuv data size larger",
__func__, __LINE__);
return 0;
}
ge2d_keeplastframe_block(cur_index, GE2D_FORMAT_M24_NV21);
if (get_video_debug_flags() & DEBUG_FLAG_BLACKOUT)
pr_info("%s: VIDTYPE_VIU_NV21\n", __func__);
} else {
canvas_read(y_index, &cs0);
canvas_read(u_index, &cs1);
canvas_read(v_index, &cs2);
if ((Y_BUFFER_SIZE < (cs0.width * cs0.height))
|| (U_BUFFER_SIZE < (cs1.width * cs1.height))
|| (V_BUFFER_SIZE < (cs2.width * cs2.height))) {
pr_info("## [%s::%d] error: yuv data size larger",
__func__, __LINE__);
return 0;
}
ge2d_keeplastframe_block(cur_index, GE2D_FORMAT_M24_YUV420);
if (get_video_debug_flags() & DEBUG_FLAG_BLACKOUT)
pr_info("%s: VIDTYPE_VIU_420\n", __func__);
}
pr_info("%s: use ge2d keep video\n", __func__);
return 1;
}
#endif
static unsigned int vf_keep_current_locked(
struct vframe_s *cur_dispbuf,
struct vframe_s *cur_dispbuf_el)
{
u32 cur_index;
u32 y_index, u_index, v_index;
struct canvas_s cs0, cs1, cs2, cd;
int ret;
if (!cur_dispbuf) {
@@ -1024,185 +1111,23 @@ static unsigned int vf_keep_current_locked(
}
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);
if (ret) {
/*keeped ok with codec keeper!*/
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");
return 0;
}
#endif
if (cur_dispbuf->type & VIDTYPE_COMPRESS) {
/* todo: duplicate compressed video frame */
pr_info("keep exit is skip VIDTYPE_COMPRESS\n");
return -1;
}
cur_index = READ_VCBUS_REG(VD1_IF0_CANVAS0 +
get_video_cur_dev()->viu_off);
y_index = cur_index & 0xff;
u_index = (cur_index >> 8) & 0xff;
v_index = (cur_index >> 16) & 0xff;
canvas_read(y_index, &cd);
if ((cd.width * cd.height) <= 1920 * 1088 * 3
&& !keep_y_addr) {
alloc_keep_buffer();
}
if (!keep_y_addr
|| (cur_dispbuf->type & VIDTYPE_VIU_422)
== VIDTYPE_VIU_422) {
/* no support VIDTYPE_VIU_422... */
pr_info("%s:no support VIDTYPE_VIU_422\n", __func__);
return -1;
}
if (get_video_debug_flags() & DEBUG_FLAG_BLACKOUT) {
pr_info("%s keep_y_addr=%p %x\n",
__func__, (void *)keep_y_addr,
canvas_get_addr(y_index));
}
if ((cur_dispbuf->type & VIDTYPE_VIU_422) == VIDTYPE_VIU_422) {
return -1;
} else if ((cur_dispbuf->type & VIDTYPE_VIU_444) == VIDTYPE_VIU_444) {
if ((Y_BUFFER_SIZE < (cd.width * cd.height))) {
pr_info
("[%s::%d] error: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;
}
#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),
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
}
#endif
if (get_video_debug_flags() & DEBUG_FLAG_BLACKOUT)
pr_info("%s: VIDTYPE_VIU_444\n", __func__);
} else if ((cur_dispbuf->type & VIDTYPE_VIU_NV21) == VIDTYPE_VIU_NV21) {
canvas_read(y_index, &cs0);
canvas_read(u_index, &cs1);
if ((Y_BUFFER_SIZE < (cs0.width * cs0.height))
|| (U_BUFFER_SIZE < (cs1.width * cs1.height))) {
pr_info("## [%s::%d] error: yuv data size larger",
__func__, __LINE__);
return -1;
}
#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) &&
canvas_dup(keep_phy_addr(keep_y_addr),
canvas_get_addr(y_index),
(cs0.width * cs0.height))
&& canvas_dup(keep_phy_addr(keep_u_addr),
canvas_get_addr(u_index),
(cs1.width * cs1.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));
canvas_update_addr(disp_canvas_index[0][1],
keep_phy_addr(keep_u_addr));
canvas_update_addr(disp_canvas_index[1][1],
keep_phy_addr(keep_u_addr));
#else
canvas_update_addr(y_index,
keep_phy_addr(keep_y_addr));
canvas_update_addr(u_index,
keep_phy_addr(keep_u_addr));
#endif
}
#endif
if (get_video_debug_flags() & DEBUG_FLAG_BLACKOUT)
pr_info("%s: VIDTYPE_VIU_NV21\n", __func__);
pr_info("ppmgr use ge2d keep frame!\n");
ret = vf_ge2d_keep_frame_locked(cur_dispbuf);
} else {
canvas_read(y_index, &cs0);
canvas_read(u_index, &cs1);
canvas_read(v_index, &cs2);
if ((Y_BUFFER_SIZE < (cs0.width * cs0.height))
|| (U_BUFFER_SIZE < (cs1.width * cs1.height))
|| (V_BUFFER_SIZE < (cs2.width * cs2.height))) {
pr_info("## [%s::%d] error: yuv data size larger than buf size: %x,%x,%x, %x,%x, %x,%x, %x,%x,\n",
__func__, __LINE__, Y_BUFFER_SIZE,
U_BUFFER_SIZE, V_BUFFER_SIZE, cs0.width,
cs0.height, cs1.width, cs1.height, cs2.width,
cs2.height);
return -1;
}
#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) &&
/*must not the same address */
canvas_dup(keep_phy_addr(keep_y_addr),
canvas_get_addr(y_index),
(cs0.width * cs0.height))
&& canvas_dup(keep_phy_addr(keep_u_addr),
canvas_get_addr(u_index),
(cs1.width * cs1.height))
&& canvas_dup(keep_phy_addr(keep_v_addr),
canvas_get_addr(v_index),
(cs2.width * cs2.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));
canvas_update_addr(disp_canvas_index[0][1],
keep_phy_addr(keep_u_addr));
canvas_update_addr(disp_canvas_index[1][1],
keep_phy_addr(keep_u_addr));
canvas_update_addr(disp_canvas_index[0][2],
keep_phy_addr(keep_v_addr));
canvas_update_addr(disp_canvas_index[1][2],
keep_phy_addr(keep_v_addr));
#else
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));
#endif
}
if (get_video_debug_flags() & DEBUG_FLAG_BLACKOUT)
pr_info("%s: VIDTYPE_VIU_420\n", __func__);
#endif
pr_info("use keep buffer keep frame!\n");
ret = video_keeper_frame_keep_locked(
cur_dispbuf,
cur_dispbuf_el);
}
keep_video_on = 1;
pr_info("%s: keep video on with keep\n", __func__);
return 1;
if (ret) {
keep_video_on = 1;
pr_info("%s: keep video successful!\n", __func__);
} else {
keep_video_on = 0;
pr_info("%s: keep video failed!\n", __func__);
}
return ret;
}
unsigned int vf_keep_pip_current_locked(