Files
TAIXIN/sdk/lib/video/vpp/vpp_dev.c

1803 lines
57 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "basic_include.h"
#include "lib/video/dvp/cmos_sensor/csi.h"
#include "lib/video/dvp/cmos_sensor/csi_V2.h"
#include "devid.h"
#include "hal/gpio.h"
#include "osal/irq.h"
#include "osal/string.h"
#include "dev/vpp/hgvpp.h"
#include "dev/csi/hgdvp.h"
#include "lib/lcd/lcd.h"
#include "hal/jpeg.h"
#include "lib/video/vpp/vpp_dev.h"
#include "lib/video/gen/gen420_dev.h"
#include "lib/scale/scale_dev.h"
#include "basic_include.h"
#include "lib/multimedia/msi.h"
#include <sys/time.h>
#include "lib/heap/av_heap.h"
#include "lib/heap/av_psram_heap.h"
#include "hal/osd_enc.h"
uint32 motion_det_pot_check(uint8_t *old_y, uint8_t *new_y, uint8_t *copy, uint16 w, uint16 h, uint8_t blk_thd, uint8_t md_blk_num);
void md_set_pot_x_y(uint16 x, uint16 y);
#define VPP_MALLOC av_malloc
#define VPP_FREE av_free
#define VPP_ZALLOC av_zalloc
#define VPP_PSRAM_MALLOC av_psram_malloc
#define VPP_PSRAM_FREE av_psram_free
#define VPP_PSRAM_ZALLOC av_psram_zalloc
/***************************************
shrink:
//0: 1/2
//1: 1/3
//2: 1/4
//3: 1/6
//4: 2/3
//5: 1/1
***************************************** */
enum SHRINK_ENUM
{
SHRINK_1_2,
SHRINK_1_3,
SHRINK_1_4,
SHRINK_1_6,
SHRINK_2_3,
SHRINK_1_1,
};
struct vpp_cfg_s
{
uint8_t vpp_buf0_line_num;
uint8_t vpp_buf1_line_num;
uint8_t vpp_buf0_mode : 1, vpp_buf1_mode : 1, scale1_from_vpp : 1, scale3_from_vpp : 1, shrink : 3, mdt : 1;
uint8_t double_psram_for_buf1;
uint16_t vpp_w, vpp_h;
uint16_t vpp_scale_w, vpp_scale_h;
};
// 默认值
#ifdef SYS_APP_WALKIE_TALKIE
struct vpp_cfg_s vpp_msg = {
.vpp_buf0_line_num = VPP_BUF0_LINEBUF_NUM,
.vpp_buf1_line_num = VPP_BUF1_LINEBUF_NUM,
.vpp_buf0_mode = VPP_BUF0_MODE,
.vpp_buf1_mode = VPP_BUF1_MODE,
.scale1_from_vpp = SCALE1_FROM_VPPBF,
.scale3_from_vpp = SCALE3_FROM_VPPBF,
.vpp_w = 640,
.vpp_h = 480,
.vpp_scale_w = 0,
.vpp_scale_h = 0,
.shrink = SHRINK_1_2,
.double_psram_for_buf1 = 1,
};
#else
struct vpp_cfg_s vpp_msg = {
.vpp_buf0_line_num = VPP_BUF0_LINEBUF_NUM,
.vpp_buf1_line_num = VPP_BUF1_LINEBUF_NUM,
.vpp_buf0_mode = VPP_BUF0_MODE,
.vpp_buf1_mode = VPP_BUF1_MODE,
.scale1_from_vpp = SCALE1_FROM_VPPBF,
.scale3_from_vpp = SCALE3_FROM_VPPBF,
.vpp_w = 1280,
.vpp_h = 720,
.vpp_scale_w = 0,
.vpp_scale_h = 0,
.shrink = SHRINK_1_2,
.double_psram_for_buf1 = 0,
.mdt = 0,
};
#endif
// uint8 motion_detect_buf[9*1024/*((IMAGE_W+31)/32) * ((IMAGE_H+31)/32) + 3 + 4*((IMAGE_W+31)/32)*/]__attribute__ ((aligned(4)));//加3是为了防止blk数不是word对齐
uint8 *motion_detect_buf = NULL;
uint8 *motion_detect_oldframe_buf = NULL;
uint8 *mdet_result;
uint16 motion_blk_threshold = 0;
uint16 motion_blknum_threshold = 0;
uint8 *yuvbuf1 = NULL;
uint8_t *vpp_data1_psram_buf = NULL;
uint8_t *vpp_data2_psram_buf = NULL;
volatile uint8_t *psram_ptr = NULL;
volatile uint8_t *psram_user_ptr = NULL;
uint8 *yuvbuf = NULL;
uint8 *vpp_encode_ipf = NULL;
struct video_cfg_t video_msg;
func_done_fn vpp_deal_dev_func_table[VPP_FUNC_DONE_NUM];
volatile uint32 vpp_deal_dev_func_arg_table[VPP_FUNC_DONE_NUM];
int32 vppdone_func_register(uint8_t id, func_done_fn func, uint32 arg)
{
struct vpp_device *vpp_dev = (struct vpp_device *) dev_get(HG_VPP_DEVID);
int32_t closed = vpp_is_closed(vpp_dev);
if (closed)
{
os_printf(KERN_DEBUG "vpp is closed, func:%p, arg:%X\tclosed:%d\n", func, arg, closed);
func(arg);
}
else
{
uint32_t flags = disable_irq();
vpp_deal_dev_func_table[id] = func;
vpp_deal_dev_func_arg_table[id] = arg;
enable_irq(flags);
}
return 0;
}
int32 vppdone_func_unregister(uint8_t id)
{
uint32_t flags = disable_irq();
vpp_deal_dev_func_table[id] = NULL;
vpp_deal_dev_func_arg_table[id] = 0;
enable_irq(flags);
return 0;
}
// 设置buf1输出的size(需要整除,否则不会修改或者异常)
uint8_t set_vpp_bu1_shrink(uint16_t w, uint16_t shrink_w)
{
uint8_t ret = 1;
if (!w)
{
return ret;
}
if (w * 2 / 3 == shrink_w)
{
vpp_msg.shrink = SHRINK_2_3;
return 0;
}
uint8_t shrink_calc = w / shrink_w;
uint8_t shrink = vpp_msg.shrink;
// 是倍数关系,检查是否有符合
if (shrink_w * shrink_calc == w)
{
ret = 0;
switch (shrink_calc)
{
case 1:
shrink = SHRINK_1_1;
break;
case 2:
shrink = SHRINK_1_2;
break;
case 3:
shrink = SHRINK_1_3;
break;
case 4:
shrink = SHRINK_1_4;
break;
case 6:
shrink = SHRINK_1_6;
break;
default:
shrink = vpp_msg.shrink;
ret = 1;
break;
}
}
vpp_msg.shrink = shrink;
if (ret)
{
os_printf(KERN_ERR "%s err,w:%d\tshrink_w:%d\tshrink:%d\n", __FUNCTION__, w, shrink_w, shrink);
}
else
{
os_printf(KERN_INFO "%s success,w:%d\tshrink_w:%d\tshrink:%d\n", __FUNCTION__, w, shrink_w, shrink);
}
return ret;
}
uint8_t get_vpp_scale_w_h(uint16_t *w, uint16_t *h)
{
uint8_t ret = 0;
if (w)
{
*w = vpp_msg.vpp_scale_w;
}
if (h)
{
*h = vpp_msg.vpp_scale_h;
}
if (!vpp_msg.vpp_scale_w || !vpp_msg.vpp_scale_h)
{
ret = 1;
}
return ret;
}
uint8_t get_vpp_w_h(uint16_t *w, uint16_t *h)
{
uint8_t ret = 0;
if (w)
{
*w = vpp_msg.vpp_w;
}
if (h)
{
*h = vpp_msg.vpp_h;
}
if (!vpp_msg.vpp_w || !vpp_msg.vpp_h)
{
ret = 1;
}
return ret;
}
uint8_t get_vpp1_w_h(uint16_t *w, uint16_t *h)
{
uint8_t ret = 0;
switch (vpp_msg.shrink)
{
case SHRINK_1_2:
if (w)
{
*w = vpp_msg.vpp_w / 2;
}
if (h)
{
*h = vpp_msg.vpp_h / 2;
}
break;
case SHRINK_1_3:
if (w)
{
*w = vpp_msg.vpp_w / 3;
}
if (h)
{
*h = vpp_msg.vpp_h / 3;
}
break;
case SHRINK_1_4:
if (w)
{
*w = vpp_msg.vpp_w / 4;
}
if (h)
{
*h = vpp_msg.vpp_h / 4;
}
break;
case SHRINK_1_6:
if (w)
{
*w = vpp_msg.vpp_w / 6;
}
if (h)
{
*h = vpp_msg.vpp_h / 6;
}
break;
case SHRINK_2_3:
if (w)
{
*w = vpp_msg.vpp_w * 2 / 3;
}
if (h)
{
*h = vpp_msg.vpp_h * 2 / 3;
}
break;
case SHRINK_1_1:
if (w)
{
*w = vpp_msg.vpp_w;
}
if (h)
{
*h = vpp_msg.vpp_h;
}
break;
default:
os_printf("%s:%d err,shrink:%d\n", __FUNCTION__, __LINE__, vpp_msg.shrink);
break;
}
if (VPP_BUF1_EN == 0)
{
ret = 1;
}
return ret;
}
uint32_t yuv_buf_line(uint8_t which)
{
ASSERT(which == 0 || which == 1);
uint8_t mode;
uint8_t line_num;
uint8_t malloc_line;
if (which == 0)
{
mode = vpp_msg.vpp_buf0_mode;
line_num = vpp_msg.vpp_buf0_line_num;
}
else
{
mode = vpp_msg.vpp_buf1_mode;
line_num = vpp_msg.vpp_buf1_line_num;
}
if (mode == VPP_MODE_2N)
{
malloc_line = line_num * 2; // 2N
}
else
{
malloc_line = line_num * 2 + 16; // 16+2N
}
return malloc_line;
}
void *get_vpp_buf(uint8_t which)
{
ASSERT(which == 0 || which == 1);
if (which == 0)
{
return yuvbuf;
}
else if (which == 1)
{
return yuvbuf1;
}
return NULL;
}
void *get_vpp_psram_buf()
{
return vpp_data1_psram_buf;
}
uint8 photo_lib2[48 * 6] __attribute__((aligned(4))) = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x07, 0x80, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x40, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x70, 0x00, 0x01, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x08, 0x00,
0xE0, 0x08, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x04, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x06, 0x00, 0x00, 0x00, 0x03, 0x82, 0x03, 0x00, 0x00, 0x00, 0x03, 0x83, 0x81, 0x80, 0x00, 0x00, 0x07, 0x03, 0x81,
0xC0, 0x00, 0x00, 0x0E, 0x03, 0x00, 0xE0, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x70, 0x00, 0x00, 0x3C, 0x03, 0x03, 0x38, 0x00, 0x00, 0x73, 0x83, 0x07, 0x9E, 0x00, 0x00, 0xE1, 0xE3, 0x0F, 0xCF, 0x80,
0x01, 0xC0, 0xE3, 0x1C, 0x07, 0xF0, 0x03, 0x80, 0x63, 0x60, 0x03, 0xFC, 0x06, 0x00, 0x63, 0x80, 0x00, 0xE0, 0x1C, 0x00, 0x03, 0x00, 0x00, 0x40, 0x30, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
0xC3, 0x3C, 0x00, 0x00, 0x00, 0x07, 0x83, 0x0F, 0x80, 0x00, 0x00, 0x1E, 0x03, 0x03, 0xE0, 0x00, 0x00, 0xFC, 0x03, 0x01, 0xF0, 0x00, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x00, 0x00, 0x60, 0xFF, 0x00,
0x70, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8 ele_lib[13][64] __attribute__((aligned(4))) = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x0F, 0xF8, 0x1E, 0x3C, 0x3C, 0x3C, 0x3C, 0x1E,
0x38, 0x1E, 0x78, 0x0E, 0x78, 0x0E, 0x78, 0x0E, 0x78, 0x0E, 0x78, 0x0E, 0x78, 0x0E, 0x78, 0x0E, 0x78, 0x0E, 0x78, 0x0E, 0x38, 0x1E,
0x3C, 0x1E, 0x3C, 0x1C, 0x1E, 0x3C, 0x1F, 0xF8, 0x07, 0xF0, 0x01, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"0",0*/
/* (16 X 32 , 楷体, 加粗 )*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x01, 0xE0, 0x03, 0xE0, 0x07, 0xE0, 0x1F, 0xE0,
0x1D, 0xE0, 0x19, 0xE0, 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xE0,
0x01, 0xE0, 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"1",1*/
/* (16 X 32 , 楷体, 加粗 )*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x1F, 0xFC, 0x3E, 0x3C, 0x3C, 0x1E, 0x78, 0x1E,
0x00, 0x1E, 0x00, 0x1E, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x00, 0xE0, 0x01, 0xE0, 0x03, 0xC0, 0x07, 0x80,
0x0F, 0x00, 0x1E, 0x00, 0x3E, 0x00, 0x3F, 0xFE, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"2",2*/
/* (16 X 32 , 楷体, 加粗 )*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x0F, 0xFC, 0x1E, 0x3C, 0x3C, 0x1E, 0x38, 0x1E,
0x18, 0x1E, 0x00, 0x1E, 0x00, 0x1C, 0x00, 0x7C, 0x03, 0xF0, 0x03, 0xF8, 0x00, 0x7C, 0x00, 0x1E, 0x00, 0x1E, 0x00, 0x1E, 0x18, 0x0E,
0x78, 0x1E, 0x3C, 0x1E, 0x3E, 0x3C, 0x1F, 0xFC, 0x0F, 0xF0, 0x01, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"3",3*/
/* (16 X 32 , 楷体, 加粗 )*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x78, 0x00, 0x78, 0x00, 0xF8, 0x01, 0xF8,
0x01, 0xF8, 0x03, 0xF8, 0x07, 0xB8, 0x0F, 0x38, 0x0E, 0x38, 0x1E, 0x38, 0x3C, 0x38, 0x38, 0x38, 0x78, 0x38, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"4",4*/
/* (16 X 32 , 楷体, 加粗 )*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x1F, 0xFC, 0x1C, 0x00, 0x1C, 0x00, 0x1C, 0x00,
0x3C, 0x00, 0x38, 0x00, 0x3F, 0xE0, 0x3F, 0xF8, 0x7C, 0x7C, 0x78, 0x3C, 0x00, 0x1E, 0x00, 0x1E, 0x00, 0x0E, 0x00, 0x0E, 0x30, 0x1E,
0x70, 0x1E, 0x78, 0x1E, 0x78, 0x7C, 0x3F, 0xF8, 0x1F, 0xF0, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"5",5*/
/* (16 X 32 , 楷体, 加粗 )*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x01, 0xE0, 0x03, 0xC0, 0x03, 0xC0,
0x07, 0x80, 0x0F, 0x00, 0x0F, 0x00, 0x1F, 0xF8, 0x1F, 0xFC, 0x3E, 0x1E, 0x3C, 0x0F, 0x78, 0x0F, 0x78, 0x0F, 0x78, 0x0F, 0x78, 0x0F,
0x78, 0x0F, 0x3C, 0x0F, 0x3E, 0x1E, 0x1F, 0xFC, 0x0F, 0xF8, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"6",6*/
/* (16 X 32 , 楷体, 加粗 )*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x7F, 0xFF, 0x00, 0x0F, 0x00, 0x1E, 0x00, 0x1C,
0x00, 0x3C, 0x00, 0x38, 0x00, 0x78, 0x00, 0x70, 0x00, 0xF0, 0x00, 0xE0, 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
0x03, 0x80, 0x07, 0x80, 0x07, 0x80, 0x07, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"7",7*/
/* (16 X 32 , 楷体, 加粗 )*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x1F, 0xF8, 0x3C, 0x3C, 0x38, 0x1E, 0x38, 0x1E,
0x38, 0x1E, 0x38, 0x1E, 0x3C, 0x3C, 0x3E, 0x7C, 0x0F, 0xF0, 0x1F, 0xF8, 0x3E, 0x7C, 0x7C, 0x1E, 0x78, 0x1E, 0x70, 0x0E, 0x70, 0x0E,
0x78, 0x0E, 0x78, 0x1E, 0x7C, 0x3E, 0x3F, 0xFC, 0x1F, 0xF8, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"8",8*/
/* (16 X 32 , 楷体, 加粗 )*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x1F, 0xF8, 0x3E, 0x7C, 0x78, 0x3E, 0x78, 0x1E,
0x70, 0x1E, 0x70, 0x1E, 0x70, 0x1E, 0x70, 0x1E, 0x78, 0x3C, 0x7C, 0x7C, 0x3F, 0xFC, 0x1F, 0xF8, 0x00, 0xF0, 0x00, 0xF0, 0x01, 0xE0,
0x01, 0xE0, 0x03, 0xC0, 0x03, 0xC0, 0x07, 0x80, 0x07, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"9",9*/
/* (16 X 32 , 楷体, 加粗 )*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x0C, 0x00, 0x1C, 0x00, 0x38,
0x00, 0x30, 0x00, 0x70, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xC0, 0x01, 0xC0, 0x03, 0x80, 0x03, 0x80, 0x07, 0x00, 0x06, 0x00, 0x0E, 0x00,
0x0C, 0x00, 0x1C, 0x00, 0x18, 0x00, 0x38, 0x00, 0x70, 0x00, 0x70, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"/",11*/
/* (16 X 32 , 楷体, 加粗 )*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*":",12*/
/* (16 X 32 , 楷体, 加粗 )*/
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*" ",10*/
/* (16 X 32 , 楷体, 加粗 )*/
};
uint32_t water2_change_ipf(uint16_t srcw, uint16_t srch, uint8_t *bittable, uint16_t bitw, uint16_t bith, uint16_t x, uint16_t y, uint8_t *outbuf)
{
int i, j, k;
int l_ofset;
int r_ofset;
uint32_t count = 0; // 压缩长度
int len; // 已计算长度
int img_w = srcw;
int img_h = srch; // 1280x720图像
int bt_w = bitw, bt_h = bith; // 256x32 bit表
int pos_x = x; // 水平居中放置
int pos_y = y; // 垂直居中放置
uint8_t *ptr;
uint8_t *optr;
int wobuf = 0;
uint8_t lb;
ptr = (uint8_t *) bittable;
optr = outbuf;
len = pos_y * img_w + pos_x;
r_ofset = len % 0xfffe;
l_ofset = len / 0xfffe;
count = l_ofset * 6;
if (optr != NULL)
{
for (i = 0; i < l_ofset; i++)
{
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xfd;
optr[wobuf++] = 0xff;
optr[wobuf++] = 0x00;
optr[wobuf++] = 0x00;
}
}
for (j = 0; j < bt_h; j++)
{
lb = 0;
for (i = 0; i < bt_w; i++)
{
if (ptr[i / 8] & BIT(7 - i % 8))
{ // 1
if (lb == 0)
{ // 之前有透明度,透明度数据写0
if (r_ofset > 2)
{
count += 6;
if (optr != NULL)
{
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xff;
optr[wobuf++] = (r_ofset - 1) & 0xff;
optr[wobuf++] = ((r_ofset - 1) & 0xff00) >> 8;
optr[wobuf++] = 0x00;
optr[wobuf++] = 0x00;
}
}
else
{
count += (r_ofset * 2);
if (optr != NULL)
{
for (k = 0; k < r_ofset; k++)
{
optr[wobuf++] = 0x00;
optr[wobuf++] = 0x00;
}
}
}
r_ofset = 1;
}
else
{
r_ofset++;
if (r_ofset == 0xfffe)
{
count += 6;
if (optr != NULL)
{
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xff;
optr[wobuf++] = (r_ofset - 1) & 0xff;
optr[wobuf++] = ((r_ofset - 1) & 0xff00) >> 8;
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xff;
}
r_ofset = 0;
}
}
lb = 1;
}
else
{ // 0
if (lb == 1)
{ // 之前无透明度,无透明度数据写0xff,因为是ff,所以都得按格式写
count += 6;
if (optr != NULL)
{
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xff;
optr[wobuf++] = (r_ofset - 1) & 0xff;
optr[wobuf++] = ((r_ofset - 1) & 0xff00) >> 8;
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xff;
}
r_ofset = 1;
}
else
{
r_ofset++;
if (r_ofset == 0xfffe)
{
count += 6;
if (optr != NULL)
{
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xff;
optr[wobuf++] = (r_ofset - 1) & 0xff;
optr[wobuf++] = ((r_ofset - 1) & 0xff00) >> 8;
optr[wobuf++] = 0x00;
optr[wobuf++] = 0x00;
}
r_ofset = 0;
}
}
lb = 0;
}
}
ptr = ptr + bt_w / 8;
if (lb == 0)
{ // 保持着透明度
r_ofset += (img_w - bt_w);
l_ofset = r_ofset / 0xfffe;
r_ofset = r_ofset % 0xfffe;
count += (l_ofset * 6);
if (optr != NULL)
{
for (k = 0; k < l_ofset; k++)
{
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xfd;
optr[wobuf++] = 0xff;
optr[wobuf++] = 0x00;
optr[wobuf++] = 0x00;
}
}
len += img_w;
}
else
{ // 最后一bit不是透明色
count += 6;
if (optr != NULL)
{
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xff;
optr[wobuf++] = (r_ofset - 1) & 0xff;
optr[wobuf++] = ((r_ofset - 1) & 0xff00) >> 8;
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xff;
}
r_ofset = (img_w - bt_w);
len += img_w;
}
}
r_ofset += (img_w * img_h) - len;
l_ofset = r_ofset / 0xfffe;
r_ofset = r_ofset % 0xfffe;
count += (l_ofset * 6);
count += 6;
if (optr != NULL)
{
for (i = 0; i < l_ofset; i++)
{
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xfd;
optr[wobuf++] = 0xff;
optr[wobuf++] = 0x00;
optr[wobuf++] = 0x00;
}
optr[wobuf++] = 0xff;
optr[wobuf++] = 0xff;
optr[wobuf++] = (r_ofset - 1) & 0xff;
optr[wobuf++] = ((r_ofset - 1) & 0xff00) >> 8;
optr[wobuf++] = 0x00;
optr[wobuf++] = 0x00;
}
printf("count:%d\r\n", count);
return count;
}
void set_time_watermark(struct vpp_device *vpp_dev, uint16 year, uint16 month, uint16 day, uint16 hour, uint16 min, uint16 sec)
{
vpp_set_watermark0_idx(vpp_dev, 0, year / 1000);
vpp_set_watermark0_idx(vpp_dev, 1, (year / 100) % 10);
vpp_set_watermark0_idx(vpp_dev, 2, (year / 10) % 10);
vpp_set_watermark0_idx(vpp_dev, 3, year % 10);
vpp_set_watermark0_idx(vpp_dev, 4, 10);
vpp_set_watermark0_idx(vpp_dev, 5, month / 10);
vpp_set_watermark0_idx(vpp_dev, 6, month % 10);
vpp_set_watermark0_idx(vpp_dev, 7, 10);
vpp_set_watermark0_idx(vpp_dev, 8, day / 10);
vpp_set_watermark0_idx(vpp_dev, 9, day % 10);
vpp_set_watermark0_idx(vpp_dev, 10, 12);
vpp_set_watermark0_idx(vpp_dev, 11, hour / 10);
vpp_set_watermark0_idx(vpp_dev, 12, hour % 10);
vpp_set_watermark0_idx(vpp_dev, 13, 11);
vpp_set_watermark0_idx(vpp_dev, 14, min / 10);
vpp_set_watermark0_idx(vpp_dev, 15, min % 10);
vpp_set_watermark0_idx(vpp_dev, 16, 11);
vpp_set_watermark0_idx(vpp_dev, 17, sec / 10);
vpp_set_watermark0_idx(vpp_dev, 18, sec % 10);
}
void vpp_reset()
{
struct vpp_device *vpp_dev;
vpp_dev = (struct vpp_device *) dev_get(HG_VPP_DEVID);
vpp_close(vpp_dev);
os_printf("fv\r\n");
vpp_open(vpp_dev);
}
void vpp_video_recfg(uint32 dev, uint32_t w, uint32_t h, uint8_t input_from)
{
struct vpp_device *p_vpp = (struct vpp_device *) dev;
vpp_set_video_size(p_vpp, w, h);
vpp_msg.vpp_w = w;
vpp_msg.vpp_h = h;
#if VPP_BUF1_EN
uint32_t buf1w = 0, buf1h = 0;
uint8_t shrink = vpp_msg.shrink; // 0: 1/2
// 1: 1/3
// 2: 1/4
// 3: 1/6
// 4: 2/3
// 5: 1/1
switch (shrink)
{
case 0:
buf1w = w / 2;
buf1h = h / 2;
break;
case 1:
buf1w = w / 3;
buf1h = h / 3;
break;
case 2:
buf1w = w / 4;
buf1h = h / 4;
break;
case 3:
buf1w = w / 6;
buf1h = h / 6;
break;
case 4:
buf1w = (w * 2) / 3;
buf1h = (h * 2) / 3;
break;
case 5:
buf1w = w;
buf1h = h;
break;
default:
_os_printf("buf1 shrink no this cfg\r\n");
break;
}
// buf1的配置
{
uint32_t malloc_line;
if (vpp_msg.vpp_buf1_mode == VPP_MODE_2N)
{
malloc_line = vpp_msg.vpp_buf1_line_num * 2; // 2N
}
else
{
malloc_line = vpp_msg.vpp_buf1_line_num * 2 + 16; // 16+2N
}
vpp_set_buf1_count(p_vpp, vpp_msg.vpp_buf1_line_num);
vpp_set_buf1_shrink(p_vpp, vpp_msg.shrink);
vpp_set_buf1_y_addr(p_vpp, (uint32) yuvbuf1);
vpp_set_buf1_u_addr(p_vpp, (uint32) yuvbuf1 + buf1w * malloc_line);
vpp_set_buf1_v_addr(p_vpp, (uint32) yuvbuf1 + buf1w * malloc_line + buf1w * (malloc_line / 4));
}
vpp_set_buf1_en(p_vpp, 1);
#endif
// buf0的配置
{
uint32_t malloc_line;
if (vpp_msg.vpp_buf0_mode == VPP_MODE_2N)
{
malloc_line = vpp_msg.vpp_buf0_line_num * 2; // 2N
}
else
{
malloc_line = vpp_msg.vpp_buf0_line_num * 2 + 16; // 16+2N
}
vpp_set_buf0_count(p_vpp, vpp_msg.vpp_buf0_line_num);
vpp_set_buf0_en(p_vpp, 1);
vpp_set_buf0_y_addr(p_vpp, (uint32) yuvbuf);
vpp_set_buf0_u_addr(p_vpp, (uint32) yuvbuf + w * malloc_line);
vpp_set_buf0_v_addr(p_vpp, (uint32) yuvbuf + w * malloc_line + w * (malloc_line / 4));
}
#if DET_EN
vpp_set_motion_calbuf(p_vpp, (uint32_t) motion_detect_buf);
vpp_set_motion_range(p_vpp, 0, 0, w, h); // 检测图像范围,blk大小为32*32个像素点
vpp_set_motion_blk_threshold(p_vpp, 20); // 检测对应的blk移动的阀值
vpp_set_motion_frame_threshold(p_vpp, ((w + 31) / 32) * ((h + 31) / 32) / 20); // 检测多少个blk超过阀值再触发移动检测中断
#endif
vpp_set_mode(p_vpp, VPP_INPUT_FORMAT);
vpp_set_input_interface(p_vpp, input_from);
}
uint32 autorc[64] __attribute__((aligned(256)));
volatile uint8 done_num = 0;
volatile uint8 done_percent = 0; // 0 ~ 100
volatile uint32_t vpp_md_cnt = 0; // 有移动,则关闭
scale3_kick_fn scale3_kick_func;
void vpp_hsie_isr(uint32 irq, uint32 dev, uint32 param)
{
}
void vpp_vsie_isr(uint32 irq, uint32 dev, uint32 param)
{
// uint8_t itk;
//struct vpp_device *p_vpp = (struct vpp_device *) dev;
//_os_printf("V");
if (vpp_deal_dev_func_table[VPP_IFP_EN_CTRL])
{
vpp_deal_dev_func_table[VPP_IFP_EN_CTRL](vpp_deal_dev_func_arg_table[VPP_IFP_EN_CTRL]);
}
if (video_msg.video_num == 1)
{
video_msg.video_type_vpp = ISP_VIDEO_0;
}
else if (video_msg.video_num == 2)
{
if (video_msg.video_type_cur == ISP_VIDEO_0)
{
video_msg.video_type_vpp = ISP_VIDEO_1;
}
else
{
video_msg.video_type_vpp = ISP_VIDEO_0;
}
}
else if (video_msg.video_num == 3)
{
if (video_msg.video_type_cur == ISP_VIDEO_0)
{
if (video_msg.video_type_last == ISP_VIDEO_1)
{
video_msg.video_type_vpp = ISP_VIDEO_2;
}
else
{
video_msg.video_type_vpp = ISP_VIDEO_1;
}
}
else
{
video_msg.video_type_vpp = ISP_VIDEO_0;
}
}
done_num = 0;
done_percent = 0;
}
void vpp_data_done(uint32 irq, uint32 high, uint32 param)
{
done_num++;
done_percent = (done_num * 16 * 100) / high;
// printf("D");
}
uint8_t vpp_video_type_map(uint8_t stype)
{
uint8_t video_type;
if (video_msg.video_num == 3)
{
if ((video_msg.video_type_vpp + FSTYPE_YUV_P0) == stype)
{ // 如果vpp已经处理当前数据流中那则返回错误防止误匹配
return 0;
}
if (video_msg.video_type_cur == ISP_VIDEO_0)
{ // 当前完成的是摄像头0
if (video_msg.video_type_last == ISP_VIDEO_1)
{
video_type = ISP_VIDEO_2; // 即将要处理的是摄像头2
}
else
{
video_type = ISP_VIDEO_1; // 即将要处理的是摄像头1
}
}
else
{ // 当前完成的是摄像头1/2
video_type = ISP_VIDEO_0; // 即将要处理的是摄像头0
}
}
else if (video_msg.video_num == 2)
{
if ((video_msg.video_type_vpp + FSTYPE_YUV_P0) == stype)
{ // 如果vpp已经处理当前数据流中那则返回错误防止误匹配
return 0;
}
if (video_msg.video_type_cur == ISP_VIDEO_0)
{ // 当前完成的是摄像头0
video_type = ISP_VIDEO_1; // 即将要处理的是摄像头1
}
else
{
video_type = ISP_VIDEO_0; // 即将要处理的是摄像头0
}
}
else
{
video_type = ISP_VIDEO_0;
}
if ((video_type + FSTYPE_YUV_P0) != stype)
{
return 0;
}
else
{
return 1;
}
}
void vpp_set_time(struct vpp_device *p_vpp, uint32_t time_val)
{
struct tm *time_info;
time_info = gmtime((const time_t*)&time_val);
uint32_t year = time_info->tm_year + 1900;
uint32_t mon = time_info->tm_mon + 1;
uint32_t day = time_info->tm_mday;
uint32_t hour = time_info->tm_hour;
uint32_t min = time_info->tm_min;
uint32_t sec = time_info->tm_sec;
set_time_watermark(p_vpp, year, mon, day, hour, min, sec);
}
void vpp_frame_done(uint32 irq, uint32 dev, uint32 param)
{
static uint32_t md_isr_cnt = 0;
// static uint32_t done_num=0;
// static uint32_t detnum=0;
uint8_t itk = 0;
int32_t ret = 0;
uint16_t w, h;
uint16_t detw, deth;
uint32_t loc;
uint16_t buf1w = 0, buf1h = 0;
uint8_t *ptr_cache;
_os_printf(KERN_DEBUG "F");
static time_t last_time_val = 0;
struct vpp_device *p_vpp = (struct vpp_device *) dev;
struct timeval ptimeval;
gettimeofday(&ptimeval, NULL);
time_t time_val = (time_t) ptimeval.tv_sec;
if ((motion_detect_buf != NULL) && (motion_detect_oldframe_buf != NULL))
{ // det enable
if (vpp_md_cnt != md_isr_cnt)
{
detw = (vpp_msg.vpp_w + 31) / 32;
deth = (vpp_msg.vpp_h + 31) / 32;
loc = motion_det_pot_check(motion_detect_oldframe_buf, motion_detect_buf + 4 * ((vpp_msg.vpp_w + 31) / 32), mdet_result, detw, deth, 30, 20);
if (loc != 0xffffffff)
{
md_set_pot_x_y((loc % detw) * 32, (loc / detw) * 32);
}
}
memcpy(motion_detect_oldframe_buf, motion_detect_buf + 4 * ((vpp_msg.vpp_w + 31) / 32), ((vpp_msg.vpp_w + 31) / 32) * ((vpp_msg.vpp_h + 31) / 32));
}
if (last_time_val != time_val)
{
vpp_set_time(p_vpp, time_val);
last_time_val = time_val;
}
if (video_msg.video_num > 1)
{
if (video_msg.video_type_cur != ISP_VIDEO_0)
{ // 上次完成是副镜头,这次要处理主镜头
if (video_msg.dvp_type == 1)
{
vpp_video_recfg(dev, video_msg.dvp_iw, video_msg.dvp_ih, VPP_INPUT_FROM);
}
else if (video_msg.csi0_type == 1)
{
vpp_video_recfg(dev, video_msg.csi0_iw, video_msg.csi0_ih, VPP_INPUT_FROM);
}
else if (video_msg.csi1_type == 1)
{
vpp_video_recfg(dev, video_msg.csi1_iw, video_msg.csi1_ih, VPP_INPUT_FROM);
}
}
else
{ // 上次完成是主镜头,这次要处理副镜头
if (video_msg.dvp_type == 2)
{
vpp_video_recfg(dev, video_msg.dvp_iw, video_msg.dvp_ih, VPP_INPUT_FROM);
}
else if (video_msg.csi0_type == 2)
{
vpp_video_recfg(dev, video_msg.csi0_iw, video_msg.csi0_ih, VPP_INPUT_FROM);
}
else if (video_msg.csi1_type == 2)
{
vpp_video_recfg(dev, video_msg.csi1_iw, video_msg.csi1_ih, VPP_INPUT_FROM);
}
}
}
for (itk = 0; itk < VPP_FUNC_DONE_NUM; itk++)
{
if (vpp_deal_dev_func_table[itk])
{
ret = vpp_deal_dev_func_table[itk](vpp_deal_dev_func_arg_table[itk]);
if (ret)
{
vpp_deal_dev_func_table[itk] = NULL;
vpp_deal_dev_func_arg_table[itk] = 0;
}
}
}
if (scale3_kick_func)
{
scale3_kick_func();
}
if (vpp_msg.double_psram_for_buf1)
{
uint8_t shrink = vpp_msg.shrink; // 0: 1/2
// 1: 1/3
// 2: 1/4
// 3: 1/6
// 4: 2/3
// 5: 1/1
w = vpp_msg.vpp_w;
h = vpp_msg.vpp_h;
switch (shrink)
{
case 0:
buf1w = w / 2;
buf1h = h / 2;
break;
case 1:
buf1w = w / 3;
buf1h = h / 3;
break;
case 2:
buf1w = w / 4;
buf1h = h / 4;
break;
case 3:
buf1w = w / 6;
buf1h = h / 6;
break;
case 4:
buf1w = (w * 2) / 3;
buf1h = (h * 2) / 3;
break;
case 5:
buf1w = w;
buf1h = h;
break;
default:
_os_printf("buf1 shrink no this cfg\r\n");
break;
}
ptr_cache = (uint8_t*)psram_user_ptr;
psram_user_ptr = psram_ptr;
psram_ptr = ptr_cache;
vpp_set_buf1_shrink(p_vpp, shrink);
vpp_set_psram_ycnt(p_vpp, buf1w, buf1h);
vpp_set_psram_uvcnt(p_vpp, buf1w, buf1h);
vpp_set_buf1_y_addr(p_vpp, (uint32) psram_ptr);
vpp_set_buf1_u_addr(p_vpp, (uint32) psram_ptr + buf1w * buf1h);
vpp_set_buf1_v_addr(p_vpp, (uint32) psram_ptr + buf1w * buf1h + buf1w * buf1h / 4);
}
md_isr_cnt = vpp_md_cnt;
}
volatile uint8 itp_done = 0;
void vpp_itp_done(uint32 irq, uint32 dev, uint32 param)
{
os_printf("ITP_finish..\r\n");
itp_done = 1;
}
void vpp_itp_error(uint32 irq, uint32 dev, uint32 param)
{
os_printf("ITP_ER..\r\n");
}
void vpp_lib_error(uint32 irq, uint32 dev, uint32 param)
{
// dvp_vpp_reset();
os_printf("LIB_ER..\r\n");
}
void vpp_ipf_error(uint32 irq, uint32 dev, uint32 param)
{
// vpp_reset();
os_printf("IPF ERR..\r\n");
// outbuff_isr[0] = 0xff;
}
void vpp_md_find(uint32 irq, uint32 dev, uint32 param)
{
//_os_printf("MDHP..");
//_os_printf(KERN_DEBUG"?");
vpp_md_cnt++;
}
void vpp_itp_save_only(struct vpp_device *p_vpp, uint16_t w, uint16_t h, uint32_t psram_adr)
{
vpp_set_itp_y_addr(p_vpp, psram_adr);
vpp_set_itp_u_addr(p_vpp, psram_adr + w * h);
vpp_set_itp_v_addr(p_vpp, psram_adr + w * h + w * h / 4);
vpp_set_itp_auto_close(p_vpp, 0);
vpp_set_itp_enable(p_vpp, 1);
}
// uint8 yuv_staic_buf[1280*32 + 1280*16]__attribute__ ((aligned(4),section(".usersram2.src")));;
bool vpp_cfg(uint32_t w, uint32_t h, uint8_t input_from)
{
vpp_msg.vpp_w = w;
vpp_msg.vpp_h = h;
if (!w || !h)
{
os_printf(KERN_ERR "vpp_cfg err:w=%d,h=%d\r\n", w, h);
return FALSE;
}
#if IPF_EN
uint32_t len;
#endif
struct vpp_device *vpp_dev;
vpp_dev = (struct vpp_device *) dev_get(HG_VPP_DEVID);
#if IPF_EN
struct osdenc_device *osdenc_dev;
osdenc_dev = (struct osdenc_device *) dev_get(HG_OSD_ENC_DEVID);
osd_enc_open(osdenc_dev);
osd_enc_tran_config(osdenc_dev, 0xFFFFFF, 0xFFFFFF, 0x000000, 0x000000);
#endif
#if SCEN_EN
vpp_set_video_size(vpp_dev, w * 2, h * 2);
#else
os_printf("csi dvp_size_set\r\n");
vpp_set_video_size(vpp_dev, w, h);
#endif
vpp_set_ycbcr(vpp_dev, YUV_MODE);
#if (ONLY_Y == 1)
vpp_dis_uv_mode(vpp_dev, 1, 1);
#endif
vpp_set_threshold(vpp_dev, 0x00000000, 0x00ffffff);
vpp_set_sram_buf_mode(vpp_dev, vpp_msg.vpp_buf0_mode, vpp_msg.vpp_buf1_mode);
vpp_set_scale_buf_select(vpp_dev, vpp_msg.scale1_from_vpp, vpp_msg.scale3_from_vpp);
#if VPP_BUF1_EN
uint32_t buf1w = 0, buf1h = 0;
uint8_t shrink = vpp_msg.shrink; // 0: 1/2
// 1: 1/3
// 2: 1/4
// 3: 1/6
// 4: 2/3
// 5: 1/1
switch (shrink)
{
case 0:
buf1w = w / 2;
buf1h = h / 2;
break;
case 1:
buf1w = w / 3;
buf1h = h / 3;
break;
case 2:
buf1w = w / 4;
buf1h = h / 4;
break;
case 3:
buf1w = w / 6;
buf1h = h / 6;
break;
case 4:
buf1w = (w * 2) / 3;
buf1h = (h * 2) / 3;
break;
case 5:
buf1w = w;
buf1h = h;
break;
default:
_os_printf("buf1 shrink no this cfg\r\n");
break;
}
#if (PSRAM_FRAME_SAVE == 0)
// buf1的配置
{
uint32_t malloc_line;
if (vpp_msg.vpp_buf1_mode == VPP_MODE_2N)
{
malloc_line = vpp_msg.vpp_buf1_line_num * 2; // 2N
}
else
{
malloc_line = vpp_msg.vpp_buf1_line_num * 2 + 16; // 16+2N
}
if (yuvbuf1 == NULL)
{
yuvbuf1 = VPP_MALLOC(buf1w * malloc_line + buf1w * (malloc_line / 2));
if (yuvbuf1 == NULL)
{
_os_printf("no room yuvbuf1\r\n");
return FALSE;
}
}
vpp_set_buf1_y_addr(vpp_dev, (uint32) yuvbuf1);
vpp_set_buf1_u_addr(vpp_dev, (uint32) yuvbuf1 + buf1w * malloc_line);
vpp_set_buf1_v_addr(vpp_dev, (uint32) yuvbuf1 + buf1w * malloc_line + buf1w * (malloc_line / 4));
vpp_set_buf1_count(vpp_dev, vpp_msg.vpp_buf1_line_num);
}
#else
uint16_t p_w, p_h;
p_w = buf1w;
p_h = buf1h;
// vpp_set_sram_buf_mode(vpp_dev,1,1);
// vpp_set_scale_buf_select(vpp_dev,1,1);
vpp_set_nosram_buf_enable(vpp_dev, 2);
// vpp_set_nosram_buf1_enable(vpp_dev,1);
vpp_set_psram_ycnt(vpp_dev, p_w, p_h);
vpp_set_psram_uvcnt(vpp_dev, p_w, p_h);
// vpp_set_psram1_ycnt(vpp_dev,w/2,h/2);
// vpp_set_psram1_uvcnt(vpp_dev,w/2,h/2);
// vpp_set_buf1_y_addr(vpp_dev,(uint32)psram_all_frame_buf1);
// vpp_set_buf1_u_addr(vpp_dev,(uint32)psram_all_frame_buf1+w*h/4);
// vpp_set_buf1_v_addr(vpp_dev,(uint32)psram_all_frame_buf1+w*h/4+w*h/16);
if (vpp_data1_psram_buf)
{
VPP_PSRAM_FREE(vpp_data1_psram_buf);
vpp_data1_psram_buf = NULL;
}
vpp_data1_psram_buf = (uint8_t *) VPP_PSRAM_MALLOC(p_w * p_h * 3 / 2);
ASSERT(vpp_data1_psram_buf);
if (vpp_msg.double_psram_for_buf1)
{
vpp_data2_psram_buf = (uint8_t *) VPP_PSRAM_MALLOC(p_w * p_h * 3 / 2);
ASSERT(vpp_data2_psram_buf);
psram_ptr = vpp_data1_psram_buf;
psram_user_ptr = vpp_data2_psram_buf;
}
vpp_set_buf1_y_addr(vpp_dev, (uint32) vpp_data1_psram_buf);
vpp_set_buf1_u_addr(vpp_dev, (uint32) vpp_data1_psram_buf + p_w * p_h);
vpp_set_buf1_v_addr(vpp_dev, (uint32) vpp_data1_psram_buf + p_w * p_h + p_w * p_h / 4);
#endif
vpp_set_buf1_shrink(vpp_dev, vpp_msg.shrink);
vpp_set_buf1_en(vpp_dev, 1);
#endif
// buf0 的配置
{
uint32_t malloc_line;
if (vpp_msg.vpp_buf0_mode == VPP_MODE_2N)
{
malloc_line = vpp_msg.vpp_buf0_line_num * 2; // 2N
}
else
{
malloc_line = vpp_msg.vpp_buf0_line_num * 2 + 16; // 16+2N
}
if (yuvbuf == NULL)
{
yuvbuf = (uint8_t *) VPP_MALLOC(w * malloc_line + w * (malloc_line / 2));
if (yuvbuf == NULL)
{
_os_printf("no room yuvbuf0\r\n");
return FALSE;
}
}
vpp_set_buf0_count(vpp_dev, vpp_msg.vpp_buf0_line_num);
vpp_set_buf0_en(vpp_dev, 1);
#if (ONLY_Y == 1)
vpp_set_buf0_y_addr(vpp_dev, (uint32) psram_buf);
#else
vpp_set_buf0_y_addr(vpp_dev, (uint32) yuvbuf);
vpp_set_buf0_u_addr(vpp_dev, (uint32) yuvbuf + w * malloc_line);
vpp_set_buf0_v_addr(vpp_dev, (uint32) yuvbuf + w * malloc_line + w * (malloc_line / 4));
#endif
}
vpp_set_water0_color(vpp_dev, 0xff, 0x80, 0x80);
vpp_set_water0_bitmap(vpp_dev, (uint32) ele_lib);
vpp_set_water0_locate(vpp_dev, 8, 16);
vpp_set_water0_contrast(vpp_dev, 0);
vpp_set_watermark0_charsize_and_num(vpp_dev, 16, 32, 19);
vpp_set_watermark0_mode(vpp_dev, 1);
struct timeval ptimeval;
gettimeofday(&ptimeval, NULL);
time_t time_val = (time_t) ptimeval.tv_sec;
vpp_set_time(vpp_dev, time_val);
vpp_set_water0_rc(vpp_dev, 0);
vpp_set_watermark0_auto_rc_sram_adr(vpp_dev, (uint32_t) autorc);
vpp_set_watermark0_auto_rc_threshold(vpp_dev, 16 * 32 * 128, 16 * 32 * 32);
vpp_set_watermark_auto_rc_mode(vpp_dev, 0); // double sensor
vpp_set_watermark0_auto_rc(vpp_dev, 1, 0x00, 0x80, 0x80);
#if IPF_EN
len = water2_change_ipf(w, h, photo_lib2, 48, 48, 100, 300, NULL);
vpp_encode_ipf = (uint8_t *) VPP_MALLOC(len);
water2_change_ipf(w, h, photo_lib2, 48, 48, 100, 300, vpp_encode_ipf);
vpp_set_ifp_addr(vpp_dev, (uint32_t) vpp_encode_ipf);
#endif
#if 0
vpp_set_water1_color(vpp_dev,0xff,0x80,0x80);
vpp_set_water1_bitmap(vpp_dev,(uint32)photo_lib2);
vpp_set_water1_locate(vpp_dev,45,30);
vpp_set_water1_contrast(vpp_dev,0);
// vpp_set_watermark1_size(vpp_dev,224,48);
vpp_set_watermark1_size(vpp_dev,48,48);
vpp_set_watermark1_mode(vpp_dev,0);
vpp_set_water1_rc(vpp_dev,0);
#endif
// vpp_request_irq(vpp_dev, HSIE_ISR, (vpp_irq_hdl) &vpp_hsie_isr, (uint32) vpp_dev);
vpp_request_irq(vpp_dev, VSIE_ISR, (vpp_irq_hdl) &vpp_vsie_isr, (uint32) vpp_dev);
vpp_request_irq(vpp_dev, FRAME_DONE_ISR, (vpp_irq_hdl) &vpp_frame_done, (uint32) vpp_dev);
vpp_request_irq(vpp_dev, SCIE_ISR, (vpp_irq_hdl) &vpp_data_done, h);
vpp_request_irq(vpp_dev, LOVIE_ISR, (vpp_irq_hdl) &vpp_lib_error, (uint32) vpp_dev);
vpp_request_irq(vpp_dev, IPF_OV_ISR, (vpp_irq_hdl) &vpp_ipf_error, (uint32) vpp_dev);
vpp_request_irq(vpp_dev, MDPIE_ISR, (vpp_irq_hdl) &vpp_md_find, (uint32) vpp_dev);
vpp_request_irq(vpp_dev, ITP_OV_ISR, (vpp_irq_hdl) &vpp_itp_error, (uint32) vpp_dev);
vpp_request_irq(vpp_dev, ITP_DONE_ISR, (vpp_irq_hdl) &vpp_itp_done, (uint32) vpp_dev);
#if DET_EN
motion_detect_buf = (uint8_t *) VPP_MALLOC(((w + 31) / 32) * ((h + 31) / 32) + 4 * ((w + 31) / 32));
if ((motion_detect_buf == NULL))
{
goto det_module_end;
}
vpp_set_motion_calbuf(vpp_dev, (uint32_t) motion_detect_buf);
vpp_set_motion_range(vpp_dev, 0, 0, w, h); // 检测图像范围,blk大小为32*32个像素点
vpp_set_motion_blk_threshold(vpp_dev, 10); // 检测对应的blk移动的阀值
vpp_set_motion_frame_threshold(vpp_dev, 10); // 检测多少个blk超过阀值再触发移动检测中断
if (vpp_msg.mdt)
{
// 申请空间,支持返回移动的区域坐标
motion_detect_oldframe_buf = (uint8_t *) VPP_MALLOC(((w + 31) / 32) * ((h + 31) / 32));
mdet_result = (uint8_t *) VPP_MALLOC(((w + 31) / 32) * ((h + 31) / 32));
if (mdet_result == NULL || motion_detect_oldframe_buf == NULL)
{
VPP_FREE(motion_detect_oldframe_buf);
VPP_FREE(mdet_result);
motion_detect_oldframe_buf = NULL;
mdet_result = NULL;
}
else
{
motion_blk_threshold = 10;
motion_blknum_threshold = 10;
memset(motion_detect_oldframe_buf, 0, ((w + 31) / 32) * ((h + 31) / 32));
}
}
vpp_set_motion_det_enable(vpp_dev, 1);
det_module_end:
#endif
vpp_set_mode(vpp_dev, VPP_INPUT_FORMAT);
vpp_set_input_interface(vpp_dev, input_from);
vpp_set_watermark0_enable(vpp_dev, 1);
// vpp_set_watermark1_enable(vpp_dev,1);
#if IPF_EN
vpp_set_ifp_en(vpp_dev, 1);
#endif
vpp_msg.vpp_scale_w = VPP_SCALE_WIDTH;
vpp_msg.vpp_scale_h = VPP_SCALE_HIGH;
vpp_open(vpp_dev);
return TRUE;
}
void set_vpp_scale_w_h(uint8_t en, uint16_t w, uint16_t h)
{
struct scale_device *scale_dev;
uint8_t *vpp_buf = get_vpp_buf(0);
if (vpp_buf)
{
vpp_msg.vpp_scale_w = w;
vpp_msg.vpp_scale_h = h;
if (en)
{
scale_dev = (struct scale_device *) dev_get(HG_SCALE1_DEVID);
scale_from_vpp(scale_dev, (uint32_t) vpp_buf, vpp_msg.vpp_w, vpp_msg.vpp_h, w, h);
}
}
}
bool vpp_cfg_release()
{
struct vpp_device *p_vpp = (struct vpp_device *) dev_get(HG_VPP_DEVID);
vpp_close(p_vpp);
if (yuvbuf)
{
VPP_FREE(yuvbuf);
yuvbuf = NULL;
}
#if VPP_BUF1_EN
if (yuvbuf1)
{
VPP_FREE(yuvbuf1);
yuvbuf1 = NULL;
}
#endif
if (vpp_encode_ipf)
{
VPP_FREE(vpp_encode_ipf);
vpp_encode_ipf = NULL;
}
if (motion_detect_buf)
{
VPP_FREE(motion_detect_buf);
motion_detect_buf = NULL;
}
if (vpp_data1_psram_buf)
{
VPP_PSRAM_FREE(vpp_data1_psram_buf);
vpp_data1_psram_buf = NULL;
}
if (vpp_data2_psram_buf)
{
VPP_PSRAM_FREE(vpp_data2_psram_buf);
vpp_data2_psram_buf = NULL;
}
return TRUE;
}
int8_t vpp_dev_open()
{
struct vpp_device *vpp_dev;
vpp_dev = (struct vpp_device *) dev_get(HG_VPP_DEVID);
vpp_open(vpp_dev);
return 0;
}
/**************************************************检测移动侦测接口***************************************************** */
struct mdt_coord_msg mdet_msg[4];
uint32 mdxy;
uint32 motion_det_pot_check(uint8_t *old_y, uint8_t *new_y, uint8_t *copy, uint16 w, uint16 h, uint8_t blk_thd, uint8_t md_blk_num)
{
uint16 i, j;
uint16 mw, mh;
// uint16 mwc,mhc;
uint16 bx, by;
// uint16 bmx,bmy;
// uint16 bxc,byc;
uint32 local_base = 0;
// uint32 check_local;
// uint32 mov_cnt_max;
// uint32 mov_cnt;
// uint8_t turnaround;
uint16 i1, j1;
uint8_t mloop;
// uint8_t mxj;
uint8_t potd;
uint8_t mask;
uint16_t mx0, mx1;
uint16_t my0, my1;
uint16_t mapdt_loc[4][6];
uint16_t mapdt_num;
uint8_t result_cnt[4];
uint32_t result_loc[4];
// uint8_t xad,yad;
uint16 mvblk = 0;
uint8_t x0m, x1m, y0m, y1m;
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++)
{
if (abs(old_y[i + j * w] - new_y[i + j * w]) >= blk_thd)
{
old_y[i + j * w] = 255;
mvblk++;
}
else
{
old_y[i + j * w] = 0;
}
}
}
if (mvblk < md_blk_num)
{
return 0xffffffff;
}
memcpy(copy, old_y, w * h);
memset(mapdt_loc, 0xff, 4 * 6 * 2);
memset(result_cnt, 0, 4);
memset(result_loc, 0, 4 * 4);
mapdt_num = 0;
for (j1 = 0; j1 < h - 1; j1++)
{
for (i1 = 0; i1 < w - 1; i1++)
{
potd = 0;
for (j = 0; j < 2; j++)
{
for (i = 0; i < 2; i++)
{
if (old_y[i1 + j1 * w + i + j * w] == 255)
{
potd++;
if (potd == 4)
{
mask = 1;
for (mloop = 0; mloop < 4; mloop++)
{
if (mapdt_loc[mloop][0] != 0xffff)
{ // 有座标
mx0 = mapdt_loc[mloop][2];
mx1 = mapdt_loc[mloop][3];
my0 = mapdt_loc[mloop][4];
my1 = mapdt_loc[mloop][5];
if (mx0 > 3)
{
x0m = mx0 - 3;
}
else
{
x0m = 0;
}
if ((mx1 + 3) > w)
{
x1m = w - 1;
}
else
{
x1m = mx1 + 3;
}
if (my0 > 3)
{
y0m = my0 - 3;
}
else
{
y0m = 0;
}
if ((my1 + 3) > h)
{
y1m = h - 1;
}
else
{
y1m = my1 + 3;
}
if (((i1 + i) >= x0m) && ((i1 + i) <= x1m) && ((j1 + j) >= y0m) && ((j1 + j) <= y1m))
{
mask = 0;
}
}
}
if (mask == 1)
{
for (mloop = 0; mloop < 4; mloop++)
{
if (mapdt_loc[mloop][0] == 0xffff)
{
mapdt_loc[mloop][0] = i1 + i;
mapdt_loc[mloop][1] = j1 + j;
if (mapdt_loc[mloop][0] > 3)
{
mx0 = mapdt_loc[mloop][0] - 3;
}
else
{
mx0 = 0;
}
if ((mapdt_loc[mloop][0] + 3) > w)
{
mx1 = w - 1;
}
else
{
mx1 = mapdt_loc[mloop][0] + 3;
}
if (mapdt_loc[mloop][1] > 3)
{
my0 = mapdt_loc[mloop][1] - 3;
}
else
{
my0 = 0;
}
if ((mapdt_loc[mloop][1] + 3) > h)
{
my1 = h - 1;
}
else
{
my1 = mapdt_loc[mloop][1] + 3;
}
mapdt_loc[mloop][2] = mx0;
mapdt_loc[mloop][3] = mx1;
mapdt_loc[mloop][4] = my0;
mapdt_loc[mloop][5] = my1;
break;
}
}
if (mapdt_loc[3][0] != 0xffff)
{
goto mdt_end;
}
}
}
}
}
}
}
}
mdt_end:
for (mloop = 0; mloop < 4; mloop++)
{
if (mapdt_loc[mloop][0] != 0xffff)
{
bx = mapdt_loc[mloop][2];
by = mapdt_loc[mloop][4];
mw = mapdt_loc[mloop][3] - mapdt_loc[mloop][2];
mh = mapdt_loc[mloop][5] - mapdt_loc[mloop][4];
potd = 0;
for (j = 0; j < mh; j++)
{
for (i = 0; i < mw; i++)
{
if (old_y[bx + by * w + i + j * w] == 0xff)
{
potd++;
}
}
}
result_cnt[mloop] = potd;
// printf("(%d %d===>%d %d pot:%d)\r\n",bx,by,mw,mh,potd);
if (potd < 7)
{
result_loc[mloop] = (mapdt_loc[mloop][0] - 1) + (mapdt_loc[mloop][1] - 1) * w;
}
else
{
result_loc[mloop] = mapdt_loc[mloop][0] + mapdt_loc[mloop][1] * w;
}
}
}
for (i = 0; i < 4; i++)
{
if (mapdt_loc[i][0] != 0xffff)
{
mdet_msg[i].blkmv_cnt = result_cnt[i];
mdet_msg[i].x0 = mapdt_loc[i][2];
mdet_msg[i].x1 = mapdt_loc[i][3];
mdet_msg[i].y0 = mapdt_loc[i][4];
mdet_msg[i].y1 = mapdt_loc[i][5];
mdet_msg[i].x = mapdt_loc[i][0];
mdet_msg[i].y = mapdt_loc[i][1];
}
else
{
mdet_msg[i].blkmv_cnt = 0;
}
}
if (result_loc[0] != 0)
{
for (i = 0; i < 4; i++)
{
if (local_base < result_loc[i])
{
local_base = result_loc[i];
// printf("local_base:%d\r\n",local_base);
}
}
return local_base;
}
else
{
return 0xffffffff;
}
}
void md_set_pot_x_y(uint16 x, uint16 y)
{
mdxy = ((y & 0xffff) << 16 | (x & 0xffff));
}
// 获取绝对位置
uint32 md_get_pot_x_y()
{
return mdxy;
}
// 获取相对位置
uint32 md_get_relative_pot_x_y(uint16_t r_w, uint16_t r_h, uint16_t *gx, uint16_t *gy)
{
uint16_t x = (r_w * (mdxy & 0xffff) / vpp_msg.vpp_w) & 0xffff;
uint16_t y = (r_h * (mdxy >> 16) / vpp_msg.vpp_h) & 0xffff;
if (gx)
{
*gx = x;
}
if (gy)
{
*gy = y;
}
return y << 16 | x;
}
uint32 md_get_relative_pot_x0_y0_x1_y1(uint8_t num, uint16_t r_w, uint16_t r_h, uint16_t *gx0, uint16_t *gy0, uint16_t *gx1, uint16_t *gy1)
{
uint16_t x0 = (r_w * (mdet_msg[num].x0 * 32) / vpp_msg.vpp_w) & 0xffff;
uint16_t y0 = (r_h * (mdet_msg[num].y0 * 32) / vpp_msg.vpp_h) & 0xffff;
uint16_t x1 = (r_w * (mdet_msg[num].x1 * 32) / vpp_msg.vpp_w) & 0xffff;
uint16_t y1 = (r_h * (mdet_msg[num].y1 * 32) / vpp_msg.vpp_h) & 0xffff;
if (mdet_msg[num].blkmv_cnt == 0)
{
if (gx0)
{
*gx0 = 0;
}
if (gy0)
{
*gy0 = 0;
}
if (gx1)
{
*gx1 = 1;
}
if (gy1)
{
*gy1 = 1;
}
return 1;
}
if (gx0)
{
*gx0 = x0;
}
if (gy0)
{
*gy0 = y0;
}
if (gx1)
{
*gx1 = x1;
}
if (gy1)
{
*gy1 = y1;
}
return 0;
}