ppmgr: modify first frame garbage. [1/1]
authorrenjiang.han <renjiang.han@amlogic.com>
Sat, 15 Jun 2019 15:16:39 +0000 (23:16 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Tue, 25 Jun 2019 04:39:15 +0000 (21:39 -0700)
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>
drivers/amlogic/media/video_processor/ppmgr/ppmgr_dev.h
drivers/amlogic/media/video_processor/ppmgr/ppmgr_drv.c
drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c
drivers/amlogic/media/video_sink/video_keeper.c

index ae45cca..02f3299 100644 (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 {
index 3768123..6988337 100644 (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();
index 93af166..47d0d80 100644 (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);
index 2b5b35c..27dbfaa 100644 (file)
@@ -982,59 +982,13 @@ void video_pip_keeper_new_frame_notify(void)
 
 }
 
-
-static unsigned int vf_keep_current_locked(
-       struct vframe_s *cur_dispbuf,
-       struct vframe_s *cur_dispbuf_el)
+#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;
-       int ret;
-
-       if (!cur_dispbuf) {
-               pr_info("keep exit without cur_dispbuf\n");
-               return 0;
-       }
-
-       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;
-       }
-
-#ifdef CONFIG_AMLOGIC_MEDIA_VIDEOCAPTURE
-       ext_frame_capture_poll(1); /*pull  if have capture end frame */
-#endif
-
-       if (get_blackout_policy()) {
-               pr_info("keep exit is skip current\n");
-               return 0;
-       }
-
-       if (VSYNC_RD_MPEG_REG(DI_IF1_GEN_REG) & 0x1) {
-               pr_info("keep exit is di\n");
-               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);
-       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");
@@ -1045,7 +999,7 @@ GE2D_KEEP_FRAME:
        if (cur_dispbuf->type & VIDTYPE_COMPRESS) {
                /* todo: duplicate compressed video frame */
                pr_info("keep exit is skip VIDTYPE_COMPRESS\n");
-               return -1;
+               return 0;
        }
        cur_index = READ_VCBUS_REG(VD1_IF0_CANVAS0 +
                get_video_cur_dev()->viu_off);
@@ -1058,12 +1012,10 @@ GE2D_KEEP_FRAME:
                && !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 (!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) {
@@ -1073,7 +1025,8 @@ GE2D_KEEP_FRAME:
        }
 
        if ((cur_dispbuf->type & VIDTYPE_VIU_422) == VIDTYPE_VIU_422) {
-               return -1;
+               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
@@ -1081,26 +1034,9 @@ GE2D_KEEP_FRAME:
                             __func__, __LINE__, Y_BUFFER_SIZE,
                             U_BUFFER_SIZE, V_BUFFER_SIZE,
                                cd.width, cd.height);
-                       return -1;
+                       return 0;
                }
-#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) {
@@ -1110,35 +1046,9 @@ GE2D_KEEP_FRAME:
                        || (U_BUFFER_SIZE < (cs1.width * cs1.height))) {
                        pr_info("## [%s::%d] error: yuv data size larger",
                                __func__, __LINE__);
-                       return -1;
+                       return 0;
                }
-#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__);
        } else {
@@ -1149,59 +1059,74 @@ GE2D_KEEP_FRAME:
                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;
+                       pr_info("## [%s::%d] error: yuv data size larger",
+                               __func__, __LINE__);
+                       return 0;
                }
-#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
        }
-       keep_video_on = 1;
-       pr_info("%s: keep video on with keep\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)
+{
+       int ret;
+
+       if (!cur_dispbuf) {
+               pr_info("keep exit without cur_dispbuf\n");
+               return 0;
+       }
+
+       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;
+       }
+
+#ifdef CONFIG_AMLOGIC_MEDIA_VIDEOCAPTURE
+       ext_frame_capture_poll(1); /*pull  if have capture end frame */
+#endif
+
+       if (get_blackout_policy()) {
+               pr_info("keep exit is skip current\n");
+               return 0;
+       }
+
+       if (VSYNC_RD_MPEG_REG(DI_IF1_GEN_REG) & 0x1) {
+               pr_info("keep exit is di\n");
+               return 0;
+       }
+
+       if (cur_dispbuf->source_type == VFRAME_SOURCE_TYPE_PPMGR) {
+               pr_info("ppmgr use ge2d keep frame!\n");
+               ret = vf_ge2d_keep_frame_locked(cur_dispbuf);
+       } else {
+               pr_info("use keep buffer keep frame!\n");
+               ret = video_keeper_frame_keep_locked(
+                       cur_dispbuf,
+                       cur_dispbuf_el);
+       }
+
+       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(
        struct vframe_s *cur_dispbuf,