Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources

This commit is contained in:
2026-07-06 11:30:13 +08:00
commit e76462eeb7
3451 changed files with 1415300 additions and 0 deletions

View File

@@ -0,0 +1,483 @@
#include <stdio.h>
#include <string.h>
#include "osal_file.h"
#include "avidemux.h"
#include "osal/string.h"
#define FourCC(aa, bb, cc, dd) ( ((aa)&0xFF) | (((bb)<<8)&0xFF00) | (((cc)<<16)&0xFF0000) | (((dd)<<24)&0xFF000000) )
#define FourCCCC(i) (i)&0xFF,(i>>8)&0xFF,(i>>16)&0xFF,(i>>24)&0xFF
#ifndef BIT
#define BIT(b) (1<<(b))
#endif
// 在parse階段哪些LIST是需要深入分析的
static int need_parse_list(uint32_t fourcc)
{
return
fourcc == FourCC('A','V','I',' ') ||
fourcc == FourCC('h','d','r','l') ||
fourcc == FourCC('s','t','r','l') ||
0;
}
#define MAX_LIST_DEPTH 5
//avi数据头解析不是全局变量
void *avidemux_parse(void *fp,void *aviinfo_point)
{
AVISTREAMHEADER strh;
struct _aviindex_chunk indx;
struct avistrinfo *str = NULL;
struct aviinfo *aviinfo = (struct aviinfo *)aviinfo_point;
uint32_t list_end[MAX_LIST_DEPTH]; // RIFF/LIST棧記錄其結束地址
uint32_t lvl;
uint32_t fcc_size[3]; // 緩存讀入的FourCC及其size
uint32_t pos;
uint32_t err;
memset(aviinfo_point,0,sizeof(struct aviinfo));
lvl = 0;
list_end[lvl] = osal_fsize (fp);
_os_printf ("%s : file size %08X\n", __func__, list_end[lvl]);
uint32_t msk = 0;
pos = 0;
while (pos < list_end[lvl]) {
if (osal_fread ((char*)fcc_size, 1, 8, fp) < 8) {
_os_printf ("%s : read fourcc & size error\n", __func__);
break;
}
// _os_printf ("%s : %c%c%c%c %08X", __func__, FourCCCC(fcc_size[0]), fcc_size[1]);
pos += 8;
// 檢查長度
if (fcc_size[1] + pos > list_end[lvl]) {
_os_printf ("%s : fourcc length error\n", __func__);
break;
}
err = 0;
switch (fcc_size[0]) {
case FourCC('R','I','F','F'):
case FourCC('L','I','S','T'):
// 檢查LIST的類型
if (osal_fread((char*)&fcc_size[2], 1, 4, fp) < 4) {
_os_printf ("%s : read LIST name error\n", __func__);
err = 1;
break;
}
if (need_parse_list(fcc_size[2]) && lvl < MAX_LIST_DEPTH-1) {
// 需要分析這個LIST並且棧空間還夠用
list_end[++lvl] = pos + fcc_size[1];
pos += 4;
// _os_printf ("%s : pos %08X %08X %08X", __func__, pos, list_end[lvl], fcc_size[1]);
} else {
pos += fcc_size[1];
osal_fseek (fp, pos);
}
break;
case FourCC('s','t','r','h'):
if (osal_fread(((void*)&strh)+2*sizeof(DWORD), 1, sizeof(strh)-2*sizeof(DWORD), fp) < sizeof(strh)-2*sizeof(DWORD)) {
_os_printf ("%s : read strh type error\n", __func__);
err = 1;
break;
}
pos += fcc_size[1];
// _os_printf ("found strh %s %dx%d %d frames", &strh.fccType, strh.rcFrame.right, strh.rcFrame.bottom, strh.dwLength);
if (strh.fccType == FourCC('v','i','d','s')) {
str = &aviinfo->str[0];
str->type = 0;
aviinfo->strmsk |= BIT(0);
msk |= BIT(0);
} else {
str = &aviinfo->str[1];
str->type = 1;
aviinfo->strmsk |= BIT(1);
msk |= BIT(1);
}
str->dwScale = strh.dwScale * 1000;
str->dwRate = strh.dwRate;
str->dwTotalFrames = strh.dwLength;
str->cur = 0;
str->avi = aviinfo;
break;
case FourCC('i','n','d','x'):
if (NULL == str) {
_os_printf ("%s : indx but no strh\n", __func__);
err = 1;
break;
}
if (osal_fread(((void*)&indx)+2*sizeof(DWORD), 1, sizeof(indx)-2*sizeof(DWORD), fp) < sizeof(indx)-2*sizeof(DWORD)) {
_os_printf ("%s : read indx type error\n", __func__);
err = 1;
break;
}
//找到超级索引的数量,然后保存超级索引表,并且计算序号(用于快速搜索)
str->dwIndexNum = indx.nEntriesInUse;
//一次性申请足够空间,读取超级索引表
str->superindex_cache = (struct _avisuperindex_entry_cache*)malloc(str->dwIndexNum*sizeof(struct _avisuperindex_entry_cache));
if(str->superindex_cache)
{
if(osal_fread((char*)str->superindex_cache, 1, str->dwIndexNum*sizeof(struct _avisuperindex_entry_cache), fp) < str->dwIndexNum*sizeof(struct _avisuperindex_entry_cache))
{
_os_printf ("%s : read indx type error\n", __func__);
err = 1;
break;
}
//扫描超级索引,记录索引序号起始
uint32_t offset = 0;
uint32_t max_size = 0;
uint32_t count = 0;
for(int i=0;i<str->dwIndexNum;i++)
{
str->superindex_cache[i].offset = offset;
count = ((str->superindex_cache[i].dwSize - sizeof(struct _aviindex_chunk))/sizeof(struct _avistdindex_entry));
str->superindex_cache[i].dwSize = count;
offset+= count;
if(count > max_size)
{
max_size = count;
}
//_os_printf("offset:%d\t%X\n",str->superindex_cache[i].offset,str->superindex_cache[i].dwOffsetl);
}
//如果是音频,则帧数修改一下
if(str->type == 1)
{
str->dwTotalFrames = offset;
}
//读取完毕后,去扫描索引最大值,申请最大空间,一次读取一个超级索引
str->stindex_cache = (struct _avistdindex_entry*)malloc(max_size*sizeof(struct _avistdindex_entry));
if(!str->stindex_cache)
{
err = 1;
break;
}
}
str->dwIndexBase = pos + sizeof(indx)-2*sizeof(DWORD);
//str->dwDuration = str->indx[0].dwDuration;
str->cached_indx_base = 0;
str->cached_ixnn_base = 0;
str->super_idx = ~0;
str->cur = 0;
// _os_printf ("found indx @%08X", str->dwIndexBase);
pos += fcc_size[1];
// 雖然緩存了512B的超級索引但該長度不是最終的長度
osal_fseek (fp, pos);
break;
default:
pos += fcc_size[1];
osal_fseek (fp, pos);
} // switch (fcc_size[0])
if (err) break;
if (pos == list_end[lvl]) {
// pop
--lvl;
}
if (pos > list_end[lvl]) {
_os_printf ("%s : list overread\n", __func__);
break;
}
} // while (pos < list_end[lvl])
_os_printf ("str[0] : %d @%08X:%08X\n", (int)aviinfo->str[0].dwTotalFrames, (int)aviinfo->str[0].dwIndexBase, (int)aviinfo->str[0].dwIndexNum);
_os_printf ("str[1] : %d @%08X:%08X\n", (int)aviinfo->str[1].dwTotalFrames, (int)aviinfo->str[1].dwIndexBase, (int)aviinfo->str[1].dwIndexNum);
aviinfo->fp = fp;
if(err)
{
for(int i=0;i<2;i++)
{
if(aviinfo->str[i].superindex_cache)
{
free(aviinfo->str[i].superindex_cache);
}
if(aviinfo->str[i].stindex_cache)
{
free(aviinfo->str[i].stindex_cache);
}
}
return NULL;
}
return aviinfo;
}
uint32_t get_avidemux_parse_stream(char *path,struct avi_msg *msg)
{
_os_printf("my path:%s\n",path);
void *fp = osal_fopen(path,"rb");
if(!fp)
{
return 0;
}
memset(msg,0,sizeof(struct avi_msg));
AVISTREAMHEADER strh;
//DWORD fccType;
uint32_t list_end[MAX_LIST_DEPTH]; // RIFF/LIST棧記錄其結束地址
uint32_t lvl;
uint32_t fcc_size[3]; // 緩存讀入的FourCC及其size
uint32_t pos;
uint32_t err;
uint32_t msk = 0;
lvl = 0;
list_end[lvl] = osal_fsize (fp);
pos = 0;
while (pos < list_end[lvl])
{
if (osal_fread ((char*)fcc_size, 1, 8, fp) < 8) {
_os_printf ("%s : read fourcc & size error\n", __func__);
break;
}
pos += 8;
// 檢查長度
if (fcc_size[1] + pos > list_end[lvl]) {
_os_printf ("%s : fourcc length error\n", __func__);
break;
}
err = 0;
switch (fcc_size[0])
{
case FourCC('R','I','F','F'):
case FourCC('L','I','S','T'):
// 檢查LIST的類型
if (osal_fread((char*)&fcc_size[2], 1, 4, fp) < 4) {
_os_printf ("%s : read LIST name error\n", __func__);
err = 1;
break;
}
if (need_parse_list(fcc_size[2]) && lvl < MAX_LIST_DEPTH-1) {
// 需要分析這個LIST並且棧空間還夠用
list_end[++lvl] = pos + fcc_size[1];
pos += 4;
} else {
pos += fcc_size[1];
osal_fseek (fp, pos);
}
break;
case FourCC('s','t','r','h'):
if (osal_fread((void*)&strh.fccType, 1, sizeof(strh)-2*sizeof(DWORD), fp) < sizeof(strh)-2*sizeof(DWORD)) {
_os_printf ("%s : read strh type error\n", __func__);
err = 1;
break;
}
pos += fcc_size[1];
if (strh.fccType == FourCC('v','i','d','s')) {
msk |= BIT(0);
msg->video_sample_rate = strh.dwRate;
} else {
msk |= BIT(1);
msg->audio_sample_rate = strh.dwRate/strh.dwSampleSize;
}
osal_fseek (fp, pos);
break;
default:
pos += fcc_size[1];
osal_fseek (fp, pos);
break;
}
if (pos == list_end[lvl])
{
--lvl;
}
if (pos > list_end[lvl]) {
_os_printf ("%s : list overread\n", __func__);
break;
}
}
_os_printf("end pos:%X\t%X\t%X\n",pos,list_end[lvl],msk);
if(fp)
{
osal_fclose(fp);
}
return msk;
}
//主要是偏移到cur的对应位置,并且返回对应数据的位置以及size,返回一个错误
uint32_t read_avi_offset(struct avistrinfo *str,uint32_t *base,uint32_t *size)
{
uint32_t err = 0;
*base = 0;
*size = 0;
uint8_t st_index_read = 0;
if(str->cur >= str->dwTotalFrames)
{
err = 1;
goto read_avi_offset_end;
}
//如果超级索引序号比最大的索引大,可能是第一次读取
if(str->super_idx >= str->dwIndexNum)
{
err = 2;
//那么计算cur当前的位置
for(int i=0;i<str->super_idx;i++)
{
if(str->superindex_cache[i].offset+str->superindex_cache[i].dwSize > str->cur && str->superindex_cache[i].offset <= str->cur)
{
str->super_idx = i;
st_index_read = 1;
err = 0;
break;
}
}
}
else
{
err = 3;
//如果在范围,则不需要处理
if(str->superindex_cache[str->super_idx].offset+str->superindex_cache[str->super_idx].dwSize > str->cur && str->superindex_cache[str->super_idx].offset <= str->cur)
{
err = 0;
}
else
{
//现在超级索引得到的偏移比cur大,那么就要从0开始搜索
if(str->superindex_cache[str->super_idx].offset > str->cur)
{
for(int i=0;i<str->dwIndexNum;i++)
{
if(str->superindex_cache[i].offset+str->superindex_cache[i].dwSize > str->cur && str->superindex_cache[i].offset <= str->cur)
{
str->super_idx = i;
st_index_read = 1;
err = 0;
break;
}
}
}
//从当前位置开始搜索
else
{
for(int i=str->super_idx;i<str->dwIndexNum;i++)
{
if(str->superindex_cache[i].offset+str->superindex_cache[i].dwSize > str->cur && str->superindex_cache[i].offset <= str->cur)
{
str->super_idx = i;
st_index_read = 1;
err = 0;
break;
}
}
}
}
}
if(err)
{
_os_printf("err:%d\n",err);
goto read_avi_offset_end;
}
//已经找到对应的索引号,那就判断是否需要读取标准索引区
if(!err && st_index_read)
{
//读取标准索引区
osal_fseek (str->avi->fp, str->superindex_cache[str->super_idx].dwOffsetl);
osal_fread((char*)&str->chunk,1,sizeof(struct _aviindex_chunk),str->avi->fp);
osal_fread ((char*)str->stindex_cache, 1, str->superindex_cache[str->super_idx].dwSize*sizeof(struct _avistdindex_entry), str->avi->fp);
}
//读取完标准索引,就返回base、size
uint32_t offset = str->cur - str->superindex_cache[str->super_idx].offset;
*base = str->stindex_cache[offset].dwOffset+str->chunk.dwBaseOffsetl;
*size = str->stindex_cache[offset].dwSize;
//偏移位置
osal_fseek (str->avi->fp, *base);
str->cur ++;
read_avi_offset_end:
return err;
}
//从当前位置去读取数据内容,buf是4 byte对齐
uint32_t read_avi_data(struct avistrinfo *str,char *buf,uint32_t size)
{
uint32_t read_len = 0;
read_len = osal_fread(buf,1,size,str->avi->fp);
return read_len;
}
void free_aviinfo_point(struct aviinfo *info)
{
for(int i=0;i<2;i++)
{
if(info->str[i].superindex_cache)
{
free(info->str[i].superindex_cache);
}
if(info->str[i].stindex_cache)
{
free(info->str[i].stindex_cache);
}
}
}
void set_avi_cur(struct avistrinfo *info,int cur)
{
info->cur = cur;
}
uint32_t get_avi_cur(struct avistrinfo *info)
{
return info->cur;
}
#if 0
uint32_t test_space[100*1024];
void play_avi_file(void *aviinfo_point)
{
uint32_t base,size;
uint32_t base_tmp = 0;
char *buf = (char*)test_space;
struct aviinfo *info = (struct aviinfo *)aviinfo_point;
_os_printf("%s:%d\n",__FUNCTION__,__LINE__);
int count = 0;
int count_tmp = 0;
while(1)
{
read_avi_offset(&info->str[0],&base,&size);
_os_printf("base:%X\tsize:%d\tcount:%d\n",base,size,count++);
if(base == 0)
{
break;
}
if(base_tmp != base)
{
base_tmp = base;
}
else
{
count_tmp++;
}
}
_os_printf("count_tmp:%d\n",count_tmp);
}
#endif

View File

@@ -0,0 +1,138 @@
#ifndef __AVIDEMUX_H
#define __AVIDEMUX_H
typedef unsigned long DWORD;
//typedef unsigned int uint32_t;
//typedef unsigned int uint32_t;
typedef unsigned short int WORD;
typedef unsigned char BYTE;
//typedef unsigned char uint8_t;
struct avi_msg
{
uint32_t audio_sample_rate;
uint32_t video_sample_rate;
};
struct _avisuperindex_entry_cache {
DWORD dwOffsetl;
DWORD dwOffseth;
//超级索引表的数量
DWORD dwSize;
//编号起始地址
DWORD offset; // frames
};
#ifndef AVI_STREAM_HEADER
#define AVI_STREAM_HEADER
typedef struct _avistreamheader {
DWORD fcc;
DWORD cb;
DWORD fccType;
DWORD fccHandler;
DWORD dwFlags;
WORD wPriority;
WORD wLanguage;
DWORD dwInitialFrames;
DWORD dwScale;
DWORD dwRate;
DWORD dwStart;
DWORD dwLength;
DWORD dwSuggestedBufferSize;
DWORD dwQuality;
DWORD dwSampleSize;
struct {
short int left;
short int top;
short int right;
short int bottom;
} rcFrame;
} AVISTREAMHEADER;
#endif
struct _aviindex_chunk {
DWORD fcc;
DWORD cb;
WORD wLongsPerEntry;
BYTE bIndexSubType;
BYTE bIndexType;
DWORD nEntriesInUse;
DWORD dwChunkId;
DWORD dwBaseOffsetl;
DWORD dwBaseOffseth;
DWORD dwReserved;
};
#ifndef AVI_SUPER_INDEX
#define AVI_SUPER_INDEX
struct _avisuperindex_entry {
DWORD dwOffsetl;
DWORD dwOffseth;
DWORD dwSize;
DWORD dwDuration; // frames
};
struct _avistdindex_entry {
DWORD dwOffset;
DWORD dwSize;
};
#endif
struct avistrinfo {
struct aviinfo *avi;
uint32_t type;
DWORD dwScale; // 來自strh的dwScale但乘以1000以折算成毫秒
DWORD dwRate; // 來自strh的dwRate
DWORD dwTotalFrames; // 來自strh的dwLength
DWORD dwIndexNum; // 來自indx的dwEntriesInUse,超级索引数量
DWORD dwIndexBase; // 指向indx的aIndex[]在文件中的位置
DWORD dwDuration; // 要求所有超級索引都指向相同長度的標準索引,這樣可以加速索引計算
DWORD dwEntryNum; // 緩存的std_index中的nEntriesInUse,某个超级索引指向的标准索引数量
DWORD dwEntryBase; // 緩存的std_index中的dwBaseOffsetl
uint32_t cur; // 當前播放點。視頻幀號、或音頻包號
uint32_t super_idx; // 當前緩存的標準索引,對應超級索引的哪一項
DWORD cached_indx_base; // 當前緩存的超級索引扇區地址
DWORD cached_ixnn_base; // 當前緩存的標準索引扇區地址
struct _aviindex_chunk chunk;
struct _avisuperindex_entry_cache *superindex_cache;
struct _avistdindex_entry *stindex_cache;
};
struct aviinfo {
void *fp; // 文件句柄
uint32_t start_time; // 第一幀播放的起始時間
uint32_t strmsk; // 有效流的掩碼
uint8_t speed;
struct avistrinfo str[2]; // 兩個流
};
struct avifp
{
void *fp;
void *thread_handle;
struct aviinfo *aviinfo_point;
int running;
};
void *avidemux_parse(void *fp,void *aviinfo_point);
uint32_t avidemux_read_begin(struct avistrinfo *str, uint32_t *base, uint32_t *size);
void avi_read_thread(void *d);
uint32_t avidemux_read (struct avistrinfo *str, uint8_t *buf, uint32_t len);
void *avidemux_stream (struct aviinfo *avi, uint32_t idx);
uint32_t avidemux_set_cur (struct avistrinfo *str,uint32_t cur);
uint32_t get_avidemux_parse_stream(char *path,struct avi_msg *msg);
void free_aviinfo_point(struct aviinfo *info);
uint32_t read_avi_offset(struct avistrinfo *str,uint32_t *base,uint32_t *size);
uint32_t read_avi_data(struct avistrinfo *str,char *buf,uint32_t size);
uint32_t get_avi_cur(struct avistrinfo *info);
#endif

View File

@@ -0,0 +1,11 @@
#ifndef __AVITYPE_H
#define __AVITYPE_H
typedef unsigned long DWORD;
typedef unsigned int uint32_t;
typedef unsigned int uint32_t;
typedef unsigned short int WORD;
typedef unsigned char BYTE;
typedef unsigned char uint8_t;
#endif

View File

@@ -0,0 +1,184 @@
#include "sys_config.h"
#include "tx_platform.h"
#include "list.h"
#include "dev.h"
#include "typesdef.h"
#include "lib/video/dvp/cmos_sensor/csi.h"
#include "lib/video/mipi_csi/mipi_csi.h"
#include "lib/video/vpp/vpp_dev.h"
#include "lib/video/h264/h264_drv.h"
#include "devid.h"
#include "osal/irq.h"
#include "osal/string.h"
#include "lib/video/dvp/jpeg/jpg.h"
#include "hal/dual_org.h"
#include "dev/scale/hgscale.h"
#include "dev/dual/hgdual_org.h"
#include "hal/gpio.h"
#include "hal/jpeg.h"
#include "lib/heap/av_psram_heap.h"
volatile uint32_t dual_arg[4];
void dual_org0_done_isr(uint32 irq,uint32 dev,uint32 param){
struct jpg_device *jpeg_dev;
uint32_t *dl_dev;
dl_dev = (uint32_t *)dev;
_os_printf("{0}");
video_msg.video_type_last = video_msg.video_type_cur;
video_msg.video_type_cur = ISP_VIDEO_0;
jpeg_dev = (struct jpg_device *)dl_dev[1];//dev_get(HG_JPG0_DEVID);
jpg_set_oe_state(jpeg_dev,1);
// if (param == 1) dual_save_addr_cfg((void *)dl_dev[0]);
}
void dual_org1_done_isr(uint32 irq,uint32 dev,uint32 param){
uint32 org1_num;
static int32_t org_select = 0;
struct jpg_device *jpeg_dev;
struct dual_device *dual_dev;
struct isp_device *isp_dev;
uint32_t *dl_dev;
dl_dev = (uint32_t *)dev;
dual_dev = (struct dual_device *)dl_dev[0];//dev_get(HG_DUALORG_DEVID);
jpeg_dev = (struct jpg_device *)dl_dev[1];//dev_get(HG_JPG0_DEVID);
isp_dev = (struct isp_device *)dl_dev[2];//dev_get(HG_ISP_DEVID);
org1_num = dl_dev[3];
_os_printf("{1}");
if(org1_num == 2){
org_select = isp_sensor_slave_index(isp_dev);
if (org_select == 1)
{
dual_input_type(dual_dev,1,IN_MIPI_CSI0);
video_msg.video_type_last = video_msg.video_type_cur;
video_msg.video_type_cur = ISP_VIDEO_2;
} else if (org_select == 2) {
dual_input_type(dual_dev,1,IN_MIPI_CSI1);
video_msg.video_type_last = video_msg.video_type_cur;
video_msg.video_type_cur = ISP_VIDEO_1;
} else {
os_printf("sensor slave index : %d err\r\n", org_select);
}
}else{
video_msg.video_type_last = video_msg.video_type_cur;
video_msg.video_type_cur = ISP_VIDEO_1;
}
jpg_set_oe_state(jpeg_dev,0);
// if (param == 2) dual_save_addr_cfg((void *)dual_dev);
}
void dual_org_rd_done_isr(uint32 irq,uint32 dev,uint32 param){
//_os_printf("(rd)");
}
void dual_org_rd_slow_isr(uint32 irq,uint32 dev,uint32 param){
_os_printf("(rd slow)");
}
void dorg_double_sensor(uint32 src0_w,uint32 src0_h,uint32 src1_w,uint32 src1_h,uint32 src0_raw_num,uint32 src1_raw_num,uint8_t dvp_type,uint8_t csi0_type,uint8_t csi1_type){
struct dual_device *dual_dev;
struct jpg_device *jpeg_dev;
struct isp_device *isp_dev;
uint8_t *psram_photo_buf;
uint8_t *psram_photo_buf1;
uint8_t raw_dw;
uint8_t type_master = 0;
uint8_t type_slave = 0;
isp_dev = (struct isp_device *)dev_get(HG_ISP_DEVID);
dual_dev = (struct dual_device *)dev_get(HG_DUALORG_DEVID);
jpeg_dev = (struct jpg_device *)dev_get(HG_JPG0_DEVID);
raw_dw = 8+(src0_raw_num-1)*2;
psram_photo_buf = (uint8_t *)av_psram_malloc((src0_w*src0_h*raw_dw)/8);
raw_dw = 8+(src1_raw_num-1)*2;
psram_photo_buf1 = (uint8_t *)av_psram_malloc((src1_w*src1_h*raw_dw)/8);
_os_printf("psram:%08x %08x size:%d\r\n",psram_photo_buf,psram_photo_buf1,(src1_w*src1_h*raw_dw)/8);
if(video_msg.dvp_type == 1){
video_msg.dvp_type = dvp_type;
}
if(video_msg.csi0_type == 1){
video_msg.csi0_type = csi0_type;
}else if(video_msg.csi1_type == 1){
video_msg.csi1_type = csi0_type;
}
if(video_msg.csi1_type == 1){
video_msg.csi1_type = csi1_type;
}
if(video_msg.dvp_type == 1){
type_master = IN_DVP0;
}else if(video_msg.csi0_type == 1){
type_master = IN_MIPI_CSI0;
}else{
type_master = IN_MIPI_CSI1;
}
if(video_msg.dvp_type == 2){
type_slave = IN_DVP0;
}else if(video_msg.csi0_type == 2){
type_slave = IN_MIPI_CSI0;
}else{
type_slave = IN_MIPI_CSI1;
}
dual_init(dual_dev);
dual_input_type(dual_dev,0,type_master); //主 dvp
dual_input_type(dual_dev,1,type_slave);
// dual_input_type(dual_dev,1,IN_DVP0); //副 mipi
dual_work_mode(dual_dev,0);
//dual_input_src_num(dual_dev,2);
dual_input_src_num(dual_dev,(video_msg.video_num>1)?2:1);
dual_open_hdr(dual_dev,0);
dual_size_cfg(dual_dev,src0_w,src1_w,src0_raw_num,src1_raw_num);
#if 0 //master:gc1084, slave:gc1084
dual_timer_cfg(dual_dev,32,2,512);
dual_fs_trig(dual_dev,420);
dual_rd_trig(dual_dev,422,425);
#elif 0 //master:2336p, slave:gc1084
dual_timer_cfg(dual_dev,32,1,256);
dual_fs_trig(dual_dev,400);
dual_rd_trig(dual_dev,330,540);
#else //master:sc1346, slave:gc1084
#if ISP_TUNNING_EN
dual_timer_cfg(dual_dev,16,2,256);
dual_fs_trig(dual_dev,460);
dual_rd_trig(dual_dev,10,452);
#else
//master:gc2053, slave:jxv03
dual_timer_cfg(dual_dev,32,1,256);
dual_fs_trig(dual_dev,734);
dual_rd_trig(dual_dev,300,400);
#endif
//dual_timer_cfg(dual_dev,16,20,500);
//dual_rd_trig(dual_dev,16,336);
#endif
dual_wr_cnt_cfg(dual_dev,src0_w,src0_h,src1_w,src1_h,src0_raw_num,src1_raw_num);
dual_set_addr(dual_dev,(uint32_t)psram_photo_buf,(uint32_t)psram_photo_buf1);
//dual_set_addr(dual_dev,0x28000000,0x28151800);
dual_arg[0] = (uint32_t)dual_dev;
dual_arg[1] = (uint32_t)jpeg_dev;
dual_arg[2] = (uint32_t)isp_dev;
//dual_arg[3] = 2;
dual_arg[3] = (video_msg.video_num>2)?2:1;
dual_request_irq(dual_dev,ORG0_SD_ISR,(dual_irq_hdl )&dual_org0_done_isr,(uint32_t)dual_arg);
dual_request_irq(dual_dev,ORG1_SD_ISR,(dual_irq_hdl )&dual_org1_done_isr,(uint32_t)dual_arg);
dual_request_irq(dual_dev,ORG_RD_DONE_IE,(dual_irq_hdl )&dual_org_rd_done_isr,(uint32_t)dual_arg);
dual_request_irq(dual_dev,ORG_RD_SLOW_IE,(dual_irq_hdl )&dual_org_rd_slow_isr,(uint32_t)dual_arg);
dual_open(dual_dev);
}

View File

@@ -0,0 +1,727 @@
#include "sys_config.h"
#include "typesdef.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/isp/isp_dev.h"
#include "app_iic/app_iic.h"
#include "lib/video/vpp/vpp_dev.h"
#include "lib/heap/av_heap.h"
#ifdef PIN_FROM_PARAM
#include "pin_param.h"
#endif
#define RESET_HIGH() {gpio_set_val(rsn,1);}
#define RESET_LOW() {gpio_set_val(rsn,0);}
#define IIC_CLK 120000UL
uint8 u8SensorwriteID,u8SensorreadID;
uint8 u8Addrbytnum,u8Databytnum;
static uint8 g_byDevWriteAddr;
static uint8 g_byDevReadAddr;
_Sensor_Ident_ *devSensorInit=NULL;
SNSER snser;
struct dvp_device *dvp_test;
struct i2c_device *iic_test;
struct vpp_device *vpp_test;
static const _Sensor_Ident_ *devSensorInitTable[] = {
#if DEV_SENSOR_GC0308
&gc0308_init,
#endif
#if DEV_SENSOR_BF20A6
&bf20a6_init,
#endif
#if DEV_SENSOR_GC0309
&gc0309_init,
#endif
#if DEV_SENSOR_GC0311
&gc0311_init,
#endif
#if DEV_SENSOR_GC0312
&gc0312_init,
#endif
#if DEV_SENSOR_GC0328
&gc0328_init,
#endif
#if DEV_SENSOR_GC0329
&gc0329_init,
#endif
#if DEV_SENSOR_BF3A03
&bf3a03_init,
#endif
#if DEV_SENSOR_BF3703
&bf3703_init,
#endif
#if DEV_SENSOR_OV2640
&ov2640_init,
#endif
#if DEV_SENSOR_OV7725
&ov7725_init,
#endif
#if DEV_SENSOR_OV7670
&ov7670_init,
#endif
#if DEV_SENSOR_BF2013
&bf2013_init,
#endif
#if DEV_SENSOR_XC7016_H63
&xc7016_h63_init,
#endif
#if DEV_SENSOR_XC7011_H63
&xc7011_h63_init,
#endif
#if DEV_SENSOR_XC7011_GC1054
&xc7011_gc1054_init,
#endif
#if DEV_SENSOR_XCG532
&xcg532_init,
#endif
#if DEV_SENSOR_GC2145
&gc2145_init,
#endif
#if DEV_SENSOR_SP0718
&sp0718_init,
#endif
#if DEV_SENSOR_SP0A19
&sp0a19_init,
#endif
#if DEV_SENSOR_BF3720
&bf3720_init,
#endif
#if DEV_SENSOR_SC1346
&sc1346_init,
#endif
NULL,
};
static const _Sensor_Adpt_ *devSensorOPTable[] = {
#if DEV_SENSOR_GC0308
&gc0308_cmd,
#endif
#if DEV_SENSOR_BF20A6
&bf20a6_cmd,
#endif
#if DEV_SENSOR_GC0309
&gc0309_cmd,
#endif
#if DEV_SENSOR_GC0311
&gc0311_cmd,
#endif
#if DEV_SENSOR_GC0312
&gc0312_cmd,
#endif
#if DEV_SENSOR_GC0328
&gc0328_cmd,
#endif
#if DEV_SENSOR_GC0329
&gc0329_cmd,
#endif
#if DEV_SENSOR_BF3A03
&bf3a03_cmd,
#endif
#if DEV_SENSOR_BF3703
&bf3703_cmd,
#endif
#if DEV_SENSOR_OV2640
&ov2640_cmd,
#endif
#if DEV_SENSOR_OV7725
&ov7725_cmd,
#endif
#if DEV_SENSOR_OV7670
&ov7670_cmd,
#endif
#if DEV_SENSOR_BF2013
&bf2013_cmd,
#endif
#if DEV_SENSOR_XC7016_H63
&xc7016_h63_cmd,
#endif
#if DEV_SENSOR_XC7011_H63
&xc7011_h63_cmd,
#endif
#if DEV_SENSOR_XC7011_GC1054
&xc7011_gc1054_cmd,
#endif
#if DEV_SENSOR_XCG532
&xcg532_cmd,
#endif
#if DEV_SENSOR_GC2145
&gc2145_cmd,
#endif
#if DEV_SENSOR_SP0718
&sp0718_cmd,
#endif
#if DEV_SENSOR_SP0A19
&sp0a19_cmd,
#endif
#if DEV_SENSOR_BF3720
&bf3720_cmd,
#endif
#if DEV_SENSOR_SC1346
&sc1346_cmd,
#endif
};
const _Sensor_Ident_ null_init={0x00,0x00,0x00,0x00,0x00,0x00};
volatile uint8 mipi_dvp_devid0;
volatile uint8 mipi_dvp_devid1;
/*******************************************************************************
* Function Name : Delay_Cnt
* Description : delay cnt nop
* Input : nop number
* Output : None
* Return : None
*******************************************************************************/
extern void Delay_nopCnt(uint32 cnt);
/*******************************************************************************
* Function Name : sensor_reset
* Description : for sensor reset before start
* Input : nop number
* Output : None
* Return : None
*******************************************************************************/
__weak void sensor_reset(void){
uint8_t rsn,pdn;
pdn = PIN_DVP_PDN;//get_func_io("dvp", "PDN");
if(pdn != 255){
gpio_iomap_output(pdn,GPIO_IOMAP_OUTPUT);
gpio_set_val(pdn,0);
os_sleep_ms(100);
gpio_set_val(pdn,1);
os_sleep_ms(1);
gpio_set_val(pdn,1);
}
rsn = PIN_DVP_RESET;//get_func_io("dvp", "RSN");
if(rsn != 255){
gpio_iomap_output(rsn,GPIO_IOMAP_OUTPUT);
}
else{
os_sleep_ms(200);
return;
}
RESET_HIGH();
os_sleep_ms(50);
RESET_LOW();
os_sleep_ms(200);
RESET_HIGH();
os_sleep_ms(50);
}
void i2c_SetSetting(struct i2c_setting *p_i2c_setting)
{
if(!p_i2c_setting)
return;
g_byDevWriteAddr = p_i2c_setting->u8DevWriteAddr;
g_byDevReadAddr = p_i2c_setting->u8DevReadAddr;
return;
}
int sensorCheckId(uint8_t devid,const _Sensor_Ident_ *p_sensor_ident,const _Sensor_Adpt_ *p_sensor_adpt)
{
int8 u8Buf[3];
uint8_t tablebuf[16];
uint32 id= 0;
uint32 i = 0;
uint32 k = 0;
u8SensorwriteID = p_sensor_ident->w_cmd;
u8SensorreadID =p_sensor_ident->r_cmd;
u8Addrbytnum = p_sensor_ident->addr_num;
u8Databytnum = p_sensor_ident->data_num;
tablebuf[0] = p_sensor_ident->addr_num;
tablebuf[1] = p_sensor_ident->data_num;
//i2c_ioctl(p_iic,IIC_SET_DEVICE_ADDR,u8SensorwriteID>>1);
tablebuf[2] = u8SensorwriteID>>1;
//id = i2c_sensor_read(p_iic,u8Buf,p_sensor_ident->addr_num,p_sensor_ident->data_num,u8SensorwriteID,u8SensorreadID);
if(p_sensor_adpt->preset){
for(i=0;;i+=p_sensor_ident->data_num+p_sensor_ident->addr_num){
if((p_sensor_adpt->preset[i]==0xFF)&&(p_sensor_adpt->preset[i+1]==0xFF)){
os_printf("preset table num:%d\r\n",i);
break;
}
for(k = 0;k < (p_sensor_ident->addr_num + p_sensor_ident->data_num);k++){
tablebuf[3+k] = p_sensor_adpt->preset[i+k];
}
wake_up_iic_queue(devid,tablebuf,0,1,(uint8_t*)NULL);
while(iic_devid_finish(devid) != 1){
os_sleep_ms(1);
}
//i2c_write(iic_test, (int8*)&p_sensor_adpt->preset[i],p_sensor_ident->addr_num, (int8*)&p_sensor_adpt->preset[i+p_sensor_ident->addr_num], p_sensor_ident->data_num);
}
}
u8Buf[0] = p_sensor_ident->id_reg;
if(p_sensor_ident->addr_num == 2)
{
u8Buf[0] = p_sensor_ident->id_reg>>8;
u8Buf[1] = p_sensor_ident->id_reg;
}
k = 0;
tablebuf[3+k] = u8Buf[0];
k++;
if(p_sensor_ident->addr_num == 2){
tablebuf[3+k] = u8Buf[1];
k++;
}
tablebuf[3+k] = tablebuf[4+k] = tablebuf[5+k] = tablebuf[6+k] = 0;
//i2c_read(p_iic,u8Buf,p_sensor_ident->addr_num,(int8*)&id,p_sensor_ident->data_num);
wake_up_iic_queue(devid,tablebuf,0,0,(uint8_t*)NULL);
while(iic_devid_finish(devid) != 1){
os_sleep_ms(1);
}
id = tablebuf[3+k] | (tablebuf[4+k]<<8) | (tablebuf[5+k]<<16) | (tablebuf[6+k]<<24);
os_printf("SID: %x, %x, %x, %x,%x\r\n",id,p_sensor_ident->id,u8SensorwriteID,u8SensorreadID,p_sensor_ident->id_reg);
if(id == p_sensor_ident->id){
iic_devid_set_addr(devid,u8SensorwriteID>>1);
return 1;
}
else
return -1;
}
/*******************************************************************************
* Function Name : Sensor_ReadRegister
* Description : read sensor register
* Input : *pbdata :sensor register addr
u8AddrLength:sensor register addr length
u8DataLength:sensor register data length
* Output : None
* Return : u32i2cReadResult:the result from sensor register
*******************************************************************************/
static _Sensor_Adpt_ * sensorAutoCheck(uint8_t devid,uint8 *init_buf)
{
uint8 i;
_Sensor_Adpt_ * devSensor_Struct=NULL;
for(i=0;devSensorInitTable[i] != NULL;i++)
{
sensor_reset();
if(sensorCheckId(devid,devSensorInitTable[i],devSensorOPTable[i])>=0)
{
os_printf("id =%x num:%d \n",devSensorInitTable[i]->id,i);
devSensorInit = (_Sensor_Ident_ *) devSensorInitTable[i];
//#if CMOS_AUTO_LOAD
// devSensor_Struct = sensor_adpt_load(devSensorInit->id,devSensorInit->w_cmd,devSensorInit->r_cmd,init_buf);
//#else
devSensor_Struct = (_Sensor_Adpt_ *) devSensorOPTable[i];
//#endif
break;
}
}
if(devSensor_Struct == NULL)
{
os_printf("Er: unkown!");
devSensorInit = (_Sensor_Ident_ *)&null_init;
return NULL; // index 0 is test only
}
return devSensor_Struct;
}
volatile uint8 yuv_buf_head[16]__attribute__ ((section(".sbss")));;
__psram_data uint8 psram_ybuf_src[IMAGE_H*IMAGE_W+IMAGE_H*IMAGE_W/2] __aligned(4);
//__psram_data uint8 psram_ubuf_src[IMAGE_H*IMAGE_W/4] __aligned(4);
//__psram_data uint8 psram_vbuf_src[IMAGE_H*IMAGE_W/4] __aligned(4);
__psram_data volatile uint8 psram_buf_head[16];
#if ONLY_Y
__psram_data uint8 psram_buf[IMAGE_H][IMAGE_W] __aligned(4);
#endif
__psram_data uint8 psram_buf_tail[2032];
volatile uint32 line_buf = 0;
extern volatile uint32 done_dvp;
volatile uint32 vs_isr;
volatile uint32 vpp_get_src = 0;
void dvp_line_isr(uint32 irq,uint32 image_h,uint32 param){
}
void dvp_fhfie_isr(uint32 irq,uint32 dev,uint32 param){
os_printf("fh\r\n");
}
void dvp_fovie_isr(uint32 irq,uint32 dev,uint32 param){
//dvp_vpp_reset();
os_printf("------------------------------------------------------------------------------dvp fv\r\n");
}
void dvp_sip_isr(uint32 irq,uint32 dev,uint32 param){
//dvp_vpp_reset();
os_printf("sip reset DVP\r\n");
}
void dvp_line_isr_test(uint32 irq,uint32 image_h,uint32 param){
return;
}
struct hgdvp_hw *dvp_watch;
bool csi_yuv_mode(){
struct i2c_device *iic_dev;
static _Sensor_Adpt_ *p_sensor_cmd = NULL;
struct i2c_setting i2c_setting;
int8 idbuf[8];
uint8_t itk=0;
uint32 i=0;
uint32 k = 0;
uint8 adr_num,dat_num;
uint8 sen_w_cmd,sen_r_cmd,id_c = 0;
uint16 image_w,image_h;
uint8_t tablebuf[16];
dvp_test = (struct dvp_device *)dev_get(HG_DVP_DEVID);
iic_dev = (struct i2c_device *)dev_get(HG_I2C1_DEVID);
dvp_init(dvp_test);
dvp_close(dvp_test);
//1:init iic
os_printf("csi_test start,iic init\r\n");
mipi_dvp_devid0 = register_iic_queue(iic_dev,MACRO_PIN(PIN_DVP0_IIC_CLK),MACRO_PIN(PIN_DVP0_IIC_SDA),0);
gpio_iomap_output(MACRO_PIN(PIN_DVP_MCLK), GPIO_IOMAP_OUT_DVP_MCLK_OUT);
os_printf("iic init finish,sensor reset & set sensor clk into 6M\r\n");
//2:init sensor
dvp_set_baudrate(dvp_test,6000000);
os_sleep_ms(3);
os_printf("set sensor finish ,Auto Check sensor id\r\n");
p_sensor_cmd = snser.p_sensor_cmd = sensorAutoCheck(mipi_dvp_devid0,NULL);
if(p_sensor_cmd == NULL){
// i2c_close(iic_test);
return FALSE;
}
sensor_info_add(SENSOR_TYPE_MASTER, (DUAL_EN) ? (ISP_INPUT_DAT_SRC_ORG_DMA) : (ISP_INPUT_DAT_SRC_DVP), (uint32)p_sensor_cmd->sensor_isp, mipi_dvp_devid0, u8SensorwriteID);
os_printf("Auto Check sensor id finish\r\n");
i2c_setting.u8DevWriteAddr = p_sensor_cmd->w_cmd;
i2c_setting.u8DevReadAddr = p_sensor_cmd->r_cmd;
i2c_SetSetting(&i2c_setting);
os_printf("mclk:%dMHz\r\n",p_sensor_cmd->mclk);
dvp_set_baudrate(dvp_test,p_sensor_cmd->mclk);
os_printf("init:%x u8Addrbytnum:%d,u8Databytnum:%d\r\n",(uint32)p_sensor_cmd->init,u8Addrbytnum,u8Databytnum);
if(p_sensor_cmd->init!=NULL)
{
os_printf("SENSER....init\r\n");
for(i=0;;i+=u8Addrbytnum+u8Databytnum)
{
if((p_sensor_cmd->init[i]==0xFF)&&(p_sensor_cmd->init[i+1]==0xFF)){
os_printf("init table num:%d\r\n",i);
break;
}
if((p_sensor_cmd->init[i]==0xFE)&&(p_sensor_cmd->init[i+1]==0xFE)){
if(p_sensor_cmd->init[i+2]==0x01){
os_sleep_ms(100);
}
}
else{
for(itk = 0;itk < u8Addrbytnum+u8Databytnum;itk++){
idbuf[itk] = p_sensor_cmd->init[i+itk];
}
tablebuf[0] = u8Addrbytnum;
tablebuf[1] = u8Databytnum;
tablebuf[2] = u8SensorwriteID>>1;
for(k = 0;k < (tablebuf[0] + tablebuf[1]);k++){
tablebuf[3+k] = idbuf[k];
}
wake_up_iic_queue(mipi_dvp_devid0,tablebuf,0,1,(uint8_t*)NULL);
while(iic_devid_finish(mipi_dvp_devid0) != 1){
os_sleep_ms(1);
}
//i2c_write(iic_test, (int8*)&idbuf[0], u8Addrbytnum, (int8*)&idbuf[u8Addrbytnum], u8Databytnum);
if(i==0)
{
os_sleep_ms(1);
}
}
}
if(p_sensor_cmd->p_xc7016_adapt.sensor_init_table != NULL)
{
adr_num = p_sensor_cmd->p_xc7016_adapt.addr_num;
dat_num = p_sensor_cmd->p_xc7016_adapt.data_num;
sen_w_cmd = u8SensorwriteID;
sen_r_cmd = u8SensorreadID;
u8SensorwriteID = p_sensor_cmd->p_xc7016_adapt.w_cmd;
u8SensorreadID = p_sensor_cmd->p_xc7016_adapt.r_cmd;
idbuf[0] = p_sensor_cmd->p_xc7016_adapt.id_reg;
//id_c = i2c_sensor_read(iic_test,idbuf,adr_num,dat_num,u8SensorwriteID,u8SensorreadID);
//i2c_ioctl(iic_test,IIC_SET_DEVICE_ADDR,u8SensorwriteID>>1);
tablebuf[0] = adr_num;
tablebuf[1] = dat_num;
tablebuf[2] = u8SensorwriteID>>1;
iic_devid_set_addr(mipi_dvp_devid0,u8SensorwriteID>>1);
k = 0;
tablebuf[3+k] = idbuf[0];
k++;
if(adr_num == 2){
tablebuf[3+k] = idbuf[1];
k++;
}
tablebuf[3+k] = tablebuf[4+k] = tablebuf[5+k] = tablebuf[6+k] = 0;
wake_up_iic_queue(mipi_dvp_devid0,tablebuf,0,0,(uint8_t*)NULL);
while(iic_devid_finish(mipi_dvp_devid0) != 1){
os_sleep_ms(1);
}
//i2c_read(iic_test,idbuf,adr_num,(int8*)&id_c,dat_num);
id_c = tablebuf[3+k] | (tablebuf[4+k]<<8) | (tablebuf[5+k]<<16) | (tablebuf[6+k]<<24);
os_printf("\r\nchildren SID: %x %x %x\r\n",id_c,u8SensorwriteID,u8SensorreadID);
for(i=0;;i+=adr_num+dat_num)
{
if((p_sensor_cmd->p_xc7016_adapt.sensor_init_table[i]==0xFF)&&(p_sensor_cmd->p_xc7016_adapt.sensor_init_table[i+1]==0xFF)){
os_printf("sensor table num:%d\r\n",i);
break;
}
for(itk = 0;itk < adr_num+dat_num;itk++){
idbuf[itk] = p_sensor_cmd->p_xc7016_adapt.sensor_init_table[i+itk];
}
tablebuf[0] = u8Addrbytnum;
tablebuf[1] = u8Databytnum;
tablebuf[2] = u8SensorwriteID>>1;
for(k = 0;k < (tablebuf[0] + tablebuf[1]);k++){
tablebuf[3+k] = idbuf[k];
}
wake_up_iic_queue(mipi_dvp_devid0,tablebuf,0,1,(uint8_t*)NULL);
while(iic_devid_finish(mipi_dvp_devid0) != 1){
os_sleep_ms(1);
}
//i2c_write(iic_test, (int8*)&idbuf[0], adr_num, (int8*)&idbuf[adr_num], dat_num);
if(i==0)
{
os_sleep_ms(1);
}
}
u8SensorwriteID = sen_w_cmd;
u8SensorreadID = sen_r_cmd;
i2c_ioctl(iic_test,IIC_SET_DEVICE_ADDR,u8SensorwriteID>>1);
for(i=0;;i+=u8Addrbytnum+u8Databytnum)
{
if((p_sensor_cmd->p_xc7016_adapt.bypass_off[i]==0xFF)&&(p_sensor_cmd->p_xc7016_adapt.bypass_off[i+1]==0xFF)){
os_printf("bypass table num:%d\r\n",i);
break;
}
for(itk = 0;itk < u8Addrbytnum+u8Databytnum;itk++){
idbuf[itk] = p_sensor_cmd->p_xc7016_adapt.bypass_off[i+itk];
}
tablebuf[0] = u8Addrbytnum;
tablebuf[1] = u8Databytnum;
tablebuf[2] = u8SensorwriteID>>1;
for(k = 0;k < (tablebuf[0] + tablebuf[1]);k++){
tablebuf[3+k] = idbuf[k];
}
wake_up_iic_queue(mipi_dvp_devid0,tablebuf,0,1,(uint8_t*)NULL);
while(iic_devid_finish(mipi_dvp_devid0) != 1){
os_sleep_ms(1);
}
//i2c_write(iic_test, (int8*)&idbuf[0], u8Addrbytnum, (int8*)&idbuf[u8Addrbytnum], u8Databytnum);
if(i==0)
{
os_sleep_ms(1);
}
}
}
}
os_printf("SENSR ident ok:%d*%d\r\n",p_sensor_cmd->pixelw,p_sensor_cmd->pixelh);
#if SCEN_EN
image_h = p_sensor_cmd->pixelh/2;
image_w = p_sensor_cmd->pixelw/2;
#else
image_h = p_sensor_cmd->pixelh;
image_w = p_sensor_cmd->pixelw;
#endif
video_msg.dvp_iw = image_w;
video_msg.dvp_ih = image_h;
// video_msg.dvp_ow = image_w;
// video_msg.dvp_oh = image_h;
video_msg.dvp_type = 1;
video_msg.video_type_cur = ISP_VIDEO_0;
video_msg.video_type_last = ISP_VIDEO_0;
video_msg.video_num++;
//3:init csi
os_printf("csi init start --\r\n");
os_printf("csi set size ====>%d*%d\r\n",image_w,image_h);
dvp_set_vsync_rst_offline(dvp_test,0,30*1000/32);
#if SCEN_EN
dvp_set_half_size(dvp_test,1);
#endif
dvp_set_size(dvp_test,0,0,p_sensor_cmd->pixelw,p_sensor_cmd->pixelh);
dvp_set_hsync_polarity(dvp_test,p_sensor_cmd->hsyn);
dvp_set_vsync_polarity(dvp_test,p_sensor_cmd->vsyn);
dvp_set_format(dvp_test,IMAGE_FORMAT);
dvp_8BITS_map(dvp_test,0);
//dvp_set_exchange_d5_d6(dvp_test,0);
os_printf("csi IRQ init\r\n");
dvp_request_irq(dvp_test,HSIP_ISR, (dvp_irq_hdl )&dvp_sip_isr,0);
dvp_request_irq(dvp_test,FOVIE_ISR,(dvp_irq_hdl )&dvp_fovie_isr,0);
//dvp_open(dvp_test);
os_printf("csi IRQ init finish,start get data\r\n");
return TRUE;
}
bool csi_cfg(){
bool ret;
ret = csi_yuv_mode();
return ret;
}
bool csi_open(){
dvp_open(dvp_test);
return 1;
}
bool csi_close(){
dvp_close(dvp_test);
return 1;
}
void get_single_dvp(uint16_t *w,uint16_t *h)
{
if(w)
{
*w = video_msg.dvp_iw;
}
if(h)
{
*h = video_msg.dvp_ih;
}
return;
}

View File

@@ -0,0 +1,460 @@
#include "basic_include.h"
#include "lib/multimedia/msi.h"
#include "stream_define.h"
#include "lib/video/dvp/jpeg/jpg.h"
#include "dev/jpg/hgjpg.h"
#include "lib/heap/av_heap.h"
#include "lib/heap/av_psram_heap.h"
/***********************************************************
* 可以存放mjpg的公用函数组件
**********************************************************/
#define HARDWARE_JPG_NUM 2
// data申请空间函数
#define STREAM_MALLOC av_psram_malloc
#define STREAM_FREE av_psram_free
#define STREAM_ZALLOC av_psram_zalloc
// 结构体申请空间函数
#define STREAM_LIBC_MALLOC av_malloc
#define STREAM_LIBC_FREE av_free
#define STREAM_LIBC_ZALLOC av_zalloc
/*****************************************************************
* 增加mjpg模块锁,主要用于复用的时候需要对mjeg模块锁
****************************************************************/
typedef struct
{
os_event_t jpg_event;
uint8_t init;
uint8_t lock_value;
uint8_t last_lock_value;
} jpg_mutex;
enum
{
JPG_LOCK = BIT(0),
};
static jpg_mutex *jpg_mutex_table[HARDWARE_JPG_NUM];
int32 jpg_mutex_init()
{
int32_t ret = 0;
int32_t res = 0;
jpg_mutex *mutex = (jpg_mutex *) STREAM_LIBC_ZALLOC(sizeof(jpg_mutex) * 2);
jpg_mutex_table[0] = &mutex[0];
jpg_mutex_table[1] = &mutex[1];
res = os_event_init(&jpg_mutex_table[0]->jpg_event);
ret |= res;
if (!res)
{
jpg_mutex_table[0]->init = 1;
os_event_set(&jpg_mutex_table[0]->jpg_event, JPG_LOCK, NULL);
}
res = os_event_init(&jpg_mutex_table[1]->jpg_event);
ret |= res;
if (!res)
{
jpg_mutex_table[1]->init = 1;
os_event_set(&jpg_mutex_table[1]->jpg_event, JPG_LOCK, NULL);
}
os_printf("%s:%d\tret:%d\n", __FUNCTION__, __LINE__, ret);
return ret;
}
/************************************************************************
* jpgid: 硬件jpg模块ID,0:jpg0 1:jpg1
* value: 设置lock的值,只有一致才能释放
* last_value: 如果不为NULL,则返回上一次的锁值
***********************************************************************/
int32_t jpg_mutex_lock(uint32_t jpgid, uint8_t value, uint8_t *last_value)
{
ASSERT(jpgid < HARDWARE_JPG_NUM);
jpg_mutex *mutex = jpg_mutex_table[jpgid];
ASSERT(mutex && mutex->init == 1);
uint32_t rflags;
if (mutex->lock_value || value == 0)
{
if (last_value)
{
*last_value = mutex->last_lock_value;
}
return 1;
}
// 如果获取到锁,就将lock_value设置value
int32_t ret = os_event_wait(&mutex->jpg_event, JPG_LOCK, &rflags, OS_EVENT_WMODE_CLEAR, 0);
if (ret == 0)
{
if (last_value)
{
*last_value = mutex->last_lock_value;
}
mutex->lock_value = value;
}
return ret;
}
/********************************************************
* jpgid: 硬件jpg模块ID,0:jpg0 1:jpg1
* value: 设置lock的值,只有一致才能释放
******************************************************/
int32_t jpg_mutex_unlock(uint32_t jpgid, int32_t value)
{
ASSERT(jpgid < HARDWARE_JPG_NUM);
jpg_mutex *mutex = jpg_mutex_table[jpgid];
ASSERT(mutex && mutex->init == 1);
int32_t ret = 1;
// 只有相同的值才支持解锁
if (mutex->lock_value == value)
{
ret = os_event_set(&mutex->jpg_event, JPG_LOCK, NULL);
if (ret == 0)
{
mutex->last_lock_value = mutex->lock_value;
mutex->lock_value = 0;
}
}
return ret;
}
int32_t jpg_mutex_unlock_check(uint32_t jpgid, int32_t value)
{
ASSERT(jpgid < HARDWARE_JPG_NUM);
jpg_mutex *mutex = jpg_mutex_table[jpgid];
ASSERT(mutex && mutex->init == 1);
int32_t ret = 1;
// 只有相同的值才支持解锁
if (mutex->lock_value == value)
{
ret = os_event_set(&mutex->jpg_event, JPG_LOCK, NULL);
if (ret == 0)
{
mutex->lock_value = 0;
}
}
return ret;
}
struct jpg_mem_list_s;
#define JPG_MEM_LIST_COUNT (4)
struct jpg_mem_chunk
{
struct jpg_mem_chunk *next;
uint8_t del : 1, jpg_mem_map : 5, rev : 2;
uint8_t count;
uint16_t len;
struct jpg_mem_list_s *jpg_mem_list;
uint32_t t_bitmap; // 当前chunk的内存位图
uint32_t bitmap; // 内存位图
struct jpg_mem *mem[32];
};
// 内存池列表,最多N个内存池
struct jpg_mem_list_s
{
uint32_t bitmap; // 1代表有空间,0代表没有空间
uint32_t total_count; // 记录当前内存池最大的空间数量,动态增加以及动态释放
// 剩余总共内存块数量,如果有,就判断bitmap,从最低位开始寻找,释放空间优先释放高位的内存块,低位内存块尽量在完全没用的时候才释放(防止频繁申请),可以通过一个超时机制去释放(影响立刻申请空间的模块,也可以实现一个立刻释放的命令)
uint32_t remain_block_count;
struct jpg_mem_chunk *last_chunk; // 记录上一次申请空间的chunk,如果释放,还需要检查是否是最低位的,尽量从最低位的chunk申请(利于释放空间)
struct jpg_mem_chunk *chunk[JPG_MEM_LIST_COUNT];
};
// 32byte对齐,所以前面留32byte作为其他数据保存作用
struct jpg_mem
{
struct jpg_mem_chunk *chunk; // chunk的地址,相当于申请空间的chunk
struct jpg_mem *next;
uint32_t bitmap; // 固定只有一个bit被置位(代表内存块的位置)
uint32_t rev[5];
};
static struct jpg_mem_list_s jpg_mem_list;
// mjpg的内存管理,暂时不支持动态扩展,相当于预先分配
// 正常应该是可以后面动态添加以及删除
struct jpg_mem_chunk *jpg_mem_manage_init(uint8_t chunk_block)
{
if (chunk_block > 32)
{
chunk_block = 32;
}
if (!chunk_block)
{
return NULL;
}
uint8_t ret = 1;
// 先去申请空间,清除cache问题,然后再挂接到链表中
uint32_t malloc_count = 0;
struct jpg_mem_chunk *chunk = NULL;
chunk = (struct jpg_mem_chunk *) STREAM_ZALLOC(sizeof(struct jpg_mem_chunk));
if (!chunk)
{
goto jpg_mem_manage_init_end;
}
chunk->len = 16 * 1024;
for (malloc_count = 0; malloc_count < chunk_block; malloc_count++)
{
chunk->mem[malloc_count] = (struct jpg_mem *) STREAM_MALLOC(16 * 1024 + sizeof(struct jpg_mem));
if (chunk->mem[malloc_count])
{
sys_dcache_invalid_range((uint32_t *) chunk->mem[malloc_count], 16 * 1024 + sizeof(struct jpg_mem));
chunk->t_bitmap |= BIT(malloc_count);
chunk->mem[malloc_count]->bitmap = BIT(malloc_count);
chunk->mem[malloc_count]->chunk = chunk;
}
}
chunk->bitmap = chunk->t_bitmap;
chunk->count = malloc_count + 1;
// 没有申请到空间,返回错误
if (!chunk->bitmap)
{
goto jpg_mem_manage_init_end;
}
ret = 0;
jpg_mem_manage_init_end:
if (ret)
{
if (chunk)
{
STREAM_FREE(chunk);
chunk = NULL;
}
}
return chunk;
}
// 释放一个chunk
static void free_jpg_chunk(struct jpg_mem_chunk *chunk)
{
if (chunk)
{
// 不一致,不能释放,报错
ASSERT(chunk->t_bitmap == chunk->bitmap);
for (int i = 0; i < chunk->count; i++)
{
ASSERT(chunk->mem[i]);
STREAM_FREE(chunk->mem[i]);
chunk->mem[i] = NULL;
}
STREAM_FREE(chunk);
}
}
// 增加一个内存块到列表
uint8_t add_jpg_block(uint8_t chunk_block)
{
uint8_t ret = 1;
uint8_t map = 0;
struct jpg_mem_chunk *chunk = jpg_mem_manage_init(chunk_block);
if (chunk)
{
// 检查最低位是否有0,代表空闲
if (jpg_mem_list.bitmap)
{
map = __builtin_ctz(~jpg_mem_list.bitmap);
}
os_printf("jpg_block map:%d\n", map);
// list没有满,则可以添加
if (map < JPG_MEM_LIST_COUNT)
{
uint32_t flags = disable_irq();
jpg_mem_list.chunk[map] = chunk;
jpg_mem_list.bitmap |= BIT(map);
jpg_mem_list.total_count = chunk->count;
jpg_mem_list.remain_block_count += chunk->count;
chunk->jpg_mem_list = &jpg_mem_list;
chunk->jpg_mem_map = map;
enable_irq(flags);
ret = 0;
}
// 释放chunk
else
{
free_jpg_chunk(chunk);
}
}
return ret;
}
// 获取一个有内存块的chunk
static struct jpg_mem_chunk *get_free_chunk()
{
struct jpg_mem_chunk *chunk;
uint8_t map;
// os_printf("jpg_mem_list.last_chunk:%X\n", jpg_mem_list.last_chunk);
if (jpg_mem_list.last_chunk)
{
chunk = jpg_mem_list.last_chunk;
}
else
{
if (jpg_mem_list.bitmap)
{
map = __builtin_ctz(jpg_mem_list.bitmap);
chunk = jpg_mem_list.chunk[map];
}
else
{
chunk = NULL;
}
}
return chunk;
}
void *get_jpg_node(uint16_t *len)
{
struct jpg_mem *buf = NULL;
uint32_t flags = disable_irq();
struct jpg_mem_chunk *next_chunk = get_free_chunk();
uint8_t map;
uint8_t change = 1;
if (next_chunk && next_chunk->bitmap)
{
map = __builtin_ctz(next_chunk->bitmap);
buf = next_chunk->mem[map];
buf->next = NULL;
buf += 1;
next_chunk->bitmap &= (~BIT(map));
// os_printf("next_chunk->bitmap:%X\n", next_chunk->bitmap);
if (!next_chunk->bitmap)
{
next_chunk->jpg_mem_list->bitmap &= (~BIT(next_chunk->jpg_mem_map));
next_chunk->jpg_mem_list->last_chunk = NULL;
}
else
{
if (next_chunk->jpg_mem_list->last_chunk)
{
if (next_chunk->jpg_mem_list->last_chunk->jpg_mem_map < next_chunk->jpg_mem_map)
{
change = 0;
}
}
if (change)
{
next_chunk->jpg_mem_list->last_chunk = next_chunk;
}
}
if (len)
{
*len = next_chunk->len;
}
}
else
{
if (len)
{
*len = 0;
}
}
enable_irq(flags);
if (buf)
{
// os_printf("malloc map:%X\tbuf:%X\taddr:%X\n",BIT(map),buf,RETURN_ADDR());
}
else
{
os_printf("%s:%d err\n", __FUNCTION__, __LINE__);
}
return (void *) buf;
}
uint16_t get_node_len(void *buf)
{
struct jpg_mem *node = (struct jpg_mem *) buf;
if (node)
{
node -= 1;
return node->chunk->len;
}
else
{
return 0;
}
}
// 获取node是否有足够的保留空间来填充额外的数据
void *get_node_rev(void *buf, uint32_t rev_len)
{
struct jpg_mem *node = (struct jpg_mem *) buf;
if (node)
{
node -= 1;
if (sizeof(node->rev) > rev_len)
{
return node->rev;
}
}
return NULL;
}
void free_jpg_node(void *buf)
{
// os_printf("buf:%X\n",buf);
struct jpg_mem *free_buf = (struct jpg_mem *) buf;
struct jpg_mem_chunk *chunk;
free_buf -= 1;
chunk = free_buf->chunk;
uint8_t change = 1;
// 正常应该要检查是否符合,这里默认传入的地址是正确的
uint32_t flags = disable_irq();
// uint32_t map = free_buf->bitmap;
chunk->bitmap |= free_buf->bitmap;
chunk->jpg_mem_list->bitmap |= BIT(chunk->jpg_mem_map);
// os_printf("chunk->bitmap:%X\n", chunk->bitmap);
if (chunk->jpg_mem_list->last_chunk)
{
if (chunk->jpg_mem_list->last_chunk->jpg_mem_map < chunk->jpg_mem_map)
{
change = 0;
}
}
if (change)
{
chunk->jpg_mem_list->last_chunk = chunk;
}
enable_irq(flags);
// os_printf("free map:%X\tbuf:%X\n",map,buf);
// 正常应该要检查当前chunk是否要被释放,如果需要被释放,是要考虑释放空间
}
// 将一个节点放到另一个节点
void *push_node(void *head, void *next)
{
struct jpg_mem *h = (struct jpg_mem *) head;
struct jpg_mem *n = (struct jpg_mem *) next;
if (head)
{
h -= 1;
n -= 1;
h->next = n;
}
// os_printf("head:%X\tnext:%X\n",head,next);
return next;
}
// pop一个节点头出去
void *pop_node(void *head)
{
if (!head)
{
return NULL;
}
struct jpg_mem *h = (struct jpg_mem *) head;
h -= 1;
if (!h->next)
{
return NULL;
}
return h->next + 1;
}

View File

@@ -0,0 +1,549 @@
#include "sys_config.h"
#include "typesdef.h"
#if JPG_EN
#ifndef DQT_NUM
#define DQT_NUM 12
#endif
const uint16 htable[] __attribute__ ((aligned(4))) ={
#if 1
0x100,0x101,0x204,0x30b,0x41a,0x678,0x7f8,0x9f6,
0xf82,0xf83,0x30c,0x41b,0x679,0x8f6,0xaf6,0xf84,
0xf85,0xf86,0xf87,0xf88,0x41c,0x7f9,0x9f7,0xbf4,
0xf89,0xf8a,0xf8b,0xf8c,0xf8d,0xf8e,0x53a,0x8f7,
0xbf5,0xf8f,0xf90,0xf91,0xf92,0xf93,0xf94,0xf95,
0x53b,0x9f8,0xf96,0xf97,0xf98,0xf99,0xf9a,0xf9b,
0xf9c,0xf9d,0x67a,0xaf7,0xf9e,0xf9f,0xfa0,0xfa1,
0xfa2,0xfa3,0xfa4,0xfa5,0x67b,0xbf6,0xfa6,0xfa7,
0xfa8,0xfa9,0xfaa,0xfab,0xfac,0xfad,0x7fa,0xbf7,
0xfae,0xfaf,0xfb0,0xfb1,0xfb2,0xfb3,0xfb4,0xfb5,
0x8f8,0xec0,0xfb6,0xfb7,0xfb8,0xfb9,0xfba,0xfbb,
0xfbc,0xfbd,0x8f9,0xfbe,0xfbf,0xfc0,0xfc1,0xfc2,
0xfc3,0xfc4,0xfc5,0xfc6,0x8fa,0xfc7,0xfc8,0xfc9,
0xfca,0xfcb,0xfcc,0xfcd,0xfce,0xfcf,0x9f9,0xfd0,
0xfd1,0xfd2,0xfd3,0xfd4,0xfd5,0xfd6,0xfd7,0xfd8,
0x9fa,0xfd9,0xfda,0xfdb,0xfdc,0xfdd,0xfde,0xfdf,
0xfe0,0xfe1,0xaf8,0xfe2,0xfe3,0xfe4,0xfe5,0xfe6,
0xfe7,0xfe8,0xfe9,0xfea,0xfeb,0xfec,0xfed,0xfee,
0xfef,0xff0,0xff1,0xff2,0xff3,0xff4,0xff5,0xff6,
0xff7,0xff8,0xff9,0xffa,0xffb,0xffc,0xffd,0xffe,
0x30a,0xaf9,0xfff,0xfff,0xfff,0xfff,0xfff,0xfff,
0xfd0,0xfd1,0xfd2,0xfd3,0xfd4,0xfd5,0xfd6,0xfd7,
0x101,0x204,0x30a,0x418,0x419,0x538,0x678,0x8f4,
0x9f6,0xbf4,0x30b,0x539,0x7f6,0x8f5,0xaf6,0xbf5,
0xf88,0xf89,0xf8a,0xf8b,0x41a,0x7f7,0x9f7,0xbf6,
0xec2,0xf8c,0xf8d,0xf8e,0xf8f,0xf90,0x41b,0x7f8,
0x9f8,0xbf7,0xf91,0xf92,0xf93,0xf94,0xf95,0xf96,
0x53a,0x8f6,0xf97,0xf98,0xf99,0xf9a,0xf9b,0xf9c,
0xf9d,0xf9e,0x53b,0x9f9,0xf9f,0xfa0,0xfa1,0xfa2,
0xfa3,0xfa4,0xfa5,0xfa6,0x679,0xaf7,0xfa7,0xfa8,
0xfa9,0xfaa,0xfab,0xfac,0xfad,0xfae,0x67a,0xaf8,
0xfaf,0xfb0,0xfb1,0xfb2,0xfb3,0xfb4,0xfb5,0xfb6,
0x7f9,0xfb7,0xfb8,0xfb9,0xfba,0xfbb,0xfbc,0xfbd,
0xfbe,0xfbf,0x8f7,0xfc0,0xfc1,0xfc2,0xfc3,0xfc4,
0xfc5,0xfc6,0xfc7,0xfc8,0x8f8,0xfc9,0xfca,0xfcb,
0xfcc,0xfcd,0xfce,0xfcf,0xfd0,0xfd1,0x8f9,0xfd2,
0xfd3,0xfd4,0xfd5,0xfd6,0xfd7,0xfd8,0xfd9,0xfda,
0x8fa,0xfdb,0xfdc,0xfdd,0xfde,0xfdf,0xfe0,0xfe1,
0xfe2,0xfe3,0xaf9,0xfe4,0xfe5,0xfe6,0xfe7,0xfe8,
0xfe9,0xfea,0xfeb,0xfec,0xde0,0xfed,0xfee,0xfef,
0xff0,0xff1,0xff2,0xff3,0xff4,0xff5,0xec3,0xff6,
0xff7,0xff8,0xff9,0xffa,0xffb,0xffc,0xffd,0xffe,
0x100,0x9fa,0xfff,0xfff,0xfff,0xfff,0xfff,0xfff,
0xfd0,0xfd1,0xfd2,0xfd3,0xfd4,0xfd5,0xfd6,0xfd7,
0x100,0x202,0x203,0x204,0x205,0x206,0x30e,0x41e,
0x53e,0x67e,0x7fe,0x8fe,0xfff,0xfff,0xfff,0xfff,
0x100,0x101,0x102,0x206,0x30e,0x41e,0x53e,0x67e,
0x7fe,0x8fe,0x9fe,0xafe,0xfff,0xfff,0xfff,0xfff,
#else
0x0001,0x0101,0x0402,0x0b03,0x1a04,0x7806,0xf807,0xf609,
0x820f,0x830f,0x0c03,0x1b04,0x7906,0xf608,0xf60a,0x840f,
0x850f,0x860f,0x870f,0x880f,0x1c04,0xf907,0xf709,0xf40b,
0x890f,0x8a0f,0x8b0f,0x8c0f,0x8d0f,0x8e0f,0x3a05,0xf708,
0xf50b,0x8f0f,0x900f,0x910f,0x920f,0x930f,0x940f,0x950f,
0x3b05,0xf809,0x960f,0x970f,0x980f,0x990f,0x9a0f,0x9b0f,
0x9c0f,0x9d0f,0x7a06,0xf70a,0x9e0f,0x9f0f,0xa00f,0xa10f,
0xa20f,0xa30f,0xa40f,0xa50f,0x7b06,0xf60b,0xa60f,0xa70f,
0xa80f,0xa90f,0xaa0f,0xab0f,0xac0f,0xad0f,0xfa07,0xf70b,
0xae0f,0xaf0f,0xb00f,0xb10f,0xb20f,0xb30f,0xb40f,0xb50f,
0xf808,0xc00e,0xb60f,0xb70f,0xb80f,0xb90f,0xba0f,0xbb0f,
0xbc0f,0xbd0f,0xf908,0xbe0f,0xbf0f,0xc00f,0xc10f,0xc20f,
0xc30f,0xc40f,0xc50f,0xc60f,0xfa08,0xc70f,0xc80f,0xc90f,
0xca0f,0xcb0f,0xcc0f,0xcd0f,0xce0f,0xcf0f,0xf909,0xd00f,
0xd10f,0xd20f,0xd30f,0xd40f,0xd50f,0xd60f,0xd70f,0xd80f,
0xfa09,0xd90f,0xda0f,0xdb0f,0xdc0f,0xdd0f,0xde0f,0xdf0f,
0xe00f,0xe10f,0xf80a,0xe20f,0xe30f,0xe40f,0xe50f,0xe60f,
0xe70f,0xe80f,0xe90f,0xea0f,0xeb0f,0xec0f,0xed0f,0xee0f,
0xef0f,0xf00f,0xf10f,0xf20f,0xf30f,0xf40f,0xf50f,0xf60f,
0xf70f,0xf80f,0xf90f,0xfa0f,0xfb0f,0xfc0f,0xfd0f,0xfe0f,
0x0a03,0xf90a,0xff0f,0xff0f,0xff0f,0xff0f,0xff0f,0xff0f,
0xd00f,0xd10f,0xd20f,0xd30f,0xd40f,0xd50f,0xd60f,0xd70f,
0x0101,0x0402,0x0a03,0x1804,0x1904,0x3805,0x7806,0xf408,
0xf609,0xf40b,0x0b03,0x3905,0xf607,0xf508,0xf60a,0xf50b,
0x880f,0x890f,0x8a0f,0x8b0f,0x1a04,0xf707,0xf709,0xf60b,
0xc20e,0x8c0f,0x8d0f,0x8e0f,0x8f0f,0x900f,0x1b04,0xf807,
0xf809,0xf70b,0x910f,0x920f,0x930f,0x940f,0x950f,0x960f,
0x3a05,0xf608,0x970f,0x980f,0x990f,0x9a0f,0x9b0f,0x9c0f,
0x9d0f,0x9e0f,0x3b05,0xf909,0x9f0f,0xa00f,0xa10f,0xa20f,
0xa30f,0xa40f,0xa50f,0xa60f,0x7906,0xf70a,0xa70f,0xa80f,
0xa90f,0xaa0f,0xab0f,0xac0f,0xad0f,0xae0f,0x7a06,0xf80a,
0xaf0f,0xb00f,0xb10f,0xb20f,0xb30f,0xb40f,0xb50f,0xb60f,
0xf907,0xb70f,0xb80f,0xb90f,0xba0f,0xbb0f,0xbc0f,0xbd0f,
0xbe0f,0xbf0f,0xf708,0xc00f,0xc10f,0xc20f,0xc30f,0xc40f,
0xc50f,0xc60f,0xc70f,0xc80f,0xf808,0xc90f,0xca0f,0xcb0f,
0xcc0f,0xcd0f,0xce0f,0xcf0f,0xd00f,0xd10f,0xf908,0xd20f,
0xd30f,0xd40f,0xd50f,0xd60f,0xd70f,0xd80f,0xd90f,0xda0f,
0xfa08,0xdb0f,0xdc0f,0xdd0f,0xde0f,0xdf0f,0xe00f,0xe10f,
0xe20f,0xe30f,0xf90a,0xe40f,0xe50f,0xe60f,0xe70f,0xe80f,
0xe90f,0xea0f,0xeb0f,0xec0f,0xe00d,0xed0f,0xee0f,0xef0f,
0xf00f,0xf10f,0xf20f,0xf30f,0xf40f,0xf50f,0xc30e,0xf60f,
0xf70f,0xf80f,0xf90f,0xfa0f,0xfb0f,0xfc0f,0xfd0f,0xfe0f,
0x0001,0xfa09,0xff0f,0xff0f,0xff0f,0xff0f,0xff0f,0xff0f,
0xd00f,0xd10f,0xd20f,0xd30f,0xd40f,0xd50f,0xd60f,0xd70f,
0x0001,0x0202,0x0302,0x0402,0x0502,0x0602,0x0e03,0x1e04,
0x3e05,0x7e06,0xfe07,0xfe08,0xff0f,0xff0f,0xff0f,0xff0f,
0x0001,0x0101,0x0201,0x0602,0x0e03,0x1e04,0x3e05,0x7e06,
0xfe07,0xfe08,0xfe09,0xfe0a,0xff0f,0xff0f,0xff0f,0xff0f,
#endif
};
uint8 dhtable[] __attribute__ ((aligned(4)))={
0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x00, 0x02, 0x01, 0x03,
0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04,
0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00,
0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32,
0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1,
0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,
0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a,
0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35,
0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55,
0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65,
0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75,
0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85,
0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94,
0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,
0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2,
0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4,
0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x00, 0x03,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0a, 0x0b, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04,
0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07,
0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14,
0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33,
0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16,
0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19,
0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36,
0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46,
0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56,
0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85,
0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94,
0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,
0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2,
0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
0xf7, 0xf8, 0xf9, 0xfa,
};
const char quality_tab[DQT_NUM][128] __attribute__ ((aligned(4))) = {
// {
// 0x08, 0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07,
// 0x07, 0x07, 0x09, 0x09, 0x08, 0x0A, 0x0C, 0x14,
// 0x0D, 0x0C, 0x0B, 0x0B, 0x0C, 0x19, 0x12, 0x13,
// 0x0F, 0x14, 0x1D, 0x1A, 0x1F, 0x1E, 0x1D, 0x1A,
// 0x1C, 0x1C, 0x20, 0x24, 0x2E, 0x27, 0x20, 0x22,
// 0x2C, 0x23, 0x1C, 0x1C, 0x28, 0x37, 0x29, 0x2C,
// 0x30, 0x31, 0x34, 0x34, 0x34, 0x1F, 0x27, 0x39,
// 0x3D, 0x38, 0x32, 0x3C, 0x2E, 0x33, 0x34, 0x32,
// 0x09, 0x09, 0x09, 0x0C, 0x0B, 0x0C, 0x18, 0x0D,
// 0x0D, 0x18, 0x32, 0x21, 0x1C, 0x21, 0x32, 0x32,
// 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
// 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
// 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
// 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
// 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
// 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32
// },
{
16, 10, 9, 16, 24, 38, 50, 60,
11, 11, 14, 18, 25, 55, 59, 53,
14, 12, 16, 24, 38, 55, 68, 54,
14, 17, 20, 28, 50, 85, 78, 60,
17, 20, 36, 54, 65, 106, 99, 74,
24, 34, 53, 62, 79, 100, 109, 89,
47, 62, 76, 85, 99, 117, 116, 98,
70, 89, 91, 95, 108, 97, 99, 96,
17, 17, 24, 45, 96, 96, 96, 96,
17, 20, 25, 63, 96, 96, 96, 96,
24, 25, 54, 96, 96, 96, 96, 96,
45, 63, 96, 96, 96, 96, 96, 96,
96, 96, 96, 96, 96, 96, 96, 96,
96, 96, 96, 96, 96, 96, 96, 96,
96, 96, 96, 96, 96, 96, 96, 96,
96, 96, 96, 96, 96, 96, 96, 96
},
{
//Quantizaton table 0(luminance table) addr=0x20000 len=64 default:QT45
18, 12, 11, 18, 27, 44, 57, 68,
13, 13, 16, 21, 29, 64, 67, 61,
16, 14, 18, 27, 44, 63, 77, 62,
16, 19, 24, 32, 57, 97, 89, 69,
20, 24, 41, 62, 75, 121, 114, 85,
27, 39, 61, 71, 90, 115, 125, 102,
54, 71, 87, 97, 114, 134, 133, 112,
80, 102, 105, 109, 124, 111, 114, 110,
//Quantizaton table 1 (chrominance table) addr=0x20040 len = 64 default:QT45
19, 20, 27, 52, 110, 110, 110, 110,
20, 23, 29, 73, 110, 110, 110, 110,
27, 29, 62, 110, 110, 110, 110, 110,
52, 73, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110
},
{
20, 14, 13, 20, 30, 50, 64, 76,
15, 15, 18, 24, 33, 73, 75, 69,
18, 16, 20, 30, 50, 71, 86, 70,
18, 21, 28, 36, 64, 109, 100, 78,
23, 28, 46, 70, 85, 136, 129, 96,
30, 44, 69, 80, 101, 130, 141, 115,
61, 80, 98, 109, 129, 151, 150, 126,
90, 115, 119, 123, 140, 125, 129, 124,
21, 23, 30, 59, 124, 124, 124, 124,
23, 26, 33, 83, 124, 124, 124, 124,
30, 33, 70, 124, 124, 124, 124, 124,
59, 83, 124, 124, 124, 124, 124, 124,
124, 124, 124, 124, 124, 124, 124, 124,
124, 124, 124, 124, 124, 124, 124, 124,
124, 124, 124, 124, 124, 124, 124, 124,
124, 124, 124, 124, 124, 124, 124, 124
},
{
23, 16, 14, 23, 34, 57, 72, 87,
17, 17, 20, 27, 37, 82, 85, 78,
20, 18, 23, 34, 57, 81, 98, 80,
20, 24, 31, 41, 72, 124, 114, 88,
26, 31, 53, 80, 97, 155, 146, 109,
34, 50, 78, 91, 115, 148, 160, 131,
70, 91, 111, 124, 146, 172, 170, 143,
102, 131, 135, 139, 159, 142, 146, 141,
24, 26, 34, 67, 141, 141, 141, 141,
26, 30, 37, 94, 141, 141, 141, 141,
34, 37, 80, 141, 141, 141, 141, 141,
67, 94, 141, 141, 141, 141, 141, 141,
141, 141, 141, 141, 141, 141, 141, 141,
141, 141, 141, 141, 141, 141, 141, 141,
141, 141, 141, 141, 141, 141, 141, 141,
141, 141, 141, 141, 141, 141, 141, 141
},
{
27, 18, 17, 27, 40, 66, 85, 101,
20, 20, 23, 32, 43, 96, 100, 91,
23, 22, 27, 40, 66, 95, 115, 93,
23, 28, 37, 48, 85, 144, 133, 103,
30, 37, 61, 93, 113, 181, 171, 128,
40, 58, 91, 106, 134, 173, 188, 153,
81, 106, 129, 144, 171, 201, 199, 168,
120, 153, 158, 163, 186, 166, 171, 164,
28, 30, 40, 78, 164, 164, 164, 164,
30, 35, 43, 110, 164, 164, 164, 164,
40, 43, 93, 164, 164, 164, 164, 164,
78, 110, 164, 164, 164, 164, 164, 164,
164, 164, 164, 164, 164, 164, 164, 164,
164, 164, 164, 164, 164, 164, 164, 164,
164, 164, 164, 164, 164, 164, 164, 164,
164, 164, 164, 164, 164, 164, 164, 164
},
{
32, 22, 20, 32, 48, 80, 102, 122,
24, 24, 28, 38, 52, 116, 120, 110,
28, 26, 32, 48, 80, 114, 138, 112,
28, 34, 44, 58, 102, 174, 160, 124,
36, 44, 74, 112, 136, 218, 206, 154,
48, 70, 110, 128, 162, 208, 226, 184,
98, 128, 156, 174, 206, 242, 240, 202,
144, 184, 190, 196, 224, 200, 206, 198,
34, 36, 48, 94, 198, 198, 198, 198,
36, 42, 52, 132, 198, 198, 198, 198,
48, 52, 112, 198, 198, 198, 198, 198,
94, 132, 198, 198, 198, 198, 198, 198,
198, 198, 198, 198, 198, 198, 198, 198,
198, 198, 198, 198, 198, 198, 198, 198,
198, 198, 198, 198, 198, 198, 198, 198,
198, 198, 198, 198, 198, 198, 198, 198
},
{
39, 26, 24, 39, 58, 97, 124, 148,
29, 29, 34, 46, 63, 141, 146, 134,
34, 31, 39, 58, 97, 138, 168, 136,
34, 41, 53, 70, 124, 212, 195, 151,
43, 53, 90, 136, 165, 255, 251, 187,
58, 85, 134, 156, 197, 253, 255, 224,
119, 156, 190, 212, 251, 255, 255, 246,
175, 224, 231, 238, 225, 243, 251, 241,
41, 43, 58, 114, 241, 241, 241, 241,
43, 51, 63, 160, 241, 241, 241, 241,
58, 63, 136, 241, 241, 241, 241, 241,
114, 160, 241, 241, 241, 241, 241, 241,
241, 241, 241, 241, 241, 241, 241, 241,
241, 241, 241, 241, 241, 241, 241, 241,
241, 241, 241, 241, 241, 241, 241, 241,
241, 241, 241, 241, 241, 241, 241, 241
},
{
47, 31, 29, 47, 70, 118, 151, 180,
35, 35, 41, 56, 76, 171, 177, 163,
41, 37, 47, 70, 118, 168, 204, 165,
41, 49, 64, 85, 151, 255, 237, 184,
52, 64, 109, 165, 201, 255, 255, 227,
70, 103, 163, 190, 240, 255, 255, 255,
145, 190, 231, 255, 255, 255, 255, 255,
213, 255, 255, 255, 255, 255, 255, 255,
49, 52, 70, 138, 255, 255, 255, 255,
52, 62, 76, 195, 255, 255, 255, 255,
70, 76, 165, 255, 255, 255, 255, 255,
138, 195, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
},
{
57, 37, 35, 57, 85, 143, 184, 219,
42, 42, 49, 68, 92, 208, 215, 198,
49, 45, 57, 85, 143, 204, 248, 201,
49, 59, 78, 103, 184, 255, 255, 224,
63, 78, 132, 201, 244, 255, 255, 255,
85, 125, 198, 231, 255, 255, 255, 255,
176, 231, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
59, 63, 85, 168, 255, 255, 255, 255,
63, 75, 92, 237, 255, 255, 255, 255,
85, 92, 201, 255, 255, 255, 255, 255,
168, 237, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
},
{
69, 45, 42, 69, 103, 174, 224, 255,
51, 51, 59, 82, 112, 253, 255, 241,
59, 54, 69, 103, 174, 248, 255, 244,
59, 71, 95, 125, 224, 255, 255, 255,
76, 95, 160, 244, 255, 255, 255, 255,
103, 152, 241, 255, 255, 255, 255, 255,
214, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
71, 76, 103, 204, 255, 255, 255, 255,
76, 91, 112, 255, 255, 255, 255, 255,
103, 112, 244, 255, 255, 255, 255, 255,
204, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
},
{
84, 54, 51, 84, 125, 212, 255, 255,
62, 62, 71, 99, 136, 255, 255, 255,
71, 65, 84, 125, 212, 255, 255, 255,
71, 86, 115, 152, 255, 255, 255, 255,
92, 115, 195, 255, 255, 255, 255, 255,
125, 185, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
86, 92, 125, 248, 255, 255, 255, 255,
92, 110, 136, 255, 255, 255, 255, 255,
125, 136, 255, 255, 255, 255, 255, 255,
248, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
},
{
102, 65, 62, 102, 152, 255, 255, 255,
75, 75, 86, 120, 165, 255, 255, 255,
86, 79, 102, 152, 255, 255, 255, 255,
86, 104, 140, 185, 255, 255, 255, 255,
112, 140, 237, 255, 255, 255, 255, 255,
152, 225, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
104, 112, 152, 255, 255, 255, 255, 255,
112, 134, 165, 255, 255, 255, 255, 255,
152, 165, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
}
};
#if 0
char quality0[128] __attribute__ ((aligned(4)))= {
0x08, 0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07,
0x07, 0x07, 0x09, 0x09, 0x08, 0x0A, 0x0C, 0x14,
0x0D, 0x0C, 0x0B, 0x0B, 0x0C, 0x19, 0x12, 0x13,
0x0F, 0x14, 0x1D, 0x1A, 0x1F, 0x1E, 0x1D, 0x1A,
0x1C, 0x1C, 0x20, 0x24, 0x2E, 0x27, 0x20, 0x22,
0x2C, 0x23, 0x1C, 0x1C, 0x28, 0x37, 0x29, 0x2C,
0x30, 0x31, 0x34, 0x34, 0x34, 0x1F, 0x27, 0x39,
0x3D, 0x38, 0x32, 0x3C, 0x2E, 0x33, 0x34, 0x32,
0x09, 0x09, 0x09, 0x0C, 0x0B, 0x0C, 0x18, 0x0D,
0x0D, 0x18, 0x32, 0x21, 0x1C, 0x21, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
};
/*QT45*/
char quality1[128] __attribute__ ((aligned(4)))= {
//Quantizaton table 0(luminance table) addr=0x20000 len=64 default:QT45
18, 12, 11, 18, 27, 44, 57, 68,
13, 13, 16, 21, 29, 64, 67, 61,
16, 14, 18, 27, 44, 63, 77, 62,
16, 19, 24, 32, 57, 97, 89, 69,
20, 24, 41, 62, 75, 121, 114, 85,
27, 39, 61, 71, 90, 115, 125, 102,
54, 71, 87, 97, 114, 134, 133, 112,
80, 102, 105, 109, 124, 111, 114, 110,
//Quantizaton table 1 (chrominance table) addr=0x20040 len = 64 default:QT45
19, 20, 27, 52, 110, 110, 110, 110,
20, 23, 29, 73, 110, 110, 110, 110,
27, 29, 62, 110, 110, 110, 110, 110,
52, 73, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110,
};
/*QT40*/
char quality2[128] __attribute__ ((aligned(4)))= {
20, 14, 13, 20, 30, 50, 64, 76,
15, 15, 18, 24, 33, 73, 75, 69,
18, 16, 20, 30, 50, 71, 86, 70,
18, 21, 28, 36, 64, 109, 100, 78,
23, 28, 46, 70, 85, 136, 129, 96,
30, 44, 69, 80, 101, 130, 141, 115,
61, 80, 98, 109, 129, 151, 150, 126,
90, 115, 119, 123, 140, 125, 129, 124,
21, 23, 30, 59, 124, 124, 124, 124,
23, 26, 33, 83, 124, 124, 124, 124,
30, 33, 70, 124, 124, 124, 124, 124,
59, 83, 124, 124, 124, 124, 124, 124,
124, 124, 124, 124, 124, 124, 124, 124,
124, 124, 124, 124, 124, 124, 124, 124,
124, 124, 124, 124, 124, 124, 124, 124,
124, 124, 124, 124, 124, 124, 124, 124,
};
/*QT35*/
char quality3[128] __attribute__ ((aligned(4)))= {
23, 16, 14, 23, 34, 57, 72, 87,
17, 17, 20, 27, 37, 82, 85, 78,
20, 18, 23, 34, 57, 81, 98, 80,
20, 24, 31, 41, 72, 124, 114, 88,
26, 31, 53, 80, 97, 155, 146, 109,
34, 50, 78, 91, 115, 148, 160, 131,
70, 91, 111, 124, 146, 172, 170, 143,
102, 131, 135, 139, 159, 142, 146, 141,
24, 26, 34, 67, 141, 141, 141, 141,
26, 30, 37, 94, 141, 141, 141, 141,
34, 37, 80, 141, 141, 141, 141, 141,
67, 94, 141, 141, 141, 141, 141, 141,
141, 141, 141, 141, 141, 141, 141, 141,
141, 141, 141, 141, 141, 141, 141, 141,
141, 141, 141, 141, 141, 141, 141, 141,
141, 141, 141, 141, 141, 141, 141, 141,
};
/*QT30*/
char quality4[128] __attribute__ ((aligned(4)))= {
27, 18, 17, 27, 40, 66, 85, 101,
20, 20, 23, 32, 43, 96, 100, 91,
23, 22, 27, 40, 66, 95, 115, 93,
23, 28, 37, 48, 85, 144, 133, 103,
30, 37, 61, 93, 113, 181, 171, 128,
40, 58, 91, 106, 134, 173, 188, 153,
81, 106, 129, 144, 171, 201, 199, 168,
120, 153, 158, 163, 186, 166, 171, 164,
28, 30, 40, 78, 164, 164, 164, 164,
30, 35, 43, 110, 164, 164, 164, 164,
40, 43, 93, 164, 164, 164, 164, 164,
78, 110, 164, 164, 164, 164, 164, 164,
164, 164, 164, 164, 164, 164, 164, 164,
164, 164, 164, 164, 164, 164, 164, 164,
164, 164, 164, 164, 164, 164, 164, 164,
164, 164, 164, 164, 164, 164, 164, 164,
};
/*QT25*/
char quality5[128] __attribute__ ((aligned(4)))= {
32, 22, 20, 32, 48, 80, 102, 122,
24, 24, 28, 38, 52, 116, 120, 110,
28, 26, 32, 48, 80, 114, 138, 112,
28, 34, 44, 58, 102, 174, 160, 124,
36, 44, 74, 112, 136, 218, 206, 154,
48, 70, 110, 128, 162, 208, 226, 184,
98, 128, 156, 174, 206, 242, 240, 202,
144, 184, 190, 196, 224, 200, 206, 198,
34, 36, 48, 94, 198, 198, 198, 198,
36, 42, 52, 132, 198, 198, 198, 198,
48, 52, 112, 198, 198, 198, 198, 198,
94, 132, 198, 198, 198, 198, 198, 198,
198, 198, 198, 198, 198, 198, 198, 198,
198, 198, 198, 198, 198, 198, 198, 198,
198, 198, 198, 198, 198, 198, 198, 198,
198, 198, 198, 198, 198, 198, 198, 198,
};
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,432 @@
#ifndef _OPENDML_H_
#define _OPENDML_H_
//include "type.h"
#include "typesdef.h"
#include "osal_file.h"
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
//最后可改成变量模式
#define FPS 30
/*
#define STRL 0x6c727473
#define STRH 0x68727473
#define STRF 0x66727473
#define VIDS 0x73646976
#define AUDS 0x73647561
#define MJPG 0x47504a4d
#define INDX 0x78646e69
#define DC 0x63643030//00dc
#define WB 0x62773130//01wb
#define VPRP 0x70727076
#define LIST 0x5453494c
#define ODML 0x6c6d646f
#define DMLH 0x686c6d64
#define JUNK 0x4b4e554a
*/
#define AVIF_HASINDEX 0x10
#define AVIF_MUSTUSEINDEX 0x20
#define AVIF_ISINTERLEAVED 0x100
#define AVIF_WASCAPTUREFILE 0x10000
#define AVIF_COPYRIGHTED 0x20000
#define AVI_KNOWN_FLAGS 0x30130
#define AVI_INDEX_OF_INDEXES 0x00
#define AVI_INDEX_OF_CHUNKS 0x01
#define AVI_INDEX_OF_TIMED_CHUNKS 0x02
#define AVI_INDEX_OF_SUB_2FIELD 0x03
#define AVI_INDEX_IS_DATA 0x80
#define FIL_SIZE_4G 0XF85A2000
#define FIL_SIZE_3G 0XDC758000
#define FIL_SIZE_2G 0X7D000000
#define FIL_SIZE_1G 0X3E800000
#define PCM_SHEET_SIZE 8192
/************** user seting *****************/
//#define SECTOR_SYNC
//#define HEAD_SYNC
#define SYNC_EN 1
#define FILE_SIZE_MAX_ FIL_SIZE_1G //size of one file
#define SYNTIME 10 //how many second sync file
#define FRAME_SIZE 40*1024 // Probably size every frame(720p)
/*************************************************/
#define SUPERIDXLEN (FILE_SIZE_MAX_ / (SYNTIME*30*FRAME_SIZE))
#define SupIDXBUFLEN SUPERIDXLEN //buff len
#define StdIDXBUFLEN (SYNTIME*30)
#define _ODML_AVI_HEAD_SIZE__ (((2048 + SUPERIDXLEN*16*2)/1024 +1)*1024)
#define MOVIMAXLEN (1024*1024)*900 //ever AVIX chunk size
#define AVIXMAXNUM 6
typedef struct
{
uint32 win_w;
uint32 win_h;
uint32 audiofrq;
uint32 frame_rate;
uint32 pcm;
}AVI_INFO;
typedef struct {
DWORD ckid;
DWORD dwFlags;
DWORD dwChunkOffset;
DWORD dwChunkLength;
} AVIINDEXENTRY;
typedef struct {
DWORD fcc;//avih
DWORD cb;//size
DWORD dwMicroSecPerFrame;
DWORD dwMaxBytesPerSec;
DWORD dwPaddingGranularity;
DWORD dwFlags;
DWORD dwTotalFrames;
DWORD dwInitialFrames;
DWORD dwStreams;
DWORD dwSuggestedBufferSize;
DWORD dwWidth;
DWORD dwHeight;
DWORD dwReserved[4];
} AVIMAINHEADER;
#ifndef AVI_STREAM_HEADER
#define AVI_STREAM_HEADER
typedef struct {
DWORD fcc;//4//strh
DWORD cb;//4//size
DWORD fccType;//4//vids|auds
DWORD fccHandler;//4
DWORD dwFlags;//4
WORD wPriority;//2
WORD wLanguage;//2
DWORD dwInitialFrames;//4
DWORD dwScale;//4
DWORD dwRate; //4/* dwRate / dwScale == samples/second */
DWORD dwStart;//4
DWORD dwLength; //4/* In units above... */
DWORD dwSuggestedBufferSize;//4
DWORD dwQuality;//4
DWORD dwSampleSize;//4
struct {
short int left;//2
short int top;//2
short int right;//2
short int bottom;//2
} rcFrame;
} AVISTREAMHEADER;
#endif
typedef struct{
uint32 rv[34];
}BITMAPAUDIODC;
typedef struct{
uint32 rv[2];
}WAVEDECPR;
typedef struct {
DWORD biSize;
DWORD biWidth;//4
DWORD biHeight;//4
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
DWORD biXPelsPerMeter;
DWORD biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} AVIBITMAPINFOHEADER;
//修改nBlockAlign它的类型否则ffmpeg识别不了
typedef struct {
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAlign;
WORD wBitsPerSample;
WORD cbSize;
} AVIWAVEFORMATEX;
typedef struct {
DWORD dwFourCC;
DWORD dwSize;
} CHUNK;
typedef struct{
DWORD fcc;
DWORD cb;
DWORD fcctype;
} LIST;
struct _avistdindex_chunk {
uint32 fcc; // ¡¯ix##¡¯
uint32 cb;
uint16 wLongsPerEntry ; // must be sizeof(aIndex[0])/sizeof(DWORD)
uint8 bIndexSubType ; // must be 0
uint8 bIndexType ; // must be AVI_INDEX_OF_CHUNKS
uint32 nEntriesInUse ; //
uint32 dwChunkId ; // ¡¯##dc¡¯ or ¡¯##db¡¯ or ¡¯##wb¡¯ etc..
uint32 qwBaseOffset ; // all dwOffsets in aIndex array are
uint32 qwBaseOffset1 ; // all dwOffsets in aIndex array are
uint32 dwReserved ; // all dwOffsets in aIndex array are
// relative to this
//uint32 dwReserved; // must be 0
} __attribute__((packed)) ;
typedef struct _avistdindex_chunk AVISTDINDEXHEAD;
#ifndef AVI_SUPER_INDEX
#define AVI_SUPER_INDEX
typedef struct _avistdindex_entry {
DWORD dwOffset; // qwBaseOffset + this is absolute file offset
DWORD dwSize; // bit 31 is set if this is NOT a keyframe
} stdindx;
typedef struct _avisuperindex_entry {
uint64 qwOffset; // absolute file offset
DWORD dwSize; // size of index chunk at this offset include stdindx head
DWORD dwDuration; // time span in stream ticks
} superindx;
#endif
typedef struct _avisuperindex_chunk {
WORD wLongsPerEntry; // must be 4 (size of each entry in aIndex array)
BYTE bIndexSubType; // must be 0 or AVI_INDEX_2FIELD
BYTE bIndexType; // must be AVI_INDEX_OF_INDEXES
DWORD nEntriesInUse; // number of entries in aIndex array that
// are used
DWORD dwChunkId; // ¡¯##dc¡¯ or ¡¯##db¡¯ or ¡¯##wb¡¯, etc
DWORD dwReserved[3]; // must be 0
} AVISUPERINDEXHEAD;
typedef struct {
DWORD CompressedBMHeight;
DWORD CompressedBMWidth;
DWORD ValidBMHeight;
DWORD ValidBMWidth;
DWORD ValidBMXOffset;
DWORD ValidBMYOffset;
DWORD VideoXOffsetInT;
DWORD VideoYValidStartLine;
} VIDEO_FIELD_DESC;
typedef struct {
DWORD VideoFormatToken;
DWORD VideoStandard;
DWORD dwVerticalRefreshRate;
DWORD dwHTotalInT;
DWORD dwVTotalInLines;
DWORD dwFrameAspectRatio;
DWORD dwFrameWidthInPixels;
DWORD dwFrameHeightInLines;
DWORD nbFieldPerFrame;
VIDEO_FIELD_DESC FieldInfo;
} VideoPropHeader;
typedef struct {
DWORD OpenDML_Header;
DWORD size;
DWORD dwTotalFrames; //video total frame + auds frame
DWORD dwFuture[61];
} ODMLExtendedAVIHeader;
typedef struct {
LIST riff; //{"RIFF",dwsize,"AVIX "};
LIST movi; //{"LIST",dwsize,"movi"};
} AVIXMOVILIST;
// sizeof(LIST)*5+sizeof(AVIMAINHEADER)+sizeof(AVISTREAMHEADER)*2+sizeof(CHUNK)*11+
//sizeof(AVIBITMAPINFOHEADER)+sizeof(AVISUPERINDEXHEAD)*2+sizeof(superindx)*2*SUPERIDXLEN+sizeof(VideoPropHeader)+sizeof(AVIWAVEFORMATEX)+sizeof(ODMLExtendedAVIHeader);
//sizeof(aviheader->strl_a.fcctype)+3*sizeof(CHUNK)+sizeof(AVISTREAMHEADER)+sizeof(AVIWAVEFORMATEX) +
//sizeof(AVISUPERINDEXHEAD)+SUPERIDXLEN*sizeof(superindx)+367;
typedef struct {
LIST riff; //{"RIFF",dwsize,"AVI "};
LIST hdrl; //{"LIST",dwsize,"hdr1"};
AVIMAINHEADER avih; //aviheader
LIST strl_v; //strl vids
AVISTREAMHEADER strh_v; //stream vids
CHUNK strf_v; //vids stream info
AVIBITMAPINFOHEADER bitmapinfo;
CHUNK sector1_junk;
uint8 sector1fill[260];
//CHUNK strd_v;
//BITMAPAUDIODC bitmapvideodc;
CHUNK sidx_v;
AVISUPERINDEXHEAD vsupindxh; //superindx head for video
/**********sector 1*********************/
superindx vindx[SUPERIDXLEN]; //super indx for video
CHUNK sector2_junk;
uint8 sector2fill[512-(SUPERIDXLEN*16)%512-8];
/**********sector 2*********************/
CHUNK c_vprp;
VideoPropHeader vprp; //Video Properties Header
CHUNK sector3_junk;
uint8 sector3fill[428];
/**********sector 3*********************/
LIST strl_a; //strl auds
AVISTREAMHEADER strh_a; //stream auds
CHUNK strf_a; //auds stream info
AVIWAVEFORMATEX wavinfo;
CHUNK sector4_junk;
uint8 sector4fill[368];
//CHUNK strd_a;
//WAVEDECPR wavedcpr;
CHUNK sidx_a;
AVISUPERINDEXHEAD asupindxh; //superindx head for auds
/**********sector 4*********************/
superindx aindx[SUPERIDXLEN]; //super indx for auds
CHUNK sector5_junk;
uint8 sector5fill[512-(SUPERIDXLEN*16)%512-8];
/**********sector 5*********************/
LIST obml;
ODMLExtendedAVIHeader strodml; //Extended AVI Header (dmlh)
CHUNK junk;
} __attribute__((packed)) ODMLAVIFILEHEADER;
#if SYNC_EN
typedef struct {
LIST riff; //{"RIFF",dwsize,"AVI "};
LIST hdrl; //{"LIST",dwsize,"hdr1"};
AVIMAINHEADER avih; //aviheader
LIST strl_v; //strl vids
AVISTREAMHEADER strh_v; //stream vids
CHUNK strf_v; //vids stream info
AVIBITMAPINFOHEADER bitmapinfo;
CHUNK sector1_junk;
uint8 sector1fill[259];
//CHUNK strd_v;
//BITMAPAUDIODC bitmapvideodc;
CHUNK sidx_v;
AVISUPERINDEXHEAD vsupindxh; //superindx head for video
}VIDEO_SECTOR;
typedef struct {
LIST strl_a; //strl auds
AVISTREAMHEADER strh_a; //stream auds
CHUNK strf_a; //auds stream info
AVIWAVEFORMATEX wavinfo;
CHUNK sector4_junk;
uint8 sector4fill[367];
//CHUNK strd_a;
//WAVEDECPR wavedcpr;
CHUNK sidx_a;
AVISUPERINDEXHEAD asupindxh; //superindx head for auds
/**********sector 4*********************/
}AUDS_SECTOR;
typedef struct {
superindx vindx[32];
}VIDSUPIND_SECTOR;
typedef struct {
superindx Aindx[32];
}AUDSUPIND_SECTOR;
typedef struct {
LIST obml;
ODMLExtendedAVIHeader strodml; //Extended AVI Header (dmlh)
CHUNK junk;
uint8 junkfill[_ODML_AVI_HEAD_SIZE__ - (sizeof(ODMLAVIFILEHEADER) + 12)];
LIST list_movi;
}MOVI_SECTOR;
typedef struct{
uint16 vsupindx_count;
uint16 asupindx_count;
uint32 vsupidx_sector;
uint32 asupidx_sector;
uint32 video_sector;
uint32 auds_sector;
uint32 movi_sector;
VIDEO_SECTOR video;
AUDS_SECTOR auds;
VIDSUPIND_SECTOR vsupidx;
AUDSUPIND_SECTOR asupidx;
MOVI_SECTOR movi;
}ODMLAVI_SECTOR;
#endif
typedef struct {
//buff for video and auds's std record the ""indx
stdindx vstdindx[StdIDXBUFLEN];
stdindx astdindx[StdIDXBUFLEN];
//buff for video and auds's super indx
superindx vsuperindx[SupIDXBUFLEN];
superindx asuperindx[SupIDXBUFLEN];
//record the "movi" offest that is using
uint64 qwOffset;
//how many frame in a std indx
uint32 vidxcount;
uint32 aidxcount;
//how many indx of indx in super indx
uint32 svidxcount;
uint32 saidxcount;
/*
//record how many frame int one stdindx enter arry(not use now)
uint32 vframecount;
uint32 aframecount;
*/
uint64 fileofset_last;//record the offset that end of last movi list(point to new RIFF )
uint64 fileofset;//record the file offset about now
int cur_timestamp;
int last_timestamp;
int ef_time; //ever frame time,每一帧的时间,但由于忽略小数,因此存在一定误差
int ef_fps; //fps,记录帧率,如果需要准确计算时间,则需要通过帧率来计算
uint32 avilisframecnt; //AVI list total frame
uint32 vframecnt; // video frame count total
uint32 aframecnt; // auds frame count total
uint16_t aframeSample;//音频单包的长度,这样不再用宏控制,可以通过初始化的时候修改
int size; //size of frame
//use when insert frame
uint64 inserofset;
uint32 insersize;
//buff for list "movi" movlist[n] math moviofest[n]
short AVIXnum; //init value is -1 ,when it is 0 that mean have 1 AVIX List
AVIXMOVILIST movlist[AVIXMAXNUM];
uint64 moviofest[AVIXMAXNUM];
//#if SYNC_EN
//ODMLAVI_SECTOR Sync_buff;
uint8_t * sync_buf;
//#endif
} ODMLBUFF;
typedef int (*opendml_write_priv)(void *fp,void *d,int size);
void ODMLbuff_init(ODMLBUFF *buff);
int OMDLvideo_header_write(void *f_write,void *f, AVI_INFO *msg,ODMLAVIFILEHEADER *headerbuf);
void stdindx_updata(void *f,ODMLBUFF *buff);
int ODMLUpdateAVIInfo(void * file,ODMLBUFF *buff,bool Enpcm,void *f_write,ODMLAVIFILEHEADER * headerbuf);
void opendml_write_video(ODMLBUFF *odml_buff,void *fp,void *jpeg,int size);
int opendml_write_video2(ODMLBUFF *odml_buff,void *fp,opendml_write_priv write_priv,int size,void *d);
int insert_frame(ODMLBUFF *buff,void *pavi,float *tim_diff);
int opendml_write_audio(ODMLBUFF *odml_buff,void *fp,opendml_write_priv write_priv,int size,void *d);
bool ODMLadd_indx(bool type,void *f, ODMLBUFF *buff);
#endif /*_OPENDML_H_*/

View File

@@ -0,0 +1,44 @@
#include "sys_config.h"
#include "typesdef.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 "dev/gen/hggen420.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"
void gen420_run(uint8_t *psram_buf,uint32_t width,uint32_t high){
struct gen420_device *gen420_dev;
gen420_dev = (struct gen420_device *)dev_get(HG_GEN420_DEVID);
gen420_psram_adr(gen420_dev,(uint32_t)psram_buf,(uint32_t)psram_buf+width*high,(uint32_t)psram_buf+width*high+width*high/4);
_os_printf("G");
gen420_dma_run(gen420_dev);
}
void gen420_done_isr(uint32 irq,uint32 dev,uint32 param){
//struct gen420_device *gen420_dev = (struct gen420_device *)dev;
_os_printf("%s %d\r\n",__func__,__LINE__);
}
void gen420_dev_init(uint32_t width,uint32_t high){
struct gen420_device *gen420_dev;
uint8_t *gen420_sram;
gen420_dev = (struct gen420_device *)dev_get(HG_GEN420_DEVID);
gen420_sram = malloc(12*1024);
gen420_open(gen420_dev);
gen420_request_irq(gen420_dev,GEN420_DONE_ISR,(gen420_irq_hdl )&gen420_done_isr,(uint32_t)gen420_dev);;
gen420_sram_linebuf_adr(gen420_dev,(uint32_t)gen420_sram,(uint32_t)gen420_sram+8*1024,(uint32_t)gen420_sram+10*1024);
gen420_frame_size(gen420_dev,width,high);
gen420_dst_h264_and_jpg(gen420_dev,0);
}

View File

@@ -0,0 +1,78 @@
#include "sys_config.h"
#include "typesdef.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 "dev/gen/hggen422.h"
#include "lib/lcd/lcd.h"
#include "hal/jpeg.h"
#include "lib/video/vpp/vpp_dev.h"
#include "lib/video/gen/gen422_dev.h"
#include "lib/scale/scale_dev.h"
void gen422_done_isr(uint32 irq,uint32 dev,uint32 param){
//struct gen420_device *gen420_dev = (struct gen420_device *)dev;
_os_printf("%s %d\r\n",__func__,__LINE__);
}
void gen422_rdone_isr(uint32 irq,uint32 dev,uint32 param){
//struct gen420_device *gen420_dev = (struct gen420_device *)dev;
_os_printf("%s %d\r\n",__func__,__LINE__);
}
void gen422_rd_slow_isr(uint32 irq,uint32 dev,uint32 param){
//struct gen420_device *gen420_dev = (struct gen420_device *)dev;
_os_printf("%s %d\r\n",__func__,__LINE__);
}
void gen422_wr_slow_isr(uint32 irq,uint32 dev,uint32 param){
//struct gen420_device *gen420_dev = (struct gen420_device *)dev;
_os_printf("%s %d\r\n",__func__,__LINE__);
}
void gen422_ov_isr(uint32 irq,uint32 dev,uint32 param){
//struct gen420_device *gen420_dev = (struct gen420_device *)dev;
_os_printf("%s %d\r\n",__func__,__LINE__);
}
void gen422_init(uint32_t w,uint32_t h,uint8_t sigle_frm){
struct gen422_device *gen422_dev;
uint8_t *gen420_sram;
gen422_dev = (struct gen422_device *)dev_get(HG_GEN422_DEVID);
gen422_open(gen422_dev);
gen422_request_irq(gen422_dev,GEN422_GDONE_ISR,(gen422_irq_hdl )&gen422_done_isr,(uint32)gen422_dev);
gen422_request_irq(gen422_dev,GEN422_RDONE_ISR,(gen422_irq_hdl )&gen422_rdone_isr,(uint32)gen422_dev);
gen422_request_irq(gen422_dev,GEN422_RD_SLOW_ISR,(gen422_irq_hdl )&gen422_rd_slow_isr,(uint32)gen422_dev);
gen422_request_irq(gen422_dev,GEN422_WR_SLOW_ISR,(gen422_irq_hdl )&gen422_wr_slow_isr,(uint32)gen422_dev);
gen422_request_irq(gen422_dev,GEN422_GEN_OV_ISR,(gen422_irq_hdl )&gen422_ov_isr,(uint32)gen422_dev);
gen420_sram = malloc(w*6);
gen422_sram_linebuf_adr(gen422_dev,(uint32)gen420_sram,(uint32)gen420_sram+w*4,(uint32)gen420_sram+w*5);
gen422_yuv_mode(gen422_dev,0);
gen422_input_from_sram_or_psram(gen422_dev,0);
gen422_output_single_mode(gen422_dev,sigle_frm);
gen422_frame_time(gen422_dev,65530,1000/16,16);
gen422_frame_size(gen422_dev,w,h);
gen422_output_enable(gen422_dev,1,0);
}
void gen422_set_frame(uint32_t psram0,uint32_t psram1,uint32_t w,uint32_t h){
struct gen422_device *gen422_dev;
gen422_dev = (struct gen422_device *)dev_get(HG_GEN422_DEVID);
gen422_psram_adr(gen422_dev,psram0,psram1,w,h);
}
void gen422_run(){
struct gen422_device *gen422_dev;
gen422_dev = (struct gen422_device *)dev_get(HG_GEN422_DEVID);
gen422_dma_run(gen422_dev);
gen422_sw_enable(gen422_dev,1);
}

File diff suppressed because it is too large Load Diff

244
sdk/lib/video/isp/isp_dev.c Normal file
View File

@@ -0,0 +1,244 @@
#include "sys_config.h"
#include "typesdef.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 "hal/isp.h"
#include "hal/i2c.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 "hal/gpio.h"
#include "app/app_iic/app_iic.h"
#include "lib/video/isp/isp_dev.h"
#include "lib/video/isp/isp_ircut.h"
#include "osal/event.h"
#include "osal/msgqueue.h"
#include "lib/heap/av_heap.h"
#ifndef ISP_HARDWARE_CLK
#define ISP_HARDWARE_CLK ISP_MODULE_CLK_320M
#endif
extern _Sensor_YGAMMA y_gamma_tbl[];
// extern uint32 gamma2p4_tbl[];
extern uint32 gamma_table_addr[3] ;
extern uint32 luma_ca_addr[];
extern IRCUT_INFO ircut_info;
#if ISP_DMA_EN
#define ISP_IRQ_HANDLE_TYPE ISP_IRQ_FLAG_DMA_DONE
#else
#define ISP_IRQ_HANDLE_TYPE ISP_IRQ_FLAG_FRM_END
#endif
volatile struct list_head sensor_info_head;
const float ev_offset_lut[] = {0.015625, 0.03125, 0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 64};
const struct isp_awb_mode_param isp_awb_mode_map[] =
{
// awb_mode awb_gain_r awb_gain_gr awb_gain_gb awb_gain_b
{ 0, 0, 256, 256, 0},
{ 1, 480, 256, 256, 430},
{ 2, 530, 256, 256, 380},
{ 3, 551, 256, 256, 360},
};
void sensor_info_init()
{
INIT_LIST_HEAD((struct list_head *)&sensor_info_head);
}
void sensor_info_add(enum sensor_type type, enum isp_input_dat_src sensor_src, uint32 sensor_config, uint32 iic_id, uint32 opt_cmd)
{
SENSOR_BASIC_INFO *info = os_malloc(sizeof(SENSOR_BASIC_INFO));
if (info)
{
os_memset(info, 0, sizeof(sizeof(SENSOR_BASIC_INFO)));
info->sensor_src = sensor_src;
info->sensor_type = type;
info->sensor_dev_id = iic_id;
info->sensor_opt_cmd = opt_cmd;
info->sensor_config = sensor_config;
INIT_LIST_HEAD(&info->list);
list_add_tail(&info->list,(struct list_head*)&sensor_info_head);
}
}
void sensor_info_destory()
{
SENSOR_BASIC_INFO *info = NULL;
struct list_head *nhead = NULL;
while(1)
{
if (list_empty((void *)&sensor_info_head)) break;
nhead = sensor_info_head.next;
info = list_entry(nhead, SENSOR_BASIC_INFO, list);
list_del(nhead);
os_free(info);
}
}
void hgisp_frame_start_handle(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2) {
// _os_printf("d");
// os_printf("%s %d\r\n",__func__,__LINE__);
}
void hgisp_frame_done_handle(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2){
os_printf("%s %d\r\n",__func__,__LINE__);
}
void hgisp_frame_slow_handle(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2){
os_printf("%s %d\r\n",__func__,__LINE__);
}
void hgisp_frame_fast_handle(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2){
os_printf("%s %d\r\n",__func__,__LINE__);
}
void hgisp_motion_detect_handle(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2){
os_printf("%s %d\r\n",__func__,__LINE__);
}
void hgisp_data_overflow_handle(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2){
os_printf("%s %d\r\n",__func__,__LINE__);
}
void *isp_task_hdl;
volatile struct os_event isp_event;
volatile struct os_msgqueue isp_msg;
int32 isp_task(void *data)
{
uint32 flag = 0;
int32 event_ret = 0;
int32 msg_ret = 0;
uint8 msg_cnt = 0;
struct isp_device *dev = (struct isp_device *)data;
struct isp_exposure_opt *cfg = NULL;
struct isp_sensor_opt *opt = NULL;
while (1)
{
event_ret = os_event_wait((void *)&isp_event, EVENT_ISP_CALC | EVENT_ISP_FPS_OPT | EVENT_ISP_IMG_OPT, &flag, OS_EVENT_WMODE_OR | OS_EVENT_WMODE_CLEAR, 50);
if (event_ret)
{
continue;
}
if (flag & EVENT_ISP_CALC)
{
if (cfg && iic_devid_finish(cfg->devid_id) == 1)
{
cfg->data.size = 0;
cfg = NULL;
}
isp_calculate(dev, (void *)&cfg);
if (cfg)
{
wake_up_iic_queue(cfg->devid_id, (void *)&cfg->data, cfg->cmd_len, 2, NULL);
}
}
if ((flag & EVENT_ISP_IMG_OPT) || (flag & EVENT_ISP_FPS_OPT))
{
msg_cnt = os_msgq_cnt((void *)&isp_msg);
for (int i = 0; i < msg_cnt; i++)
{
opt = (struct isp_sensor_opt *)os_msgq_get2((void *)&isp_msg, 100, &msg_ret);
if (msg_ret == 0)
{
while(iic_devid_finish(opt->devid_id) != 1)
{
os_sleep_ms(1);
}
wake_up_iic_queue(opt->devid_id, (uint8_t*)&opt->data, opt->cmd_len, 2, (uint8_t*)NULL);
}
}
}
}
}
extern const uint16_t isp_param[];
void isp_cfg_dev(){
uint8_t ret;
struct hgisp_sensor_init *sensor_init = NULL;
struct isp_device *isp_dev;
SENSOR_BASIC_INFO *info = NULL;
isp_dev = (struct isp_device *)dev_get(HG_ISP_DEVID);
if (isp_dev == NULL)
{
os_printf("get isp device err\r\n");
return;
}
os_printf("isp cfg....\r\n");
sensor_init = (struct hgisp_sensor_init *)isp_sensor_param_load((void *)isp_param);
if (sensor_init && !list_empty((void *)&sensor_info_head))
{
os_event_init((void *)&isp_event);
os_msgq_init((void *)&isp_msg, 2);
ret = isp_open(isp_dev, ISP_HARDWARE_CLK, ISP_INPUT_FIFO_FULL);
if (!ret)
{
isp_yuv_range(isp_dev, VIDEO_YUV_RANGE_TYPE);
isp_sensor_param_config(isp_dev, (uint32)sensor_init);
isp_y_gamma_init(isp_dev , (uint32)y_gamma_tbl);
isp_rgb_gamma_init(isp_dev, (uint32)gamma_table_addr[1]);
isp_awb_mannul_mode_map(isp_dev, (uint32)isp_awb_mode_map);
isp_ae_ev_offset_lut(isp_dev, (uint32)ev_offset_lut);
isp_awb_gain_type(isp_dev, AWB_GAIN_TYPE_AWB, SENSOR_TYPE_MASTER);
isp_awb_gain_type(isp_dev, AWB_GAIN_TYPE_AWB, SENSOR_TYPE_SLAVE0);
isp_awb_gain_type(isp_dev, AWB_GAIN_TYPE_AWB, SENSOR_TYPE_SLAVE1);
list_for_each_entry(info, (struct list_head*)&sensor_info_head, list)
{
ret = isp_sensor_init(isp_dev, info->sensor_type, info->sensor_src, info->sensor_config);
if (ret)
{
os_printf(KERN_ERR"config sensor param err!\r\n");
isp_close(isp_dev);
goto end;
} else {
isp_sensor_iic_devid_init(isp_dev, info->sensor_dev_id, info->sensor_type);
isp_sensor_iic_cmd_init(isp_dev, info->sensor_opt_cmd, info->sensor_type);
}
}
ircut_init();
isp_request_irq(isp_dev, ISP_IRQ_FLAG_DMA_DONE , hgisp_frame_start_handle , 0);
// isp_request_irq(isp_dev, ISP_IRQ_FLAG_FRM_END , hgisp_frame_done_handle , (uint32)isp_dev);
isp_request_irq(isp_dev, ISP_IRQ_FLAG_DAT_OF , hgisp_data_overflow_handle , 0);
isp_request_irq(isp_dev, ISP_IRQ_FLAG_INTF_SLOW, hgisp_frame_slow_handle , 0);
isp_request_irq(isp_dev, ISP_IRQ_FLAG_FRM_FAST , hgisp_frame_fast_handle , 0);
isp_request_irq(isp_dev, ISP_IRQ_FLAG_MD_DONE , hgisp_motion_detect_handle , 0);
isp_task_hdl = os_task_create("isp", (void *)isp_task, isp_dev, OS_TASK_PRIORITY_HIGH+1, 0, NULL, 1024);
} else {
os_printf("isp open err");
goto end;
}
} else {
os_printf("sensor param init err!\r\n");
}
end:
sensor_info_destory();
}
void isp_dev_close()
{
struct isp_device *isp_dev = (struct isp_device *)dev_get(HG_ISP_DEVID);
if (isp_dev == NULL)
{
os_printf("get isp device err\r\n");
return;
}
isp_close(isp_dev);
os_task_destroy(isp_task_hdl);
os_event_del((void *)&isp_event);
os_msgq_del((void *)&isp_msg);
}

View File

@@ -0,0 +1,113 @@
#include "sys_config.h"
#include "typesdef.h"
#include "hal/isp_param.h"
const uint32 gamma2p4_tbl[] = {
0x08715C00,0x0C62A887,0x0F537CC6,0x11C424F5,0x13D4B51C,0x15A5313D,0x1755A15A,0x18E60575,
0x1A46658E,0x1BA6BDA4,0x1CE711BA,0x1E1761CE,0x1F37A9E1,0x2057F1F3,0x21583605,0x22587615,
0x2358B625,0x2448F235,0x25292E44,0x26096652,0x26E99E60,0x27B9D66E,0x288A0A7B,0x295A3E88,
0x2A1A6E95,0x2ADA9EA1,0x2B9ACEAD,0x2C5AFEB9,0x2D0B2AC5,0x2DBB56D0,0x2E6B82DB,0x2F0BAEE6,
0x2FBBDAF0,0x305C02FB,0x30FC2B05,0x319C530F,0x323C7B19,0x32CCA323,0x336CC72C,0x33FCEB36,
0x348D133F,0x351D3748,0x35AD5B51,0x363D7F5A,0x36CD9F63,0x374DC36C,0x37DDE774,0x385E077D,
0x38DE2785,0x396E478D,0x39EE6B96,0x3A6E8B9E,0x3ADEABA6,0x3B5EC7AD,0x3BDEE7B5,0x3C5F07BD,
0x3CCF23C5,0x3D4F43CC,0x3DBF5FD4,0x3E2F7FDB,0x3EAF9BE2,0x3F1FB7EA,0x3F8FD3F1,0x3FFFEFF8
};
#if 0
const uint32 gamma2p2_tbl[] = {
0x09A1C400,0x0D42E89A,0x0FF3A8D4,0x122444FF,0x1414C922,0x15D53D41,0x1765A95D,0x18E60976,
0x1A36658E,0x1B86B9A3,0x1CB709B8,0x1DE755CB,0x1F079DDE,0x2017E1F0,0x21182601,0x22186611,
0x2308A221,0x23F8DE30,0x24D91A3F,0x25B9524D,0x26898A5B,0x2769BE68,0x2829F276,0x28FA2682,
0x29BA568F,0x2A7A869B,0x2B3AB6A7,0x2BFAE6B3,0x2CAB12BF,0x2D5B3ECA,0x2E0B6AD5,0x2EBB96E0,
0x2F5BC2EB,0x2FFBEAF5,0x30AC12FF,0x314C3F0A,0x31DC6714,0x327C8B1D,0x331CB327,0x33ACDB31,
0x344CFF3A,0x34DD2344,0x356D474D,0x35FD6B56,0x368D8F5F,0x370DB368,0x379DD770,0x382DF779,
0x38AE1B82,0x392E3B8A,0x39BE5F92,0x3A3E7F9B,0x3ABE9FA3,0x3B3EBFAB,0x3BBEDFB3,0x3C3EFFBB,
0x3CBF1FC3,0x3D2F3BCB,0x3DAF5BD2,0x3E1F7BDA,0x3E9F97E1,0x3F0FB7E9,0x3F8FD3F0,0x3FFFEFF8
};
#else
// BT 709 gamma 20/9=2.222...
const uint32 gamma2p2_tbl[] = {
0x04809000,0x0871A848,0x0B628087,0x0DD32CB6,0x1003BCDD,0x11E43D00,0x13A4B11E,0x15451D3A,
0x16C58154,0x1825DD6C,0x19863582,0x1AC68998,0x1BF6D9AC,0x1D2725BF,0x1E476DD2,0x1F57B5E4,
0x2067F9F5,0x21683A06,0x22687A16,0x2358B626,0x2448F235,0x25292E44,0x26096652,0x26E99E60,
0x27B9D26E,0x288A0A7B,0x295A3E88,0x2A2A6E95,0x2AEAA2A2,0x2BAAD2AE,0x2C6B02BA,0x2D2B32C6,
0x2DDB5ED2,0x2E8B8EDD,0x2F4BBAE8,0x2FFBE6F4,0x309C12FF,0x314C3F09,0x31EC6714,0x329C931E,
0x333CBB29,0x33DCE333,0x347D0B3D,0x351D3347,0x35AD5751,0x364D7F5A,0x36DDA364,0x376DCB6D,
0x380DEF76,0x389E1380,0x392E3789,0x39BE5B92,0x3A4E7F9B,0x3ACEA3A4,0x3B5EC7AC,0x3BDEE7B5,
0x3C6F0BBD,0x3CEF2BC6,0x3D7F4BCE,0x3DFF6FD7,0x3E7F8FDF,0x3EFFAFE7,0x3F7FCFEF,0x3FFFEFF7
};
#endif
const uint32 gamma1p8_tbl[] = {
0x06511400,0x0951FC65,0x0BB2A495,0x0DB330BB,0x0F83A8DB,0x113418F8,0x12B47D13,0x1424DD2B,
0x15853542,0x16D58D58,0x1815DD6D,0x19462981,0x1A667594,0x1B86BDA6,0x1C9701B8,0x1DA745C9,
0x1EA789DA,0x1FA7C9EA,0x209805FA,0x21884609,0x22787E18,0x2358BA27,0x2438F235,0x25192A43,
0x25F96251,0x26C99A5F,0x2799CE6C,0x286A0279,0x293A3686,0x2A0A6693,0x2ACA9AA0,0x2B8ACAAC,
0x2C4AFAB8,0x2D0B2AC4,0x2DCB5AD0,0x2E7B86DC,0x2F3BB6E7,0x2FEBE2F3,0x309C0EFE,0x314C3B09,
0x31FC6714,0x32AC931F,0x334CBF2A,0x33FCE734,0x349D133F,0x354D3B49,0x35ED6754,0x368D8F5E,
0x372DB768,0x37CDDF72,0x386E077C,0x390E2F86,0x399E5390,0x3A3E7B99,0x3ACEA3A3,0x3B6EC7AC,
0x3BFEEFB6,0x3C9F13BF,0x3D2F37C9,0x3DBF5BD2,0x3E4F83DB,0x3EDFA7E4,0x3F6FCBED,0x3FFFEFF6
};
// 预设的Gamma曲线和对应的BV值
const _Sensor_YGAMMA y_gamma_tbl[NUM_CURVES] = {
{
.bv = 3.4028235e+38,
.packed_lut = {
0x01002000, 0x02006010, 0x0300A020, 0x0400E030, 0x05012040, 0x06016050, 0x0701A060, 0x0801E070,
0x09022080, 0x0A026090, 0x0B02A0A0, 0x0C02E0B0, 0x0D0320C0, 0x0E0360D0, 0x0F03A0E0, 0x1003E0F0,
0x11042100, 0x12046110, 0x1304A120, 0x1404E130, 0x15052140, 0x16056150, 0x1705A160, 0x1805E170,
0x19062180, 0x1A066190, 0x1B06A1A0, 0x1C06E1B0, 0x1D0721C0, 0x1E0761D0, 0x1F07A1E0, 0x2007E1F0,
0x21082200, 0x22086210, 0x2308A220, 0x2408E230, 0x25092240, 0x26096250, 0x2709A260, 0x2809E270,
0x290A2280, 0x2A0A6290, 0x2B0AA2A0, 0x2C0AE2B0, 0x2D0B22C0, 0x2E0B62D0, 0x2F0BA2E0, 0x300BE2F0,
0x310C2300, 0x320C6310, 0x330CA320, 0x340CE330, 0x350D2340, 0x360D6350, 0x370DA360, 0x380DE370,
0x390E2380, 0x3A0E6390, 0x3B0EA3A0, 0x3C0EE3B0, 0x3D0F23C0, 0x3E0F63D0, 0x3F0FA3E0, 0x3FFFE3F0,}},
{
.bv = 500,
.packed_lut = {
0x01002000, 0x02006010, 0x0300A020, 0x0400E030, 0x05012040, 0x06016050, 0x0701A060, 0x0801E070,
0x09022080, 0x0A026090, 0x0B02A0A0, 0x0C02E0B0, 0x0D0320C0, 0x0E0360D0, 0x0F03A0E0, 0x1003E0F0,
0x11042100, 0x12046110, 0x1304A120, 0x1404E130, 0x15052140, 0x16056150, 0x1705A160, 0x1805E170,
0x19062180, 0x1A066190, 0x1B06A1A0, 0x1C06E1B0, 0x1D0721C0, 0x1E0761D0, 0x1F07A1E0, 0x2007E1F0,
0x21082200, 0x22086210, 0x2308A220, 0x2408E230, 0x25092240, 0x26096250, 0x2709A260, 0x2809E270,
0x290A2280, 0x2A0A6290, 0x2B0AA2A0, 0x2C0AE2B0, 0x2D0B22C0, 0x2E0B62D0, 0x2F0BA2E0, 0x300BE2F0,
0x310C2300, 0x320C6310, 0x330CA320, 0x340CE330, 0x350D2340, 0x360D6350, 0x370DA360, 0x380DE370,
0x390E2380, 0x3A0E6390, 0x3B0EA3A0, 0x3C0EE3B0, 0x3D0F23C0, 0x3E0F63D0, 0x3F0FA3E0, 0x3FFFE3F0,}},
{
.bv = 1000,
.packed_lut = {
0x01002000, 0x02006010, 0x0300A020, 0x0400E030, 0x05012040, 0x06016050, 0x0701A060, 0x0801E070,
0x09022080, 0x0A026090, 0x0B02A0A0, 0x0C02E0B0, 0x0D0320C0, 0x0E0360D0, 0x0F03A0E0, 0x1003E0F0,
0x11042100, 0x12046110, 0x1304A120, 0x1404E130, 0x15052140, 0x16056150, 0x1705A160, 0x1805E170,
0x19062180, 0x1A066190, 0x1B06A1A0, 0x1C06E1B0, 0x1D0721C0, 0x1E0761D0, 0x1F07A1E0, 0x2007E1F0,
0x21082200, 0x22086210, 0x2308A220, 0x2408E230, 0x25092240, 0x26096250, 0x2709A260, 0x2809E270,
0x290A2280, 0x2A0A6290, 0x2B0AA2A0, 0x2C0AE2B0, 0x2D0B22C0, 0x2E0B62D0, 0x2F0BA2E0, 0x300BE2F0,
0x310C2300, 0x320C6310, 0x330CA320, 0x340CE330, 0x350D2340, 0x360D6350, 0x370DA360, 0x380DE370,
0x390E2380, 0x3A0E6390, 0x3B0EA3A0, 0x3C0EE3B0, 0x3D0F23C0, 0x3E0F63D0, 0x3F0FA3E0, 0x3FFFE3F0,}},
{
.bv = 1500,
.packed_lut = {
0x01002000, 0x02006010, 0x0300A020, 0x0400E030, 0x05012040, 0x06016050, 0x0701A060, 0x0801E070,
0x09022080, 0x0A026090, 0x0B02A0A0, 0x0C02E0B0, 0x0D0320C0, 0x0E0360D0, 0x0F03A0E0, 0x1003E0F0,
0x11042100, 0x12046110, 0x1304A120, 0x1404E130, 0x15052140, 0x16056150, 0x1705A160, 0x1805E170,
0x19062180, 0x1A066190, 0x1B06A1A0, 0x1C06E1B0, 0x1D0721C0, 0x1E0761D0, 0x1F07A1E0, 0x2007E1F0,
0x21082200, 0x22086210, 0x2308A220, 0x2408E230, 0x25092240, 0x26096250, 0x2709A260, 0x2809E270,
0x290A2280, 0x2A0A6290, 0x2B0AA2A0, 0x2C0AE2B0, 0x2D0B22C0, 0x2E0B62D0, 0x2F0BA2E0, 0x300BE2F0,
0x310C2300, 0x320C6310, 0x330CA320, 0x340CE330, 0x350D2340, 0x360D6350, 0x370DA360, 0x380DE370,
0x390E2380, 0x3A0E6390, 0x3B0EA3A0, 0x3C0EE3B0, 0x3D0F23C0, 0x3E0F63D0, 0x3F0FA3E0, 0x3FFFE3F0, }},
{// 线性曲线BV=500
.bv = 2000,
.packed_lut = {
0x01002000, 0x02006010, 0x0300A020, 0x0400E030, 0x05012040, 0x06016050, 0x0701A060, 0x0801E070,
0x09022080, 0x0A026090, 0x0B02A0A0, 0x0C02E0B0, 0x0D0320C0, 0x0E0360D0, 0x0F03A0E0, 0x1003E0F0,
0x11042100, 0x12046110, 0x1304A120, 0x1404E130, 0x15052140, 0x16056150, 0x1705A160, 0x1805E170,
0x19062180, 0x1A066190, 0x1B06A1A0, 0x1C06E1B0, 0x1D0721C0, 0x1E0761D0, 0x1F07A1E0, 0x2007E1F0,
0x21082200, 0x22086210, 0x2308A220, 0x2408E230, 0x25092240, 0x26096250, 0x2709A260, 0x2809E270,
0x290A2280, 0x2A0A6290, 0x2B0AA2A0, 0x2C0AE2B0, 0x2D0B22C0, 0x2E0B62D0, 0x2F0BA2E0, 0x300BE2F0,
0x310C2300, 0x320C6310, 0x330CA320, 0x340CE330, 0x350D2340, 0x360D6350, 0x370DA360, 0x380DE370,
0x390E2380, 0x3A0E6390, 0x3B0EA3A0, 0x3C0EE3B0, 0x3D0F23C0, 0x3E0F63D0, 0x3F0FA3E0, 0x3FFFE3F0,}}
};
uint32 gamma_table_addr[3] = {(uint32)gamma1p8_tbl, (uint32)gamma2p2_tbl, (uint32)gamma2p4_tbl};

View File

@@ -0,0 +1,75 @@
#include "sys_config.h"
#include "typesdef.h"
//luma_ca mode0
const uint32 luma_ca_lut_mode0[] = {0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0300,0x0500,0x0600,0x0900,0x0B00,0x0E00,0x1100,0x1400,0x1700,0x1A00,
0x1E00,0x2200,0x2600,0x2A00,0x2E00,0x3300,0x3700,0x3B00,0x4000,0x4500,0x4900,0x4E00,0x5200,0x5700,0x5B00,0x5F00,
0x6300,0x6700,0x6B00,0x6F00,0x7200,0x7500,0x7800,0x7B00,0x7D00,0x7F00,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8000,0x8000,0x8000,0x8000,0x7E00,0x7B00,0x7700,0x7200,0x6D00,0x6700,0x6100,0x5B00,0x5400,0x4E00,0x4700,0x4000,
0x3900,0x3300,0x2C00,0x2600,0x2000,0x1A00,0x1500,0x1100,0x0C00,0x0900,0x0500,0x0300,0x0100,0x0000,0x0000,0x0000};
//luma_ca_mode1
//color_pattern == 0, Iron
const uint32 luma_ca_lut_iron[] = {0x11867F,0x138D7E,0x14927D,0x15957D,0x15987C,0x169B7C,0x179E7B,0x17A17B,0x18A47A,0x19A67A,0x19A77A,0x1AA97B,0x1BAA7B,0x1BAC7B,0x1CAD7C,0x1DAF7C,
0x1EB07C,0x1EB17D,0x1FB27D,0x20B27E,0x20B27F,0x22B380,0x22B482,0x23B483,0x25B584,0x25B685,0x27B587,0x28B688,0x29B689,0x2AB68B,0x2BB78C,0x2CB68E,
0x2CB78E,0x2DB790,0x2EB791,0x2FB892,0x30B893,0x30B894,0x31B795,0x32B796,0x33B797,0x33B698,0x34B69A,0x35B69B,0x36B69D,0x37B69D,0x37B69F,0x39B5A0,
0x39B5A1,0x3AB5A3,0x3BB5A4,0x3CB4A5,0x3CB4A6,0x3DB4A7,0x3EB3A9,0x3EB3AA,0x3FB3AB,0x40B2AD,0x41B2AE,0x41B1AF,0x42B1B0,0x43B1B1,0x43B0B2,0x44AFB4,
0x45AFB5,0x46AEB6,0x46AEB8,0x47ADB9,0x47ADB9,0x48ADBB,0x49ACBC,0x49ACBD,0x4AABBE,0x4AABBF,0x4AAABF,0x4BAAC0,0x4CA9C1,0x4DA8C2,0x4DA8C2,0x4DA8C3,
0x4EA7C4,0x4EA6C4,0x4FA5C5,0x50A5C5,0x50A5C6,0x51A3C6,0x51A3C7,0x52A2C7,0x52A2C7,0x53A1C7,0x54A0C7,0x559FC7,0x569EC7,0x569DC8,0x579CC8,0x589AC8,
0x5999C8,0x5A98C9,0x5B97C9,0x5C95C9,0x5D94C8,0x5D92C9,0x5E90C9,0x5F8EC9,0x5F8DC9,0x608BC9,0x6189C9,0x6288C9,0x6385C9,0x6483C9,0x6481C9,0x657FC9,
0x677CC9,0x687BC9,0x6878C9,0x6975CA,0x6A72CA,0x6A6FCA,0x6A6CCA,0x6B69CA,0x6B66CA,0x6C63CA,0x6C60CA,0x6D5DCB,0x6D5ACB,0x6F57CA,0x6F56CA,0x7055C9,
0x7152CA,0x7251C9,0x734FC9,0x734EC9,0x744DC9,0x754CC9,0x764BC9,0x774AC8,0x7749C8,0x7948C7,0x7A47C7,0x7A46C7,0x7B45C6,0x7C44C6,0x7C44C6,0x7E43C6,
0x7F42C5,0x8041C5,0x8041C4,0x8240C4,0x8240C4,0x833FC3,0x843EC3,0x843EC2,0x853DC2,0x863DC2,0x873CC1,0x883BC1,0x893AC1,0x8A3AC0,0x8B39BF,0x8C39BF,
0x8D38BE,0x8E37BE,0x8F37BD,0x9036BD,0x9135BC,0x9235BC,0x9334BB,0x9434BB,0x9533BB,0x9533BA,0x9633B9,0x9732BA,0x9832B9,0x9931B8,0x9A31B8,0x9A30B7,
0x9B30B7,0x9D2FB7,0x9E2EB6,0x9F2DB5,0xA12CB4,0xA22CB3,0xA32BB4,0xA42BB3,0xA52AB2,0xA629B1,0xA729B0,0xA828AF,0xA928AF,0xAA27AF,0xAB27AE,0xAB26AE,
0xAC26AD,0xAE25AC,0xAE25AC,0xAF24AB,0xB024AA,0xB123AA,0xB222A9,0xB322A8,0xB421A7,0xB521A7,0xB620A6,0xB720A6,0xB720A5,0xB820A5,0xB920A4,0xB920A4,
0xBA20A3,0xBB20A2,0xBD21A1,0xBE21A1,0xBF21A0,0xC0219F,0xC1219F,0xC1229E,0xC2239E,0xC3249D,0xC4259C,0xC6279B,0xC6289B,0xC7299A,0xC92A99,0xCA2D98,
0xCB2F98,0xCC3197,0xCD3396,0xCE3595,0xCF3894,0xD13A93,0xD23C92,0xD33F92,0xD44191,0xD54490,0xD6478F,0xD74A8F,0xD84D8E,0xD9518D,0xDB538C,0xDB568B,
0xDD598B,0xDD5C8A,0xDE5F89,0xE06188,0xE16488,0xE16687,0xE26987,0xE36A86,0xE46D85,0xE56F84,0xE67284,0xE77483,0xE87682,0xE97882,0xE97A81,0xEA7C81};
//color_pattern == 1, Glowbow
const uint32 luma_ca_lut_glowbow[] = {0x118081,0x127F82,0x137F84,0x147F84,0x157F86,0x167E87,0x177E89,0x187E89,0x197D8B,0x1B7D8C,0x1B7D8D,0x1C7C8E,0x1E7C8F,0x1F7C91,0x1F7C92,0x207B93,
0x227B95,0x237A96,0x247A97,0x257A98,0x267A99,0x27799A,0x28799C,0x29799D,0x2A789E,0x2B78A0,0x2C78A1,0x2E77A3,0x3076A5,0x3176A7,0x3376A8,0x3476AA,
0x3575AB,0x3675AB,0x3775AD,0x3874AE,0x3974AF,0x3B73B1,0x3B73B2,0x3C73B4,0x3D73B4,0x3E72B6,0x3F72B7,0x4072B8,0x4272B9,0x4271BA,0x4471BB,0x4570BD,
0x4570BE,0x4670BF,0x4870C1,0x4970C2,0x4A6FC4,0x4B6FC4,0x4C6EC5,0x4D6EC7,0x4E6EC8,0x4F6EC9,0x506DCA,0x516DCB,0x526DCD,0x546CCE,0x546CCF,0x556BCF,
0x566ACF,0x566ACF,0x5769CE,0x5868CF,0x5868CF,0x5967CF,0x5A66CF,0x5A66CF,0x5B65CF,0x5C64CE,0x5D63CF,0x5D63CF,0x5E62CF,0x5E62CF,0x5F61CE,0x5F60CF,
0x615FCE,0x615ECF,0x625ECF,0x635DCF,0x635DCF,0x645CCF,0x655BCF,0x655ACE,0x665ACE,0x6659CF,0x6759CF,0x6858CF,0x6857CE,0x6956CE,0x6A56CE,0x6B55CE,
0x6C54CF,0x6C54CE,0x6D53CE,0x6E52CE,0x6E52CE,0x6F51CE,0x6F50CE,0x714FCE,0x714FCF,0x714ECE,0x724DCE,0x734DCE,0x734CCF,0x744BCE,0x754BCE,0x764ACE,
0x7649CE,0x7649CE,0x7749CE,0x7847CF,0x7946CE,0x7A46CE,0x7A45CE,0x7B44CE,0x7B44CE,0x7C44CE,0x7D43CE,0x7D42CE,0x7E41CE,0x7F40CE,0x7F40CF,0x803FCE,
0x813FCD,0x823ECC,0x833DCC,0x843DCB,0x853CCA,0x863CC9,0x873BC9,0x883AC8,0x893AC8,0x8A39C6,0x8B39C6,0x8C38C5,0x8D38C5,0x8E37C4,0x8F37C3,0x9036C2,
0x9235C1,0x9335C1,0x9334C0,0x9434BF,0x9533BF,0x9633BE,0x9732BD,0x9831BD,0x9931BC,0x9A31BB,0x9B30BA,0x9C2FBA,0x9D2FB9,0x9E2EB8,0x9F2DB7,0xA02DB7,
0xA12DB6,0xA22CB6,0xA32BB5,0xA42BB4,0xA52AB3,0xA62AB3,0xA729B2,0xA828B1,0xA928B0,0xAA27B0,0xAB27AF,0xAC26AE,0xAC26AE,0xAD25AD,0xAF24AC,0xB024AB,
0xB123AA,0xB223AA,0xB222A9,0xB322A9,0xB521A8,0xB521A7,0xB620A6,0xB71FA6,0xB81FA5,0xB91EA4,0xBA1EA4,0xBC1DA2,0xBC1DA2,0xBD1CA1,0xBE1BA1,0xBF1BA0,
0xC01CA0,0xC11E9F,0xC11F9F,0xC2219E,0xC3229D,0xC4249D,0xC4259C,0xC5279C,0xC5299B,0xC62A9B,0xC72C9B,0xC82D9A,0xC82F9A,0xC93199,0xCA3298,0xCB3498,
0xCB3597,0xCB3797,0xCC3896,0xCD3A96,0xCD3B96,0xCE3D95,0xCF3F95,0xD04094,0xD14193,0xD14393,0xD14593,0xD24792,0xD34892,0xD44A91,0xD44B90,0xD54D90,
0xD64E90,0xD7508F,0xD7518F,0xD8538E,0xD8548E,0xD9568D,0xDA588D,0xDA598D,0xDB5B8C,0xDC5C8B,0xDD5E8B,0xDD5F8A,0xDE618A,0xDE6389,0xDF6489,0xDF6688,
0xE06788,0xE16988,0xE26A87,0xE36C86,0xE36E85,0xE46F85,0xE47185,0xE57284,0xE67484,0xE67683,0xE77783,0xE87982,0xE97A82,0xE97B81,0xEA7E81,0xEB7F80};
//color_pattern == 2, Rainbow
const uint32 luma_ca_lut_rainbow[] = {0x1C9D78,0x1B9E78,0x1B9E78,0x1B9E78,0x1B9E78,0x1B9F78,0x1CA077,0x1DA177,0x1DA377,0x1EA476,0x20A474,0x22A473,0x24A471,0x26A470,0x28A56E,0x2AA66D,
0x2BA76C,0x2EA76A,0x30A869,0x32A967,0x34AA66,0x34AB65,0x36AC65,0x36AC64,0x37AD64,0x38AE63,0x39AE62,0x3AAE62,0x3AAF61,0x3BAF61,0x3CB060,0x3EB15F,
0x3FB25E,0x40B25D,0x42B35C,0x42B45B,0x43B65B,0x44B75A,0x46B859,0x47B858,0x48B957,0x49BA56,0x4ABB56,0x4BBB55,0x4CBC54,0x4EBB53,0x4EBC53,0x50BC51,
0x51BC50,0x52BE50,0x53BE4F,0x54BE4E,0x54C04E,0x55C04E,0x56C04E,0x57C04D,0x58C04C,0x59C04B,0x59C04B,0x5AC04A,0x5BBF49,0x5CBF48,0x5DBF48,0x5EBE47,
0x5FBE47,0x5FBD47,0x60BC46,0x61BA46,0x62B944,0x62B844,0x64B643,0x64B543,0x65B242,0x66AF41,0x67AC41,0x67AA41,0x67A740,0x68A541,0x68A241,0x689F42,
0x699A42,0x699743,0x699444,0x6B9145,0x6B8E45,0x6B8B46,0x6C8748,0x6D8249,0x6F7C4B,0x70784D,0x727450,0x736F52,0x756A54,0x776557,0x796059,0x7C5C5C,
0x7E585E,0x815560,0x825261,0x854D63,0x864A65,0x884768,0x8A4469,0x8C416B,0x8D406C,0x8E3E6D,0x903D6E,0x923B70,0x953872,0x963674,0x983575,0x9A3377,
0x9B3179,0x9D2F7A,0x9F2E7C,0x9F2D7D,0xA12C7F,0xA22C80,0xA42B81,0xA62A83,0xA72985,0xA82886,0xAA2787,0xAB2788,0xAD2689,0xAE258A,0xAF248B,0xB0248C,
0xB1248E,0xB22390,0xB22391,0xB32293,0xB42294,0xB42195,0xB52196,0xB52197,0xB52298,0xB52298,0xB52298,0xB52298,0xB5239A,0xB5239A,0xB5249B,0xB4249C,
0xB4259E,0xB2269F,0xB327A0,0xB226A0,0xB227A0,0xB127A1,0xB028A2,0xB028A4,0xB029A4,0xAF29A5,0xAF29A7,0xAD2BA8,0xAB2DA9,0xAB2EAA,0xA92FAB,0xA831AC,
0xA632AD,0xA432AE,0xA332AF,0xA234B0,0xA234B1,0xA135B2,0x9F36B3,0x9E38B4,0x9C39B5,0x9B3AB6,0x983CB7,0x963FB9,0x9441BA,0x9244BD,0x8F46BF,0x8D46C0,
0x8948C3,0x864AC5,0x844CC5,0x824EC7,0x8051CA,0x7E54CC,0x7B57CE,0x7859CF,0x755CD1,0x725ED2,0x7060D5,0x6E62D7,0x6B64D9,0x6966DA,0x6868DB,0x6768DB,
0x6868DB,0x6768DB,0x6769DB,0x6869DA,0x696ADB,0x696BDB,0x696CDA,0x6A6DDB,0x6A6DDB,0x696EDA,0x696FD9,0x696FD9,0x6871D7,0x6872D7,0x6873D6,0x6974D6,
0x6975D6,0x6976D5,0x6A77D6,0x6C76D5,0x6E76D5,0x7275D4,0x7474D2,0x7873CF,0x7C72CD,0x7F71CA,0x8270C8,0x846FC6,0x876EC4,0x8A6DC2,0x8B6DC1,0x8D6DC0,
0x8F6DBE,0x926EBD,0x946EBC,0x966DB9,0x996DB7,0x9B6EB5,0x9E6EB3,0xA16EB1,0xA46DAF,0xA66DAD,0xAA6CAB,0xAD6BA9,0xB06CA6,0xB36CA4,0xB56BA2,0xB86BA0,
0xBB6B9E,0xBC6C9D,0xBF6D9B,0xC16C9A,0xC36C98,0xC66C97,0xC86C95,0xCB6D93,0xCD6F91,0xCF7190,0xD0728F,0xD3738E,0xD4738D,0xD6728B,0xD7738A,0xD9728A};
uint32 luma_ca_addr[] = {(uint32)luma_ca_lut_mode0, (uint32)luma_ca_lut_iron, (uint32)luma_ca_lut_glowbow, (uint32)luma_ca_lut_rainbow};

View File

@@ -0,0 +1,295 @@
#include "sys_config.h"
#include "typesdef.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 "hal/isp.h"
#include "hal/i2c.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 "hal/gpio.h"
#include "lib/video/isp/isp_ircut.h"
#ifdef PIN_FROM_PARAM
#include "pin_param.h"
#endif
#include "syscfg.h"
IRCUT_INFO ircut_info;
void irled_control(uint8 led_state)
{
gpio_set_val(MACRO_PIN(PIN_IRCUT_LED), led_state);
}
void whiteled_control(uint8 led_state)
{
gpio_set_val(MACRO_PIN(PIN_WHITE_LED), led_state);
}
void ircut_control(IRCUT_INFO *info)
{
switch (info->ircut_opt_status)
{
case IRCUT_OPT_STATE_ON:
if (info->ircut_status == IRCUT_OFF)
{
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN1), 1);
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN2), 0);
info->ircut_opt_status = IRCUT_OPT_STATE_SW_OFF;
}
break;
case IRCUT_OPT_STATE_OFF:
if (info->ircut_status == IRCUT_ON)
{
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN1), 0);
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN2), 1);
info->ircut_opt_status = IRCUT_OPT_STATE_SW_ON;
}
break;
case IRCUT_OPT_STATE_IDLE:
if (info->ircut_status == IRCUT_ON)
{
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN1), 0);
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN2), 1);
info->ircut_opt_status = IRCUT_OPT_STATE_SW_ON;
} else if (info->ircut_status == IRCUT_OFF) {
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN1), 1);
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN2), 0);
info->ircut_opt_status = IRCUT_OPT_STATE_SW_ON;
}
break;
case IRCUT_OPT_STATE_SW_ON:
if (++info->frame_cnt >= info->frame_to_switch)
{
info->frame_cnt = 0;
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN1), 0);
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN2), 0);
info->ircut_opt_status = IRCUT_OPT_STATE_ON;
info->action_status = IRCUT_ACTION_STOP;
}
break;
case IRCUT_OPT_STATE_SW_OFF:
if (++info->frame_cnt >= info->frame_to_switch)
{
info->frame_cnt = 0;
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN1), 0);
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN2), 0);
info->ircut_opt_status = IRCUT_OPT_STATE_OFF;
info->action_status = IRCUT_ACTION_STOP;
}
break;
default:
info->ircut_opt_status = IRCUT_OPT_STATE_OFF;
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN1), 0);
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN2), 0);
break;
}
}
void ircut_action(struct os_work *work)
{
switch (ircut_info.irled_detect_mode)
{
case IRCUT_DET_MODE_HW:
if (ircut_info.irdet_gpio_en)
{
ircut_info.irdet_status = gpio_get_val(MACRO_PIN(PIN_IRCUT_DETECT));
if (ircut_info.irdet_status && (ircut_info.irled_status == IRLED_OFF)) {
if (++ircut_info.switch_cnt >= ircut_info.switch_max)
{
ircut_info.switch_cnt = 0;
ircut_info.whiteled_status = WHITELED_ON;
ircut_info.irled_status = IRLED_ON;
ircut_info.ircut_status = IRCUT_OFF;
ircut_info.action_status = IRCUT_ACTION_START;
isp_black_white_enable(ircut_info.dev, ircut_info.irled_status, SENSOR_TYPE_MASTER);
}
} else if (!ircut_info.irdet_status && (ircut_info.irled_status == IRLED_ON)) {
if (++ircut_info.switch_cnt >= ircut_info.switch_max)
{
ircut_info.switch_cnt = 0;
ircut_info.whiteled_status = WHITELED_OFF;
ircut_info.irled_status = IRLED_OFF;
ircut_info.ircut_status = IRCUT_ON;
ircut_info.action_status = IRCUT_ACTION_START;
isp_black_white_enable(ircut_info.dev, ircut_info.irled_status, SENSOR_TYPE_MASTER);
}
} else {
ircut_info.switch_cnt = 0;
}
}
break;
case IRCUT_DET_MODE_SW:
{
ISP_IRCUT_STAT isp_stat;
isp_get_isp_ircut_statistics(ircut_info.dev,&isp_stat,SENSOR_TYPE_MASTER);
// os_printf("r_mean=%d g_mean=%d b_mean=%d \r\n",isp_stat.r_mean,isp_stat.g_mean,isp_stat.b_mean);
//
// os_printf("sat=%d bv=%f \r\n",isp_stat.saturation,isp_stat.curr_bv);
switch (ircut_info.sw_state)
{
//Status 1: from day to night
case IRCUT_STAT_DAY_TO_NIGHT:
{
if (isp_stat.curr_bv < ircut_info.to_night_bv){
ircut_info.switch_cnt++;
if (ircut_info.switch_cnt >= ircut_info.switch_max ){
ircut_info.switch_cnt = 0;
ircut_info.whiteled_status = WHITELED_ON;
ircut_info.irled_status = IRLED_ON;
ircut_info.ircut_status = IRCUT_OFF;
ircut_info.action_status = IRCUT_ACTION_START;
isp_black_white_enable(ircut_info.dev, ircut_info.irled_status, SENSOR_TYPE_MASTER);
isp_awb_measure_mode_config(ircut_info.dev, AWB_MEAS_MODE_RGB, SENSOR_TYPE_MASTER);
ircut_info.sw_state = IRCUT_STAT_WB_REC;
}
}else{
ircut_info.switch_cnt = 0;
}
break;
}
// State 2: Save stable white balance statistics
case IRCUT_STAT_WB_REC:
{
ircut_info.switch_cnt++;
if (ircut_info.switch_cnt >= 20){//after one second
ircut_info.switch_cnt = 0;
//os_printf("REC r_gain=%d b_gain=%d \r\n",isp_stat.r_gain,isp_stat.b_gain);
ircut_info.last_r_gain = isp_stat.r_gain;
ircut_info.last_b_gain = isp_stat.b_gain;
ircut_info.sw_state = IRCUT_STAT_NIGHT_TO_DAY;
}
break;
}
//Status 3: from night to day
case IRCUT_STAT_NIGHT_TO_DAY:
{
uint16 diff_r_gain = IR_ABS(isp_stat.r_gain - ircut_info.last_r_gain);
uint16 diff_b_gain = IR_ABS(isp_stat.b_gain - ircut_info.last_b_gain);
//os_printf("diff_r_gain=%d diff_b_gain=%d \r\n",diff_r_gain,diff_b_gain);
if (((isp_stat.curr_bv > ircut_info.to_day_bv) &&(isp_stat.saturation > ircut_info.to_day_sat)
&& ((diff_r_gain + diff_b_gain) > ircut_info.to_day_diff_rb_gain || diff_b_gain > ircut_info.to_day_diff_b_gain))
|| ((isp_stat.saturation > ircut_info.to_day_sat) && (isp_stat.curr_bv > ircut_info.to_day_bv_max))){
ircut_info.switch_cnt++;
if (ircut_info.switch_cnt >= ircut_info.switch_max)
{
ircut_info.switch_cnt = 0;
ircut_info.whiteled_status = WHITELED_OFF;
ircut_info.irled_status = IRLED_OFF;
ircut_info.ircut_status = IRCUT_ON;
ircut_info.action_status = IRCUT_ACTION_START;
isp_black_white_enable(ircut_info.dev, ircut_info.irled_status, SENSOR_TYPE_MASTER);
isp_awb_measure_mode_config(ircut_info.dev, AWB_MEAS_MODE_YUV_NEW, SENSOR_TYPE_MASTER);
ircut_info.sw_state = IRCUT_STAT_DAY_TO_NIGHT;
}
}else{
ircut_info.switch_cnt = 0;
}
break;
}
}
break;
}
case IRCUT_DET_MODE_MANUAL:
ircut_info.action_status = IRCUT_ACTION_STOP;
break;
default :
os_printf(KERN_ERR"ircut detect mode : %d err", ircut_info.irled_detect_mode);
}
if (ircut_info.action_status)
{
if (ircut_info.ircut_gpio_en) ircut_control(&ircut_info);
if (ircut_info.irled_gpio_en) irled_control(ircut_info.irled_status);
//if (ircut_info.whiteled_gpio_en) whiteled_control(ircut_info.whiteled_status);
}
os_run_work_delay(&ircut_info.ircut_action_work, 50);
}
void ircut_init()
{
os_memset(&ircut_info, 0, sizeof(IRCUT_INFO));
ircut_info.dev = (struct isp_device *)dev_get(HG_ISP_DEVID);
if (ircut_info.dev == NULL)
{
os_printf(KERN_ERR"ircut get isp device err!\r\n");
return;
}
ircut_info.frame_cnt = 0;
ircut_info.frame_to_switch = 3;
ircut_info.switch_cnt = 0;
ircut_info.switch_max = 30;
ircut_info.to_day_bv = 8000;
ircut_info.to_night_bv = 3500;
ircut_info.to_day_sat = 30;
ircut_info.to_day_bv_max = 10000;
ircut_info.to_day_diff_rb_gain = 45;
ircut_info.to_day_diff_b_gain = 30;
ircut_info.ircut_opt_status = IRCUT_OPT_STATE_IDLE;
ircut_info.ircut_status = IRCUT_ON;
ircut_info.irled_status = IRLED_OFF;
ircut_info.irdet_status = IRDET_OFF;
ircut_info.whiteled_status = WHITELED_OFF;
ircut_info.action_status = IRCUT_ACTION_START;
ircut_info.irled_detect_mode = IRCUT_DET_MODE_MANUAL;
if (MACRO_PIN(PIN_IRCUT_DETECT) != 255)
{
gpio_set_dir(MACRO_PIN(PIN_IRCUT_DETECT), GPIO_DIR_INPUT);
ircut_info.irled_detect_mode = IRCUT_DET_MODE_HW;
ircut_info.irdet_gpio_en = 1;
} else {
ircut_info.irdet_gpio_en = 0;
}
if (MACRO_PIN(PIN_IRCUT_LED) != 255)
{
gpio_iomap_output(MACRO_PIN(PIN_IRCUT_LED), GPIO_IOMAP_OUTPUT);
irled_control(ircut_info.irled_status);
ircut_info.irled_gpio_en = 1;
}
if (MACRO_PIN(PIN_WHITE_LED) != 255)
{
gpio_iomap_output(MACRO_PIN(PIN_WHITE_LED), GPIO_IOMAP_OUTPUT);
whiteled_control(ircut_info.whiteled_status);
ircut_info.whiteled_gpio_en = 1;
}
if ((MACRO_PIN(PIN_IRCUT_IN1) != 255) && (MACRO_PIN(PIN_IRCUT_IN2) != 255))
{
gpio_iomap_output(MACRO_PIN(PIN_IRCUT_IN1), GPIO_IOMAP_OUTPUT);
gpio_iomap_output(MACRO_PIN(PIN_IRCUT_IN2), GPIO_IOMAP_OUTPUT);
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN1), 1);
gpio_set_val(MACRO_PIN(PIN_IRCUT_IN2), 0);
ircut_info.ircut_en = 1;
ircut_info.ircut_gpio_en = 1;
} else {
ircut_info.ircut_en = 0;
ircut_info.ircut_gpio_en = 0;
}
if (ircut_info.ircut_en)
{
OS_WORK_INIT(&ircut_info.ircut_action_work, (void *)ircut_action, 0);
os_run_work_delay(&ircut_info.ircut_action_work, 50);
}
}

View File

@@ -0,0 +1,524 @@
#include "sys_config.h"
#include "typesdef.h"
#include "osal/string.h"
#include "hal/isp_param.h"
#define ISP_DMA_ENABLE 1
const struct hgisp_param_info isp_master_param =
{
.enable_param = {
.test_pattern_en = 0,
.dma_flush_en = ISP_DMA_ENABLE,
.blc_en = 1,
.awb_en = 1,
.ae_en = 1,
.hist_en = 1,
.ccm_en = 1,
.y_gamma_en = 1,
.rgb_gamma_en = 1,
.ce_en = 1,
.sharpen_en = 1,
.bnr_en = 1,
.ynr_en = 1,
.cnr_en = 1,
.csupp_en = 1,
.adj_hue_en = 1,
.lsc_en = 1,
.dpc_en = 1,
.af_en = 0,
.dehaze_en = 0,
.gic_en = 0,
.md_en = 0,
.luma_ca_en = 0,
},
.awb_param = {
.coarse_scale = 128,
.coarse_thr = 3 << 2,
.fine_step = 1 << 2,
.lock_hi_thr = 4,
.lock_lo_thr = 0,
.stable_thr = 16,
.cbcr_thr = 3 << 2,
.awb_auto_en = 1,
.awb_meas_mode = 2,
.cr_target = 2048,
.cb_target = 2048,
.front_cr_val = 30,
.front_cb_val = 30,
.front_uv_sum = 15,
.back_cr_val = 30,
.back_cb_val = 30,
.back_uv_sum = 10,
.cons_cr_max = 40,
.cons_cb_max = 40,
.cons_uv_max = 30,
.cons_cr_min = 10,
.cons_cb_min = 10,
.cons_uv_min = 2,
.back_cr_max = 30,
.back_cb_max = 30,
.back_uv_max = 10,
.back_cr_min = 5,
.back_cb_min = 5,
.back_uv_min = 5,
.awb_wp_max = 0xc0,
.awb_wp_min = 32,
.awb_r_max = 0xc0,
.awb_g_max = 0xc0,
.awb_b_max = 0xc0,
.awb_precision = 1,
.awb_fine_cons_en = 0,
.awb_coarse_cons_en = 0,
.awb_back_cons_en = 1,
.awb_back_wp_min_ratio = 0.2,
.manual_gain = {256, 256, 256, 256},
.awb_crop_pixel_start_h = 0,
.awb_crop_pixel_start_v = 0,
.awb_crop_pixel_end_h = 0,
.awb_crop_pixel_end_v = 0,
},
.cfg_ae = {
.ae_manual_en = 0,
.luma_target = 55,
.luma_weight_sum = 61,
.luma_weight = { 2, 2, 2, 2, 2,
2, 3, 3, 3, 2,
2, 3, 5, 3, 2,
2, 3, 3, 3, 2,
2, 2, 2, 2, 2},
.ae_crop_start_h = 0,
.ae_crop_start_v = 0,
.ae_crop_size_h = 0,
.ae_crop_size_v = 0,
.hist_crop_start_h = 1,
.hist_crop_start_v = 1,
.hist_crop_end_h = 0,
.hist_crop_end_v = 0,
.ae_lock_cnt = 10,
.ae_lock_tolerance = 12,
.exposure_alpha = 16,
.reduce_fps_en = 0,
.lowlight_lsb_gain_en = 0,
.lowlight_lsb_gain_4hi_fps = 16,
.lowlight_lsb_gain_4lo_fps = 16,
.hist_hs_bin_thr = 180,
.hist_upper_hs_pixel_ratio = 0.94,
.hist_upper_pixel_ratio = 0.88,
.hist_lower_pixel_ratio = 0.00,
.abl_bv_gain_sel = 1,
.abl_expo_line_low_ratio = 0,
.abl_expo_line_high_ratio = 0,
.abl_expo_gain_low_thr = 0,
.abl_expo_gain_high_thr = 0,
.aoe_expo_gain_thr[0] = 65535,
.aoe_expo_gain_thr[1] = 65535,
.abl_bv_thr[0] = 1e20,
.abl_bv_thr[1] = 1e20,
.aoe_bv_thr[0] = 0,
.aoe_bv_thr[1] = 0,
.abl_hist_thr[0] = 50, // hist
.abl_hist_thr[1] = 236,
.dark_pixel_low_ratio = 0.60,
.dark_pixel_high_ratio = 0.90,
.bright_pixel_high_ratio = 0.15,
.bright_pixel_sub_ratio = 0.05,
.dark_pos_thr_max = 50, // position
.bright_pos_adjust_ratio = 0.90,
.abl_dark_pos_low_wthr = 0.40 * 61,
.abl_dark_pos_add_wthr = 0.10 * 61,
.aoe_dark_pos_wthr = 0.60 * 61,
.aoe_bright_pos_wthr = 0.20 * 61,
.abl_luma_target_max = 100, // stable
.abl_diff_ratio = 0.05,
.abl_dark_pos_diff_thr = 0.15 * 61,
.abl_bright_pos_diff_thr = 0.10 * 61,
.stg_mode = 0,
.stg_ratio_slope = 0.3*256,
.stg_max_offset = 20,
},
.config_wdr = {
.dynamic_gamma_en = 0,
.y_gamma_opt = 0,
.wdr_en = 0,
.temporal_smooth_alpha = 0.1,
.noise_floor = 128,
.noise_floor_out = 128,
.shadow_boost_target = 512,
.highlight_compress_target = 870,
.auto_noise_floor_out = 1,
.min_ns_percentile = 0.01,
.max_ns_percentile = 0.07,
},
};
const struct hgisp_param_info isp_slave0_param =
{
.enable_param = {
.test_pattern_en = 0,
.dma_flush_en = ISP_DMA_ENABLE,
.blc_en = 1,
.awb_en = 1,
.ae_en = 1,
.hist_en = 1,
.ccm_en = 1,
.y_gamma_en = 1,
.rgb_gamma_en = 1,
.ce_en = 1,
.sharpen_en = 1,
.bnr_en = 1,
.ynr_en = 1,
.cnr_en = 1,
.csupp_en = 1,
.adj_hue_en = 1,
.lsc_en = 1,
.dpc_en = 0,
.af_en = 0,
.dehaze_en = 0,
.gic_en = 0,
.md_en = 0,
.luma_ca_en = 0,
},
.awb_param = {
.coarse_scale = 128,
.coarse_thr = 3 << 2,
.fine_step = 1 << 2,
.lock_hi_thr = 4,
.lock_lo_thr = 0,
.stable_thr = 16,
.cbcr_thr = 3 << 2,
.awb_auto_en = 1,
.awb_meas_mode = 0,
.cr_target = 2048,
.cb_target = 2048,
.front_cr_val = 30,
.front_cb_val = 30,
.front_uv_sum = 15,
.back_cr_val = 30,
.back_cb_val = 30,
.back_uv_sum = 10,
.cons_cr_max = 40,
.cons_cb_max = 40,
.cons_uv_max = 30,
.cons_cr_min = 10,
.cons_cb_min = 10,
.cons_uv_min = 2,
.back_cr_max = 30,
.back_cb_max = 30,
.back_uv_max = 10,
.back_cr_min = 5,
.back_cb_min = 5,
.back_uv_min = 5,
.awb_wp_max = 0xc0,
.awb_wp_min = 0x08,
.awb_r_max = 0xc0,
.awb_g_max = 0xc0,
.awb_b_max = 0xc0,
.awb_precision = 1,
.awb_fine_cons_en = 0,
.awb_coarse_cons_en = 0,
.awb_back_cons_en = 1,
.awb_back_wp_min_ratio = 0.2,
.manual_gain = {256, 256, 256, 256},
.awb_crop_pixel_start_h = 0,
.awb_crop_pixel_start_v = 0,
.awb_crop_pixel_end_h = 0,
.awb_crop_pixel_end_v = 0,
},
.cfg_ae = {
.ae_manual_en = 0,
.luma_target = 55,
.luma_weight_sum = 61,
.luma_weight = { 2, 2, 2, 2, 2,
2, 3, 3, 3, 2,
2, 3, 5, 3, 2,
2, 3, 3, 3, 2,
2, 2, 2, 2, 2},
.ae_crop_start_h = 0,
.ae_crop_start_v = 0,
.ae_crop_size_h = 0,
.ae_crop_size_v = 0,
.hist_crop_start_h = 1,
.hist_crop_start_v = 1,
.hist_crop_end_h = 0,
.hist_crop_end_v = 0,
.ae_lock_cnt = 10,
.ae_lock_tolerance = 12,
.exposure_alpha = 16,
.reduce_fps_en = 0,
.lowlight_lsb_gain_en = 0,
.lowlight_lsb_gain_4hi_fps = 16,
.lowlight_lsb_gain_4lo_fps = 16,
.hist_hs_bin_thr = 180,
.hist_upper_hs_pixel_ratio = 0.94,
.hist_upper_pixel_ratio = 0.88,
.hist_lower_pixel_ratio = 0.00,
.abl_bv_gain_sel = 1,
.abl_expo_line_low_ratio = 0,
.abl_expo_line_high_ratio = 0,
.abl_expo_gain_low_thr = 0,
.abl_expo_gain_high_thr = 0,
.aoe_expo_gain_thr[0] = 65535,
.aoe_expo_gain_thr[1] = 65535,
.abl_bv_thr[0] = 1e20,
.abl_bv_thr[1] = 1e20,
.aoe_bv_thr[0] = 0,
.aoe_bv_thr[1] = 0,
.abl_hist_thr[0] = 50, // hist
.abl_hist_thr[1] = 236,
.dark_pixel_low_ratio = 0.60,
.dark_pixel_high_ratio = 0.90,
.bright_pixel_high_ratio = 0.15,
.bright_pixel_sub_ratio = 0.05,
.dark_pos_thr_max = 50, // position
.bright_pos_adjust_ratio = 0.90,
.abl_dark_pos_low_wthr = 0.40 * 61,
.abl_dark_pos_add_wthr = 0.10 * 61,
.aoe_dark_pos_wthr = 0.60 * 61,
.aoe_bright_pos_wthr = 0.20 * 61,
.abl_luma_target_max = 100, // stable
.abl_diff_ratio = 0.05,
.abl_dark_pos_diff_thr = 0.15 * 61,
.abl_bright_pos_diff_thr = 0.10 * 61,
.stg_mode = 0,
.stg_ratio_slope = 0.3*256,
.stg_max_offset = 20,
},
.config_wdr = {
.dynamic_gamma_en = 0,
.y_gamma_opt = 0,
.wdr_en = 0,
.temporal_smooth_alpha = 0.1,
.noise_floor = 128,
.noise_floor_out = 128,
.shadow_boost_target = 512,
.highlight_compress_target = 870,
.auto_noise_floor_out = 1,
.min_ns_percentile = 0.01,
.max_ns_percentile = 0.07,
},
};
const struct hgisp_param_info isp_slave1_param =
{
.enable_param = {
.test_pattern_en = 0,
.dma_flush_en = ISP_DMA_ENABLE,
.blc_en = 1,
.awb_en = 1,
.ae_en = 1,
.hist_en = 1,
.ccm_en = 1,
.y_gamma_en = 1,
.rgb_gamma_en = 1,
.ce_en = 1,
.sharpen_en = 1,
.bnr_en = 1,
.ynr_en = 1,
.cnr_en = 1,
.csupp_en = 1,
.adj_hue_en = 1,
.lsc_en = 1,
.dpc_en = 0,
.af_en = 0,
.dehaze_en = 0,
.gic_en = 0,
.md_en = 0,
.luma_ca_en = 0,
},
.awb_param = {
.coarse_scale = 128,
.coarse_thr = 3 << 2,
.fine_step = 1 << 2,
.lock_hi_thr = 4,
.lock_lo_thr = 0,
.stable_thr = 16,
.cbcr_thr = 3 << 2,
.awb_auto_en = 1,
.awb_meas_mode = 0,
.cr_target = 2048,
.cb_target = 2048,
.front_cr_val = 30,
.front_cb_val = 30,
.front_uv_sum = 15,
.back_cr_val = 30,
.back_cb_val = 30,
.back_uv_sum = 10,
.cons_cr_max = 40,
.cons_cb_max = 40,
.cons_uv_max = 30,
.cons_cr_min = 10,
.cons_cb_min = 10,
.cons_uv_min = 2,
.back_cr_max = 30,
.back_cb_max = 30,
.back_uv_max = 10,
.back_cr_min = 5,
.back_cb_min = 5,
.back_uv_min = 5,
.awb_wp_max = 0xc0,
.awb_wp_min = 32,
.awb_r_max = 0xc0,
.awb_g_max = 0xc0,
.awb_b_max = 0xc0,
.awb_precision = 1,
.awb_fine_cons_en = 1,
.awb_coarse_cons_en = 1,
.awb_back_cons_en = 1,
.awb_back_wp_min_ratio = 0.2,
.manual_gain = {256, 256, 256, 256},
.awb_crop_pixel_start_h = 0,
.awb_crop_pixel_start_v = 0,
.awb_crop_pixel_end_h = 0,
.awb_crop_pixel_end_v = 0,
},
.cfg_ae = {
.ae_manual_en = 0,
.luma_target = 55,
.luma_weight_sum = 61,
.luma_weight = { 2, 2, 2, 2, 2,
2, 3, 3, 3, 2,
2, 3, 5, 3, 2,
2, 3, 3, 3, 2,
2, 2, 2, 2, 2},
.ae_crop_start_h = 0,
.ae_crop_start_v = 0,
.ae_crop_size_h = 0,
.ae_crop_size_v = 0,
.hist_crop_start_h = 1,
.hist_crop_start_v = 1,
.hist_crop_end_h = 0,
.hist_crop_end_v = 0,
.ae_lock_cnt = 10,
.ae_lock_tolerance = 12,
.exposure_alpha = 16,
.reduce_fps_en = 0,
.lowlight_lsb_gain_en = 0,
.lowlight_lsb_gain_4hi_fps = 16,
.lowlight_lsb_gain_4lo_fps = 16,
.hist_hs_bin_thr = 180,
.hist_upper_hs_pixel_ratio = 0.94,
.hist_upper_pixel_ratio = 0.88,
.hist_lower_pixel_ratio = 0.00,
.abl_bv_gain_sel = 1,
.abl_expo_line_low_ratio = 0,
.abl_expo_line_high_ratio = 0,
.abl_expo_gain_low_thr = 0,
.abl_expo_gain_high_thr = 0,
.aoe_expo_gain_thr[0] = 65535,
.aoe_expo_gain_thr[1] = 65535,
.abl_bv_thr[0] = 1e20,
.abl_bv_thr[1] = 1e20,
.aoe_bv_thr[0] = 0,
.aoe_bv_thr[1] = 0,
.abl_hist_thr[0] = 50, // hist
.abl_hist_thr[1] = 236,
.dark_pixel_low_ratio = 0.60,
.dark_pixel_high_ratio = 0.90,
.bright_pixel_high_ratio = 0.15,
.bright_pixel_sub_ratio = 0.05,
.dark_pos_thr_max = 50, // position
.bright_pos_adjust_ratio = 0.90,
.abl_dark_pos_low_wthr = 0.40 * 61,
.abl_dark_pos_add_wthr = 0.10 * 61,
.aoe_dark_pos_wthr = 0.60 * 61,
.aoe_bright_pos_wthr = 0.20 * 61,
.abl_luma_target_max = 100, // stable
.abl_diff_ratio = 0.05,
.abl_dark_pos_diff_thr = 0.15 * 61,
.abl_bright_pos_diff_thr = 0.10 * 61,
.stg_mode = 0,
.stg_ratio_slope = 0.3*256,
.stg_max_offset = 20,
},
.config_wdr = {
.dynamic_gamma_en = 0,
.y_gamma_opt = 0,
.wdr_en = 0,
.temporal_smooth_alpha = 0.1,
.noise_floor = 128,
.noise_floor_out = 128,
.shadow_boost_target = 512,
.highlight_compress_target = 870,
.auto_noise_floor_out = 1,
.min_ns_percentile = 0.01,
.max_ns_percentile = 0.07,
},
};
void *isp_sensor_param_load(uint16 *buff)
{
struct hgisp_sensor_init *init = NULL;
uint8 sensor_index = 0;
uint32 data_offset = 0;
uint32 param_size = buff[2] << 16 | buff[1];
uint32 gamma_size = 256;
uint32 lsc_size = 153*4*4;
uint32 info_szie = sizeof(struct hgisp_sensor_info);
uint32 sensor_param_size = (gamma_size << 1) + lsc_size + info_szie;
init = (struct hgisp_sensor_init *)os_malloc(sizeof(struct hgisp_sensor_init));
if (init)
{
os_memset(init, 0, sizeof(struct hgisp_sensor_init));
sensor_index = buff[3];
if (sensor_index && (param_size >= sensor_index * sensor_param_size))
{
data_offset = 4;
for (int i = 0; i < sensor_index; i++)
{
if (buff[data_offset+2] == ISPCFG_MAGIC)
{
os_memcpy((void *)&init->sensor_info[i], (void *)&buff[data_offset], info_szie);
init->sensor_info[i].info_src = ISP_INFO_SRC_TYPE_CODE_PARAM;
data_offset += (info_szie >> 1);
// init->sensor_info[i].sensor_param.y_gamma.local_ygamma_map = (_Sensor_YGAMMA *)&buff[data_offset];
// data_offset += (gamma_size >> 1);
init->sensor_info[i].sensor_param.rgb_gamma = (uint32 *)&buff[data_offset];
data_offset += (gamma_size >> 1);
init->sensor_info[i].sensor_param.lsc_tbl = (uint32 *)&buff[data_offset];
data_offset += (lsc_size >> 1);
} else {
os_printf("param_data flash : %04x target : %04x err!\r\n", buff[data_offset], ISPCFG_MAGIC);
goto _err;
}
}
os_printf("sensor param use flash_param!\r\n");
goto _end;
} else {
os_printf("param_size : %d calc_size : %d\r\n", param_size, sensor_index * sensor_param_size);
goto _err;
}
} else {
os_printf("%s malloc sram size : %d err!\r\n", sizeof(struct hgisp_sensor_init));
}
return (void *)NULL;
_err:
os_printf("sensor param use default param!\r\n");
init->sensor_info[0].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
init->sensor_info[1].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
init->sensor_info[2].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
os_memcpy((void *)&init->sensor_info[0].sensor_param, (void *)&isp_master_param, sizeof(struct hgisp_param_info));
os_memcpy((void *)&init->sensor_info[1].sensor_param, (void *)&isp_slave0_param, sizeof(struct hgisp_param_info));
os_memcpy((void *)&init->sensor_info[2].sensor_param, (void *)&isp_slave1_param, sizeof(struct hgisp_param_info));
_end:
return (void *)init;
}

View File

@@ -0,0 +1,221 @@
#include "sys_config.h"
#include "typesdef.h"
#include "osal/string.h"
#include "hal/isp_param.h"
#define ISP_DMA_ENABLE 1
const struct hgisp_param_info isp_master_param =
{
.enable_param = {
.test_pattern_en = 0,
.dma_flush_en = ISP_DMA_ENABLE,
.blc_en = 1,
.awb_en = 1,
.ae_en = 1,
.hist_en = 1,
.ccm_en = 1,
.y_gamma_en = 0,
.rgb_gamma_en = 1,
.ce_en = 1,
.sharpen_en = 1,
.bnr_en = 1,
.ynr_en = 1,
.cnr_en = 1,
.csupp_en = 1,
.adj_hue_en = 1,
.lsc_en = 0,
.dpc_en = 0,
.af_en = 0,
.dehaze_en = 0,
.gic_en = 0,
.md_en = 0,
.luma_ca_en = 0,
},
.awb_param = {
.coarse_scale = 128,
.coarse_thr = 3 << 2,
.fine_step = 1 << 2,
.lock_hi_thr = 4,
.lock_lo_thr = 0,
.stable_thr = 16,
.cbcr_thr = 6 << 2,
.awb_auto_en = 1,
.awb_meas_mode = 2,
.cr_target = 2048,
.cb_target = 2048,
.front_cr_val = 30,
.front_cb_val = 30,
.front_uv_sum = 15,
.back_cr_val = 30,
.back_cb_val = 30,
.back_uv_sum = 10,
.cons_cr_max = 40,
.cons_cb_max = 40,
.cons_uv_max = 30,
.cons_cr_min = 10,
.cons_cb_min = 10,
.cons_uv_min = 2,
.back_cr_max = 30,
.back_cb_max = 30,
.back_uv_max = 10,
.back_cr_min = 5,
.back_cb_min = 5,
.back_uv_min = 5,
.awb_wp_max = 0xc0,
.awb_wp_min = 8,
.awb_r_max = 0xc0,
.awb_g_max = 0xc0,
.awb_b_max = 0xc0,
.awb_precision = 1,
.awb_fine_cons_en = 1,
.awb_coarse_cons_en = 1,
.awb_back_cons_en = 1,
.awb_back_wp_min_ratio = 0.2,
.manual_gain = {256, 256, 256, 256},
.awb_crop_pixel_start_h = 0,
.awb_crop_pixel_start_v = 0,
.awb_crop_pixel_end_h = 0,
.awb_crop_pixel_end_v = 0,
},
.cfg_ae = {
.ae_manual_en = 0,
.luma_target = 55,
.luma_weight_sum = 610,
.luma_weight = { 20, 20, 20, 20, 20,//100
20, 30, 30, 30, 20,//130
20, 30, 50, 30, 20,//150
20, 30, 30, 30, 20,//130
20, 20, 20, 20, 20},//100
.ae_crop_start_h = 0,
.ae_crop_start_v = 0,
.ae_crop_size_h = 0,
.ae_crop_size_v = 0,
.hist_crop_start_h = 1,
.hist_crop_start_v = 1,
.hist_crop_end_h = 0,
.hist_crop_end_v = 0,
.ae_lock_cnt = 10,
.ae_lock_tolerance = 12,
.reduce_fps_en = 0,
.lowlight_lsb_gain_en = 1,
.lowlight_lsb_gain_4hi_fps = 64, // lowlight_lsb_gain_en==0 ? 16 : 64
.lowlight_lsb_gain_4lo_fps = 64, // lowlight_lsb_gain_en==0 ? 16 : 64
.hist_hs_bin_thr = 224,
.hist_upper_hs_pixel_ratio = 0.94,
.hist_upper_pixel_ratio = 0.88,
.hist_lower_pixel_ratio = 0.00,
.abl_bv_gain_sel = 0,
.abl_expo_line_low_ratio = 0.80,
.abl_expo_gain_low_thr = 260,
.abl_expo_line_high_ratio = 1.00,
.abl_expo_gain_high_thr = 324,
.aoe_expo_gain_thr[0] = 384-50,
.aoe_expo_gain_thr[1] = 384,
.abl_bv_thr[0] = 6645, // 80lx
.abl_bv_thr[1] = 13216, // 160lx
.aoe_bv_thr[0] = 3531, // 40lx
.aoe_bv_thr[1] = 6645, // 80lx
.abl_hist_thr[0] = 50,
.abl_hist_thr[1] = 230,
.dark_pixel_low_ratio = 0.55,
.dark_pixel_high_ratio = 0.85,
.bright_pixel_high_ratio = 0.10,
.bright_pixel_sub_ratio = 0.05,
.dark_pos_thr_max = 50,
.bright_pos_adjust_ratio = 0.80,
.abl_dark_pos_low_wthr = 18, // 0.30 * 61,
.abl_dark_pos_add_wthr = 12, // 0.20 * 61,
.aoe_dark_pos_wthr = 30, // 0.50 * 61,
.aoe_bright_pos_wthr = 9, // 0.15 * 61,
.abl_luma_target_max = 100,
.abl_diff_ratio = 0.03,
.abl_dark_pos_diff_thr = 9, // 0.15 * 61
.abl_bright_pos_diff_thr = 6, // 0.10 * 61
.stg_mode = 0,
.stg_ratio_slope = 0.3*256,
.stg_max_offset = 0,
},
.config_wdr = {
.dynamic_gamma_en = 0,
.y_gamma_opt = 0,
.wdr_en = 0,
.temporal_smooth_alpha = 0.1,
.noise_floor = 128,
.noise_floor_out = 128,
.shadow_boost_target = 512,
.highlight_compress_target = 870,
.auto_noise_floor_out = 1,
.min_ns_percentile = 0.01,
.max_ns_percentile = 0.07,
},
};
#define SENSOR_PARAM_SIZE (64*4*2+153*4*4)
void *isp_sensor_param_load(uint16 *buff)
{
struct hgisp_sensor_init *init = NULL;
uint8 sensor_index = 0;
uint32 data_offset = 0;
uint32 param_size = buff[2] << 16 | buff[1];
uint32 gamma_size = 256;
uint32 lsc_size = 153*4*4;
uint32 info_szie = sizeof(struct hgisp_sensor_info);
uint32 sensor_param_size = (gamma_size << 1) + lsc_size + info_szie;
init = (struct hgisp_sensor_init *)os_malloc(sizeof(struct hgisp_sensor_init));
if (init)
{
os_memset(init, 0, sizeof(struct hgisp_sensor_init));
sensor_index = buff[3];
if (sensor_index && (param_size >= sensor_index * sensor_param_size))
{
data_offset = 4;
for (int i = 0; i < sensor_index; i++)
{
if (buff[data_offset+2] == ISPCFG_MAGIC)
{
os_memcpy((void *)&init->sensor_info[i], (void *)&buff[data_offset], info_szie);
init->sensor_info[i].info_src = ISP_INFO_SRC_TYPE_CODE_PARAM;
data_offset += (info_szie >> 1);
init->sensor_info[i].sensor_param.y_gamma = (uint32 *)&buff[data_offset];
data_offset += (gamma_size >> 1);
init->sensor_info[i].sensor_param.rgb_gamma = (uint32 *)&buff[data_offset];
data_offset += (gamma_size >> 1);
init->sensor_info[i].sensor_param.lsc_tbl = (uint32 *)&buff[data_offset];
data_offset += (lsc_size >> 1);
} else {
os_printf("param_data flash : %04x target : %04x err!\r\n", buff[data_offset], ISPCFG_MAGIC);
goto _err;
}
}
os_printf("sensor param use flash_param!\r\n");
goto _end;
} else {
os_printf("param_size : %d calc_size : %d\r\n", param_size, sensor_index * sensor_param_size);
goto _err;
}
} else {
os_printf("%s malloc sram size : %d err!\r\n", sizeof(struct hgisp_sensor_init));
}
return (void *)NULL;
_err:
os_printf("sensor param use default param!\r\n");
init->sensor_info[0].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
init->sensor_info[1].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
init->sensor_info[2].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
os_memcpy((void *)&init->sensor_info[0].sensor_param, (void *)&isp_master_param, sizeof(struct hgisp_param_info));
// os_memcpy((void *)&init->sensor_info[1].sensor_param, (void *)&isp_slave0_param, sizeof(struct hgisp_param_info));
// os_memcpy((void *)&init->sensor_info[2].sensor_param, (void *)&isp_slave1_param, sizeof(struct hgisp_param_info));
_end:
return (void *)init;
}

View File

@@ -0,0 +1,513 @@
#include "sys_config.h"
#include "typesdef.h"
#include "osal/string.h"
#include "hal/isp_param.h"
#define ISP_DMA_ENABLE 1
const struct hgisp_param_info isp_master_param =
{
.enable_param = {
.test_pattern_en = 0,
.dma_flush_en = ISP_DMA_ENABLE,
.blc_en = 1,
.awb_en = 1,
.ae_en = 1,
.hist_en = 1,
.ccm_en = 1,
.y_gamma_en = 1,
.rgb_gamma_en = 1,
.ce_en = 1,
.sharpen_en = 1,
.bnr_en = 1,
.ynr_en = 1,
.cnr_en = 1,
.csupp_en = 1,
.adj_hue_en = 1,
.lsc_en = 1,
.dpc_en = 1,
.af_en = 0,
.dehaze_en = 0,
.gic_en = 0,
.md_en = 0,
.luma_ca_en = 0,
},
.awb_param = {
.coarse_scale = 255,
.coarse_thr = 3 << 2,
.fine_step = 1 << 2,
.lock_hi_thr = 4,
.lock_lo_thr = 0,
.stable_thr = 16,
.cbcr_thr = 6 << 2,
.awb_auto_en = 1,
.awb_meas_mode = 2,
.cr_target = 2048,
.cb_target = 2048,
.front_cr_val = 30,
.front_cb_val = 30,
.front_uv_sum = 15,
.back_cr_val = 30,
.back_cb_val = 30,
.back_uv_sum = 10,
.cons_cr_max = 40,
.cons_cb_max = 40,
.cons_uv_max = 30,
.cons_cr_min = 10,
.cons_cb_min = 10,
.cons_uv_min = 2,
.back_cr_max = 30,
.back_cb_max = 30,
.back_uv_max = 10,
.back_cr_min = 5,
.back_cb_min = 5,
.back_uv_min = 5,
.awb_wp_max = 0xc0,
.awb_wp_min = 0x08,
.awb_r_max = 0xc0,
.awb_g_max = 0xc0,
.awb_b_max = 0xc0,
.awb_precision = 1,
.awb_fine_cons_en = 1,
.awb_coarse_cons_en = 1,
.awb_back_cons_en = 1,
.awb_back_wp_min_ratio = 0.2,
.manual_gain = {256, 256, 256, 256},
.awb_crop_pixel_start_h = 0,
.awb_crop_pixel_start_v = 360,
.awb_crop_pixel_end_h = 1919,
.awb_crop_pixel_end_v = 1079,
},
.cfg_ae = {
.ae_manual_en = 0,
.luma_target = 55,
.luma_weight_sum = 380,
.luma_weight = { 5, 5, 5, 5, 5, //25
10, 20, 30, 20, 10, //90
20, 30, 50, 30, 20, //150
10, 20, 30, 20, 10, //90
5, 5, 5, 5, 5},//25
.ae_crop_start_h = 0,
.ae_crop_start_v = 270,
.ae_crop_size_h = 1920,
.ae_crop_size_v = 810,
.hist_crop_start_h = 1,
.hist_crop_start_v = 271,
.hist_crop_end_h = 1920,
.hist_crop_end_v = 1080,
.ae_lock_cnt = 10,
.ae_lock_tolerance = 12,
.reduce_fps_en = 0,
.lowlight_lsb_gain_en = 1,
.lowlight_lsb_gain_4hi_fps = 64, // lowlight_lsb_gain_en==0 ? 16 : 64
.lowlight_lsb_gain_4lo_fps = 64, // lowlight_lsb_gain_en==0 ? 16 : 64
.hist_hs_bin_thr = 180,
.hist_upper_hs_pixel_ratio = 0.94,
.hist_upper_pixel_ratio = 0.88,
.hist_lower_pixel_ratio = 0.00,
.abl_bv_gain_sel = 1,
.abl_expo_line_low_ratio = 0,
.abl_expo_gain_low_thr = 0,
.abl_expo_line_high_ratio = 0,
.abl_expo_gain_high_thr = 0,
.aoe_expo_gain_thr[0] = 65535,
.aoe_expo_gain_thr[1] = 65535,
.abl_bv_thr[0] = 1e20,
.abl_bv_thr[1] = 1e20,
.aoe_bv_thr[0] = 0,
.aoe_bv_thr[1] = 0,
.abl_hist_thr[0] = 50, // hist
.abl_hist_thr[1] = 236,
.dark_pixel_low_ratio = 0.60,
.dark_pixel_high_ratio = 0.90,
.bright_pixel_high_ratio = 0.15,
.bright_pixel_sub_ratio = 0.05,
.dark_pos_thr_max = 50, // position
.bright_pos_adjust_ratio = 0.90,
.abl_dark_pos_low_wthr = 0.40 * 61,
.abl_dark_pos_add_wthr = 0.10 * 61,
.aoe_dark_pos_wthr = 0.60 * 61,
.aoe_bright_pos_wthr = 0.20 * 61,
.abl_luma_target_max = 100, // stable
.abl_diff_ratio = 0.05,
.abl_dark_pos_diff_thr = 0.15 * 61,
.abl_bright_pos_diff_thr = 0.10 * 61,
.stg_mode = 0,
.stg_ratio_slope = 0.3*256,
.stg_max_offset = 0,
},
.config_wdr = {
.wdr_en = 1,
.temporal_smooth_alpha = 0.1,
.noise_floor = 80,
.noise_floor_out = 0,
.shadow_boost_target = 512,
.highlight_compress_target = 870,
.auto_noise_floor_out = 1,
.min_ns_percentile = 0.01,
.max_ns_percentile = 0.07,
},
};
const struct hgisp_param_info isp_slave0_param =
{
.enable_param = {
.test_pattern_en = 0,
.dma_flush_en = ISP_DMA_ENABLE,
.blc_en = 1,
.awb_en = 1,
.ae_en = 1,
.hist_en = 1,
.ccm_en = 1,
.y_gamma_en = 1,
.rgb_gamma_en = 1,
.ce_en = 1,
.sharpen_en = 1,
.bnr_en = 1,
.ynr_en = 1,
.cnr_en = 1,
.csupp_en = 1,
.adj_hue_en = 1,
.lsc_en = 1,
.dpc_en = 0,
.af_en = 0,
.dehaze_en = 0,
.gic_en = 0,
.md_en = 0,
.luma_ca_en = 0,
},
.awb_param = {
.coarse_scale = 128,
.coarse_thr = 3 << 2,
.fine_step = 1 << 2,
.lock_hi_thr = 4,
.lock_lo_thr = 0,
.stable_thr = 16,
.cbcr_thr = 3 << 2,
.awb_auto_en = 1,
.awb_meas_mode = 0,
.cr_target = 2048,
.cb_target = 2048,
.front_cr_val = 30,
.front_cb_val = 30,
.front_uv_sum = 15,
.back_cr_val = 30,
.back_cb_val = 30,
.back_uv_sum = 10,
.cons_cr_max = 40,
.cons_cb_max = 40,
.cons_uv_max = 30,
.cons_cr_min = 10,
.cons_cb_min = 10,
.cons_uv_min = 2,
.back_cr_max = 30,
.back_cb_max = 30,
.back_uv_max = 10,
.back_cr_min = 5,
.back_cb_min = 5,
.back_uv_min = 5,
.awb_wp_max = 0xc0,
.awb_wp_min = 0x08,
.awb_r_max = 0xc0,
.awb_g_max = 0xc0,
.awb_b_max = 0xc0,
.awb_precision = 1,
.awb_fine_cons_en = 1,
.awb_coarse_cons_en = 0,
.awb_back_cons_en = 1,
.awb_back_wp_min_ratio = 0.2,
.manual_gain = {256, 256, 256, 256},
.awb_crop_pixel_start_h = 0,
.awb_crop_pixel_start_v = 0,
.awb_crop_pixel_end_h = 0,
.awb_crop_pixel_end_v = 0,
},
.cfg_ae = {
.ae_manual_en = 0,
.luma_target = 55,
.luma_weight_sum = 61,
.luma_weight = { 2, 2, 2, 2, 2,
2, 3, 3, 3, 2,
2, 3, 5, 3, 2,
2, 3, 3, 3, 2,
2, 2, 2, 2, 2},
.ae_crop_start_h = 0,
.ae_crop_start_v = 0,
.ae_crop_size_h = 0,
.ae_crop_size_v = 0,
.hist_crop_start_h = 1,
.hist_crop_start_v = 1,
.hist_crop_end_h = 0,
.hist_crop_end_v = 0,
.ae_lock_cnt = 10,
.ae_lock_tolerance = 12,
.reduce_fps_en = 0,
.lowlight_lsb_gain_en = 0,
.lowlight_lsb_gain_4hi_fps = 16,
.lowlight_lsb_gain_4lo_fps = 16,
.hist_hs_bin_thr = 232,
.abl_luma_target_max = 100,
.dark_pos_thr_max = 50,
.abl_diff_ratio = 0.03,
.abl_dark_pos_diff_thr = 9, // 0.15 * 61
.abl_bright_pos_diff_thr = 6, // 0.10 * 61
.bright_pixel_high_ratio = 0.10,
.bright_pixel_sub_ratio = 0.05,
.abl_dark_pos_low_wthr = 18, // 0.30 * 61,
.abl_dark_pos_add_wthr = 12, // 0.20 * 61,
.bright_pos_adjust_ratio = 0.80,
.dark_pixel_low_ratio = 0.55,
.dark_pixel_high_ratio = 0.85,
.aoe_dark_pos_wthr = 30, // 0.50 * 61,
.aoe_bright_pos_wthr = 9, // 0.15 * 61,
.abl_bv_gain_sel = 0,
.abl_expo_line_low_ratio = 0.80,
.abl_expo_line_high_ratio = 1.00,
.abl_expo_gain_low_thr = 256,
.abl_expo_gain_high_thr = 324,
.abl_hist_thr[0] = 50,
.abl_hist_thr[1] = 230,
.aoe_expo_gain_thr[0] = 384-50,
.aoe_expo_gain_thr[1] = 384,
.abl_bv_thr[0] = 5000,
.abl_bv_thr[1] = 8000,
.aoe_bv_thr[0] = 4000,
.aoe_bv_thr[1] = 6000,
.hist_upper_pixel_ratio = 0.88,
.hist_upper_hs_pixel_ratio = 0.92,
.hist_lower_pixel_ratio = 0.00,
},
.config_wdr = {
.wdr_en = 0,
.temporal_smooth_alpha = 0.1,
.noise_floor = 128,
.noise_floor_out = 128,
.shadow_boost_target = 512,
.highlight_compress_target = 870,
.auto_noise_floor_out = 1,
.min_ns_percentile = 0.01,
.max_ns_percentile = 0.07,
},
};
const struct hgisp_param_info isp_slave1_param =
{
.enable_param = {
.test_pattern_en = 0,
.dma_flush_en = ISP_DMA_ENABLE,
.blc_en = 1,
.awb_en = 1,
.ae_en = 1,
.hist_en = 1,
.ccm_en = 1,
.y_gamma_en = 1,
.rgb_gamma_en = 1,
.ce_en = 1,
.sharpen_en = 1,
.bnr_en = 1,
.ynr_en = 1,
.cnr_en = 1,
.csupp_en = 1,
.adj_hue_en = 1,
.lsc_en = 1,
.dpc_en = 0,
.af_en = 0,
.dehaze_en = 0,
.gic_en = 0,
.md_en = 0,
.luma_ca_en = 0,
},
.awb_param = {
.coarse_scale = 128,
.coarse_thr = 3 << 2,
.fine_step = 1 << 2,
.lock_hi_thr = 4,
.lock_lo_thr = 0,
.stable_thr = 16,
.cbcr_thr = 3 << 2,
.awb_auto_en = 1,
.awb_meas_mode = 0,
.cr_target = 2048,
.cb_target = 2048,
.front_cr_val = 30,
.front_cb_val = 30,
.front_uv_sum = 15,
.back_cr_val = 30,
.back_cb_val = 30,
.back_uv_sum = 10,
.cons_cr_max = 40,
.cons_cb_max = 40,
.cons_uv_max = 30,
.cons_cr_min = 10,
.cons_cb_min = 10,
.cons_uv_min = 2,
.back_cr_max = 30,
.back_cb_max = 30,
.back_uv_max = 10,
.back_cr_min = 5,
.back_cb_min = 5,
.back_uv_min = 5,
.awb_wp_max = 0xc0,
.awb_wp_min = 0x08,
.awb_r_max = 0xc0,
.awb_g_max = 0xc0,
.awb_b_max = 0xc0,
.awb_precision = 1,
.awb_fine_cons_en = 1,
.awb_coarse_cons_en = 0,
.awb_back_cons_en = 1,
.awb_back_wp_min_ratio = 0.2,
.manual_gain = {256, 256, 256, 256},
.awb_crop_pixel_start_h = 0,
.awb_crop_pixel_start_v = 360,
.awb_crop_pixel_end_h = 1919,
.awb_crop_pixel_end_v = 1079,
},
.cfg_ae = {
.ae_manual_en = 0,
.luma_target = 55,
.luma_weight_sum = 480,
.luma_weight = { 10, 10, 10, 10, 10,
10, 10, 10, 10, 10,
20, 30, 50, 30, 20,
20, 30, 30, 30, 20,
20, 20, 20, 20, 20},
.ae_crop_start_h = 0,
.ae_crop_start_v = 0,
.ae_crop_size_h = 0,
.ae_crop_size_v = 0,
.hist_crop_start_h = 1,
.hist_crop_start_v = 1,
.hist_crop_end_h = 0,
.hist_crop_end_v = 0,
.ae_lock_cnt = 10,
.ae_lock_tolerance = 12,
.reduce_fps_en = 0,
.lowlight_lsb_gain_en = 1,
.lowlight_lsb_gain_4hi_fps = 64, // lowlight_lsb_gain_en==0 ? 16 : 64
.lowlight_lsb_gain_4lo_fps = 64, // lowlight_lsb_gain_en==0 ? 16 : 64
.hist_hs_bin_thr = 180,
.abl_luma_target_max = 100,
.dark_pos_thr_max = 50,
.abl_diff_ratio = 0.03,
.abl_dark_pos_diff_thr = 9,
.abl_bright_pos_diff_thr = 6,
.bright_pixel_high_ratio = 0.10,
.bright_pixel_sub_ratio = 0.05,
.dark_pixel_low_ratio = 0.55,
.dark_pixel_high_ratio = 0.85,
.abl_dark_pos_low_wthr = 18, // 0.30 * 61,
.abl_dark_pos_add_wthr = 12, // 0.20 * 61,
.bright_pos_adjust_ratio = 0.80,
.aoe_dark_pos_wthr = 30, // 0.50 * 61,
.aoe_bright_pos_wthr = 9, // 0.15 * 61,
.abl_bv_gain_sel = 0,
.abl_expo_line_low_ratio = 0.80,
.abl_expo_line_high_ratio = 1.00,
.abl_expo_gain_low_thr = 256,
.abl_expo_gain_high_thr = 324,
.abl_hist_thr[0] = 50,
.abl_hist_thr[1] = 230,
.aoe_expo_gain_thr[0] = 384-50,
.aoe_expo_gain_thr[1] = 384,
.abl_bv_thr[0] = 6645, // 80lx
.abl_bv_thr[1] = 13216, // 160lx
.aoe_bv_thr[0] = 3531, // 40lx
.aoe_bv_thr[1] = 6645, // 80lx
.hist_upper_pixel_ratio = 0.88,
.hist_upper_hs_pixel_ratio = 0.94,
.hist_lower_pixel_ratio = 0.00,
.stg_mode = 0, // 自动曝光策略 0高光优先 1低光优先
.stg_ratio_slope = 0.3*256, // fix(0,16,8), 值越大roi对权重的影响越大。
.stg_max_offset = 20, // fix(0,8,0) roi对权重影响的最大程度
},
.config_wdr = {
.dynamic_gamma_en = 0,
.y_gamma_opt = 0,
.wdr_en = 0,
.temporal_smooth_alpha = 0.1,
.noise_floor = 128,
.noise_floor_out = 128,
.shadow_boost_target = 512,
.highlight_compress_target = 870,
.auto_noise_floor_out = 1,
.min_ns_percentile = 0.01,
.max_ns_percentile = 0.07,
},
};
#define SENSOR_PARAM_SIZE (64*4*4+153*4*4)
void *isp_sensor_param_load(uint16 *buff)
{
struct hgisp_sensor_init *init = NULL;
uint8 sensor_index = 0;
uint32 data_offset = 0;
uint32 param_size = buff[2] << 16 | buff[1];
uint32 gamma_size = 256;
uint32 lsc_size = 153*4*4;
uint32 info_szie = sizeof(struct hgisp_sensor_info);
uint32 sensor_param_size = (gamma_size << 1) + lsc_size + info_szie;
init = (struct hgisp_sensor_init *)os_malloc(sizeof(struct hgisp_sensor_init));
if (init)
{
os_memset(init, 0, sizeof(struct hgisp_sensor_init));
sensor_index = buff[3];
if (sensor_index && (param_size >= sensor_index * sensor_param_size))
{
data_offset = 4;
for (int i = 0; i < sensor_index; i++)
{
if (buff[data_offset+2] == ISPCFG_MAGIC)
{
os_memcpy((void *)&init->sensor_info[i], (void *)&buff[data_offset], info_szie);
init->sensor_info[i].info_src = ISP_INFO_SRC_TYPE_CODE_PARAM;
data_offset += (info_szie >> 1);
init->sensor_info[i].sensor_param.y_gamma = (uint32 *)&buff[data_offset];
data_offset += (gamma_size >> 1);
init->sensor_info[i].sensor_param.rgb_gamma = (uint32 *)&buff[data_offset];
data_offset += (gamma_size >> 1);
init->sensor_info[i].sensor_param.lsc_tbl = (uint32 *)&buff[data_offset];
data_offset += (lsc_size >> 1);
} else {
os_printf("param_data flash : %04x target : %04x err!\r\n", buff[data_offset], ISPCFG_MAGIC);
goto _err;
}
}
os_printf("sensor param use flash_param!\r\n");
goto _end;
} else {
os_printf("param_size : %d calc_size : %d\r\n", param_size, sensor_index * sensor_param_size);
goto _err;
}
} else {
os_printf("%s malloc sram size : %d err!\r\n", sizeof(struct hgisp_sensor_init));
}
return (void *)NULL;
_err:
os_printf("sensor param use default param!\r\n");
init->sensor_info[0].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
init->sensor_info[1].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
init->sensor_info[2].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
os_memcpy((void *)&init->sensor_info[0].sensor_param, (void *)&isp_master_param, sizeof(struct hgisp_param_info));
os_memcpy((void *)&init->sensor_info[1].sensor_param, (void *)&isp_slave0_param, sizeof(struct hgisp_param_info));
os_memcpy((void *)&init->sensor_info[2].sensor_param, (void *)&isp_slave1_param, sizeof(struct hgisp_param_info));
_end:
return (void *)init;
}

View File

@@ -0,0 +1,489 @@
#include "sys_config.h"
#include "typesdef.h"
#include "osal/string.h"
#include "hal/isp_param.h"
#define ISP_DMA_ENABLE 1
const struct hgisp_param_info isp_master_param =
{
.enable_param = {
.test_pattern_en = 0,
.dma_flush_en = ISP_DMA_ENABLE,
.blc_en = 1,
.awb_en = 1,
.ae_en = 1,
.hist_en = 1,
.ccm_en = 1,
.y_gamma_en = 1,
.rgb_gamma_en = 1,
.ce_en = 1,
.sharpen_en = 1,
.bnr_en = 1,
.ynr_en = 1,
.cnr_en = 1,
.csupp_en = 1,
.adj_hue_en = 1,
.lsc_en = 1,
.dpc_en = 1,
.af_en = 0,
.dehaze_en = 0,
.gic_en = 0,
.md_en = 0,
.luma_ca_en = 0,
},
.awb_param = {
.coarse_scale = 128,
.coarse_thr = 3 << 2,
.fine_step = 1 << 2,
.lock_hi_thr = 4,
.lock_lo_thr = 0,
.stable_thr = 16,
.cbcr_thr = 6 << 2,
.awb_auto_en = 1,
.awb_meas_mode = 2,
.cr_target = 2048,
.cb_target = 2048,
.front_cr_val = 30,
.front_cb_val = 30,
.front_uv_sum = 15,
.back_cr_val = 30,
.back_cb_val = 30,
.back_uv_sum = 10,
.cons_cr_max = 40,
.cons_cb_max = 40,
.cons_uv_max = 30,
.cons_cr_min = 10,
.cons_cb_min = 10,
.cons_uv_min = 2,
.back_cr_max = 30,
.back_cb_max = 30,
.back_uv_max = 10,
.back_cr_min = 5,
.back_cb_min = 5,
.back_uv_min = 5,
.awb_wp_max = 0xc0,
.awb_wp_min = 32,
.awb_r_max = 0xc0,
.awb_g_max = 0xc0,
.awb_b_max = 0xc0,
.awb_precision = 1,
.awb_fine_cons_en = 1,
.awb_coarse_cons_en = 1,
.awb_back_cons_en = 1,
.awb_back_wp_min_ratio = 0.2,
.manual_gain = {256, 256, 256, 256},
.awb_crop_pixel_start_h = 0,
.awb_crop_pixel_start_v = 0,
.awb_crop_pixel_end_h = 0,
.awb_crop_pixel_end_v = 0,
},
.cfg_ae = {
.ae_manual_en = 0,
.luma_target = 55,
.luma_weight_sum = 61,
.luma_weight = { 2, 2, 2, 2, 2,
2, 3, 3, 3, 2,
2, 3, 5, 3, 2,
2, 3, 3, 3, 2,
2, 2, 2, 2, 2},
.ae_crop_start_h = 0,
.ae_crop_start_v = 0,
.ae_crop_size_h = 0,
.ae_crop_size_v = 0,
.hist_crop_start_h = 1,
.hist_crop_start_v = 1,
.hist_crop_end_h = 0,
.hist_crop_end_v = 0,
.ae_lock_cnt = 10,
.ae_lock_tolerance = 12,
.reduce_fps_en = 0,
.lowlight_lsb_gain_en = 1,
.lowlight_lsb_gain_4hi_fps = 64,
.lowlight_lsb_gain_4lo_fps = 64,
.hist_hs_bin_thr = 224,
.hist_upper_hs_pixel_ratio = 0.94,
.hist_upper_pixel_ratio = 0.88,
.hist_lower_pixel_ratio = 0.00,
.abl_bv_gain_sel = 0,
.abl_expo_line_low_ratio = 0.80,
.abl_expo_line_high_ratio = 1.00,
.abl_expo_gain_low_thr = 256,
.abl_expo_gain_high_thr = 324,
.aoe_expo_gain_thr[0] = 384-50,
.aoe_expo_gain_thr[1] = 384,
.abl_bv_thr[0] = 6645, // 80lx
.abl_bv_thr[1] = 13216, // 160lx
.aoe_bv_thr[0] = 3531, // 40lx
.aoe_bv_thr[1] = 6645, // 80lx
.abl_hist_thr[0] = 50,
.abl_hist_thr[1] = 230,
.dark_pixel_low_ratio = 0.55,
.dark_pixel_high_ratio = 0.85,
.bright_pixel_high_ratio = 0.10,
.bright_pixel_sub_ratio = 0.05,
.dark_pos_thr_max = 50,
.bright_pos_adjust_ratio = 0.80,
.abl_dark_pos_low_wthr = 18, // 0.30 * 61,
.abl_dark_pos_add_wthr = 12, // 0.20 * 61,
.aoe_dark_pos_wthr = 30, // 0.50 * 61,
.aoe_bright_pos_wthr = 9, // 0.15 * 61,
.abl_luma_target_max = 100,
.abl_diff_ratio = 0.03,
.abl_dark_pos_diff_thr = 9, // 0.15 * 61
.abl_bright_pos_diff_thr = 6, // 0.10 * 61
.stg_mode = 0,
.stg_ratio_slope = 0.3*256,
.stg_max_offset = 0,
},
.config_wdr = {
.wdr_en = 1,
.temporal_smooth_alpha = 0.1,
.noise_floor = 80,
.noise_floor_out = 0,
.shadow_boost_target = 512,
.highlight_compress_target = 870,
.auto_noise_floor_out = 1,
.min_ns_percentile = 0.01,
.max_ns_percentile = 0.07,
},
};
const struct hgisp_param_info isp_slave0_param =
{
.enable_param = {
.test_pattern_en = 0,
.dma_flush_en = ISP_DMA_ENABLE,
.blc_en = 1,
.awb_en = 1,
.ae_en = 1,
.hist_en = 1,
.ccm_en = 1,
.y_gamma_en = 1,
.rgb_gamma_en = 1,
.ce_en = 1,
.sharpen_en = 1,
.bnr_en = 1,
.ynr_en = 1,
.cnr_en = 1,
.csupp_en = 1,
.adj_hue_en = 1,
.lsc_en = 1,
.dpc_en = 0,
.af_en = 0,
.dehaze_en = 0,
.gic_en = 0,
.md_en = 0,
.luma_ca_en = 0,
},
.awb_param = {
.coarse_scale = 128,
.coarse_thr = 3 << 2,
.fine_step = 1 << 2,
.lock_hi_thr = 4,
.lock_lo_thr = 0,
.stable_thr = 16,
.cbcr_thr = 3 << 2,
.awb_auto_en = 1,
.awb_meas_mode = 0,
.cr_target = 2048,
.cb_target = 2048,
.front_cr_val = 30,
.front_cb_val = 30,
.front_uv_sum = 15,
.back_cr_val = 30,
.back_cb_val = 30,
.back_uv_sum = 10,
.cons_cr_max = 40,
.cons_cb_max = 40,
.cons_uv_max = 30,
.cons_cr_min = 10,
.cons_cb_min = 10,
.cons_uv_min = 2,
.back_cr_max = 30,
.back_cb_max = 30,
.back_uv_max = 10,
.back_cr_min = 5,
.back_cb_min = 5,
.back_uv_min = 5,
.awb_wp_max = 0xc0,
.awb_wp_min = 0x08,
.awb_r_max = 0xc0,
.awb_g_max = 0xc0,
.awb_b_max = 0xc0,
.awb_precision = 1,
.awb_fine_cons_en = 1,
.awb_coarse_cons_en = 0,
.awb_back_cons_en = 1,
.awb_back_wp_min_ratio = 0.2,
.manual_gain = {256, 256, 256, 256},
.awb_crop_pixel_start_h = 0,
.awb_crop_pixel_start_v = 0,
.awb_crop_pixel_end_h = 0,
.awb_crop_pixel_end_v = 0,
},
.cfg_ae = {
.ae_manual_en = 0,
.luma_target = 55,
.luma_weight_sum = 61,
.luma_weight = { 2, 2, 2, 2, 2,
2, 3, 3, 3, 2,
2, 3, 5, 3, 2,
2, 3, 3, 3, 2,
2, 2, 2, 2, 2},
.ae_crop_start_h = 0,
.ae_crop_start_v = 0,
.ae_crop_size_h = 0,
.ae_crop_size_v = 0,
.hist_crop_start_h = 1,
.hist_crop_start_v = 1,
.hist_crop_end_h = 0,
.hist_crop_end_v = 0,
.ae_lock_cnt = 10,
.ae_lock_tolerance = 12,
.reduce_fps_en = 0,
.lowlight_lsb_gain_en = 0,
.lowlight_lsb_gain_4hi_fps = 16,
.lowlight_lsb_gain_4lo_fps = 16,
.hist_hs_bin_thr = 232,
.abl_luma_target_max = 100,
.dark_pos_thr_max = 50,
.abl_diff_ratio = 0.03,
.abl_dark_pos_diff_thr = 9, // 0.15 * 61
.abl_bright_pos_diff_thr = 6, // 0.10 * 61
.bright_pixel_high_ratio = 0.10,
.bright_pixel_sub_ratio = 0.05,
.abl_dark_pos_low_wthr = 18, // 0.30 * 61,
.abl_dark_pos_add_wthr = 12, // 0.20 * 61,
.bright_pos_adjust_ratio = 0.80,
.dark_pixel_low_ratio = 0.55,
.dark_pixel_high_ratio = 0.85,
.aoe_dark_pos_wthr = 30, // 0.50 * 61,
.aoe_bright_pos_wthr = 9, // 0.15 * 61,
.abl_bv_gain_sel = 0,
.abl_expo_line_low_ratio = 0.80,
.abl_expo_line_high_ratio = 1.00,
.abl_expo_gain_low_thr = 256,
.abl_expo_gain_high_thr = 324,
.abl_hist_thr[0] = 50,
.abl_hist_thr[1] = 230,
.aoe_expo_gain_thr[0] = 384-50,
.aoe_expo_gain_thr[1] = 384,
.abl_bv_thr[0] = 5000,
.abl_bv_thr[1] = 8000,
.aoe_bv_thr[0] = 4000,
.aoe_bv_thr[1] = 6000,
.hist_upper_pixel_ratio = 0.88,
.hist_upper_hs_pixel_ratio = 0.92,
.hist_lower_pixel_ratio = 0.00,
},
.config_wdr = {
.wdr_en = 0,
.temporal_smooth_alpha = 0.1,
.noise_floor = 128,
.noise_floor_out = 128,
.shadow_boost_target = 512,
.highlight_compress_target = 870,
},
};
const struct hgisp_param_info isp_slave1_param =
{
.enable_param = {
.test_pattern_en = 0,
.dma_flush_en = ISP_DMA_ENABLE,
.blc_en = 1,
.awb_en = 1,
.ae_en = 1,
.hist_en = 1,
.ccm_en = 1,
.y_gamma_en = 1,
.rgb_gamma_en = 1,
.ce_en = 1,
.sharpen_en = 1,
.bnr_en = 1,
.ynr_en = 1,
.cnr_en = 1,
.csupp_en = 1,
.adj_hue_en = 1,
.lsc_en = 1,
.dpc_en = 0,
.af_en = 0,
.dehaze_en = 0,
.gic_en = 0,
.md_en = 0,
.luma_ca_en = 0,
},
.awb_param = {
.coarse_scale = 128,
.coarse_thr = 3 << 2,
.fine_step = 1 << 2,
.lock_hi_thr = 4,
.lock_lo_thr = 0,
.stable_thr = 16,
.cbcr_thr = 3 << 2,
.awb_auto_en = 1,
.awb_meas_mode = 0,
.cr_target = 2048,
.cb_target = 2048,
.front_cr_val = 30,
.front_cb_val = 30,
.front_uv_sum = 15,
.back_cr_val = 30,
.back_cb_val = 30,
.back_uv_sum = 10,
.cons_cr_max = 40,
.cons_cb_max = 40,
.cons_uv_max = 30,
.cons_cr_min = 10,
.cons_cb_min = 10,
.cons_uv_min = 2,
.back_cr_max = 30,
.back_cb_max = 30,
.back_uv_max = 10,
.back_cr_min = 5,
.back_cb_min = 5,
.back_uv_min = 5,
.awb_wp_max = 0xc0,
.awb_wp_min = 0x08,
.awb_r_max = 0xc0,
.awb_g_max = 0xc0,
.awb_b_max = 0xc0,
.awb_precision = 1,
.awb_fine_cons_en = 1,
.awb_coarse_cons_en = 0,
.awb_back_cons_en = 1,
.awb_back_wp_min_ratio = 0.2,
.manual_gain = {256, 256, 256, 256},
},
.cfg_ae = {
.ae_manual_en = 0,
.luma_target = 55,
.luma_weight_sum = 61,
.luma_weight = { 2, 2, 2, 2, 2,
2, 3, 3, 3, 2,
2, 3, 5, 3, 2,
2, 3, 3, 3, 2,
2, 2, 2, 2, 2},
.ae_lock_cnt = 10,
.ae_lock_tolerance = 12,
.reduce_fps_en = 0,
.lowlight_lsb_gain_en = 0,
.lowlight_lsb_gain_4hi_fps = 16,
.lowlight_lsb_gain_4lo_fps = 16,
.hist_hs_bin_thr = 232,
.abl_luma_target_max = 100,
.dark_pos_thr_max = 50,
.abl_diff_ratio = 0.03,
.abl_dark_pos_diff_thr = 9, // 0.15 * 61
.abl_bright_pos_diff_thr = 6, // 0.10 * 61
.bright_pixel_high_ratio = 0.10,
.bright_pixel_sub_ratio = 0.05,
.dark_pixel_low_ratio = 0.55,
.dark_pixel_high_ratio = 0.85,
.abl_dark_pos_low_wthr = 18, // 0.30 * 61,
.abl_dark_pos_add_wthr = 12, // 0.20 * 61,
.bright_pos_adjust_ratio = 0.80,
.aoe_dark_pos_wthr = 30, // 0.50 * 61,
.aoe_bright_pos_wthr = 9, // 0.15 * 61,
.abl_bv_gain_sel = 0,
.abl_expo_line_low_ratio = 0.80,
.abl_expo_line_high_ratio = 1.00,
.abl_expo_gain_low_thr = 256,
.abl_expo_gain_high_thr = 324,
.abl_hist_thr[0] = 50,
.abl_hist_thr[1] = 230,
.aoe_expo_gain_thr[0] = 384-50,
.aoe_expo_gain_thr[1] = 384,
.abl_bv_thr[0] = 6645, // 80lx
.abl_bv_thr[1] = 13216, // 160lx
.aoe_bv_thr[0] = 3531, // 40lx
.aoe_bv_thr[1] = 6645, // 80lx
.hist_upper_pixel_ratio = 0.88,
.hist_upper_hs_pixel_ratio = 0.94,
.hist_lower_pixel_ratio = 0.00,
.stg_mode = 0, // <20>Զ<EFBFBD><D4B6>ع<EFBFBD><D8B9><EFBFBD><EFBFBD><EFBFBD> 0<><30><EFBFBD>߹<EFBFBD><DFB9><EFBFBD><EFBFBD>ȣ<EFBFBD> 1<><31><EFBFBD>͹<EFBFBD><CDB9><EFBFBD><EFBFBD><EFBFBD>
.stg_ratio_slope = 0.3*256, // fix(0,16,8), ֵԽ<D6B5><D4BD><EFBFBD><EFBFBD>roi<6F><69>Ȩ<EFBFBD>ص<EFBFBD>Ӱ<EFBFBD><D3B0>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
.stg_max_offset = 20, // fix(0,8,0)<29><> roi<6F><69>Ȩ<EFBFBD><C8A8>Ӱ<EFBFBD><D3B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD>
},
.config_wdr = {
.wdr_en = 0,
.temporal_smooth_alpha = 0.1,
.noise_floor = 128,
.noise_floor_out = 128,
.shadow_boost_target = 512,
.highlight_compress_target = 870,
},
};
void *isp_sensor_param_load(uint16 *buff)
{
struct hgisp_sensor_init *init = NULL;
uint8 sensor_index = 0;
uint32 data_offset = 0;
uint32 param_size = buff[2] << 16 | buff[1];
uint32 gamma_size = 256;
uint32 lsc_size = 153*4*4;
uint32 info_szie = sizeof(struct hgisp_sensor_info);
uint32 sensor_param_size = (gamma_size << 1) + lsc_size + info_szie;
init = (struct hgisp_sensor_init *)os_malloc(sizeof(struct hgisp_sensor_init));
if (init)
{
os_memset(init, 0, sizeof(struct hgisp_sensor_init));
sensor_index = buff[3];
if (sensor_index && (param_size >= sensor_index * sensor_param_size))
{
data_offset = 4;
for (int i = 0; i < sensor_index; i++)
{
if (buff[data_offset+2] == ISPCFG_MAGIC)
{
os_memcpy((void *)&init->sensor_info[i], (void *)&buff[data_offset], info_szie);
init->sensor_info[i].info_src = ISP_INFO_SRC_TYPE_CODE_PARAM;
data_offset += (info_szie >> 1);
init->sensor_info[i].sensor_param.y_gamma = (uint32 *)&buff[data_offset];
data_offset += (gamma_size >> 1);
init->sensor_info[i].sensor_param.rgb_gamma = (uint32 *)&buff[data_offset];
data_offset += (gamma_size >> 1);
init->sensor_info[i].sensor_param.lsc_tbl = (uint32 *)&buff[data_offset];
data_offset += (lsc_size >> 1);
} else {
os_printf("param_data flash : %04x target : %04x err!\r\n", buff[data_offset], ISPCFG_MAGIC);
goto _err;
}
}
os_printf("sensor param use flash_param!\r\n");
goto _end;
} else {
os_printf("param_size : %d calc_size : %d\r\n", param_size, sensor_index * sensor_param_size);
goto _err;
}
} else {
os_printf("%s malloc sram size : %d err!\r\n", sizeof(struct hgisp_sensor_init));
}
return (void *)NULL;
_err:
os_printf("sensor param use default param!\r\n");
init->sensor_info[0].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
init->sensor_info[1].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
init->sensor_info[2].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
os_memcpy((void *)&init->sensor_info[0].sensor_param, (void *)&isp_master_param, sizeof(struct hgisp_param_info));
os_memcpy((void *)&init->sensor_info[1].sensor_param, (void *)&isp_slave0_param, sizeof(struct hgisp_param_info));
os_memcpy((void *)&init->sensor_info[2].sensor_param, (void *)&isp_slave1_param, sizeof(struct hgisp_param_info));
_end:
return (void *)init;
}

View File

@@ -0,0 +1,219 @@
#include "sys_config.h"
#include "typesdef.h"
#include "osal/string.h"
#include "hal/isp_param.h"
#define ISP_DMA_ENABLE 1
const struct hgisp_param_info isp_master_param =
{
.enable_param = {
.test_pattern_en = 0,
.dma_flush_en = ISP_DMA_ENABLE,
.blc_en = 1,
.awb_en = 1,
.ae_en = 1,
.hist_en = 1,
.ccm_en = 1,
.y_gamma_en = 0,
.rgb_gamma_en = 1,
.ce_en = 1,
.sharpen_en = 1,
.bnr_en = 1,
.ynr_en = 1,
.cnr_en = 1,
.csupp_en = 1,
.adj_hue_en = 1,
.lsc_en = 0,
.dpc_en = 0,
.af_en = 0,
.dehaze_en = 0,
.gic_en = 0,
.md_en = 0,
.luma_ca_en = 0,
},
.awb_param = {
.coarse_scale = 128,
.coarse_thr = 3 << 2,
.fine_step = 1 << 2,
.lock_hi_thr = 4,
.lock_lo_thr = 0,
.stable_thr = 16,
.cbcr_thr = 6 << 2,
.awb_auto_en = 1,
.awb_meas_mode = 0,
.cr_target = 2048,
.cb_target = 2048,
.front_cr_val = 30,
.front_cb_val = 30,
.front_uv_sum = 15,
.back_cr_val = 30,
.back_cb_val = 30,
.back_uv_sum = 10,
.cons_cr_max = 40,
.cons_cb_max = 40,
.cons_uv_max = 30,
.cons_cr_min = 10,
.cons_cb_min = 10,
.cons_uv_min = 2,
.back_cr_max = 30,
.back_cb_max = 30,
.back_uv_max = 10,
.back_cr_min = 5,
.back_cb_min = 5,
.back_uv_min = 5,
.awb_wp_max = 0xc0,
.awb_wp_min = 0x08,
.awb_r_max = 0xc0,
.awb_g_max = 0xc0,
.awb_b_max = 0xc0,
.awb_precision = 1,
.awb_fine_cons_en = 1,
.awb_coarse_cons_en = 0,
.awb_back_cons_en = 1,
.awb_back_wp_min_ratio = 0.2,
.manual_gain = {256, 256, 256, 256},
.awb_crop_pixel_start_h = 0,
.awb_crop_pixel_start_v = 0,
.awb_crop_pixel_end_h = 0,
.awb_crop_pixel_end_v = 0,
},
.cfg_ae = {
.ae_manual_en = 0,
.luma_target = 55,
.luma_weight_sum = 61,
.luma_weight = { 2, 2, 2, 2, 2,
2, 3, 3, 3, 2,
2, 3, 5, 3, 2,
2, 3, 3, 3, 2,
2, 2, 2, 2, 2},
.ae_crop_start_h = 0,
.ae_crop_start_v = 0,
.ae_crop_size_h = 0,
.ae_crop_size_v = 0,
.hist_crop_start_h = 1,
.hist_crop_start_v = 1,
.hist_crop_end_h = 0,
.hist_crop_end_v = 0,
.ae_lock_cnt = 10,
.ae_lock_tolerance = 12,
.reduce_fps_en = 0,
.lowlight_lsb_gain_en = 0,
.lowlight_lsb_gain_4hi_fps = 16,
.lowlight_lsb_gain_4lo_fps = 16,
.hist_hs_bin_thr = 180,
.hist_upper_hs_pixel_ratio = 0.94,
.hist_upper_pixel_ratio = 0.88,
.hist_lower_pixel_ratio = 0.00,
.abl_bv_gain_sel = 0,
.abl_expo_line_low_ratio = 0.80,
.abl_expo_line_high_ratio = 1.00,
.abl_expo_gain_low_thr = 256,
.abl_expo_gain_high_thr = 324,
.aoe_expo_gain_thr[0] = 384-50,
.aoe_expo_gain_thr[1] = 384,
.abl_bv_thr[0] = 6645, // 80lx
.abl_bv_thr[1] = 13216, // 160lx
.aoe_bv_thr[0] = 3531, // 40lx
.aoe_bv_thr[1] = 6645, // 80lx
.abl_hist_thr[0] = 50,
.abl_hist_thr[1] = 230,
.dark_pixel_low_ratio = 0.55,
.dark_pixel_high_ratio = 0.85,
.bright_pixel_high_ratio = 0.10,
.bright_pixel_sub_ratio = 0.05,
.dark_pos_thr_max = 50,
.bright_pos_adjust_ratio = 0.80,
.abl_dark_pos_low_wthr = 18, // 0.30 * 61,
.abl_dark_pos_add_wthr = 12, // 0.20 * 61,
.aoe_dark_pos_wthr = 30, // 0.50 * 61,
.aoe_bright_pos_wthr = 9, // 0.15 * 61,
.abl_luma_target_max = 100,
.abl_diff_ratio = 0.03,
.abl_dark_pos_diff_thr = 9, // 0.15 * 61
.abl_bright_pos_diff_thr = 6, // 0.10 * 61
.stg_mode = 0,
.stg_ratio_slope = 0.3*256,
.stg_max_offset = 20,
},
.config_wdr = {
.dynamic_gamma_en = 0,
.y_gamma_opt = 0,
.wdr_en = 0,
.temporal_smooth_alpha = 0.1,
.noise_floor = 128,
.noise_floor_out = 128,
.shadow_boost_target = 512,
.highlight_compress_target = 870,
.auto_noise_floor_out = 1,
.min_ns_percentile = 0.01,
.max_ns_percentile = 0.07,
},
};
void *isp_sensor_param_load(uint16 *buff)
{
struct hgisp_sensor_init *init = NULL;
uint8 sensor_index = 0;
uint32 data_offset = 0;
uint32 param_size = buff[2] << 16 | buff[1];
uint32 gamma_size = 256;
uint32 lsc_size = 153*4*4;
uint32 info_szie = sizeof(struct hgisp_sensor_info);
uint32 sensor_param_size = (gamma_size << 1) + lsc_size + info_szie;
init = (struct hgisp_sensor_init *)os_malloc(sizeof(struct hgisp_sensor_init));
if (init)
{
os_memset(init, 0, sizeof(struct hgisp_sensor_init));
sensor_index = buff[3];
if (sensor_index && (param_size >= sensor_index * sensor_param_size))
{
data_offset = 4;
for (int i = 0; i < sensor_index; i++)
{
if (buff[data_offset+2] == ISPCFG_MAGIC)
{
os_memcpy((void *)&init->sensor_info[i], (void *)&buff[data_offset], info_szie);
init->sensor_info[i].info_src = ISP_INFO_SRC_TYPE_CODE_PARAM;
data_offset += (info_szie >> 1);
init->sensor_info[i].sensor_param.y_gamma = (uint32 *)&buff[data_offset];
data_offset += (gamma_size >> 1);
init->sensor_info[i].sensor_param.rgb_gamma = (uint32 *)&buff[data_offset];
data_offset += (gamma_size >> 1);
init->sensor_info[i].sensor_param.lsc_tbl = (uint32 *)&buff[data_offset];
data_offset += (lsc_size >> 1);
} else {
os_printf("param_data flash : %04x target : %04x err!\r\n", buff[data_offset], ISPCFG_MAGIC);
goto _err;
}
}
os_printf("sensor param use flash_param!\r\n");
goto _end;
} else {
os_printf("param_size : %d calc_size : %d\r\n", param_size, sensor_index * sensor_param_size);
goto _err;
}
} else {
os_printf("%s malloc sram size : %d err!\r\n", sizeof(struct hgisp_sensor_init));
}
return (void *)NULL;
_err:
os_printf("sensor param use default param!\r\n");
init->sensor_info[0].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
init->sensor_info[1].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
init->sensor_info[2].info_src = ISP_INFO_SRC_TYPE_CODE_DOC;
os_memcpy((void *)&init->sensor_info[0].sensor_param, (void *)&isp_master_param, sizeof(struct hgisp_param_info));
// os_memcpy((void *)&init->sensor_info[1].sensor_param, (void *)&isp_slave0_param, sizeof(struct hgisp_param_info));
// os_memcpy((void *)&init->sensor_info[2].sensor_param, (void *)&isp_slave1_param, sizeof(struct hgisp_param_info));
_end:
return (void *)init;
}

View File

@@ -0,0 +1,174 @@
#include "sys_config.h"
#include "typesdef.h"
#include "osal/string.h"
#include "hal/isp_param.h"
#define ISP_DMA_ENABLE 1
const struct hgisp_param_info isp_master_param =
{
.enable_param = {
.test_pattern_en = 0,
.dma_flush_en = ISP_DMA_ENABLE,
.blc_en = 1,
.awb_en = 1,
.ae_en = 1,
.hist_en = 1,
.ccm_en = 1,
.y_gamma_en = 0,
.rgb_gamma_en = 1,
.ce_en = 1,
.sharpen_en = 1,
.bnr_en = 1,
.ynr_en = 1,
.cnr_en = 1,
.csupp_en = 1,
.adj_hue_en = 1,
.lsc_en = 1,
.dpc_en = 0,
.af_en = 0,
.dehaze_en = 0,
.gic_en = 0,
.md_en = 0,
.luma_ca_en = 0,
},
.awb_param = {
.coarse_scale = 128,
.coarse_thr = 3 << 2,
.fine_step = 1 << 2,
.lock_hi_thr = 4,
.lock_lo_thr = 0,
.stable_thr = 16,
.cbcr_thr = 6 << 2,
.awb_auto_en = 1,
.awb_meas_mode = 2,
.cr_target = 2048,
.cb_target = 2048,
.front_cr_val = 30,
.front_cb_val = 30,
.front_uv_sum = 15,
.back_cr_val = 30,
.back_cb_val = 30,
.back_uv_sum = 10,
.cons_cr_max = 40,
.cons_cb_max = 40,
.cons_uv_max = 30,
.cons_cr_min = 10,
.cons_cb_min = 10,
.cons_uv_min = 2,
.awb_wp_max = 0xc0,
.awb_wp_min = 32,
.awb_r_max = 0xc0,
.awb_g_max = 0xc0,
.awb_b_max = 0xc0,
.awb_precision = 1,
.awb_fine_cons_en = 0,
.awb_coarse_cons_en = 0,
.manual_gain = {256, 256, 256, 256},
},
.cfg_ae = {
.ae_manual_en = 0,
.luma_target = 55,
.luma_weight_sum = 450,
.luma_weight = { 10, 10, 10, 10, 10,//50
10, 30, 30, 30, 10,//110
10, 30, 50, 30, 10,//130
10, 30, 30, 30, 10,//110
10, 10, 10, 10, 10},//50
.ae_lock_cnt = 5,
.ae_lock_tolerance = 12,
.reduce_fps_en = 0,
.lowlight_lsb_gain_en = 1,//低光<<2
.lowlight_lsb_gain_4hi_fps = 64,
.lowlight_lsb_gain_4lo_fps = 64,
.hist_hs_bin_thr = 250,
.hist_upper_hs_pixel_ratio = 0.74,
.hist_upper_pixel_ratio = 0.88,
.hist_lower_pixel_ratio = 0.00,
.abl_luma_target_max = 100,
.dark_pos_thr_max = 50,
.abl_diff_ratio = 0.03,
.abl_dark_pos_diff_thr = 9, // 0.15 * 61
.abl_bright_pos_diff_thr = 6, // 0.10 * 61
.bright_pixel_high_ratio = 0.10,
.bright_pixel_sub_ratio = 0.05,
.dark_pixel_low_ratio = 0.55,
.dark_pixel_high_ratio = 0.85,
.abl_dark_pos_low_wthr = 18, // 0.30 * 61,
.abl_dark_pos_add_wthr = 12, // 0.20 * 61,
.bright_pos_adjust_ratio = 0.80,
.aoe_dark_pos_wthr = 30, // 0.50 * 61,
.aoe_bright_pos_wthr = 9, // 0.15 * 61,
// .abl_bv_gain_sel = 0,
.abl_expo_line_low_ratio = 0.80,
.abl_expo_line_high_ratio = 1.00,
.abl_expo_gain_low_thr = 256,
.abl_expo_gain_high_thr = 324,
.abl_hist_thr[0] = 50,
.abl_hist_thr[1] = 230,
.aoe_expo_gain_thr[0] = 384-50,
.aoe_expo_gain_thr[1] = 384,
// .abl_bv_thr[0] = 6645, // 80lx
// .abl_bv_thr[1] = 13216, // 160lx
// .aoe_bv_thr[0] = 3531, // 40lx
// .aoe_bv_thr[1] = 6645, // 80lx
.stg_mode = 0,
.stg_ratio_slope = 0.3*256,
.stg_max_offset = 0,
.abl_bv_gain_sel = 1,
.abl_bv_thr[0] = 1e20,
.abl_bv_thr[1] = 1e20,
.aoe_bv_thr[0] = 1,
.aoe_bv_thr[1] = 1,
},
.config_wdr = {
.wdr_en = 0,
.temporal_smooth_alpha = 0.1,
.noise_floor = 128,
.noise_floor_out = 128,
.shadow_boost_target = 512,
.highlight_compress_target = 870,
},
};
#define SENSOR_PARAM_SIZE (64*4*4+153*4*4)
void *isp_sensor_param_load(uint16 *buff)
{
struct hgisp_sensor_init *init = NULL;
init = (struct hgisp_sensor_init *)os_malloc(sizeof(struct hgisp_sensor_init));
if (init)
{
os_memset(init, 0, sizeof(struct hgisp_sensor_init));
if (buff[0] && (buff[1]) && (buff[2] == ISPCFG_MAGIC))
{
os_printf("sensor param use flash param!\r\n");
os_memcpy(init, (void *)&buff[2], sizeof(struct hgisp_sensor_init));
goto _end;
} else {
goto _err;
}
} else {
os_printf("%s malloc sram size : %d err!\r\n", sizeof(struct hgisp_sensor_init));
}
return (void *)NULL;
_err:
os_printf("sensor param use default param!\r\n");
os_memcpy((void *)&init->sensor_info[0].sensor_param, (void *)&isp_master_param, sizeof(struct hgisp_param_info));
// os_memcpy((void *)&init->sensor_info[1].sensor_param, (void *)&isp_slave0_param, sizeof(struct hgisp_param_info));
// os_memcpy((void *)&init->sensor_info[2].sensor_param, (void *)&isp_slave1_param, sizeof(struct hgisp_param_info));
_end:
return (void *)init;
}

View File

@@ -0,0 +1,691 @@
#include "basic_include.h"
#include "hal/isp_tunning.h"
#include "hal/isp.h"
#include "hal/dual_org.h"
#include "lib/multimedia/framebuff.h"
#include "lib/multimedia/msi.h"
#include "lib/video/dvp/jpeg/jpg.h"
#if ISP_TUNNING_EN
struct isp_tunnning_dev *isp_tunning = NULL;
void isp_tunning_response(struct isp_tunnning_dev *p_dev, uint16 ret_val)
{
uint16 crc_val = 0;
os_memset(p_dev->response, 0, 8);
p_dev->response[0] = p_dev->tunning_head;
p_dev->response[1] = p_dev->cmd_num;
p_dev->response[2] = ret_val;
crc_val = hw_crc(CRC_TYPE_CRC16_MODBUS, (void *)p_dev->response, 6);
p_dev->response[3] = crc_val;
p_dev->response[5] = 0x0a;
p_dev->write_handle(p_dev->device, 0, (void *)p_dev->response, sizeof(p_dev->response));
}
void isp_tunning_message_head(struct isp_tunnning_dev *p_dev, uint32 data_addr, uint32 data_len)
{
p_dev->message_head[0] = p_dev->tunning_head;
p_dev->message_head[1] = p_dev->cmd_num;
p_dev->message_head[2] = (data_len >> 0) & 0xffff;
p_dev->message_head[3] = (data_len >> 16) & 0xffff;
p_dev->message_head[4] = hw_crc(CRC_TYPE_CRC16_MODBUS, (void *)data_addr, data_len);
p_dev->message_head[5] = hw_crc(CRC_TYPE_CRC16_MODBUS, (void *)p_dev->message_head, TUNNING_PACKAGE_INFO_SIZE - 2 - 4);
p_dev->message_head[6] = 0x00;
p_dev->message_head[7] = 0x0a;
p_dev->write_handle(p_dev->device, 0, (void *)p_dev->message_head, TUNNING_PACKAGE_INFO_SIZE);
}
uint32 isp_tunning_get_img(struct isp_tunnning_dev *p_dev)
{
uint32 ret_val = TUNNING_ERR_CODE_RIGHT;
uint32 flen = 0;
uint32 offset = 0;
uint8 *img_addr = NULL;
struct framebuff *get_f = NULL;
uint8 get_max = 10;
uint8 get_idx = 0;
uint8 first_packet = 0;
while((++get_idx) <= get_max)
{
__retry:
get_f = msi_get_fb(p_dev->v_msi, 100);
if (get_f)
{
if (abs(get_f->time - os_jiffies()) > 100)
{
msi_delete_fb(NULL, get_f);
get_f = NULL;
goto __retry;
}
flen = get_f->len;
img_addr = get_f->data;
p_dev->write_data.addr = os_zalloc(TUNNING_PACKET_SIZE+4);
if (p_dev->write_data.addr)
{
// os_printf("%s %d addr : %08x\r\n", __func__, __LINE__, (uint32)p_dev->write_data.addr);
isp_tunning_message_head(p_dev, (uint32)img_addr, flen);
p_dev->write_data.addr[TUNNING_PACKET_SIZE+0] = 0x00;
p_dev->write_data.addr[TUNNING_PACKET_SIZE+1] = 0x00;
p_dev->write_data.addr[TUNNING_PACKET_SIZE+2] = 0x0d;
p_dev->write_data.addr[TUNNING_PACKET_SIZE+3] = 0x0a;
while (flen)
{
offset = (flen > TUNNING_PACKET_SIZE) ? (TUNNING_PACKET_SIZE) : (flen);
hw_memcpy((void *)p_dev->write_data.addr, img_addr, offset);
img_addr += offset;
flen -= offset;
if (offset < TUNNING_PACKET_SIZE)
{
p_dev->write_data.addr[offset+0] = 0x00;
p_dev->write_data.addr[offset+1] = 0x00;
p_dev->write_data.addr[offset+2] = 0x0d;
p_dev->write_data.addr[offset+3] = 0x0a;
}
p_dev->write_handle(p_dev->device, 0, (void *)p_dev->write_data.addr, offset+4);
if (first_packet == 0) {
os_sleep_ms(10);
first_packet = 1;
}else {
os_sleep_ms(1);
}
}
os_free(p_dev->write_data.addr);
} else {
ret_val = TUNNING_ERR_CODE_MALLOC_ERR;
os_printf("%s %d malloc size : %d err\r\n", __func__, __LINE__, TUNNING_PACKET_SIZE);
goto __err;
}
break;
}
}
if ((get_idx > get_max) && (get_f == NULL))
{
ret_val = TUNNING_ERR_CODE_GET_PARAM_ERR;
os_printf("%s %d get frame err\r\n", __func__, __LINE__);
goto __err;
}
goto __end;
__err:
isp_tunning_response(p_dev, ret_val);
__end:
if(get_f)
{
msi_delete_fb(NULL, get_f);
p_dev->v_msi->enable = 0;
while(1)
{
get_f = msi_get_fb(p_dev->v_msi, 0);
if (get_f)
{
msi_delete_fb(NULL, get_f);
} else {
break;
}
}
get_f = NULL;
}
return ret_val;
}
void isp_tunning_get_raw(struct isp_tunnning_dev *p_dev)
{
uint32 ret_val = TUNNING_ERR_CODE_RIGHT;
uint32 flen = 0;
uint32 offset = 0;
uint8 first_packet = 0;
p_dev->backup_addr = dual_save_cfg(p_dev->p_dual, p_dev->cmd_channel, (uint32)&flen);
p_dev->write_data.size = TUNNING_PACKET_SIZE;
p_dev->write_data.addr = os_zalloc(TUNNING_PACKET_SIZE+4);
if (p_dev->write_data.addr)
{
// os_printf("%s %d addr : %08x src : %08x flen : %d\r\n", __func__, __LINE__, (uint32)p_dev->write_data.addr, p_dev->backup_addr, flen);
while(!dual_save_status(p_dev->p_dual));
sys_dcache_invalid_range((void *)p_dev->backup_addr, flen);
isp_tunning_message_head(p_dev, p_dev->backup_addr, flen);
p_dev->write_data.addr[TUNNING_PACKET_SIZE+0] = 0x00;
p_dev->write_data.addr[TUNNING_PACKET_SIZE+1] = 0x00;
p_dev->write_data.addr[TUNNING_PACKET_SIZE+2] = 0x0d;
p_dev->write_data.addr[TUNNING_PACKET_SIZE+3] = 0x0a;
while (flen)
{
// os_printf("%s %d flen : %d\r\n", __func__, __LINE__, flen);
offset = (flen > TUNNING_PACKET_SIZE) ? (TUNNING_PACKET_SIZE) : (flen);
hw_memcpy((void *)p_dev->write_data.addr, (void *)p_dev->backup_addr, offset);
p_dev->backup_addr += offset;
flen -= offset;
if (offset < TUNNING_PACKET_SIZE)
{
p_dev->write_data.addr[offset+0] = 0x00;
p_dev->write_data.addr[offset+1] = 0x00;
p_dev->write_data.addr[offset+2] = 0x0d;
p_dev->write_data.addr[offset+3] = 0x0a;
}
p_dev->write_handle(p_dev->device, 0, (void *)p_dev->write_data.addr, offset+4);
if (first_packet == 0) {
os_sleep_ms(10);
first_packet = 1;
}else {
os_sleep_ms(1);
}
}
dual_recover_cfg(p_dev->p_dual);
os_free(p_dev->write_data.addr);
} else {
os_printf("%s %d get package_size : %d err\r\n", __func__, __LINE__, TUNNING_PACKET_SIZE);
ret_val = TUNNING_ERR_CODE_MALLOC_ERR;
goto __err;
}
return;
__err:
isp_tunning_response(p_dev, ret_val);
return;
}
void isp_tunning_dump_data(struct isp_tunnning_dev *p_dev, uint32 data_addr, uint32 data_size)
{
uint32 ret_val = 0;
uint32 flen = data_size;
uint32 first_packet = 0;
uint32 offset = 0;
uint32 faddr = data_addr;
p_dev->write_data.addr = os_malloc(TUNNING_PACKET_SIZE + 4);
if (p_dev->write_data.addr)
{
isp_tunning_message_head(p_dev, faddr, flen);
p_dev->write_data.addr[TUNNING_PACKET_SIZE+0] = 0x00;
p_dev->write_data.addr[TUNNING_PACKET_SIZE+1] = 0x00;
p_dev->write_data.addr[TUNNING_PACKET_SIZE+2] = 0x0d;
p_dev->write_data.addr[TUNNING_PACKET_SIZE+3] = 0x0a;
while (flen)
{
offset = (flen > TUNNING_PACKET_SIZE) ? (TUNNING_PACKET_SIZE) : (flen);
hw_memcpy((void *)p_dev->write_data.addr, (void *)faddr, offset);
faddr += offset;
flen -= offset;
if (offset < TUNNING_PACKET_SIZE)
{
p_dev->write_data.addr[offset+0] = 0x00;
p_dev->write_data.addr[offset+1] = 0x00;
p_dev->write_data.addr[offset+2] = 0x0d;
p_dev->write_data.addr[offset+3] = 0x0a;
}
p_dev->write_handle(p_dev->device, 0, (void *)p_dev->write_data.addr, offset+4);
if (first_packet == 0) {
os_sleep_ms(10);
first_packet = 1;
}else {
os_sleep_ms(1);
}
}
os_free(p_dev->write_data.addr);
} else {
os_printf("%s %d malloc write_data err\r\n", __func__, __LINE__);
goto __err;
}
return;
__err:
isp_tunning_response(p_dev, ret_val);
return;
}
void isp_tunning_thread(void *dev)
{
uint32 ret_val = 0;
uint8 response_flag = 1;
scatter_data dump_data;
struct isp_tunnning_dev *p_dev = (struct isp_tunnning_dev *)dev;
os_memset(&dump_data, 0, sizeof(scatter_data));
while(1)
{
response_flag = 1;
os_sema_down((void *)&p_dev->usb_cmd_sema, -1);
switch (p_dev->cmd_num)
{
case ISP_IOCTL_CMD_3DNR_ENABLE:
isp_3dnr_enable(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_IMG_MIRROR:
isp_mirror_enable(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_IMG_REVERSE:
isp_reverse_enable(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_GET_IMG:
p_dev->v_msi->enable = 1;
ret_val = isp_tunning_get_img(p_dev);
response_flag = 0;
break;
case ISP_IOCTL_CMD_AWB_MANNUL_MODE_TYPE:
isp_awb_mannul_mode_type(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_CONTROL_STEP:
isp_awb_control_step_config(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_CONTROL_THR:
isp_awb_control_thr_config(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->p_data[3], p_dev->p_data[4], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_AUTO_CTRL:
isp_awb_auto_config(p_dev->p_isp, p_dev->p_data[0], (void *)&p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_FINE_CONSTRAINT_CTRL:
isp_awb_fine_constraint_enable(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_COARSE_CONSTRAINT_CTRL:
isp_awb_coarse_constraint_enable(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_MEAS_MODE:
isp_awb_measure_mode_config(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_WP_EXPECT:
isp_awb_wp_expect_val(p_dev->p_isp, p_dev->p_data[1], p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_WP_RANGE_CONSTRAINT:
isp_awb_cbcr_constraint(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_WP_RANGE_CONSTRAINTF:
isp_awb_cbcr_constraintf(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_WP_RANGE_CONSTRAINT_RESTRAIN:
isp_awb_cbcr_constraint_restrain(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_RGB_CONSTRAINT:
isp_awb_rgb_constraint(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_WP_NUM_RESTRAIN:
isp_awb_wp_constraint(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_GAIN_TYPE:
isp_awb_gain_type(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_GAIN_CONSTRAINT:
isp_awb_gain_constraint(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_GAIN_COARSE_CONSTRAINT:
isp_awb_gain_coarse_constraint(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_GAIN_FINE_CONSTRAINT:
isp_awb_gain_fine_constraint(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AWB_CROP_RANGE:
ret_val = isp_awb_crop_range(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->p_data[3], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_MANUAL_PARAM:
isp_ae_manul_config(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_ROW_TIME_US:
isp_ae_row_time(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_ANALOG_GAIN:
isp_ae_analog_gain(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_EXPOSURE_LINE:
isp_ae_exposure_line(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_CONFIG_INTERVAL:
isp_ae_interval_config(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_DAY_NIGHT_BV:
isp_ae_day_night_bv(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_SCENE_LUT:
isp_ae_scene_lut(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_LOWLIGHT_PARAM:
isp_ae_lowlight_param(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_FRAME_MAX:
isp_ae_frame_max(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_LOCK_PARAM:
isp_ae_lock_param(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_REDUCE_FPS:
isp_ae_reduce_fps(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_LOWLIGHT_LSB_GAIN_EN:
isp_ae_lowlight_gain_enable(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_LOWLIGHT_LSB_GAIN_4HI_FPS:
isp_ae_lowlight_gain_high_gain(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_LOWLIGHT_LSB_GAIN_4LO_FPS:
isp_ae_lowlight_gain_low_gain(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_HIST_HS_BIN_THR:
isp_ae_hist_hs_bin_thr(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_LUMA_TARGET:
isp_ae_luma_target_config(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_LUMA_WEIGHT:
isp_ae_luma_weight_config(p_dev->p_isp, p_dev->p_data[0], (void *)&p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_ABL_LUMA_MAX:
isp_ae_abl_luma_max(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_POS_THR:
isp_ae_pos_thr(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_HIST_THR:
isp_ae_hist_thr(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_AOE_EXPO_GAIN:
isp_ae_aoe_gain(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_ABL_LOCK_THR:
isp_ae_abl_lock(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_BRIGHT_DARK_PIXEL_RATIO:
isp_ae_brihgt_dark_pixel_ratio(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->p_data[3], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_ABL_DARK_BRIGHT_POS_THR:
isp_ae_abl_dark_bright_pos_ratio(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_AOE_DARK_BRIGHT_POS_THR:
isp_ae_aoe_dark_bright_pos_ratio(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_ABL_GAIN_MODE:
isp_ae_abl_gain_type(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_ABL_EXPO_LINE_RATIO:
isp_ae_abl_expo_line_ratio(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_ABL_EXPO_GAIN_THR:
isp_ae_abl_expo_gain_set(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_ABL_BV_THR:
isp_ae_abl_bv_thr(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_AOE_BV_THR:
isp_ae_aoe_bv_thr(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_HIST_PIXEL_THR:
isp_ae_hist_pixel_thr(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_STG_PARAM:
ret_val = isp_ae_stg_param(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_EV_OFFSET_TYPE:
isp_ae_ev_offset_type(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_AE_CROP_RANGE:
isp_ae_crop_range(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_HIST_CROP_RANGE:
isp_hist_crop_range(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_CCM_ARRAY:
isp_ccm_config(p_dev->p_isp, (void *)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_BLC_PARAM:
isp_blc_config(p_dev->p_isp, (void *)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_MD_WINDOW_PARAM:
isp_md_window_config(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->p_data[3], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_MD_DETECT_PARAM:
isp_md_param_config(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_CSC_PARAM:
isp_csc_config(p_dev->p_isp, (void *)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_DPC_PARAM:
isp_dpc_config(p_dev->p_isp, (void *)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_CE_YUV_RANGE:
isp_ce_yuv_range(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_CE_LUMA:
isp_ce_luma_config(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_CE_SATURATION:
isp_ce_saturation_config(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_CE_CONTRAST:
isp_ce_contrast_config(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_CE_HUE:
isp_ce_hue_config(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_CE_OFFSET_PARAM:
isp_ce_offset_config(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_CE_ADJ_BY_BV_PARAM:
isp_ce_adj_by_bv_param(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_SHARP_PARAM:
isp_sharp_param(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_RAWNR_MAP:
isp_rawnr_map(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], (uint32)&p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_YUVNR_MAP:
isp_yuvnr_map(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], (uint32)&p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_CSUPP_MAP:
isp_csupp_map(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], (uint32)&p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_Y_GAMMA_TUNNING:
isp_y_gamma_tunning(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_RGB_GAMMA_TUNNING:
isp_rgb_gamma_tunning(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_LSC_TUNNING:
isp_lsc_tunning(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_GIC_PARAM:
isp_gic_init(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_LHS_MAP:
isp_lhs_map(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], (uint32)&p_dev->p_data[2], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_GET_SENSOR_RAW:
isp_tunning_get_raw(p_dev);
response_flag = 0;
break;
case ISP_IOCTL_CMD_GET_Y_GAMMA:
case ISP_IOCTL_CMD_GET_SENSOR_YGAMMA:
case ISP_IOCTL_CMD_GET_RGB_GAMMA:
case ISP_IOCTL_CMD_GET_LSC:
case ISP_IOCTL_CMD_DUMP_SRAM_PARAM:
case ISP_IOCTL_CMD_DUMP_REG_PARAM:
ret_val = isp_ioctl(p_dev->p_isp, p_dev->cmd_num, p_dev->cmd_channel, (uint32)&dump_data);
//os_printf("%s %d dump addr :%08x dump_data : %08x\r\n", __func__, __LINE__, (uint32)dump_data.addr, dump_data.size);
if (!ret_val) isp_tunning_dump_data(p_dev, (uint32)dump_data.addr, dump_data.size);
response_flag = 0;
break;
case ISP_IOCTL_CMD_CONFIG_SRAM_PARAM:
isp_sensor_sram_param_config(p_dev->p_isp, p_dev->cmd_channel, (uint32)p_dev->p_data);
break;
case ISP_IOCTL_CMD_FUNC_ENABLE:
ret_val = isp_sensor_func_enable(p_dev->p_isp, p_dev->cmd_channel, (uint32)p_dev->p_data[0]);
break;
case ISP_IOCTL_CMD_WDR_EN:
isp_wdr_en_config(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_WDR_NOISE_FLOOR:
isp_wdr_noise_floor_config(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_WDR_TUNNING:
isp_wdr_tunning(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_GAMMA_BY_BV_PARAM:
isp_gamma_by_bv_param(p_dev->p_isp, (uint32)p_dev->p_data, p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_GAMMA_BY_BV_ENABLE:
isp_gamma_by_bv_enable(p_dev->p_isp, p_dev->p_data[0], p_dev->cmd_channel);
break;
case ISP_IOCTL_CMD_FPS_OPT:
{
float value = *(float *)p_dev->p_data;
isp_sensor_fps_opt(p_dev->p_isp, value, p_dev->cmd_channel);
}
break;
case ISP_IOCTL_CMD_DYN_YGAMMA_OPT:
isp_dyn_gamma_param(p_dev->p_isp, p_dev->p_data[0], p_dev->p_data[1], p_dev->cmd_channel);
break;
default:
os_printf("tunning get cmd type : %d err type : %d!\r\n", p_dev->cmd_num, ret_val);
break;
}
if (p_dev->p_data) os_free(p_dev->p_data);
if (response_flag) isp_tunning_response(p_dev, ret_val);
}
}
void isp_tunning_get_img_msi_create(struct isp_tunnning_dev *p_dev, enum tunning_img_type type, uint32 img_w, uint32 img_h, uint32 src)
{
if (type)
{
struct msi *h264_msi_init_with_mode(uint32_t drv1_from, uint32_t drv1_w, uint32_t drv1_h, uint32_t drv2_from, uint32_t drv2_w, uint32_t drv2_h);
p_dev->video_msi = msi_find("auto-h264", 1);//h264_msi_init_with_mode(src, img_w, img_h, 0, 0, 0);
} else {
struct msi *jpg_concat_msi_init_start(uint32_t jpgid,uint16_t w, uint16_t h, uint16_t *filter_type,uint8_t src_from,uint8_t run);
p_dev->video_msi = msi_find("auto-jpg", 1);//jpg_concat_msi_init_start(JPGID0, img_w, img_h, NULL, src,1);
}
if (p_dev->video_msi)
{
p_dev->v_msi = msi_new(TUNNING_IMG_MSI,1,NULL);
if (p_dev->v_msi)
{
// p_dev->v_msi->enable = 1;
msi_add_output(p_dev->video_msi, NULL, TUNNING_IMG_MSI);
} else {
p_dev->video_msi = NULL;
p_dev->v_msi = NULL;
}
} else {
p_dev->video_msi = NULL;
p_dev->v_msi = NULL;
}
}
void isp_tunning_init(uint32 img_w, uint32 img_h)
{
rt_ssize_t cdc_usb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
isp_tunning = os_zalloc(sizeof(struct isp_tunnning_dev));
if (isp_tunning == NULL)
{
os_printf("%s %d isp_tunning_dev malloc err");
return;
}
os_sema_init(&isp_tunning->usb_write_sema, 0);
os_sema_init(&isp_tunning->usb_cmd_sema , 0);
isp_tunning->tunning_head = 0xb103;
isp_tunning->tunning_succ = 0x55aa;
isp_tunning->tunning_err = 0x5a5a;
isp_tunning->p_isp = (struct isp_device *)dev_get(HG_ISP_DEVID);
isp_tunning->p_dual = (struct dual_device *)dev_get(HG_DUALORG_DEVID);
isp_tunning->write_handle = cdc_usb_write;
isp_tunning_get_img_msi_create(isp_tunning, TUNNING_IMG_JPEG, img_w, img_h, 0);
if ((isp_tunning->p_isp == NULL) || (isp_tunning->p_dual == NULL) || (isp_tunning->video_msi == NULL))
{
os_printf("%s %d get device isp:%d dual:%d msi : %d err", __func__, __LINE__, (isp_tunning->p_isp == NULL), (isp_tunning->p_dual == NULL), (isp_tunning->video_msi == NULL));
os_free(isp_tunning);
return;
}
os_printf("%s %d create succ\r\n", __func__, __LINE__);
os_task_create("isp_tunning_demo", isp_tunning_thread, (void *)isp_tunning, OS_TASK_PRIORITY_NORMAL, 0, NULL, 1024);
}
#endif

View File

@@ -0,0 +1,148 @@
/**
* @file adts.c
* @brief
* @author licaibiao
* @version 1.0
* @date 2023-12-06
*
* @copyright Copyright (c) 2023-2030 liwen01 Technology Co., Ltd
*
*/
#include "adts.h"
#include <math.h>
void set_fixed_header(adts_fixed_header *header) {
header->syncword = 0xFF;// 代表着一个帧的开始
header->id = 1;// MPEG Version: 0 for MPEG-4, 1 for MPEG-2
header->layer = 0;// always 00
header->protection_absent = 1;// 表示是否误码校验
header->profile = 1;// 表示使用哪个级别的AAC, 有些芯片只支持AAC LC.
header->sampling_frequency_index = 0xb;// 表示使用的采样率的下标
header->private_bit = 0;
header->channel_configuration = 1;// 表示声道数
header->original_copy = 0;
header->home = 0;
}
void set_variable_header(adts_variable_header *header, const int aac_raw_data_length) {
header->copyright_identification_bit = 0;
header->copyright_identification_start = 0;
header->aac_frame_length = aac_raw_data_length + 7;
header->adts_buffer_fullness = 0x7f;
header->number_of_raw_data_blocks_in_frame = 0;
}
void get_fixed_header(const unsigned char buff[7], adts_fixed_header *header) {
unsigned long long adts = 0;
const unsigned char *p = buff;
adts |= *p ++; adts <<= 8;
adts |= *p ++; adts <<= 8;
adts |= *p ++; adts <<= 8;
adts |= *p ++; adts <<= 8;
adts |= *p ++; adts <<= 8;
adts |= *p ++; adts <<= 8;
adts |= *p ++;
header->syncword = (adts >> 44);
header->id = (adts >> 43) & 0x01;
header->layer = (adts >> 41) & 0x03;
header->protection_absent = (adts >> 40) & 0x01;
header->profile = (adts >> 38) & 0x03;
header->sampling_frequency_index = (adts >> 34) & 0x0f;
header->private_bit = (adts >> 33) & 0x01;
header->channel_configuration = (adts >> 30) & 0x07;
header->original_copy = (adts >> 29) & 0x01;
header->home = (adts >> 28) & 0x01;
}
void get_variable_header(const unsigned char buff[7], adts_variable_header *header) {
unsigned long long adts = 0;
adts = buff[0]; adts <<= 8;
adts |= buff[1]; adts <<= 8;
adts |= buff[2]; adts <<= 8;
adts |= buff[3]; adts <<= 8;
adts |= buff[4]; adts <<= 8;
adts |= buff[5]; adts <<= 8;
adts |= buff[6];
header->copyright_identification_bit = (adts >> 27) & 0x01;
header->copyright_identification_start = (adts >> 26) & 0x01;
header->aac_frame_length = (adts >> 13) & ((int)pow(2, 14) - 1);
header->adts_buffer_fullness = (adts >> 2) & ((int)pow(2, 11) - 1);
header->number_of_raw_data_blocks_in_frame = adts & 0x03;
}
void convert_adts_header2int64(const adts_fixed_header *fixed_header, const adts_variable_header *variable_header, uint64_t *header) {
uint64_t ret_value = 0;
ret_value = ((fixed_header->syncword<<4) | 0x0F);
ret_value <<= 1;
ret_value |= fixed_header->id;
ret_value <<= 2;
ret_value |= fixed_header->layer;
ret_value <<= 1;
ret_value |= (fixed_header->protection_absent) & 0x01;
ret_value <<= 2;
ret_value |= fixed_header->profile;
ret_value <<= 4;
ret_value |= (fixed_header->sampling_frequency_index) & 0x0f;
ret_value <<= 1;
ret_value |= (fixed_header->private_bit) & 0x01;
ret_value <<= 3;
ret_value |= (fixed_header->channel_configuration) & 0x07;
ret_value <<= 1;
ret_value |= (fixed_header->original_copy) & 0x01;
ret_value <<= 1;
ret_value |= (fixed_header->home) & 0x01;
ret_value <<= 1;
ret_value |= (variable_header->copyright_identification_bit) & 0x01;
ret_value <<= 1;
ret_value |= (variable_header->copyright_identification_start) & 0x01;
ret_value <<= 13;
ret_value |= (variable_header->aac_frame_length) & ((int)pow(2, 13) - 1);
ret_value <<= 11;
ret_value |= ((variable_header->adts_buffer_fullness<<4) | 0x0F ) & ((int)pow(2, 11) - 1);
ret_value <<= 2;
ret_value |= (variable_header->number_of_raw_data_blocks_in_frame) & ((int)pow(2, 2) - 1);
*header = ret_value;
}
void convert_adts_header2char(const adts_fixed_header *fixed_header, const adts_variable_header *variable_header, unsigned char buffer[7]) {
uint64_t value = 0;
convert_adts_header2int64(fixed_header, variable_header, &value);
buffer[0] = (value >> 48) & 0xff;
buffer[1] = (value >> 40) & 0xff;
buffer[2] = (value >> 32) & 0xff;
buffer[3] = (value >> 24) & 0xff;
buffer[4] = (value >> 16) & 0xff;
buffer[5] = (value >> 8) & 0xff;
buffer[6] = (value) & 0xff;
}
void aac_dsi_to_adts(uint8_t *dsi, uint8_t *adts, uint32_t aac_data_length)
{
uint8_t audio_object_type = (dsi[0] >> 3) & 0x1F;
uint8_t profile = audio_object_type - 1;
uint8_t samplerate_index = ((dsi[0] & 0x07) << 1) | (dsi[1] >> 7);
uint8_t channels = (dsi[1] >> 3) & 0x0F;
;uint32_t frame_length = aac_data_length + 7;
adts[0] = 0xFF; //syncword hight 8 bits
adts[1] = 0xF0; //syncword low 4 bits
adts[1] |= (0x01 << 3); //ID 0:MPEG-4,1:MPEG-2
adts[1] |= (0x00 << 1); //layer:00
adts[1] |= (0x01 & 0x1); //1:no CRC,0:is CRC
adts[2] = (profile << 6); //profile 0x01:AAC-LC
adts[2] |= (samplerate_index << 2);
adts[2] |= (0x00 << 1); //private_bit (0)
adts[2] |= (channels & 0x4) >> 2;
adts[3] = (channels & 0x3) << 6;
adts[3] |= (frame_length >> 11); //frame_length bits12-bits13
adts[4] = (frame_length >> 3) & 0xFF; //frame_length bits4-bits11
adts[5] = (frame_length & 0x07) << 5; //frame_length low 3 bits first
adts[5] |= (0x7FF >> 6) & 0x1F; //adts_buffer_fullness high 5 bits
adts[6] = (0x7FF & 0x3F) << 2; //adts_buffer_fullness low 6 bits
adts[6] |= (0x00); //number_of_raw_data_blocks_in_frame (0)
}

View File

@@ -0,0 +1,67 @@
/**
* @file adts.h
* @brief
* @author licaibiao
* @version 1.0
* @date 2023-12-06
*
* @copyright Copyright (c) 2023-2030 liwen01 Technology Co., Ltd
*
*/
#ifndef __AdtsHeader__adts__
#define __AdtsHeader__adts__
#include <stdio.h>
#include <stdint.h>
/*
* ADTS 全称: Audio Data Transport Stream. 是 AAC音频的传输流格式.
* ADTS头中相对有用的信息包括: 采样率, 声道数, 帧长度. 每一个带ADTS头信息的AAC流都会清晰的告诉解码器他需要的这些信息.
* 一般情况下ADTS的头信息都是7个字节, 分为两部分: 前28bit是 adts_fixed_header, 后28bit是 adts_variable_header.
*/
typedef struct adts_fixed_header {
unsigned short syncword: 12;
unsigned char id: 1;
unsigned char layer: 2;
unsigned char protection_absent: 1;
unsigned char profile: 2;
unsigned char sampling_frequency_index: 4;
unsigned char private_bit: 1;
unsigned char channel_configuration: 3;
unsigned char original_copy: 1;
unsigned char home: 1;
} adts_fixed_header; // length : 28 bits
typedef struct adts_variable_header {
unsigned char copyright_identification_bit: 1;
unsigned char copyright_identification_start: 1;
unsigned short aac_frame_length: 13;
unsigned short adts_buffer_fullness: 11;
unsigned char number_of_raw_data_blocks_in_frame:2;
} adts_variable_header; // length : 28 bits
// 设置adts固定的一部分
extern void set_fixed_header(adts_fixed_header *header);
// 设置adts可变的一部分
extern void set_variable_header(adts_variable_header *header, const int aac_raw_data_length);
// 解析buff中的adts固定部分头信息
extern void get_fixed_header(const unsigned char buff[7], adts_fixed_header *header);
// 解析buff中的adts可变部分头信息
extern void get_variable_header(const unsigned char buff[7], adts_variable_header *header);
// 将adts头信息转化为一个64位的整数, PS: 前面8位空着
extern void convert_adts_header2int64(const adts_fixed_header *fixed_header, const adts_variable_header *variable_header, uint64_t *header);
// 将adts头信息转化为一个7字节的buff
extern void convert_adts_header2char(const adts_fixed_header *fixed_header, const adts_variable_header *variable_header, unsigned char buffer[7]);
extern void aac_dsi_to_adts(uint8_t *dsi, uint8_t *adts, uint32_t aac_data_length);
#endif /* defined(__AdtsHeader__adts__) */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,438 @@
/**********************************************************************
* 缩时录影的基本代码demo
*********************************************************************/
#include "basic_include.h"
#include "fatfs/osal_file.h"
#include "lib/heap/av_heap.h"
#include "lib/heap/av_psram_heap.h"
#include "lib/multimedia/msi.h"
#include "osal/string.h"
#include "stream_define.h"
#include "audio_media_ctrl/audio_code_ctrl.h"
#include "audio_msi/audio_adc.h"
#include "mp4/mp4_encode.h"
// 结构体申请空间函数
#define STREAM_MALLOC av_psram_malloc
#define STREAM_FREE av_psram_free
#define STREAM_ZALLOC av_psram_zalloc
// 结构体申请空间函数
#define STREAM_LIBC_MALLOC os_malloc
#define STREAM_LIBC_FREE os_free
#define STREAM_LIBC_ZALLOC os_zalloc
enum
{
MSI_MP4_STOP = BIT(0),
MSI_MP4_THREAD_DEAD = BIT(1),
};
#define TIME_LAPSE_DIR "0:/DCIM"
#define MP4_FILE_NAME "mp4"
struct mp4_encode_msi_s
{
struct msi *msi;
struct os_event evt;
uint16_t rec_time;
uint16_t filter_type;
};
#define MIN(a, b) ((a) > (b) ? b : a)
#define MAX(a, b) ((a) > (b) ? a : b)
static uint32_t a2i(char *str)
{
uint32_t ret = 0;
uint32_t indx = 0;
char str_buf[32];
memset(str_buf, 0, 32);
while (str[indx] != '\0')
{
if (str[indx] == '.')
{
break;
}
str_buf[indx] = str[indx];
indx++;
}
// printf("str_buf:%s str:%s\r\n",str_buf,str);
indx = 0;
while (str_buf[indx] != '\0')
{
if (str_buf[indx] >= '0' && str_buf[indx] <= '9')
{
ret = ret * 10 + str_buf[indx] - '0';
}
indx++;
}
return ret;
}
static void *creat_mp4_file(char *dir_name)
{
void *fp;
char filepath[64];
uint32_t indx = os_jiffies() % 99999999;
void *dir = osal_opendir(dir_name);
if (!dir)
{
osal_fmkdir(dir_name);
}
else
{
osal_closedir(dir);
}
sprintf(filepath, "%s/%08d.%s", dir_name, indx, MP4_FILE_NAME);
printf("filepath:%s\r\n", filepath);
fp = osal_fopen(filepath, "wb+");
return fp;
}
static void *creat_mp4_file2(char *dir_name, char *filename)
{
void *fp;
char filepath[64];
uint32_t indx = os_jiffies();
void *dir = osal_opendir(dir_name);
if (!dir)
{
osal_fmkdir(dir_name);
}
else
{
osal_closedir(dir);
}
sprintf(filename, "%016d.jpg", indx);
sprintf(filepath, "%s/%016d.%s", dir_name, indx, MP4_FILE_NAME);
printf("filepath:%s\r\n", filepath);
fp = osal_fopen(filepath, "wb+");
return fp;
}
// 获取nal的size,从0开始搜索,返回的是的nal头的size,offset相对于头的偏移(通过多次调用,可以用于计算nal_size)
// 返回0代表搜索不到nal的头
static uint8_t get_nal_size(uint8_t *buf, uint32_t size, uint32_t *offset)
{
uint32_t pos = 0;
while ((size - pos) > 3)
{
if (buf[pos] == 0 && buf[pos + 1] == 0 && buf[pos + 2] == 1)
{
*offset = pos;
return 3;
}
if (buf[pos] == 0 && buf[pos + 1] == 0 && buf[pos + 2] == 0 && buf[pos + 3] == 1)
{
*offset = pos;
return 4;
}
pos++;
}
return 0;
}
// 只是获取pps和sps的nalsize
static uint8_t *get_sps_pps_nal_size(uint8_t *buf, uint32_t size, uint32_t *nal_size, uint8_t *head_size)
{
uint32_t offset;
uint8_t nal_head_size = get_nal_size(buf, size, &offset);
uint8_t nal_type;
uint8_t *ret_buf = NULL;
// 找到头部,检查类型
if (nal_head_size && offset + nal_head_size < size)
{
nal_type = buf[nal_head_size + offset] & 0x1f;
// 找到sps和pps就返回长度和偏移(相对buf的偏移)
if (nal_type == 7 || nal_type == 8)
{
// 查找下一个nal
nal_head_size = get_nal_size(buf + offset + nal_head_size, size - (offset + nal_head_size), nal_size);
if (nal_head_size)
{
// 偏移到nal的头部
ret_buf = buf + offset;
// 返回nal的头size
*head_size = nal_head_size;
}
}
}
return ret_buf;
}
static int mp4_encode_running(struct msi *msi, uint32_t save_time)
{
int ret = 1;
struct mp4_encode_msi_s *mp4_encode = (struct mp4_encode_msi_s *) msi->priv;
//struct msi *mp4_thumb_msi = NULL;
void *mp4_msg = NULL;
void *fp = NULL;
struct framebuff *fb = NULL;
int error = 0;
uint8_t nal_head_size;
uint32_t nal_size;
char h264_filename[64];
uint8_t *buf;
uint8_t *nal_head_buf;
uint8_t *last_nal_head_buf;
int write_size = 0;
uint32_t MP4_status = 0;
uint32_t write_start_time = os_jiffies();
//uint8_t sps_pps_flag = 0;
uint8_t last_num = 0;
(void) last_num;
uint32_t v_count = 0;
//uint32_t audio_save_time = 0;
// 参考minimp4的值去配置
//uint8_t asps_data[2] = {0x15, 0x88};
fp = creat_mp4_file2(TIME_LAPSE_DIR, h264_filename);
if (!fp)
{
os_sleep_ms(1);
goto mp4_encode_thread_end;
}
mp4_msg = MP4_open_init(fp, 0);
if (!mp4_msg)
{
goto mp4_encode_thread_end;
}
mp4_video_cfg_init(mp4_msg, 1280, 720);
ret = 0;
os_printf(KERN_INFO "%s:%d\n", __FUNCTION__, __LINE__);
while (fp)
{
//mp4_encode_running_again:
os_event_wait(&mp4_encode->evt, MSI_MP4_STOP, &MP4_status, OS_EVENT_WMODE_OR, 0);
// 结束写卡
if (MP4_status & MSI_MP4_STOP)
{
ret = 1;
goto mp4_encode_thread_end;
}
fb = msi_get_fb(msi, 0);
if (fb && (fb->mtype == F_H264))
{
buf = fb->data;
nal_head_size = 0;
nal_head_buf = buf;
// 记录最后一次nal的头位置,如果没有pps或者sps,这个就是I帧或者P帧
last_nal_head_buf = nal_head_buf;
mp4_encode_thread_again:
// 检查对应头部是否是nal
// nal_head_size = get_nal_size(buf + buf_offset, 64, 0,&cur_offset);
// 检查是否存在pps或者sps,只是检查64byte就好了,硬件产生
nal_head_buf = get_sps_pps_nal_size(nal_head_buf, 64, &nal_size, &nal_head_size);
// 找到pps或者sps
if (nal_head_buf)
{
error |= write_h264_pps_sps(mp4_msg, nal_head_buf, nal_size + nal_head_size);
if (0 != error)
{
os_printf("%s:%d\n", __FUNCTION__, __LINE__);
goto mp4_encode_thread_end;
}
// 查看下一个nal是否为pps或者sps
nal_head_buf += (nal_size + nal_head_size);
last_nal_head_buf = nal_head_buf;
goto mp4_encode_thread_again;
}
// 写剩余的nal数据
_os_printf(KERN_INFO "T");
v_count++;
error |= write_h264_data(mp4_msg, last_nal_head_buf, fb->len - (last_nal_head_buf - fb->data), 120);
if (0 != error)
{
goto mp4_encode_thread_end;
}
write_size += (fb->len - (last_nal_head_buf - fb->data));
msi_delete_fb(NULL, fb);
fb = NULL;
if (os_jiffies() - write_start_time >= save_time)
{
goto mp4_encode_thread_end;
}
// 同步,缩时录影直接同步,不需要考虑定时,因为本身就是很久才录制一次
error |= mp4_syn(mp4_msg);
if (0 != error)
{
os_printf("%s:%d\n", __FUNCTION__, __LINE__);
goto mp4_encode_thread_end;
}
}
else
{
msi_delete_fb(NULL, fb);
fb = NULL;
}
os_sleep_ms(1);
}
mp4_encode_thread_end:
if (fb)
{
msi_delete_fb(NULL, fb);
}
if (mp4_msg)
{
mp4_deinit(mp4_msg);
}
if (fp)
{
osal_fclose(fp);
fp = NULL;
}
// 如果遇到写入错误之类,直接删除缓冲区的吧,防止写卡慢导致后面的帧不是连续的
if (error)
{
while (1)
{
fb = msi_get_fb(msi, 0);
if (fb)
{
msi_delete_fb(NULL, fb);
}
else
{
break;
}
}
}
os_printf("mp4 encode end\n");
return ret;
}
// 测试文件保存,保存一分钟吧,一直录卡,直到关闭msi
static void mp4_encode_thread(void *d)
{
struct msi *msi = (struct msi *) d;
struct mp4_encode_msi_s *mp4_encode = (struct mp4_encode_msi_s *) msi->priv;
int ret = 0;
//int res;
msi_get(msi);
while (msi)
{
msi->enable = 1;
ret = mp4_encode_running(msi, 60 * 1000 * mp4_encode->rec_time);
msi->enable = 0;
os_printf("%s:%d end\n", __FUNCTION__, __LINE__);
if (ret)
{
break;
}
}
//mp4_encode_thread_end:
os_event_set(&mp4_encode->evt, MSI_MP4_THREAD_DEAD, NULL);
msi_put(msi);
os_printf("%s:%d end\n", __FUNCTION__, __LINE__);
}
static int32_t MP4_encode_msi_action(struct msi *msi, uint32_t cmd_id, uint32_t param1, uint32_t param2)
{
int32_t ret = RET_OK;
struct mp4_encode_msi_s *mp4_encode = (struct mp4_encode_msi_s *) msi->priv;
switch (cmd_id)
{
case MSI_CMD_POST_DESTROY:
os_event_wait(&mp4_encode->evt, MSI_MP4_THREAD_DEAD, NULL, OS_EVENT_WMODE_OR | OS_EVENT_WMODE_CLEAR, -1);
os_event_del(&mp4_encode->evt);
STREAM_LIBC_FREE(mp4_encode);
break;
case MSI_CMD_PRE_DESTROY:
os_event_set(&mp4_encode->evt, MSI_MP4_STOP, NULL);
break;
case MSI_CMD_TRANS_FB:
{
struct framebuff *fb = (struct framebuff *) param1;
if (fb->mtype == F_H264 && mp4_encode->filter_type != (uint16_t) ~0)
{
ret = RET_ERR;
if (mp4_encode->filter_type == fb->stype)
{
struct fb_h264_s *h264_s = (struct fb_h264_s *) fb->priv;
// 只是支持I帧
if (h264_s->type == 1)
{
// os_printf(KERN_INFO"recv I frame\n");
ret = RET_OK;
}
}
}
}
break;
case MSI_CMD_GET_RUNNING:
{
uint32_t rflags = 0;
os_event_wait(&mp4_encode->evt, MSI_MP4_THREAD_DEAD | MSI_MP4_STOP, &rflags, OS_EVENT_WMODE_OR, 0);
if (param1)
{
*(uint32_t *) param1 = (rflags & (MSI_MP4_THREAD_DEAD | MSI_MP4_STOP)) ? 0 : 1;
}
}
break;
}
return ret;
}
struct msi *time_lapse_mp4_encode_msi2_init(const char *mp4_msi_name, uint16_t filter_type, uint16_t rec_time)
{
struct mp4_encode_msi_s *mp4_encode = NULL;
struct msi *msi = msi_new(mp4_msi_name, 64, NULL);
if (msi && !msi->priv)
{
mp4_encode = (struct mp4_encode_msi_s *) STREAM_LIBC_ZALLOC(sizeof(struct mp4_encode_msi_s));
ASSERT(mp4_encode);
mp4_encode->filter_type = filter_type;
mp4_encode->rec_time = rec_time;
msi->priv = mp4_encode;
os_event_init(&mp4_encode->evt);
mp4_encode->msi = msi;
msi->action = MP4_encode_msi_action;
msi->enable = 1;
}
else
{
// 不要重复打开,同一个名称需要等待上一次写入完成后并且关闭后才可以重新打开
// 因为这里new了一次,所以要destroy一次(new和destroy要配对,实际msi的destroy是在另一个地方)
if (msi)
{
msi_destroy(msi);
msi = NULL;
goto mp4_encode_msi_init_end;
}
}
void *mp4_hdl = os_task_create("time_lapse_mp4", mp4_encode_thread, msi, OS_TASK_PRIORITY_NORMAL, 0, NULL, 2048);
os_printf("mp4_hdl:%X\n", mp4_hdl);
if (!mp4_hdl && mp4_encode)
{
os_event_set(&mp4_encode->evt, MSI_MP4_THREAD_DEAD, NULL);
}
mp4_encode_msi_init_end:
return msi;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,199 @@
#include "basic_include.h"
#include "hal/para_in.h"
#include "lib/video/para_in/para_in_dev.h"
#include "app_iic.h"
static const _Sensor_Para_in_Init *para_in_dev_init_table[] = {
#if DEV_SENSOR_TP9950
#ifdef TP9950_HDA_720P_25FPS
&tp9950_HDA_720P_25FPS_para_in_init,
#endif
#endif
NULL,
};
int32_t hg_para_in_irq_hdl(uint32 irq_flags, uint32 irq_data, uint32 param, uint32 param2)
{
struct para_in_device *para_in = (struct para_in_device *)param;
switch (irq_flags)
{
case FRM_RX_DOWN_ISR:
_os_printf("P");
para_in_ioctl(para_in, PARA_IN_SET_CON_EN, 0, 0);
para_in_ioctl(para_in, PARA_IN_SET_CON_EN, 1, 0);
break;
case OFOV_ISR:
os_printf("OFOV_ISR\n");
break;
case IFOV_ISR:
os_printf("IFOV_ISR\n");
break;
case VSYNC_ERR_ISR:
os_printf("VSYNC_ERR_ISR\n");
break;
case HSYNC_ERR_ISR:
os_printf("HSYNC_ERR_ISR\n");
break;
case ESAV_ERR_ISR:
os_printf("ESAV_ERR_ISR\n");
break;
case TIMEOUT_ISR:
os_printf("TIMEOUT_ISR\n");
para_in_ioctl(para_in, PARA_IN_SET_CON_EN, 0, 0);
para_in_ioctl(para_in, PARA_IN_SET_CON_EN, 1, 0);
break;
default:
break;
}
return 0;
}
static void para_in_sensor_reset()
{
if (PIN_BT_RESET != 255) {
gpio_iomap_output(PIN_BT_RESET,GPIO_DIR_OUTPUT);
gpio_set_val(PIN_BT_RESET,1);
os_sleep_ms(1);
gpio_set_val(PIN_BT_RESET,0);
os_sleep_ms(1);
gpio_set_val(PIN_BT_RESET,1);
}
};
static _Sensor_Para_in_Init * para_in_auto_check_dev_id(uint32_t iic_dev, uint8_t **init_table)
{
uint8_t tmpbuf[16];
uint16_t id = 0;
_Sensor_Para_in_Init **p_init_table = (_Sensor_Para_in_Init **)init_table;
_Sensor_Para_in_Init *p_init = *p_init_table;
for (int i = 0; p_init != (_Sensor_Para_in_Init *)NULL; i++) {
os_printf("p_init:%x p_init_table:%x\n",p_init,p_init_table);
para_in_sensor_reset();
id = 0;
tmpbuf[0] = 0x1;
tmpbuf[1] = 0x1;
tmpbuf[2] = p_init->i2c_dev_addr; //I2C dev addr
//I2C ID 高8位
if (p_init->i2c_id_addr1 != 0) {
tmpbuf[3] = p_init->i2c_id_addr1;
tmpbuf[4] = 0;
wake_up_iic_queue(iic_dev,tmpbuf,0,0,(uint8_t*)NULL);
while(iic_devid_finish(iic_dev) != 1){
os_sleep_ms(1);
}
id = tmpbuf[4] << 8;
}
//I2C ID 低8位
if (p_init->i2c_id_addr2 != 0) {
tmpbuf[3] = p_init->i2c_id_addr2;
tmpbuf[4] = 0;
wake_up_iic_queue(iic_dev,tmpbuf,0,0,(uint8_t*)NULL);
while(iic_devid_finish(iic_dev) != 1){
os_sleep_ms(1);
}
id |= tmpbuf[4];
}
if (id == p_init->i2c_id) {
os_printf("%s id:0x%x \n",__FUNCTION__,id);
return p_init;
}
os_printf("id:0x%x addr1:0x%x addr2:0x%x sensorID:0x%x\n",id, p_init->i2c_id_addr1, p_init->i2c_id_addr2, p_init->i2c_id);
p_init++;
}
return NULL;
}
static void para_in_i2c_init_sensor(uint32_t iic_dev, _Sensor_Para_in_Init *sensor_dev)
{
int i;
uint8_t tmpbuf[16];
_PARA_IN_SENSOR_REG_INFO *preg_info = sensor_dev->i2c_init_table;
for (i = 0; ; i++)
{
if (preg_info->reg_addr == 0xFF && preg_info->value == 0xFF) {
os_printf("%s %d init num:%d\n", __FUNCTION__, __LINE__, i);
break;
}
tmpbuf[0] = 0x1;
tmpbuf[1] = 0x1;
tmpbuf[2] = sensor_dev->i2c_dev_addr;
tmpbuf[3] = preg_info->reg_addr;
tmpbuf[4] = preg_info->value;
wake_up_iic_queue(iic_dev,tmpbuf,0,1,(uint8_t*)NULL);
while(iic_devid_finish(iic_dev) != 1){
os_sleep_ms(1);
}
preg_info++;
}
}
void para_in_hareware_init()
{
struct para_in_device *para_in = (struct para_in_device *)dev_get(HG_PARA_IN_DEVID);
struct i2c_device *iic_dev = (struct i2c_device *)dev_get(HG_I2C1_DEVID);
_Sensor_Para_in_Init * p_sensor = NULL;
volatile uint32_t app_iic = 0;
app_iic = register_iic_queue(iic_dev,PC_15,PD_14,0);
p_sensor = para_in_auto_check_dev_id(app_iic, (uint8_t**)&para_in_dev_init_table);
if (p_sensor) {
para_in_i2c_init_sensor(app_iic, p_sensor);
} else {
os_printf("No found para in sensor!!!\n");
return;
}
os_printf("%s %d success find sensor\n",__FUNCTION__,__LINE__);
para_in_open(para_in);
if(p_sensor->data_format == PARA_IN_BT601)
{
para_in_ioctl(para_in, PARA_IN_RC_ST_DTC_MODE, 0, 0);
para_in_ioctl(para_in, PARA_IN_SET_VSYNC_POL, p_sensor->vs_pol, 0);
para_in_ioctl(para_in, PARA_IN_SET_HSYNC_POL, p_sensor->hs_pol, 0);
para_in_ioctl(para_in, PARA_IN_SET_VHSYNC_EN, 1, 0);
para_in_ioctl(para_in, PARA_IN_ESAV_ERR_DTC_EN, 1, 0);
}
// BT656、BT1120
else
{
para_in_ioctl(para_in, PARA_IN_RC_ST_DTC_MODE, 1, 0);
para_in_ioctl(para_in, PARA_IN_SET_VHSYNC_EN, 0, 0);
para_in_ioctl(para_in, PARA_IN_ESAV_ERR_DTC_EN, 1, 0);
}
para_in_ioctl(para_in, PARA_IN_SAV_AHEAD, 0, 0);
para_in_ioctl(para_in, PARA_IN_FRT_VSYNC_SEL, 1, 0);
//根据帧率计算超时时间,超时未获得帧,应重启模块
para_in_ioctl(para_in, PARA_IN_SET_TIMEOUT_EN, 0, 0);
para_in_ioctl(para_in, PARA_IN_SET_TIMEOUT_TIME, 1, 0);
para_in_ioctl(para_in, PARA_IN_SMAP_CLK_SEL, p_sensor->smap_edge, 0);
para_in_ioctl(para_in, PARA_IN_INTF_SEL, p_sensor->data_format, 0);
para_in_ioctl(para_in, PARA_IN_YUV_SEL, p_sensor->out_yuv_format, 0);
para_in_ioctl(para_in, PARA_IN_SET_INPUT_SEQUENCE, p_sensor->in_yuv_sequence, 0);
para_in_ioctl(para_in, PARA_IN_SET_OUTPUT_SEQUENCE, p_sensor->out_yuv_sequence, 0);
para_in_ioctl(para_in, PARA_IN_SET_PARAMS, (uint32)p_sensor, 0);
para_in_request_irq(para_in, FRM_RX_DOWN_ISR | OFOV_ISR | IFOV_ISR | VSYNC_ERR_ISR | HSYNC_ERR_ISR | ESAV_ERR_ISR,
hg_para_in_irq_hdl, (uint32)NULL);
para_in_ioctl(para_in, PARA_IN_SET_CON_EN, 1, 0);
os_printf("para in open\n");
}

View File

@@ -0,0 +1,400 @@
#include "sys_config.h"
#include "typesdef.h"
#include "lib/video/dvp/cmos_sensor/csi.h"
#include "devid.h"
#include "hal/gpio.h"
#include "hal/spi.h"
#include "hal/timer_device.h"
#include "osal/irq.h"
#include "osal/string.h"
#include "dev/csi/hgdvp.h"
#include "dev/prc/hgprc.h"
#include "hal/pwm.h"
#include "hal/prc.h"
#include "osal/task.h"
#include <csi_kernel.h>
#include "osal/semaphore.h"
#include "lib/video/dvp/jpeg/jpg.h"
#include "osal/sleep.h"
#ifdef PIN_FROM_PARAM
#include "pin_param.h"
#endif
#if PRC_EN
#define IIC_CLK 120000UL
extern SNSER snser;
int wake_up_iic_queue(uint8_t devid,uint8_t *table,uint32_t len,uint8_t rw_sta,uint8_t *trx_buff);
void spi0_read_irq(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2);
int iic_devid_finish(uint8_t devid);
int register_iic_queue(struct i2c_device *i2c,uint8_t scl_io,uint8_t sda_io,uint8_t id_addr);
int register_iic_queue(struct i2c_device *i2c,uint8_t scl_io,uint8_t sda_io,uint8_t id_addr);
void jpg_cfg(uint8 jpgid,enum JPG_SRC_FROM src_from);
#define RESET_HIGH() {gpio_set_val(rsn,1);}
#define RESET_LOW() {gpio_set_val(rsn,0);}
#define SPI_WIDTH 640 //240
#define SPI_HIGH 480 //320
k_task_handle_t dvp_manual_handle;
extern volatile uint32 outbuff_isr;
volatile uint8 prc_buf_num = 0;
struct spi_device* spi0_dev_g;
struct prc_device* prc_dev_g;
//uint8 spi_dat_buf[2][480*16]; //spi0 & spi1的buf缓存
uint8 *spi_dat_buf[2];
uint8 prc_yuv_line[SPI_WIDTH*16+SPI_WIDTH*16/2]__attribute__ ((aligned(4)));
__psram_data uint8 psram_spi_sensor[3][SPI_WIDTH*SPI_HIGH] __aligned(16);
uint32 read_len = 0;
uint32 read_app_len = 0;
uint32 last_len_num = 0;
extern struct i2c_device *iic_test;
uint32 kick_en = 1;
uint8 spi_to_jpg_open = 0;
extern Vpp_stream photo_msg;
volatile uint8 prc_to_mjpg = 0;
_Sensor_Adpt_ * sensorAutoCheck(struct i2c_device *p_iic,uint8 *init_buf);
extern _Sensor_Ident_ *devSensorInit;
const _Sensor_Ident_ spi_null_init={0x00,0x00,0x00,0x00,0x00,0x00};
void prc_deal_irq(uint32 irq, uint32 irq_data);
static const _Sensor_Ident_ *devSensorInitTable_spi[] = {
#if DEV_SENSOR_BF30A2
&bf30a2_init,
#endif
#if DEV_SENSOR_BF3A01
&bf3a01_init,
#endif
#if DEV_SENSOR_BF20A6
&bf20a6_spi_init,
#endif
NULL,
};
static const _Sensor_Adpt_ *devSensorOPTable_spi[] = {
#if DEV_SENSOR_BF30A2
&bf30a2_cmd,
#endif
#if DEV_SENSOR_BF3A01
&bf3a01_cmd,
#endif
#if DEV_SENSOR_BF20A6
&bf20a6_spi_cmd,
#endif
};
void prc_module_init(){
prc_dev_g = (struct prc_device*)dev_get(HG_PRC_DEVID);
prc_init(prc_dev_g);
prc_set_width(prc_dev_g,SPI_WIDTH);
prc_set_yuv_mode(prc_dev_g,0);
prc_set_yaddr(prc_dev_g,(uint32)prc_yuv_line);
prc_set_uaddr(prc_dev_g,(uint32)prc_yuv_line+SPI_WIDTH*16);
prc_set_vaddr(prc_dev_g,(uint32)prc_yuv_line+SPI_WIDTH*16+SPI_WIDTH*16/4);
prc_request_irq(prc_dev_g,PRC_ISR,(prc_irq_hdl)prc_deal_irq,(uint32)prc_dev_g);
}
uint8 spi_sensor_to_mjpeg_is_run(){
return prc_to_mjpg;
}
uint8 spi_to_jpg_cfg(uint8 enable){
if(enable){
prc_to_mjpg = 1;
jpg_cfg(HG_JPG0_DEVID,PRC_DATA);
}else{
prc_to_mjpg = 0;
}
return prc_to_mjpg;
}
void spi_sensor_cfg(){
spi0_dev_g = (struct spi_device*)dev_get(HG_SPI0_DEVID);
// spi_open(spi0_dev_g, 10000000, SPI_SLAVE_MODE, SPI_WIRE_SINGLE_MODE, SPI_CPOL_1_CPHA_1);
spi_open(spi0_dev_g, 10000000, SPI_SLAVE_MODE, SPI_WIRE_QUAD_MODE, SPI_CPOL_0_CPHA_0);
spi_ioctl(spi0_dev_g,SPI_CFG_SET_NONE_CS,1,0);
spi_ioctl(spi0_dev_g,SPI_SENSOR_VSYNC_TIMEOUT ,0x7530,0);
spi_ioctl(spi0_dev_g,SPI_SENSOR_VSYNC_HEAD_CNT,0,0);
spi_ioctl(spi0_dev_g,SPI_SENSOR_VSYNC_EN,1,0);
spi_ioctl(spi0_dev_g,SPI_SENSOR_HSYNC_TIMEOUT,2400,0);
spi_ioctl(spi0_dev_g,SPI_SENSOR_HSYNC_HEAD_CNT,8,0);
spi_ioctl(spi0_dev_g,SPI_HIGH_SPEED_CFG,0,0);
spi_ioctl(spi0_dev_g,SPI_SENSOR_PINGPANG_EN,1,0);
spi_ioctl(spi0_dev_g,SPI_SENSOR_BUF_LEN,SPI_WIDTH*2*16,0);
spi_ioctl(spi0_dev_g,SPI_SENSOR_LINE_LEN_CFG,SPI_WIDTH*2,0);
if(spi_dat_buf[0] == NULL){
spi_dat_buf[0] = (uint8 *)os_malloc(SPI_WIDTH*2*16);
}
if(spi_dat_buf[1] == NULL){
spi_dat_buf[1] = (uint8 *)os_malloc(SPI_WIDTH*2*16);
}
if((spi_dat_buf[0] == NULL)||(spi_dat_buf[1] == NULL)){
_os_printf("spi sensor malloc error!!\r\n");
}
spi_ioctl(spi0_dev_g,SPI_SENSOR_SET_ADR0,(uint32)spi_dat_buf[0],0);
spi_ioctl(spi0_dev_g,SPI_SENSOR_SET_ADR1,(uint32)spi_dat_buf[1],0);
spi_ioctl(spi0_dev_g,SPI_RX_TIMEOUT_CFG,1,120000); //500us
spi_request_irq(spi0_dev_g,SPI_IRQ_FLAG_RX_DONE|SPI_IRQ_FLAG_RX_TIMEOUT,spi0_read_irq,(uint32)spi0_dev_g);
spi_ioctl(spi0_dev_g,SPI_KICK_DMA_EN,0,0);
}
volatile uint32 hnum = 0;
volatile uint32 sync_start = 0;
volatile uint32 prc_new_frame;
volatile uint8 prc_deal_num = 0;
uint8 spi_video_run = 0;
//只有主spi才能保证数据是准确的
void spi0_read_irq(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2){
if(irq == SPI_IRQ_FLAG_RX_DONE){
prc_new_frame = 0;
if(sync_start){
if((hnum%2) == 0){
prc_set_src_addr(prc_dev_g,(uint32)spi_dat_buf[0]);
}else{
prc_set_src_addr(prc_dev_g,(uint32)spi_dat_buf[1]);
}
prc_run(prc_dev_g);
}
hnum++;
}
if(irq == SPI_IRQ_FLAG_RX_TIMEOUT){
prc_new_frame = 1;
prc_deal_num = 0;
sync_start = 1;
spi_close(spi0_dev_g);
spi_sensor_cfg();
prc_first_start(prc_dev_g);
hnum = 0;
}
}
void ybuf_deal(uint32 *sbuf,uint32 *ybuf,uint32 sz){
uint32 itk;
for(itk = 0;itk < sz;itk++){
sbuf[itk] = ybuf[itk];
}
}
void prc_deal_irq(uint32 irq, uint32 irq_data){
static uint8 *prc_buf;
if(prc_deal_num == 0){
prc_buf = psram_spi_sensor[prc_buf_num];
prc_buf_num++;
if(prc_buf_num == 3)
prc_buf_num = 0;
}
hw_memcpy(prc_buf+prc_deal_num*(16*SPI_WIDTH),prc_yuv_line,16*SPI_WIDTH);
prc_deal_num++;
if(prc_deal_num == (SPI_HIGH/16)){
prc_deal_num = 0;
}
}
uint32 count_timer_get = 0;
uint32 frame_end = 0;
uint32 frame_deal = 0;
void spi_sensor_reset(void){
uint8_t pdn;
uint8_t rsn;
pdn = MACRO_PIN(PIN_SPI_PDN);
rsn = MACRO_PIN(PIN_SPI_RESET);
if(pdn != 255){
gpio_iomap_output(pdn,GPIO_IOMAP_OUTPUT);
gpio_set_val(pdn,1); //pdn up
os_sleep_ms(100);
gpio_iomap_output(pdn,GPIO_IOMAP_OUTPUT);
gpio_set_val(pdn,0); //pdn down
os_sleep_ms(50);
}
if(rsn != 255){
gpio_iomap_output(rsn,GPIO_IOMAP_OUTPUT);
}
else{
os_sleep_ms(200);
return;
}
RESET_HIGH();
os_sleep_ms(50);
RESET_LOW();
os_sleep_ms(200);
RESET_HIGH();
os_sleep_ms(50);
}
static _Sensor_Adpt_ * sensorAutoCheck_spi(uint8_t devid,uint8 *init_buf)
{
uint8 i;
_Sensor_Adpt_ * devSensor_Struct=NULL;
for(i=0;devSensorInitTable_spi[i] != NULL;i++)
{
spi_sensor_reset();
if(sensorCheckId(devid,devSensorInitTable_spi[i],devSensorOPTable_spi[i])>=0)
{
os_printf("id =%x num:%d \n",devSensorInitTable_spi[i]->id,i);
devSensorInit = (_Sensor_Ident_ *) devSensorInitTable_spi[i];
//#if CMOS_AUTO_LOAD
// devSensor_Struct = sensor_adpt_load(devSensorInit->id,devSensorInit->w_cmd,devSensorInit->r_cmd,init_buf);
//#else
devSensor_Struct = (_Sensor_Adpt_ *) devSensorOPTable_spi[i];
//#endif
break;
}
}
if(devSensor_Struct == NULL)
{
os_printf("Er: unkown!");
devSensorInit = (_Sensor_Ident_ *)&spi_null_init;
return NULL; // index 0 is test only
}
return devSensor_Struct;
}
void spi_sensor_thread(){
//struct hgpwm_v0 *global_hgpwm;
int data_cnt_old = 0;
//uint8 sensor_staus = 0; //0:stop 1:run
prc_module_init();
spi_sensor_cfg();
while(1){
if(prc_buf_num == data_cnt_old){
os_sleep_ms(10);
continue;
}
data_cnt_old = prc_buf_num;
}
}
void spi_2_jpg();
void i2c_SetSetting(struct i2c_setting *p_i2c_setting);
volatile uint8 spi_sensor_devid;
void spi_senosr_open(){
//uint8 adr_num,dat_num;
//uint8 sen_w_cmd,sen_r_cmd;
//uint8 id_c = 0;
int8 idbuf[3];
uint8_t tablebuf[16];
uint32 i=0;
uint8_t itk=0;
uint32 k = 0;
static _Sensor_Adpt_ *p_sensor_cmd = NULL;
struct i2c_setting i2c_setting;
struct i2c_device *iic_dev;
struct dvp_device *dvp_dev;
iic_dev = (struct i2c_device *)dev_get(HG_I2C1_DEVID);
dvp_dev = (struct dvp_device *)dev_get(HG_DVP_DEVID);
gpio_iomap_output(PB_9, GPIO_IOMAP_OUT_DVP_MCLK_OUT);
gpio_driver_strength(PB_9, GPIO_DS_G1);
dvp_set_baudrate(dvp_dev,6000000);
os_sleep_ms(3);
os_printf("set SPI sensor finish ,Auto Check sensor id\r\n");
spi_sensor_devid = register_iic_queue(iic_dev,PC_7,PC_6,0);
p_sensor_cmd = snser.p_sensor_cmd = sensorAutoCheck_spi(spi_sensor_devid,NULL);
if(p_sensor_cmd == NULL){
return;
}
os_printf("Auto Check sensor id finish\r\n");
i2c_setting.u8DevWriteAddr = p_sensor_cmd->w_cmd;
i2c_setting.u8DevReadAddr = p_sensor_cmd->r_cmd;
i2c_SetSetting(&i2c_setting);
dvp_set_baudrate(dvp_dev,24000000);
if(p_sensor_cmd->init!=NULL)
{
os_printf("SENSER....init\r\n");
for(i=0;;i+=u8Addrbytnum+u8Databytnum)
{
if((p_sensor_cmd->init[i]==0xFF)&&(p_sensor_cmd->init[i+1]==0xFF)){
os_printf("init table num:%d\r\n",i);
break;
}
if((p_sensor_cmd->init[i]==0xFE)&&(p_sensor_cmd->init[i+1]==0xFE)){
if(p_sensor_cmd->init[i+2]==0x01){
os_sleep_ms(100);
}
}
else{
for(itk = 0;itk < u8Addrbytnum+u8Databytnum;itk++){
idbuf[itk] = p_sensor_cmd->init[i+itk];
}
tablebuf[0] = u8Addrbytnum;
tablebuf[1] = u8Databytnum;
tablebuf[2] = u8SensorwriteID>>1;
for(k = 0;k < (tablebuf[0] + tablebuf[1]);k++){
tablebuf[3+k] = idbuf[k];
}
wake_up_iic_queue(spi_sensor_devid,tablebuf,0,1,(uint8_t*)NULL);
while(iic_devid_finish(spi_sensor_devid) != 1){
os_sleep_ms(1);
}
//i2c_write(iic_test, (int8*)&p_sensor_cmd->init[i], u8Addrbytnum, (int8*)&p_sensor_cmd->init[i+u8Addrbytnum], u8Databytnum);
if(i==0)
{
os_sleep_ms(1);
}
}
}
csi_kernel_task_new((k_task_entry_t)spi_sensor_thread, "dvp_manual", 0, 40, 0, NULL, 1024, &dvp_manual_handle);
}
}
#endif

View File

@@ -0,0 +1,725 @@
#include "video/uvc/rtt_uvc_host.h"
#include "lib/heap/av_heap.h"
#include "lib/heap/av_psram_heap.h"
#ifdef PSRAM_HEAP
#define UVC_BLANK_MALLOC av_psram_zalloc
#define UVC_BLANK_FREE av_psram_free
#else
#define UVC_BLANK_MALLOC av_zalloc
#define UVC_BLANK_FREE av_free
#endif
static UVC_Device *uvc_devices[MAX_DEVICES] = {NULL}; // 设备池
static int registered_devices = 0; // 已注册设备数
static void uvc_device_wait_frame(UVC_Device* uvc_device);
/* ------------------------------- 设备缓存节点接口 ------------------------------- */
static void uvc_device_blank_node_init(UVC_Device* uvc_device)
{
os_printf("%s %d\n", __FUNCTION__, __LINE__);
if (uvc_device->blank_num == 0) {
uvc_device->blank_num = UVC_DEFAULT_BLANK_NUM;
}
if (uvc_device->blank_len == 0) {
uvc_device->blank_len = UVC_DEFAULT_BLANK_LEN;
}
uvc_device->blank_buffer = UVC_BLANK_MALLOC(sizeof(UVC_BLANK) * uvc_device->blank_num);
os_printf("blank_buffer : %x\n", uvc_device->blank_buffer);
if (!uvc_device->blank_buffer) {
os_printf("blank node head malloc failed\n");
return;
}
INIT_LIST_HEAD(&uvc_device->free_uvc_tab);
UVC_BLANK *blank = uvc_device->blank_buffer;
for (int i = 0; i < uvc_device->blank_num; i++) {
// os_printf("blank[%d] : %x\n", i, blank);
INIT_LIST_HEAD(&blank->list);
blank->blank_len = uvc_device->blank_len;
blank->blank_loop = 0;
blank->busy = UVC_DEVICE_BLANK_STATE_IDLE;
blank->frame_counter = 0;
blank->re_space = 0;
blank->buf_ptr = UVC_BLANK_MALLOC(uvc_device->blank_len);
if (!blank->buf_ptr) {
os_printf("blank node[%d] buf malloc failed\n", i);
return;
}
sys_dcache_invalid_range((uint32_t*)blank->buf_ptr, blank->blank_len);
list_add_tail(&blank->list, &uvc_device->free_uvc_tab);
os_printf("blank node[%d] :%x ptr:%x\n", i, blank, blank->buf_ptr);
blank++;
}
}
static void uvc_device_blank_node_deinit(UVC_Device* uvc_device)
{
if (!uvc_device->blank_buffer) {
return;
}
uvc_device_wait_frame(uvc_device);
UVC_BLANK *blank = uvc_device->blank_buffer;
os_printf("%s %d\n", __FUNCTION__, __LINE__);
for (int i = 0; i < uvc_device->blank_num; i++) {
if (blank->buf_ptr) {
UVC_BLANK_FREE(blank->buf_ptr);
os_printf("free blank node[%d] buf:%x\n", i, blank->buf_ptr);
blank->buf_ptr = NULL;
}
blank++;
}
if(uvc_device->blank_buffer) {
UVC_BLANK_FREE(uvc_device->blank_buffer);
os_printf("free blank_buffer:%x\n", uvc_device->blank_buffer);
uvc_device->blank_buffer = NULL;
}
}
static struct list_head *uvc_device_get_blank_node(struct list_head *head, struct list_head *del)
{
// os_printf("%s %d head:%x del:%x\n", __FUNCTION__, __LINE__,head,del);
if(list_empty(del)) {
return NULL;
}
list_move(del->prev, head);
return head->next;
}
static bool uvc_device_free_get_blank_node_list(struct list_head *head, struct list_head *free) {
if (list_empty(head)) {
return 0;
}
list_splice_init(head, free);
return 1;
}
/* ------------------------------- 设备缓存帧接口 ------------------------------- */
static void uvc_device_frame_init(UVC_Device* uvc_device)
{
os_printf("%s %d\n", __FUNCTION__, __LINE__);
for (int i = 0; i < UVC_DEFAULT_FRAME_NUM; i++) {
INIT_LIST_HEAD(&uvc_device->uvc_msg_frame[i].list);
uvc_device->uvc_msg_frame[i].state = UVC_DEVICE_FRAME_STATE_IDLE;
uvc_device->uvc_msg_frame[i].sta = 0;
}
}
static struct list_head *uvc_device_get_new_frame(UVC_Device* uvc_device, int grab)
{
uint8_t frame_num = 0;
for (frame_num = 0; frame_num < UVC_DEFAULT_FRAME_NUM; frame_num++) {
if (uvc_device->uvc_msg_frame[frame_num].state == UVC_DEVICE_FRAME_STATE_IDLE) {
uvc_device->uvc_msg_frame[frame_num].state = UVC_DEVICE_FRAME_STATE_BUSY;
uvc_device->uvc_msg_frame[frame_num].frame_end = UVC_DEIVCE_FRAME_NOT_END;
uvc_device->frame_counter++;
return &uvc_device->uvc_msg_frame[frame_num].list;
}
}
//是否开启抢占模式,开启抢占后肯定有frame返回上一帧没使用的frame肯定usable为2
if (grab) {
for (frame_num = 0; frame_num < UVC_DEFAULT_FRAME_NUM; frame_num++) {
if (uvc_device->uvc_msg_frame[frame_num].state == UVC_DEVICE_FRAME_STATE_AVAILABLE) {
uvc_device->uvc_msg_frame[frame_num].state = UVC_DEVICE_FRAME_STATE_BUSY;
uvc_device->uvc_msg_frame[frame_num].frame_end = UVC_DEIVCE_FRAME_NOT_END;
uvc_device_free_get_blank_node_list(&uvc_device->uvc_msg_frame[frame_num].list, &uvc_device->free_uvc_tab);
uvc_device->frame_counter++;
return &uvc_device->uvc_msg_frame[frame_num].list;
}
}
}
return NULL;
}
static void uvc_device_end_frame(UVC_Device* uvc_device, UVC_MANAGE *frame)
{
if (uvc_device && frame) {
if (frame->state != UVC_DEVICE_FRAME_STATE_USING) {
frame->state = UVC_DEVICE_FRAME_STATE_AVAILABLE;
}
frame->frame_end = UVC_DEIVCE_FRAME_END;
uvc_device->current_frame = NULL;
}
}
static void uvc_device_free_err_frame(UVC_Device* uvc_device, UVC_MANAGE *frame)
{
if (uvc_device && frame) {
// 重置帧状态
if (frame->state != UVC_DEVICE_FRAME_STATE_USING) {
uvc_device_free_get_blank_node_list(&frame->list, &uvc_device->free_uvc_tab);
frame->state = UVC_DEVICE_FRAME_STATE_IDLE;
}
frame->frame_end = UVC_DEVICE_FRAME_ERROR;
uvc_device->current_frame = NULL;
// uvc_device->initial_fid_detected = 0;
}
}
static void uvc_device_wait_frame(UVC_Device* uvc_device)
{
uint32_t timeout = 0;
os_printf("%s %d\n", __FUNCTION__, __LINE__);
if (uvc_device){
for(int j = 0; j < UVC_DEFAULT_FRAME_NUM; j++) {
if (uvc_device->uvc_msg_frame[j].state == UVC_DEVICE_FRAME_STATE_USING) {
os_sleep_ms(1);
timeout++;
if (timeout > 500) {
timeout = 0;
os_printf("%s %d\n", __FUNCTION__, __LINE__);
//continue;
}
}
}
}
}
/* ------------------------------- 设备池管理接口 ------------------------------- */
bool uvc_device_pool_init() {
if (uvc_devices[0]) {
os_printf("uvc device pool already init\n");
return true;
}
int32 flags = disable_irq();
for(int i = 0; i < MAX_DEVICES; i++) {
uvc_devices[i] = (UVC_Device*)os_zalloc(sizeof(UVC_Device));
if (!uvc_devices[i]) {
os_printf("uvc device pool malloc failed\n");
enable_irq(flags);
return false;
}
uvc_devices[i]->is_register = UVC_DEVICE_REGISTER_IDLE;
}
enable_irq(flags);
return true;
}
void uvc_device_pool_deinit() {
for (int i = 0; i < MAX_DEVICES; i++) {
unregister_uvc_device(uvc_devices[i]);
}
int32 flags = disable_irq();
for(int i = 0; i < MAX_DEVICES; i++) {
if (uvc_devices[i]) {
os_free(uvc_devices[i]);
uvc_devices[i] = NULL;
}
}
enable_irq(flags);
}
// 注册新设备(实际应用中需结合设备枚举过程)
void* register_uvc_device(uint8_t dev_num, uint8_t blank_num, uint32_t blank_len, void* p_dev) {
if (registered_devices >= MAX_DEVICES) return false;
UVC_Device *dev = NULL;
int32 flags = disable_irq();
for (int i = 0; i < MAX_DEVICES; i++) {
os_printf("uvc_devices[%d] = %x is_register:%d\n", i, uvc_devices[i],uvc_devices[i]->is_register);
if (uvc_devices[i]->is_register == UVC_DEVICE_REGISTER_IDLE) {
dev = uvc_devices[i];
registered_devices++;
os_printf("%s %d\n", __FUNCTION__, __LINE__);
break;
}
}
enable_irq(flags);
os_printf("%s %d\n", __FUNCTION__, __LINE__);
if (dev == NULL) {
return NULL;
}
os_printf("%s %d\n", __FUNCTION__, __LINE__);
dev->blank_num = blank_num;
dev->blank_len = blank_len;
dev->frame_counter = 0;
dev->dev_num = dev_num + 1;
dev->last_fid = 0xFF;
dev->is_register = UVC_DEVICE_REGISTER_AVAILABLE;
dev->current_frame = NULL;
dev->filter_count = 10;
dev->expected_fid = 0xFF;
dev->initial_fid_detected = 0;
dev->p_dev = (struct usb_device *)p_dev;
uvc_device_frame_init(dev);
uvc_device_blank_node_init(dev);
return dev;
}
bool unregister_uvc_device(void* device) {
UVC_Device* dev = (UVC_Device*)device;
os_printf("%s %d dev:0x%x dev->dev_num:%d\n", __FUNCTION__, __LINE__,dev,dev->dev_num);
if (!dev) {
return false;
}
dev->dev_num = 0;
dev->is_register = UVC_DEVICE_REGISTER_BUSY;
uvc_device_blank_node_deinit(dev);
dev->is_register = UVC_DEVICE_REGISTER_IDLE;
registered_devices--;
return true;
}
// 根据设备号查找设备返回NULL表示未找到
static UVC_Device* find_uvc_device(uint8_t dev_num) {
UVC_Device* ret = NULL;
for (int i = 0; i < MAX_DEVICES; i++) {
if ((uvc_devices[i]->dev_num == (dev_num + 1)) && (uvc_devices[i]->is_register == UVC_DEVICE_REGISTER_AVAILABLE)) {
ret = uvc_devices[i];
break;
}
}
return ret;
}
/* ------------------------------- 上层应用调用接口 ------------------------------- */
struct list_head *uvc_device_user_get_frame(void* device)
{
uint8_t frame_num = 0;
struct list_head* list = NULL;
UVC_Device* uvc_device = (UVC_Device*)device;
if (!uvc_device || uvc_device->is_register == UVC_DEVICE_REGISTER_IDLE || uvc_device->is_register == UVC_DEVICE_REGISTER_BUSY) {
return NULL;
}
// os_printf("%s %d\n", __FUNCTION__, __LINE__);
uint32_t flags = disable_irq();
for (frame_num = 0; frame_num < UVC_DEFAULT_FRAME_NUM; frame_num++) {
if (uvc_device->uvc_msg_frame[frame_num].state == UVC_DEVICE_FRAME_STATE_AVAILABLE) {
uvc_device->uvc_msg_frame[frame_num].state = UVC_DEVICE_FRAME_STATE_BUSY;
list = &uvc_device->uvc_msg_frame[frame_num].list;
goto __exit;
}
}
#ifdef PSRAM_HEAP
for (frame_num = 0; frame_num < UVC_DEFAULT_FRAME_NUM; frame_num++) {
if (uvc_device->uvc_msg_frame[frame_num].state == UVC_DEVICE_FRAME_STATE_BUSY) {
uvc_device->uvc_msg_frame[frame_num].state = UVC_DEVICE_FRAME_STATE_BUSY;
list = &uvc_device->uvc_msg_frame[frame_num].list;
goto __exit;
}
}
#endif
__exit:
enable_irq(flags);
return list;
}
void uvc_device_user_set_frame_using(void *uvc_msg_frame)
{
UVC_MANAGE *frame = (UVC_MANAGE*)uvc_msg_frame;
frame->state = UVC_DEVICE_FRAME_STATE_USING;
}
void uvc_device_user_set_frame_idle(void *uvc_msg_frame)
{
UVC_MANAGE *frame = (UVC_MANAGE*)uvc_msg_frame;
frame->frame_len = 0;
frame->frame_end = 0;
frame->state = UVC_DEVICE_FRAME_STATE_IDLE;
}
int uvc_device_user_get_frame_blank_node_num(void* device, struct list_head *head)
{
int count = 0;
UVC_Device* uvc_device = (UVC_Device*)device;
struct list_head *first = (struct list_head *)head;
if (!uvc_device || uvc_device->is_register == UVC_DEVICE_REGISTER_BUSY || uvc_device->is_register == UVC_DEVICE_REGISTER_BUSY) {
return count;
}
irq_disable(usb_device_ioctl(uvc_device->p_dev, USB_HOST_GET_DMA_IRQ_VECTOR, (uint32)NULL, (uint32)NULL));
while(head->next != first)
{
head = head->next;
count++;
}
irq_enable(usb_device_ioctl(uvc_device->p_dev, USB_HOST_GET_DMA_IRQ_VECTOR, (uint32)NULL, (uint32)NULL));
return count;
}
void uvc_device_user_free_blank_node(void* device, struct list_head *del)
{
UVC_Device* uvc_device = (UVC_Device*)device;
UVC_BLANK *uvc_b = (UVC_BLANK *)del;
if (!uvc_device || uvc_device->is_register == UVC_DEVICE_REGISTER_BUSY || uvc_device->is_register == UVC_DEVICE_REGISTER_BUSY) {
return ;
}
// os_printf("%s %d\n", __FUNCTION__, __LINE__);
sys_dcache_invalid_range((uint32_t*)uvc_b->buf_ptr, uvc_b->blank_len);
uint32_t flags = disable_irq();
list_move(del, &uvc_device->free_uvc_tab);
enable_irq(flags);
}
void uvc_device_user_del_frame(void* device, void *get_f)
{
UVC_Device* uvc_device = (UVC_Device*)device;
if (!uvc_device || uvc_device->is_register == UVC_DEVICE_REGISTER_BUSY || uvc_device->is_register == UVC_DEVICE_REGISTER_BUSY) {
return;
}
// os_printf("%s %d\n", __FUNCTION__, __LINE__);
uvc_device_free_get_blank_node_list(get_f, &uvc_device->free_uvc_tab);
}
/* ------------------------------- UVC数据包解析状态机 ------------------------------- */
#define UVC_DEVICE_CHECK_HEADER_EOH
#define UVC_DEVICE_BULK_CHECK_MJPEG_HEADER
// #define UVC_DEVICE_CHECK_PTS
void process_uvc_payload(uint8_t dev_num, uint8_t ep_type, uint8_t video_format, uint8_t *payload, uint32_t payload_len, bool drop) {
UVC_Device* dev = find_uvc_device(dev_num);
if (!dev || !payload || payload_len == 0) {
return;
}
// 强制丢帧处理
if (drop) {
//释放当前正在处理的帧(如果存在)
UVC_MANAGE *frame = dev->current_frame;
_os_printf("Drop frame %x\n", frame);
if (frame) {
// 重置帧状态
uvc_device_free_err_frame(dev, frame);
dev->current_frame = NULL;
}
goto _exit; // 直接返回,不处理后续数据
}
if(dev->filter_count > 0) {
dev->filter_count--;
goto _exit; // 直接返回,不处理后续数据
}
struct video_payload_header *header = NULL;
uint8_t header_len = 0;
uint8_t *data_ptr = NULL;
uint32_t data_len = 0;
uint8_t cur_fid = 0;
bool valid_header = false;
// 包头有效性验证
if (payload_len > payload[0]
&& (payload[0] == 0x0C || (payload[0] == 0x02 && !(payload[1] & 0x0C)) || (payload[0] == 0x06 && !(payload[1] & 0x08)))
&& !(payload[1] & 0x30)
#ifdef UVC_DEVICE_CHECK_HEADER_EOH
&& (payload[0] == 0x02 ? payload[1] & 0x80 : 1)
#endif
#ifdef UVC_DEVICE_BULK_CHECK_MJPEG_HEADER
&& ((((ep_type & USB_EP_ATTR_TYPE_MASK) == USB_EP_ATTR_BULK) && (video_format == USBH_VIDEO_FORMAT_MJPEG)) ? (payload_len >= payload[0] + 2 && payload[payload[0]] == 0xFF && payload[payload[0] + 1] == 0xD8) : 1)
#endif
)
{
//os_printf("UVC: Valid header detected\n");
//os_printf("UVC: Payload [0]:%x [1]:%x [payload[0]]:%x [payload[0] + 1]:%x\n", payload[0], payload[1], payload[payload[0]], payload[payload[0] + 1]);
valid_header = true;
switch(dev->initial_fid_detected)
{
case 0:
{
header = (struct video_payload_header *)payload;
dev->expected_fid = header->headerInfoUnion.headerInfoBitmap.FID;
// os_printf("UVC: Initial FID detected: %d\n", dev->expected_fid);
dev->initial_fid_detected = 1;
return;
}
break;
case 1:
{
header = (struct video_payload_header *)payload;
cur_fid = header->headerInfoUnion.headerInfoBitmap.FID;
// os_printf("UVC: Current FID detected: %d\n", cur_fid);
if(cur_fid != dev->expected_fid){
dev->initial_fid_detected = 2;
}else{
return;
}
}
break;
case 2:
{
}
break;
}
}else{
//os_printf("e UVC: Payload [0]:%x [1]:%x [payload[0]]:%x [payload[0] + 1]:%x\n", payload[0], payload[1], payload[payload[0]], payload[payload[0] + 1]);
};
//初始化变量
if (valid_header == true) {
header = (struct video_payload_header *)payload;
cur_fid = header->headerInfoUnion.headerInfoBitmap.FID;
header_len = header->bHeaderLength;
data_ptr = payload + header_len;
data_len = payload_len - header_len;
// os_printf("UVC: Header length: %d, Data: %x Data length: %d\n", header_len, data_ptr, data_len);
} else {
if(payload_len == payload[0]
&& (payload[0] == 0x0C || (payload[0] == 0x02 && !(payload[1] & 0x0C)) || (payload[0] == 0x06 && !(payload[1] & 0x08)))) {
cur_fid = dev->last_fid;
data_len = 0;
valid_header = true;
header = (struct video_payload_header *)payload;
header_len = header->bHeaderLength;
//os_printf("valid_header true\n");
}else{
cur_fid = dev->last_fid;
data_ptr = payload;
data_len = payload_len;
// os_printf("UVC: Header length: %d, Data: %x Data length: %d\n", header_len, data_ptr, data_len);
}
};
// 获取当前帧管理结构
UVC_MANAGE *frame = dev->current_frame;
//os_printf("UVC: Current frame: %x\n", frame);
// 检查是否为帧起始
if (valid_header == true) {
// 处理错误标志
if (header->headerInfoUnion.headerInfoBitmap.ERR) {
uvc_device_free_err_frame(dev, frame); // 异常结束
dev->current_blank = NULL;
dev->current_frame = NULL;
goto _exit;
}
// FID变化处理仅当有有效包头时
if ((frame ? (dev->last_fid != cur_fid) : 0)) {
if(((ep_type & USB_EP_ATTR_TYPE_MASK) == USB_EP_ATTR_ISOC))
{
//os_printf("[UVC] FID changed %d->%d payload[0]:0x%x payload[1]:0x%x\n", dev->last_fid, cur_fid, payload[0], payload[1]);
uvc_device_free_err_frame(dev, frame);//结束
dev->current_blank = NULL;
dev->current_frame = NULL;
frame = NULL;
}
}
#ifdef UVC_DEVICE_CHECK_PTS
if (header->headerInfoUnion.headerInfoBitmap.PTS) {
if ((frame ? (dev->dwPresentationTime != header->dwPresentationTime) : 0)) {
uvc_device_free_err_frame(dev, frame);//结束
dev->current_blank = NULL;
dev->current_frame = NULL;
frame = NULL;
}
}
#endif
if(frame == NULL && data_len > 0) {
// 获取新帧
struct list_head *new_frame_list = uvc_device_get_new_frame(dev, 1);
if (!new_frame_list) {
// 抢占模式获取可用帧
_os_printf("_D1_");
goto _exit; // 无法获取帧,丢弃数据
}
frame = list_entry(new_frame_list, UVC_MANAGE, list);
// os_printf("uvc_device_get_new_frame frame:%x\n", frame);
if (&dev->uvc_msg_frame[0] != frame && &dev->uvc_msg_frame[1] != frame) {
os_printf("ERR UVC: Frame %x\n", frame);
while(1);
} else {
}
if(video_format == USBH_VIDEO_FORMAT_MJPEG && (payload[payload[0]] != 0xFF || payload[payload[0] + 1] != 0xD8)){
uvc_device_free_err_frame(dev, frame);//结束
dev->current_blank = NULL;
dev->current_frame = NULL;
goto _exit;
}
dev->current_frame = frame;
dev->current_blank = NULL;
dev->last_fid = cur_fid;
#ifdef UVC_DEVICE_CHECK_PTS
if (header->headerInfoUnion.headerInfoBitmap.PTS) {
dev->dwPresentationTime = header->dwPresentationTime;
}
#endif
// 初始化帧信息
frame->frame_counter = dev->frame_counter;;
frame->frame_len = 0;
frame->data_len = 0;
frame->cpbuff = NULL;
} else {
}
} else {
}
//由于存在有效包头的判断,假如一直没有识别到有效包头,则不会获取到帧,不执行拷贝动作
if (frame) {
// 处理数据填充
uint32_t _data_len = data_len;
while (_data_len > 0) {
UVC_BLANK *blank = NULL;
uint8_t blank_loop = 0;
if(dev->current_blank) {
blank = dev->current_blank;
if (blank->re_space == 0) {
// 当前节点已满,强制分配新节点
blank->busy = UVC_DEVICE_BLANK_STATE_AVAILABLE;
struct list_head *new_node = uvc_device_get_blank_node(&frame->list, &dev->free_uvc_tab);
if (!new_node) {
_os_printf("_D2_");
uvc_device_free_err_frame(dev, frame);
dev->current_blank = NULL;
dev->current_frame = NULL;
// os_printf("Error: Failed to allocate new blank node!\n");
goto _exit;
}
blank_loop = blank->blank_loop;
blank = list_entry(new_node, UVC_BLANK, list);
dev->current_blank = blank;
blank->busy = UVC_DEVICE_BLANK_STATE_BUSY;
blank->blank_loop = blank_loop + 1;
blank->frame_counter = frame->frame_counter;
blank->re_space = blank->blank_len;
frame->cpbuff = blank->buf_ptr; // 重置写入指针到新节点
// os_printf("new blank:%x %x blank->blank_loop:%d\r\n", blank, blank->buf_ptr, blank->blank_loop);
}
} else {
struct list_head *blank_node = uvc_device_get_blank_node(&frame->list, &dev->free_uvc_tab);
if (!blank_node) {
_os_printf("_D3_");
uvc_device_free_err_frame(dev, frame);// 异常结束
dev->current_blank = NULL;
dev->current_frame = NULL;
// os_printf("Error: No free blank nodes available!\n");
goto _exit;
}
blank = list_entry(blank_node, UVC_BLANK, list);
dev->current_blank = blank;
blank->busy = UVC_DEVICE_BLANK_STATE_BUSY;
blank->blank_loop = blank_loop;
blank->frame_counter = frame->frame_counter;
blank->re_space = blank->blank_len;
frame->cpbuff = blank->buf_ptr; // 初始化写入指针
// os_printf("blank:%x %x blank->blank_loop:%d\r\n", blank, blank->buf_ptr, blank->blank_loop);
}
if(frame->cpbuff == NULL) {
os_printf("Error: cpbuff is NULL!\n");
while(1);
}
if(blank) {
// 计算实际可拷贝长度
uint32_t copy_len = MIN(_data_len, blank->re_space);
if (copy_len > 0) {
// os_printf("copy_len:%d %x %x\r\n", copy_len, data_ptr, frame->cpbuff);
hw_memcpy(frame->cpbuff, data_ptr, copy_len);
data_ptr += copy_len;
_data_len -= copy_len;
frame->cpbuff += copy_len; // 更新当前写入位置
frame->frame_len += copy_len;
blank->re_space -= copy_len;
// 标记节点为可用(若已填满)
blank->busy = (blank->re_space > 0) ? UVC_DEVICE_BLANK_STATE_BUSY : UVC_DEVICE_BLANK_STATE_AVAILABLE;
} else {
// 数据长度为0或异常情况退出循环
break;
}
}else{
os_printf("Error: blank is NULL!\n");
break;
}
}
} else {
//未能获取到frame
}
#ifdef UVC_DEVICE_BULK_CHECK_MJPEG_HEADER
if(((ep_type & USB_EP_ATTR_TYPE_MASK) == USB_EP_ATTR_BULK) && (video_format == USBH_VIDEO_FORMAT_MJPEG))
{
if ((data_len >= 2) && (payload[data_len - 2] == 0xFF && payload[data_len - 1] == 0xD9) && dev->current_frame)
{
// os_printf("[UVC] MJPEG Frame end\n");
uvc_device_end_frame(dev, frame);
if (dev->current_blank) {
dev->current_blank->busy = UVC_DEVICE_BLANK_STATE_AVAILABLE;
}
dev->current_blank = NULL; // 重置当前节点
dev->current_frame = NULL; // 重置当前帧
}
}
else
#endif
{
{
// 检查帧结束标志
if (valid_header == true && header->headerInfoUnion.headerInfoBitmap.EOI && dev->current_frame) {
// os_printf("[UVC] Frame end\n");
uvc_device_end_frame(dev, frame);
if (dev->current_blank) {
dev->current_blank->busy = UVC_DEVICE_BLANK_STATE_AVAILABLE;
}
dev->current_blank = NULL; // 重置当前节点
dev->current_frame = NULL; // 重置当前帧
}
}
}
_exit:
return;
}

1726
sdk/lib/video/uvc/uvc_host.c Normal file

File diff suppressed because it is too large Load Diff

1803
sdk/lib/video/vpp/vpp_dev.c Normal file

File diff suppressed because it is too large Load Diff