189 lines
4.2 KiB
C
189 lines
4.2 KiB
C
#include "system/includes.h"
|
||
#include "os/os_api.h"
|
||
#include "app_config.h"
|
||
#include "get_yuv_data.h"
|
||
#include "asm/isc.h"
|
||
#include "video_ioctl.h"
|
||
#include "device.h"
|
||
#include "video.h"
|
||
|
||
//sdram size must >= (2 * 1024 * 1024)
|
||
#if (defined CONFIG_VIDEO0_ENABLE && (__SDRAM_SIZE__ >= (2 * 1024 * 1024)))
|
||
|
||
#define YUV_TEST 0
|
||
#define YUV_BLOCK_SCAN 0
|
||
|
||
#if YUV_BLOCK_SCAN
|
||
static u8 isc_buf[YUV_DATA_WIDTH * 64 * 3 / 2] SEC(.sram) ALIGNE(32);
|
||
#endif
|
||
|
||
static u8 yuv_buf[YUV_DATA_WIDTH * YUV_DATA_HEIGHT * 3 / 2] ALIGNE(32);
|
||
|
||
static get_yuv_cfg __info;
|
||
|
||
static int yuv420_block_scan(void *info)
|
||
{
|
||
struct yuv_block_info *yuv_info = (struct yuv_block_info *)info;
|
||
/*
|
||
*算法处理,禁止加延时函数!
|
||
*/
|
||
if (yuv_info->start) { //帧起始第一个分块
|
||
|
||
} else {
|
||
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
static void get_yuv_task(void *priv)
|
||
{
|
||
int err;
|
||
struct video_format f = {0};
|
||
struct yuv_image yuv = {0};
|
||
void *dev;
|
||
void (*cb)(u8 * data, u32 len, int width, int height);
|
||
|
||
/*
|
||
*step 1
|
||
*/
|
||
dev = dev_open(YUV_DATA_SOURCE, NULL);
|
||
if (!dev) {
|
||
printf("open video err !!!!\n\n");
|
||
return;
|
||
}
|
||
|
||
#if 1
|
||
/********************YUV内部加外部双BUF,上层处理时间可长一些************************/
|
||
/*
|
||
*step 2
|
||
*/
|
||
f.type = VIDEO_BUF_TYPE_VIDEO_OVERLAY;
|
||
f.pixelformat = VIDEO_PIX_FMT_YUV420;
|
||
#if YUV_BLOCK_SCAN
|
||
f.static_buf = (u8 *)isc_buf;
|
||
f.sbuf_size = sizeof(isc_buf);
|
||
f.block_done_cb = yuv420_block_scan;
|
||
#endif
|
||
err = dev_ioctl(dev, VIDIOC_SET_FMT, (u32)&f);
|
||
if (err) {
|
||
goto error;
|
||
}
|
||
|
||
/*
|
||
*step 3
|
||
*/
|
||
//BUFF配置1:使用外部BUFF,上层处理时间最大为摄像头的帧率时间 - 15ms,GC0308默认驱动处理最大时间35m
|
||
#if 1 //YUV分块(行)回调,用不到yuv一帧,则关闭
|
||
yuv.addr = (u8 *)yuv_buf;
|
||
yuv.size = sizeof(yuv_buf);
|
||
#endif
|
||
err = dev_ioctl(dev, VIDIOC_SET_OVERLAY, (u32)&yuv);
|
||
if (err) {
|
||
goto error;
|
||
}
|
||
|
||
#else
|
||
/********************YUV支持外部静态BUF,上层处理时间较短************************/
|
||
/*
|
||
*step 2
|
||
*/
|
||
f.type = VIDEO_BUF_TYPE_VIDEO_OVERLAY;
|
||
f.pixelformat = VIDEO_PIX_FMT_YUV420;
|
||
f.static_buf = (u8 *)yuv_buf;
|
||
f.sbuf_size = sizeof(yuv_buf);
|
||
#if YUV_BLOCK_SCAN
|
||
f.block_done_cb = yuv420_block_scan;
|
||
#endif
|
||
err = dev_ioctl(dev, VIDIOC_SET_FMT, (u32)&f);
|
||
if (err) {
|
||
goto error;
|
||
}
|
||
|
||
//BUFF配置2:使用内部BUFF,内存节省450K,上层处理时间最大为摄像头的帧结束到帧起始时间,需要看摄像头帧同步信号波形测量,GC0308默认驱动处理最大时间16ms
|
||
err = dev_ioctl(dev, VIDIOC_SET_OVERLAY, (u32)0);
|
||
if (err) {
|
||
goto error;
|
||
}
|
||
#endif
|
||
|
||
|
||
#if YUV_TEST
|
||
FILE *fd = fopen(CONFIG_ROOT_PATH"yuv_1.yuv", "wb+");
|
||
int cnt = 0;
|
||
#endif
|
||
while (1) {
|
||
if (thread_kill_req()) {
|
||
break;
|
||
}
|
||
|
||
cb = __info.cb;
|
||
|
||
/*
|
||
*step 4
|
||
*/
|
||
err = dev_ioctl(dev, VIDIOC_GET_OVERLAY, (u32)&yuv);
|
||
if (!err) {
|
||
//do something in this step
|
||
#if YUV_TEST
|
||
if (fd) {
|
||
cnt++;
|
||
fwrite(fd, yuv.addr, yuv.size);
|
||
if (cnt > 100) {
|
||
fclose(fd);
|
||
fd = NULL;
|
||
}
|
||
printf("write file ok : %d \n", cnt);
|
||
}
|
||
#else
|
||
if (cb) {
|
||
cb(yuv.addr, yuv.size, YUV_DATA_WIDTH, YUV_DATA_HEIGHT);
|
||
}
|
||
#endif
|
||
}
|
||
#if YUV_TEST
|
||
else if (fd) {
|
||
fclose(fd);
|
||
fd = NULL;
|
||
}
|
||
#endif
|
||
|
||
/*
|
||
*step 5
|
||
*/
|
||
dev_ioctl(dev, VIDIOC_CLEAR_OVERLAY, 0);
|
||
}
|
||
error:
|
||
/*
|
||
*step 6
|
||
*/
|
||
dev_close(dev);
|
||
__info.init = 0;
|
||
}
|
||
|
||
void get_yuv_init(void (*cb)(u8 *data, u32 len, int width, int height))
|
||
{
|
||
if (__info.init) {
|
||
return;
|
||
}
|
||
__info.init = 1;
|
||
__info.cb = cb;
|
||
thread_fork("GET_YUV_TASK", 8, 2048, 0, &__info.pid, get_yuv_task, NULL);
|
||
}
|
||
|
||
void get_yuv_uninit(void)
|
||
{
|
||
if (!__info.init) {
|
||
return;
|
||
}
|
||
thread_kill(&__info.pid, KILL_WAIT);
|
||
__info.cb = NULL;
|
||
__info.init = 0;
|
||
}
|
||
|
||
void set_get_yuv_data_cb(void (*cb)(u8 *data, u32 len, int width, int height))
|
||
{
|
||
__info.cb = cb;
|
||
}
|
||
|
||
#endif
|