246 lines
6.8 KiB
C
246 lines
6.8 KiB
C
#ifdef CONFIG_UI_ENABLE //上电执行则打开app_config.h TCFG_DEMO_UI_RUN = 1
|
|
|
|
#include "app_config.h"
|
|
#include "device/device.h"//u8
|
|
#include "storage_device.h"//SD
|
|
#include "server/video_dec_server.h"//fopen
|
|
#include "system/includes.h"//GPIO
|
|
#include "lcd_drive.h"
|
|
#include "sys_common.h"
|
|
#include "yuv_soft_scalling.h"
|
|
#include "asm/jpeg_codec.h"
|
|
#include "lcd_te_driver.h"
|
|
#include "get_yuv_data.h"
|
|
#include "lcd_config.h"
|
|
|
|
|
|
/************视频部分*将摄像头数据显示到lcd上**********************************/
|
|
/* 开关打印提示 */
|
|
#if 1
|
|
#define log_info(x, ...) printf("\n[camera_to_lcd_test]>>>>>>>>>>>>>>>>>>>###" x " \n", ## __VA_ARGS__)
|
|
#else
|
|
#define log_info(...)
|
|
#endif
|
|
|
|
|
|
static void Calculation_frame(void)
|
|
{
|
|
static u32 tstart = 0, tdiff = 0;
|
|
static u8 fps_cnt = 0;
|
|
|
|
fps_cnt++ ;
|
|
|
|
if (!tstart) {
|
|
tstart = timer_get_ms();
|
|
} else {
|
|
tdiff = timer_get_ms() - tstart;
|
|
|
|
if (tdiff >= 1000) {
|
|
printf("\n [MSG]fps_count = %d\n", fps_cnt * 1000 / tdiff);
|
|
tstart = 0;
|
|
fps_cnt = 0;
|
|
}
|
|
}
|
|
}
|
|
/********保存JPG图片到SD卡中************/
|
|
static void save_jpg_ontime(u8 *buf, u32 len)
|
|
{
|
|
if (storage_device_ready()) {
|
|
char file_name[64];//定义路径存储
|
|
snprintf(file_name, 64, CONFIG_ROOT_PATH"JPG/JPG***.JPG");
|
|
FILE *fd = fopen(file_name, "wb+");
|
|
fwrite(buf, 1, len, fd);
|
|
fclose(fd);
|
|
log_info("JPG save ok name=JPG\r\n");
|
|
}
|
|
}
|
|
/********保存RGB数据到SD卡中************/
|
|
static void get_RGB_save_to_SD(char *RGB, u32 len)
|
|
{
|
|
if (storage_device_ready()) {
|
|
char file_name[64];//定义路径存储
|
|
snprintf(file_name, 64, CONFIG_ROOT_PATH"rgb/RGB***.bin");
|
|
FILE *fd = fopen(file_name, "wb+");
|
|
fwrite(RGB, 1, len, fd);
|
|
fclose(fd);
|
|
log_info("RGB save ok name=RGB\r\n");
|
|
}
|
|
}
|
|
/********保存YUV数据到SD卡中************/
|
|
static void save_YUV_date_ontime(u8 *buf, u32 len)
|
|
{
|
|
if (storage_device_ready()) {
|
|
char file_name[64];//定义路径存储
|
|
snprintf(file_name, 64, CONFIG_ROOT_PATH"YUV/YUV***.bin");
|
|
FILE *fd = fopen(file_name, "wb+");
|
|
fwrite(buf, 1, len, fd);
|
|
fclose(fd);
|
|
log_info("YUV save ok name=YUV\r\n");
|
|
}
|
|
}
|
|
|
|
/********读取JPG数据并保存在SD卡中该数据经过缩放保存大小1280*720********/
|
|
#define yuv_out_w 1280
|
|
#define yuv_out_h 720
|
|
#define in_w 640
|
|
#define in_h 480
|
|
static void get_JPG_save_to_SD(char *yuv_img_buf)
|
|
{
|
|
struct jpeg_encode_req req = {0};
|
|
u32 buf_len = yuv_out_w * yuv_out_h * 3 / 2 ;
|
|
u8 *yuv_out_buf = malloc(buf_len);
|
|
u8 err = 0;
|
|
|
|
if (!yuv_out_buf) {
|
|
log_info("jpeg buf not enough err!!!\n");
|
|
return;
|
|
}
|
|
|
|
YUV420p_Soft_Scaling(yuv_img_buf, yuv_out_buf, in_w, in_h, yuv_out_w, yuv_out_h);
|
|
//q >=2 , size = w*h*q*0.32
|
|
req.q = 13; //jepg编码质量(范围0-13),0最小 质量越好,下面的编码buf需要适当增大
|
|
req.format = JPG_SAMP_FMT_YUV420;
|
|
req.data.buf = yuv_out_buf;
|
|
req.data.len = buf_len;
|
|
req.width = yuv_out_w ;
|
|
req.height = yuv_out_h ;
|
|
req.y = yuv_out_buf;
|
|
req.u = req.y + (yuv_out_w * yuv_out_h);
|
|
req.v = req.u + (yuv_out_w * yuv_out_h) / 4;
|
|
err = jpeg_encode_one_image(&req);//获取一张JPG图片
|
|
|
|
if (!err) {
|
|
save_jpg_ontime(req.data.buf, buf_len); //保存图片到SD卡
|
|
} else {
|
|
log_info("get_jpg err!!!\n");
|
|
}
|
|
free(yuv_out_buf);
|
|
}
|
|
|
|
/*********摄像头应用部分***********/
|
|
static void test_main(u8 *buf, u32 len, yuv_in_w, yuv_in_h)
|
|
{
|
|
int msg[32];
|
|
static u8 time = 0;
|
|
|
|
if (get_lcd_show_deta_mode() == ui_camera) { //其余模式不需要推摄像头数据
|
|
YUV420p_Soft_Scaling(buf, NULL, in_w, in_h, LCD_W, LCD_H);
|
|
lcd_show_frame(buf, LCD_YUV420_DATA_SIZE); //240*320*2=153600
|
|
}
|
|
if (get_lcd_show_deta_mode() == camera) { //其余模式不需要推摄像头数据
|
|
YUV420p_Soft_Scaling(buf, NULL, in_w, in_h, LCD_W, LCD_H);
|
|
lcd_show_frame(buf, LCD_YUV420_DATA_SIZE); //240*320*2=153600
|
|
}
|
|
}
|
|
|
|
void set_video_rt_cb(u32(*cb)(void *, u8 *, u32), void *priv);
|
|
int user_net_video_rec_open(char forward);
|
|
int user_net_video_rec_close(char forward);
|
|
int jpeg2yuv_open(void);
|
|
void jpeg2yuv_yuv_callback_register(void (*cb)(u8 *data, u32 len, int width, int height));
|
|
int jpeg2yuv_jpeg_frame_write(u8 *buf, u32 len);
|
|
void jpeg2yuv_close(void);
|
|
static void uvc_video_test(void);
|
|
|
|
void get_yuv_init(void (*cb)(u8 *data, u32 len, int width, int height));
|
|
|
|
void camera_to_lcd_init(void)//摄像头选择 并初始化
|
|
{
|
|
#ifdef CONFIG_UVC_VIDEO2_ENABLE
|
|
uvc_video_test();
|
|
#else
|
|
get_yuv_init(test_main);
|
|
#endif
|
|
}
|
|
|
|
void camera_to_lcd_uninit(void)
|
|
{
|
|
void get_yuv_uninit(void);
|
|
get_yuv_uninit();
|
|
}
|
|
int isc_log_en()//如果定义该函数丢帧信息屏蔽
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static void uvc_jpeg_cb(void *hdr, void *data, u32 len)
|
|
{
|
|
#define JPEG_HEAD 0xE0FFD8FF
|
|
#define JPEG_HEAD1 0xC0FFD8FF
|
|
u32 *head = (u32 *)data;
|
|
if (*head == JPEG_HEAD || *head == JPEG_HEAD1) {
|
|
//video
|
|
jpeg2yuv_jpeg_frame_write((u8 *)data, len);
|
|
} else {
|
|
//audio
|
|
}
|
|
}
|
|
|
|
static void camera_show_lcd(u8 *buf, u32 size, int width, int height)
|
|
{
|
|
char *ssid = NULL;
|
|
char *pwd = NULL;
|
|
#if CONFIG_LCD_QR_CODE_ENABLE
|
|
qr_code_get_one_frame_YUV_420(buf, width, height);
|
|
qr_get_ssid_pwd(&ssid, &pwd);
|
|
printf(">>>>>>>>>>>>>>>sssid = %s, pwd = %s", ssid, pwd);
|
|
#endif
|
|
YUV420p_Soft_Scaling(buf, NULL, width, height, LCD_W, LCD_H);
|
|
lcd_show_frame(buf, LCD_YUV420_DATA_SIZE);
|
|
Calculation_frame();
|
|
}
|
|
|
|
static void uvc_video_task(void *priv)
|
|
{
|
|
int ret;
|
|
start:
|
|
//0.等待UVC上线
|
|
while (!dev_online("uvc")) {
|
|
os_time_dly(10);
|
|
}
|
|
//1.打开jpeg解码YUV
|
|
ret = jpeg2yuv_open();
|
|
if (ret) {
|
|
return;
|
|
}
|
|
printf(">>>>>>>>>>>>>>>111");
|
|
//2.注册YUV数据回调函数
|
|
jpeg2yuv_yuv_callback_register(camera_show_lcd);
|
|
//3.打开UVC实时流
|
|
printf(">>>>>>>>>>>>>>>222");
|
|
ret = user_net_video_rec_open(1);
|
|
if (ret) {
|
|
jpeg2yuv_close();
|
|
return;
|
|
}
|
|
printf(">>>>>>>>>>>>>>>333");
|
|
//3.注册jpeg数据回调函数
|
|
set_video_rt_cb(uvc_jpeg_cb, NULL);
|
|
|
|
#if TCFG_LCD_USB_SHOW_COLLEAGUE
|
|
void set_tcp_uvc_rt_cb(u32(*cb)(void *priv, void *data, u32 len));
|
|
void set_udp_uvc_rt_cb(u32(*cb)(void *priv, void *data, u32 len));
|
|
set_udp_uvc_rt_cb(uvc_jpeg_cb); //wifi udp
|
|
set_tcp_uvc_rt_cb(uvc_jpeg_cb); //wifi tcp
|
|
#endif
|
|
|
|
//4.检查是否掉线
|
|
struct lbuf_test_head *rbuf = NULL;
|
|
|
|
while (dev_online("uvc")) {
|
|
os_time_dly(5);
|
|
}
|
|
//5.关闭UVC实时流
|
|
user_net_video_rec_close(1);
|
|
//6.关闭jpeg解码YUV
|
|
jpeg2yuv_close();
|
|
goto start;
|
|
|
|
}
|
|
static void uvc_video_test(void)
|
|
{
|
|
thread_fork("uvc_video_task", 5, 1024, 0, 0, uvc_video_task, NULL);
|
|
}
|
|
#endif
|
|
|