pure sdk for main

This commit is contained in:
divadiow
2025-08-27 09:51:58 +01:00
parent f0d033f1c9
commit 0571416e7c
3283 changed files with 1577720 additions and 1 deletions
+483
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
+137
View File
@@ -0,0 +1,137 @@
#ifndef __AVIDEMUX_H
#define __AVIDEMUX_H
typedef unsigned long DWORD;
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);
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
+11
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
File diff suppressed because it is too large Load Diff
+530
View File
@@ -0,0 +1,530 @@
#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
};
const 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))) = {
{
13, 9, 8, 13, 20, 33, 42, 51,
9, 9, 12, 15, 21, 48, 50, 45,
12, 10, 13, 20, 33, 47, 57, 46,
12, 14, 18, 24, 42, 72, 66, 51,
15, 18, 30, 46, 56, 90, 85, 63,
20, 29, 45, 53, 67, 86, 93, 76,
40, 53, 65, 72, 85, 100, 99, 84,
60, 76, 78, 81, 93, 83, 85, 82,
14, 15, 20, 39, 82, 82, 82, 82,
15, 17, 21, 54, 82, 82, 82, 82,
20, 21, 46, 82, 82, 82, 82, 82,
39, 54, 82, 82, 82, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82
},
{
//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
+432
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_*/
+421
View File
@@ -0,0 +1,421 @@
#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/semaphore.h"
#include "custom_mem/custom_mem.h"
#include "lib/video/dvp/jpeg/jpg.h"
#include "osal/task.h"
#if PRC_EN
#define IIC_CLK 120000UL
extern SNSER snser;
#define RESET_HIGH() {gpio_set_val(rsn,1);}
#define RESET_LOW() {gpio_set_val(rsn,0);}
struct os_task 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[240*16+240*16/2]__attribute__ ((aligned(4)));
uint8 psram_spi_sensor[3][240*320+240*320/2] __attribute__ ((aligned(16),section(".psram.src")));
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_ null_init2={0x00,0x00,0x00,0x00,0x00,0x00};
void prc_deal_irq(uint32 irq, uint32 irq_data);
void spi0_read_irq(uint32 irq, uint32 irq_data);
static const _Sensor_Ident_ *devSensorInitTable_spi[] = {
#if DEV_SENSOR_BF30A2
&bf30a2_init,
#endif
NULL,
};
static const _Sensor_Adpt_ *devSensorOPTable_spi[] = {
#if DEV_SENSOR_BF30A2
&bf30a2_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,240);
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+240*16);
prc_set_vaddr(prc_dev_g,(uint32)prc_yuv_line+240*16+240*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_SPI1_DEVID);
spi_open(spi0_dev_g, 10000000, SPI_SLAVE_MODE, SPI_WIRE_SINGLE_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 ,0xea60,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,6,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,480*16,0);
if(spi_dat_buf[0] == NULL){
spi_dat_buf[0] = (uint8 *)custom_malloc(480*16);
}
if(spi_dat_buf[1] == NULL){
spi_dat_buf[1] = (uint8 *)custom_malloc(480*16);
}
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,180000);
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 display_addr = 0;
volatile uint32 prc_new_frame;
volatile int flow_data_cnt;
volatile uint8 prc_deal_num = 0;
uint8 spi_video_run = 0;
//只有主spi才能保证数据是准确的
void spi0_read_irq(uint32 irq, uint32 irq_data){
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++;
flow_data_cnt++;
spi_close(spi0_dev_g);
spi_sensor_cfg();
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;
}
memcpy(prc_buf+prc_deal_num*(16*240),prc_yuv_line,16*240);
memcpy(prc_buf+320*240+prc_deal_num*(4*240),prc_yuv_line+240*16,4*240);
memcpy(prc_buf+320*240+320*240/4+prc_deal_num*(4*240),prc_yuv_line+240*16+240*4,4*240);
prc_deal_num++;
if(prc_deal_num == 20){
prc_deal_num = 0;
display_addr = (uint32)prc_buf;
}
}
uint32 count_timer_get = 0;
uint32 frame_end = 0;
uint32 frame_deal = 0;
void spi_sensor_reset(void){
uint8_t pdn;
pdn = PIN_SPI_PDN;
if(pdn != 255){
gpio_iomap_input(pdn, GPIO_IOMAP_INPUT); //pdn up
os_sleep_ms(1);
gpio_iomap_output(pdn,GPIO_IOMAP_OUTPUT);
gpio_set_val(pdn,0); //pdn down
os_sleep_ms(50);
}
}
static _Sensor_Adpt_ * sensorAutoCheck_spi(struct i2c_device *p_iic,uint8 *init_buf)
{
uint8 i;
_Sensor_Adpt_ * devSensor_Struct=NULL;
for(i=0;devSensorInitTable_spi[i] != NULL;i++)
{
spi_sensor_reset();
if(sensorCheckId(p_iic,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_ *)&null_init2;
return NULL; // index 0 is test only
}
return devSensor_Struct;
}
void lcd_user_frame(uint32 frame_addr);
void spi_sensor_thread(){
struct hgpwm_v0 *global_hgpwm;
int data_cnt_old = 0;
uint8 sensor_staus = 0; //0:stop 1:run
global_hgpwm = (struct hgpwm_v0 *)dev_get(HG_PWM0_DEVID);
memset(psram_spi_sensor,0x80,3*(240*320+240*320/2));
prc_module_init();
//spi_sensor_cfg();
pwm_stop((struct pwm_device *)global_hgpwm, PWM_CHANNEL_0);
while(1){
if(spi_video_run == 1){
if(sensor_staus == 0){
sensor_staus = 1;
sync_start = 0;
//if(spi_dat_buf[0] == NULL){
// spi_dat_buf[0] = (uint8 *)custom_malloc(480*16);
//}
//if(spi_dat_buf[1] == NULL){
// spi_dat_buf[1] = (uint8 *)custom_malloc(480*16);
//}
spi_sensor_cfg();
pwm_start((struct pwm_device *)global_hgpwm, PWM_CHANNEL_0);
}
}
if(flow_data_cnt == data_cnt_old){
os_sleep_ms(10);
continue;
}
data_cnt_old = flow_data_cnt;
if(spi_video_run == 0){
if(sensor_staus == 1){
sensor_staus = 0;
pwm_stop((struct pwm_device *)global_hgpwm, PWM_CHANNEL_0);
if(spi_dat_buf[0]){
custom_free((void *)spi_dat_buf[0]);
spi_dat_buf[0] = NULL;
}
if(spi_dat_buf[1]){
custom_free((void *)spi_dat_buf[1]);
spi_dat_buf[1] = NULL;
}
}
continue;
}
lcd_user_frame(display_addr);
}
}
void spi_2_jpg();
void i2c_SetSetting(struct i2c_setting *p_i2c_setting);
void spi_senosr_open(){
uint8 adr_num,dat_num;
uint8 sen_w_cmd,sen_r_cmd,id_c = 0;
int8 idbuf[3];
uint32 i=0;
static _Sensor_Adpt_ *p_sensor_cmd = NULL;
struct i2c_setting i2c_setting;
struct hgpwm_v0 *global_hgpwm;
iic_test = (struct i2c_device *)dev_get(HG_I2C2_DEVID);
i2c_set_baudrate(iic_test,IIC_CLK);
i2c_open(iic_test, IIC_MODE_MASTER, IIC_ADDR_7BIT, 0);
i2c_ioctl(iic_test,IIC_SDA_OUTPUT_DELAY,20);
i2c_ioctl(iic_test,IIC_FILTERING,20);
i2c_ioctl(iic_test,IIC_STRONG_OUTPUT,1);
global_hgpwm = (struct hgpwm_v0 *)dev_get(HG_PWM0_DEVID);
gpio_driver_strength(PIN_PWM_CHANNEL_0, GPIO_DS_28MA);
pwm_init((struct pwm_device *)global_hgpwm, PWM_CHANNEL_0, 5, 3);
pwm_start((struct pwm_device *)global_hgpwm, PWM_CHANNEL_0);
os_sleep_ms(3);
os_printf("set SPI sensor finish ,Auto Check sensor id\r\n");
p_sensor_cmd = snser.p_sensor_cmd = sensorAutoCheck_spi(iic_test,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);
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{
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);
}
}
}
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);
i2c_read(iic_test,idbuf,adr_num,(int8*)&id_c,dat_num);
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;
}
i2c_write(iic_test, (int8*)&p_sensor_cmd->p_xc7016_adapt.sensor_init_table[i], adr_num, (int8*)&p_sensor_cmd->p_xc7016_adapt.sensor_init_table[i+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;
}
i2c_write(iic_test, (int8*)&p_sensor_cmd->p_xc7016_adapt.bypass_off[i], u8Addrbytnum, (int8*)&p_sensor_cmd->p_xc7016_adapt.bypass_off[i+u8Addrbytnum], u8Databytnum);
if(i==0)
{
os_sleep_ms(1);
}
}
}
}
OS_TASK_INIT("dvp_manual", &dvp_manual_handle, spi_sensor_thread, NULL, OS_TASK_PRIORITY_ABOVE_NORMAL, 1024);
}
#else
uint8 spi_video_run = 0;
#endif
+665
View File
@@ -0,0 +1,665 @@
#include "sys_config.h"
#include "typesdef.h"
#include "list.h"
#include "dev.h"
#include "devid.h"
#include "osal/string.h"
#include "osal/semaphore.h"
#include "osal/mutex.h"
#include "osal/msgqueue.h"
#include "osal/irq.h"
#include "osal/task.h"
#include "osal/sleep.h"
#include "tx_platform.h"
#include "utlist.h"
#include "hal/usb_device.h"
#include "lib/usb/usb_device_wifi.h"
#include "lib/usb/usb_device_mass.h"
#include "jpgdef.h"
#include "osal/work.h"
#include "osal/event.h"
#include "dev/usb/hgusb20_v1_dev_api.h"
#include "dev/usb/hgusb_dev_tbl.h"
#include "hal/gpio.h"
#include "dev/usb/uvc_host.h"
#include "lib/video/uvc/hg_usb_device.h"
#include "osal/mutex.h"
#include "lib/sdhost/sdhost.h"
#include "video_app_usb.h"
#if 0
#define USB_TEST_WIFI 1
#define USB_TEST_AUDIO 0
struct hg_usb_device_test {
#if USB_TEST_WIFI
//正常host不需要使用
#if USB_HOST_EN
int8 rx_buf[4]; /* usb rx buffer reserved 4byte for no overflow control */
int8 tx_buf[4];
#else
int8 rx_buf[512*16+4]; /* usb rx buffer reserved 4byte for no overflow control */
int8 tx_buf[512*16];
#endif
#endif
#if USB_TEST_AUDIO
int8 rx_buf[512*4+4];
int8 tx_buf[512*4];
#endif
int32 ready;
uint32 total_tx_len;
uint32 total_rx_len;
struct os_mutex tx_lock;
struct os_semaphore sem;
struct usb_device *dev;
struct os_task state_task;
struct os_task scsi_task;
} usb_test;
#endif
struct hg_usb_device_test usb_test;
//volatile uint8_t rx_done = 0;
#if 1
static void usb_bus_irq_test(uint32 irq, uint32 param1, uint32 param2, uint32 param3)
{
struct usb_device *usb_dev = (struct usb_device *)param1;
switch (irq) {
case USB_DEV_RESET_IRQ:
os_printf("reset\r\n");
os_sema_up(&usb_test.sem);
//usb_device_wifi_read(usb_test.dev, usb_test.rx_buf, sizeof(usb_test.rx_buf));
usb_test.ready = 1;
break;
case USB_DEV_SUSPEND_IRQ: break;
case USB_DEV_RESUME_IRQ: break;
case USB_DEV_SOF_IRQ: break;
case USB_DEV_CTL_IRQ:
usb_device_mass_uvc_ep0_setup_irq(usb_dev, param3);
break;
case USB_EP_RX_IRQ:
//os_printf("rx=%d\r\n", param3);
//rx_done = 1;
usb_test.total_rx_len += param3;
if(usb_test.ready)
os_sema_up(&usb_test.sem);
break;
case USB_EP_TX_IRQ:
//os_printf("tx_ok\r\n");
//os_mutex_unlock(&usb_test.tx_lock);
//usb_test.ready = 1;
usb_test.total_tx_len += param3;
break;
default:
break;
}
}
uint32_t scsi_count = 0;
extern struct sdh_device *sdh_test;
void usb_scsi_rqu_deal() {
if(get_cbw()) {
scsi_count++;
#if PINGPANG_BUF_EN
scsi_cmd_analysis();
#else
os_mutex_lock(&sdh_test->lock,osWaitForever);
scsi_cmd_analysis();
os_mutex_unlock(&sdh_test->lock);
#endif
}
usb_device_mass_read(usb_test.dev, usb_test.rx_buf, sizeof(usb_test.rx_buf));
}
void usb_scsi_rqu_deal_flash() {
if(get_cbw()) {
scsi_count++;
scsi_cmd_analysis_flash();
}
usb_device_mass_read(usb_test.dev, usb_test.rx_buf, sizeof(usb_test.rx_buf));
}
void usb_dev_thread_flash() {
usb_bulk_init();
//flash作为文件系统的时候,扇区是4096(如果是只读,是可以设置512的)
init_usb_disk_buf(4096);
while(1){
os_sema_down(&usb_test.sem, osWaitForever);
usb_scsi_rqu_deal_flash();
usb_test.total_rx_len = 0;
usb_test.total_tx_len = 0;
}
}
void usb_dev_thread() {
usb_bulk_init();
//sd卡作为文件系统,扇区大小是512(一般都是配置512,如果特殊需要)
init_usb_disk_buf(512);
while(1){
os_sema_down(&usb_test.sem, osWaitForever);
usb_scsi_rqu_deal();
usb_test.total_rx_len = 0;
usb_test.total_tx_len = 0;
}
}
void usbdisk_thread_exit()
{
os_mutex_lock(&sdh_test->lock,osWaitForever);
os_task_del(&usb_test.scsi_task);
deinit_usb_disk_buf();
os_mutex_unlock(&sdh_test->lock);
}
static int opcode_func(stream *s,void *priv,int opcode)
{
int res = 0;
//_os_printf("%s:%d\topcode:%d\n",__FUNCTION__,__LINE__,opcode);
switch(opcode)
{
case STREAM_OPEN_ENTER:
break;
case STREAM_OPEN_EXIT:
{
enable_stream(s,1);
}
break;
case STREAM_OPEN_FAIL:
break;
default:
//默认都返回成功
break;
}
return res;
}
extern volatile uint8_t uvc_device_on;
void set_uvc_head_scr(uint8 *headbuf){
static uint32 time_scr;
static uint8_t n=0;
uint32 source_time = 0;
uint16 Sof_1Khz = 0; //只取11位
Sof_1Khz = os_jiffies();
Sof_1Khz = Sof_1Khz&0x7ff;
source_time = os_jiffies();
source_time = source_time*15000;
if(time_scr != source_time){
time_scr = source_time;
n = 1;
}else{
source_time += 1875*n;
n++;
}
headbuf[6] = source_time&0xff;
headbuf[7] = (source_time&0xff00)>>8;
headbuf[8] = (source_time&0xff0000)>>16;
headbuf[9] = (source_time&0xff000000)>>24;
headbuf[10] = Sof_1Khz&0xff;
headbuf[11] = (Sof_1Khz&0xff00)>>8;
}
static uint8_t *g_uvcbuf = NULL;
static struct data_structure *g_data_s = NULL;
static stream *g_usbdev_s = NULL;
void usb_uvc_thread(){
#define DAT_LEN 1012
struct data_structure *get_f = NULL;
struct stream_jpeg_data_s *dest_list;
struct stream_jpeg_data_s *dest_list_tmp;
stream *s = NULL;
uint32_t node_len;
uint32_t flen;
uint8_t *uvcbuf;
uint8_t *jpeg_buf_addr = NULL;
uint8 headbuf[12];
uint32 time_info = 0;
uint32 cur_tick = 0;
uint32 start_tick = 0;
uint32 send_loop = 0;
uint32 offset_frame;
start_tick = os_jiffies();
cur_tick = start_tick;
headbuf[0] = 2; //12个字节头,字节长度
headbuf[1] = 0x00;
uvcbuf = malloc(DAT_LEN+12);
g_uvcbuf = uvcbuf;
os_sleep_ms(1000);
s = open_stream_available(R_RTP_JPEG,0,8,opcode_func,NULL);
g_usbdev_s = s;
while(1){
if(uvc_device_on){
scsi_count++;
headbuf[2] = time_info&0xff;//(u8*)time_info[0];
headbuf[3] = (time_info&0xff00)>>8;
headbuf[4] = (time_info&0xff0000)>>16;
headbuf[5] = (time_info&0xff000000)>>24;
headbuf[1] &= ~BIT(1);
get_f = recv_real_data(s);
g_data_s = get_f;
if(get_f){
cur_tick = os_jiffies();
time_info = cur_tick - start_tick;
time_info = time_info*15000;
headbuf[1] ^= BIT(0); //0X8C与0X8D互相切换
dest_list = (struct stream_jpeg_data_s *)GET_DATA_BUF(get_f);
dest_list_tmp = dest_list;
flen = get_stream_real_data_len(get_f);
node_len = GET_NODE_LEN(get_f);
jpeg_buf_addr = (uint8_t *)GET_JPG_BUF(get_f);
//os_printf("flen:%d jpeg_buf_addr:%x\r\n",flen,jpeg_buf_addr);
send_loop = (flen+DAT_LEN-1)/DAT_LEN;
offset_frame = 0;
while(flen){
if(flen > DAT_LEN){
set_uvc_head_scr(headbuf);
flen -= DAT_LEN;
if(flen == 0){
headbuf[1] |= BIT(1);
}
memcpy(uvcbuf,headbuf,2);
memcpy(uvcbuf+2,jpeg_buf_addr+offset_frame,DAT_LEN);
usb_uvc_tx(2,(uint32_t)uvcbuf,DAT_LEN+2);
if(uvc_device_on == 0){
break;
}
offset_frame += DAT_LEN;
}else{
set_uvc_head_scr(headbuf);
headbuf[1] |= BIT(1);
memcpy(uvcbuf,headbuf,2);
memcpy(uvcbuf+2,jpeg_buf_addr+offset_frame,flen);
usb_uvc_tx(2,(uint32_t)uvcbuf,flen+2);
if(uvc_device_on == 0){
break;
}
flen = 0;
}
}
free_data(get_f);
get_f = NULL;
g_data_s = NULL;
}else{
set_uvc_head_scr(headbuf);
usb_uvc_tx(2,(uint32_t)headbuf,2);
//os_sleep_ms(1);
}
}else{
os_sleep_ms(1);
}
}
}
void uvcdev_stream_deinit()
{
if(g_uvcbuf) {
free(g_uvcbuf);
}
if(g_data_s) {
free_data(g_data_s);
}
if(g_usbdev_s) {
close_stream(g_usbdev_s);
}
}
static void hg_usb_test_state(void *argument)
{
os_printf("hg_usb_test_state running ...\r\n");
while (1) {
os_sleep(5);
os_printf("RX/TX Speed:%dKB/s, %dKB/s\r\n",
(usb_test.total_rx_len / 1024) / 5,
(usb_test.total_tx_len / 1024) / 5);
usb_test.total_rx_len = 0;
usb_test.total_tx_len = 0;
}
}
struct os_semaphore global_delay_sem;
//struct test_start global_start;
struct os_task global_uvc_handle;
#if 0
//需要查找有没有足够bank才能去kick
void delay_kick(void *d)
{
global_start.dev = NULL;
global_start.buf = NULL;
global_start.len = 0;
while(1)
{
os_sema_down(&global_delay_sem, osWaitForever);
if(global_start.dev)
{
os_sleep_ms(1);
//_os_printf("d:%d\n",krhino_sys_tick_get()-time);
//time = krhino_sys_tick_get();
usb_uvc_rx_kick_dma_start(global_start.dev,(uint32)global_start.buf,global_start.len);
}
}
}
#endif
extern void uvc_user2(void *d);
int32 usb_host_uvc_ioctl(struct usb_device *p_usb_d, uint32 cmd, uint32 param1, uint32 param2);
void hg_usb_disable()
{
usb_device_request_irq(usb_test.dev, NULL, 0);
}
uint8 uvc_ioctl_index(uint8 uvc_idx){
uint8 msgbuf[1];
uint8* pt;
struct usb_device *dev;
dev = usb_test.dev;
pt = msgbuf;
pt[0] = uvc_idx;
return usb_host_uvc_ioctl(dev,USB_HOST_IO_CMD_SET_IDX,(uint32)msgbuf[0],0);
}
extern void uvc_avi_thread(void *d);
struct uvc_user_arg uvc_arg;
struct uvc_user_arg uvc_arg_dual;
void usb_hub_device_insert(struct hgusb20_dev *p_dev);
int enum_deal= 0;
extern int usb_dma_irq_times;
static void usb_host_enum_task(void *argument)
{
struct hgusb20_dev *p_dev = (struct hgusb20_dev *)argument;
while (1) {
os_sema_down(&p_dev->usb_os_msg->ep0_sema, osWaitForever); //收到connect信号,开始枚举
bool usb_uvc_host_enum(struct hgusb20_dev *p_dev);
usb_uvc_host_enum(p_dev);
enum_deal = 1;
}
}
struct usb_connect_workqueue
{
struct os_work wk;
void *arg;
};
int32 usb_iso_device_connect_det_loop(struct os_work *work)
{
struct usb_connect_workqueue *usb_connect_work = (struct usb_connect_workqueue*)work;
struct hgusb20_dev *p_dev = (struct hgusb20_dev *)usb_connect_work->arg;
static uint32_t count_iso = 0;
_os_printf("enum_deal:%d count_iso:%d usb_dma_irq_times:%d\r\n",enum_deal,count_iso,usb_dma_irq_times);
if(enum_deal)
{
if(count_iso == usb_dma_irq_times)
{
os_printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%s\n",__FUNCTION__);
if(uvc_ep_bulk_or_isoc() == USB_ENDPOINT_XFER_ISOC)
{
hgusb20_host_reset_phy(p_dev);
}
enum_deal = 0;
}
count_iso = usb_dma_irq_times;
}
os_run_work_delay(work, 2000);
return 0;
}
void usb_iso_device_connect_det(void *argument){
struct hgusb20_dev *p_dev = (struct hgusb20_dev *)argument;
int count_iso = 0;
while(1){
_os_printf("enum_deal:%d count_iso:%d usb_dma_irq_times:%d\r\n",enum_deal,count_iso,usb_dma_irq_times);
if(enum_deal){
if(count_iso == usb_dma_irq_times){
hgusb20_host_reset_phy(p_dev);
enum_deal = 0;
}
count_iso = usb_dma_irq_times;
}
os_sleep_ms(2000);
}
}
static struct usb_connect_workqueue usb_connect_work;
void usb_host_h264_uvc_reset()
{
struct hgusb20_dev *p_dev = (struct hgusb20_dev *)usb_connect_work.arg;
if(p_dev)
{
hgusb20_host_reset_phy(p_dev);
}
}
void usb_host_task_init(struct hgusb20_dev *p_dev)
{
os_sema_init(&p_dev->usb_os_msg->ep0_sema, 0);
os_sema_init(&p_dev->usb_os_msg->hub_sema, 0);
os_sema_init(&p_dev->usb_os_msg->hub_finish_sema, 0);
OS_TASK_INIT((const uint8 *)"USB_ENUM", &p_dev->usb_os_msg->ep0_task,
usb_host_enum_task, (uint32)p_dev, OS_TASK_PRIORITY_BELOW_NORMAL, 2048);
OS_TASK_INIT((const uint8 *)"USB_HUB", &p_dev->usb_os_msg->ep0_hub_task,
usb_hub_device_insert, (uint32)p_dev, OS_TASK_PRIORITY_BELOW_NORMAL, 1024);
//OS_TASK_INIT((const uint8 *)"USB_DISCONN", &p_dev->usb_os_msg->ep0_usb_connect_task,usb_iso_device_connect_det, (uint32)p_dev, OS_TASK_PRIORITY_BELOW_NORMAL, 1024);
usb_connect_work.arg = (void*)p_dev;
//OS_WORK_INIT(&usb_connect_work.wk, usb_iso_device_connect_det_loop, 0);
//os_run_work_delay(&usb_connect_work.wk, 1000);
}
void usb_host_task_del(struct hgusb20_dev *p_dev)
{
os_sema_del(&p_dev->usb_os_msg->ep0_sema);
os_sema_del(&p_dev->usb_os_msg->hub_sema);
os_sema_del(&p_dev->usb_os_msg->hub_finish_sema);
os_task_del(&p_dev->usb_os_msg->ep0_task);
os_task_del(&p_dev->usb_os_msg->ep0_hub_task);
os_work_cancle(&usb_connect_work.wk, 1);
}
void uvc_user4(void *d);
void hg_usb_test(void)
{
#if USB_HOST_EN
os_printf("hg_usb20_test init2 \r\n");
os_sema_init(&global_delay_sem, 0);
usb_test.dev = (struct usb_device *)dev_get(HG_USBDEV_DEVID);
if (usb_test.dev) {
usb_host_task_init((struct hgusb20_dev *)usb_test.dev);
if (!usb_device_open(usb_test.dev, NULL)) {
_os_printf("%s:%d\n",__FUNCTION__,__LINE__);
uint32 usb_host_bus_irq(uint32 irq, uint32 param1, uint32 param2, uint32 param3);
usb_device_request_irq(usb_test.dev, usb_host_bus_irq, (int32)usb_test.dev);
}
}
uvc_sema_init();
#if TEST_UVC_DEBUG
OS_TASK_INIT("uvc_user2", &global_uvc_handle, uvc_user2, usb_test.dev, OS_TASK_PRIORITY_NORMAL, 1024);
#else
#if LCD_EN == 1
#else
#ifndef PSRAM_HEAP
usb_jpeg_stream_init();
#endif
#endif
#endif
//uvc_user2();
#else
struct hgusb20_dev *p_dev;
usb_test.dev = (struct usb_device *)dev_get(HG_USBDEV_DEVID);
p_dev = (struct hgusb20_dev *)usb_test.dev;
os_sema_init(&usb_test.sem, 0);
p_dev->usb_os_msg->dev_type = UDISK_DEV;
if (usb_test.dev) {
if (!usb_device_mass_uvc_open(usb_test.dev))
{
usb_device_mass_auto_tx_null_pkt_disable(usb_test.dev);
usb_device_request_irq(usb_test.dev, (usbdev_irq_hdl)usb_bus_irq_test, (int32)usb_test.dev);
if(p_dev->usb_os_msg->dev_type == UDISK_DEV){
#if USBDISK == 1
OS_TASK_INIT("scsi_task",&usb_test.scsi_task, usb_dev_thread, NULL, OS_TASK_PRIORITY_NORMAL, 2048);//1024也可
#elif USBDISK == 2
OS_TASK_INIT("scsi_task",&usb_test.scsi_task, usb_dev_thread_flash, NULL, OS_TASK_PRIORITY_NORMAL, 2048);//1024也可
#endif
}else{
OS_TASK_INIT("uvc_task",&usb_test.scsi_task, usb_uvc_thread, NULL, OS_TASK_PRIORITY_NORMAL, 2048);//1024也可
}
}
}
#endif
}
void hgusb_dev_recfg(uint8_t dev_tpye){
struct hgusb20_dev *p_dev;
usb_test.dev = (struct usb_device *)dev_get(HG_USBDEV_DEVID);
p_dev = (struct hgusb20_dev *)usb_test.dev;
os_task_del(&usb_test.scsi_task);
usb_device_mass_uvc_close(usb_test.dev);
p_dev->usb_os_msg->dev_type = dev_tpye;
if (usb_test.dev) {
if (!usb_device_mass_uvc_open(usb_test.dev))
{
usb_device_mass_auto_tx_null_pkt_disable(usb_test.dev);
usb_device_request_irq(usb_test.dev, (usbdev_irq_hdl)usb_bus_irq_test, (int32)usb_test.dev);
if(p_dev->usb_os_msg->dev_type == UDISK_DEV){
OS_TASK_INIT("scsi_task",&usb_test.scsi_task, usb_dev_thread, NULL, OS_TASK_PRIORITY_NORMAL, 2048);//1024也可
}else{
OS_TASK_INIT("uvc_task",&usb_test.scsi_task, usb_uvc_thread, NULL, OS_TASK_PRIORITY_NORMAL, 2048);//1024也可
}
}
}
}
uint32_t hgusb_get_devtype(){
struct hgusb20_dev *p_dev;
struct usb_device *u_dev;
u_dev = (struct usb_device *)dev_get(HG_USBDEV_DEVID);
p_dev = (struct hgusb20_dev *)u_dev;
return p_dev->usb_os_msg->dev_type;
}
extern void uvc_stream_open(struct hgusb20_dev *p_dev,uint8 enable);
extern void uac_stream_open(struct hgusb20_dev *p_dev,uint8 enable);
extern void usb_jpeg_psram_stream_deinit();
extern void usbmic_audio_stream_deinit(void);
extern void usbspk_audio_stream_deinit(void);
void usb_host_suspend(void *dev)
{
struct hgusb20_dev *p_dev = (struct hgusb20_dev *)dev;
uvc_stream_open(p_dev,0);
os_sleep_ms(10);
uac_stream_open(p_dev,0);
os_sleep_ms(10);
usb_device_close((struct usb_device *)p_dev);
usb_host_task_del(p_dev);
usb_jpeg_psram_stream_deinit();
force_reset_uvc_frame();
usbmic_audio_stream_deinit();
usbspk_audio_stream_deinit();
force_reset_usbmic_frame();
force_reset_usbspk_frame();
}
void usb_host_resume(void *dev)
{
struct hgusb20_dev *p_dev = (struct hgusb20_dev *)dev;
usb_host_task_init((struct hgusb20_dev *)p_dev);
if(!usb_device_open((struct usb_device *)p_dev, NULL)) {
uint32 usb_host_bus_irq(uint32 irq, uint32 param1, uint32 param2, uint32 param3);
usb_device_request_irq((struct usb_device *)p_dev, usb_host_bus_irq, (int32)p_dev);
os_printf("hgusb20_host open again\n");
}
}
void usb_device_suspend(void *dev)
{
struct hgusb20_dev *p_dev = (struct hgusb20_dev *)dev;
if(p_dev->usb_os_msg->dev_type == UVC_DEV) {
uvc_device_on = 0;
os_sleep_ms(50);
os_task_del(&usb_test.scsi_task);
usb_device_mass_uvc_close((struct usb_device *)p_dev);
uvcdev_stream_deinit();
}
else if(p_dev->usb_os_msg->dev_type == UDISK_DEV) {
usbdisk_thread_exit();
usb_device_mass_uvc_close((struct usb_device *)p_dev);
}
os_sema_del(&usb_test.sem);
}
void usb_device_resume(void *dev)
{
struct hgusb20_dev *p_dev = (struct hgusb20_dev *)dev;
os_sema_init(&usb_test.sem, 0);
if (!usb_device_mass_uvc_open(usb_test.dev))
{
usb_device_mass_auto_tx_null_pkt_disable(usb_test.dev);
usb_device_request_irq(usb_test.dev, (usbdev_irq_hdl)usb_bus_irq_test, (int32)usb_test.dev);
if(p_dev->usb_os_msg->dev_type == UDISK_DEV){
OS_TASK_INIT("scsi_task",&usb_test.scsi_task, usb_dev_thread, NULL, OS_TASK_PRIORITY_NORMAL, 2048);//1024也可
}else{
OS_TASK_INIT("uvc_task",&usb_test.scsi_task, usb_uvc_thread, NULL, OS_TASK_PRIORITY_NORMAL, 2048);//1024也可
}
}
}
#endif
+412
View File
@@ -0,0 +1,412 @@
#include "dev/usb/uvc_host.h"
#include "sys_config.h"
#include "list.h"
#include "dev.h"
#include "typesdef.h"
#include "devid.h"
#include "osal/string.h"
#include "custom_mem/custom_mem.h"
#include "dev/usb/hgusb20_v1_dev_api.h"
static uint8_t *empty_buf = NULL;
uint32 usbmic_packet_len = 16;
uint8 *usbmic_buf = NULL;
uint8 *usbspk_buf = NULL;
#define UAC_FRAME_NUM 4
#define UAC_FRAME_LEN 1024
volatile UAC_MANAGE usbmic_manage[UAC_FRAME_NUM];
volatile UAC_MANAGE usbspk_manage[UAC_FRAME_NUM];
struct list_head usbmic_free_list;
struct list_head usbmic_use_list;
struct list_head usbspk_free_list;
struct list_head usbspk_use_list;
static uint8 check_usbmic_room = 0;
static uint8 check_usbspk_room = 0;
uint8_t uac_run = 0;
uint8_t uac_open = 0;
uint8 *get_uac_frame_data(UAC_MANAGE *uac_manage)
{
return uac_manage->data_addr;
}
uint8 get_uac_frame_sta(UAC_MANAGE *uac_manage)
{
return uac_manage->sta;
}
void set_uac_frame_sta(UAC_MANAGE *uac_manage, uint8 sta)
{
uac_manage->sta = sta;
}
uint32 get_uac_frame_datalen(UAC_MANAGE *uac_manage)
{
return uac_manage->data_len;
}
void set_uac_frame_datalen(UAC_MANAGE *uac_manage, uint32 len)
{
uac_manage->data_len = len;
}
uint32 get_uac_frame_respace_len(UAC_MANAGE *uac_manage)
{
return uac_manage->respace_len;
}
uint32 get_uac_frame_num(struct list_head *head)
{
int count = 0;
struct list_head *first = (struct list_head *)head;
while(head->next != first)
{
head = head->next;
count++;
}
return count;
}
void usbmic_frame_init(void)
{
for(uint8 i=0; i<UAC_FRAME_NUM; i++)
{
usbmic_manage[i].data_addr = NULL;
usbmic_manage[i].data_len = 0;
usbmic_manage[i].respace_len = UAC_FRAME_LEN;
usbmic_manage[i].offset = 0;
usbmic_manage[i].sta = 0;
}
}
void usbspk_frame_init(void)
{
for(uint8 i=0; i<UAC_FRAME_NUM; i++)
{
usbspk_manage[i].data_addr = NULL;
usbspk_manage[i].data_len = 0;
usbspk_manage[i].respace_len = UAC_FRAME_LEN;
usbspk_manage[i].offset = 0;
usbspk_manage[i].sta = 0;
}
}
void usbmic_room_init(void)
{
usbmic_frame_init();
INIT_LIST_HEAD((struct list_head *)&usbmic_free_list);
INIT_LIST_HEAD((struct list_head *)&usbmic_use_list);
if(check_usbmic_room == 0) {
usbmic_buf = (uint8*)os_zalloc(UAC_FRAME_LEN*UAC_FRAME_NUM);
if(usbmic_buf)
check_usbmic_room = 1;
}
if(!usbmic_buf)
{
os_printf("malloc usbmic room err\n");
return;
}
for(uint8 i=0; i<UAC_FRAME_NUM; i++)
{
usbmic_manage[i].data_addr = usbmic_buf+i*UAC_FRAME_LEN;
list_add_tail((struct list_head *)&usbmic_manage[i].list,(struct list_head *)&usbmic_free_list);
}
os_printf("usbmic_room_init\n");
}
void usbmic_room_del(void)
{
if(usbmic_buf) {
os_free(usbmic_buf);
os_printf("usbmic_room_del\n");
usbmic_buf = NULL;
check_usbmic_room = 0;
}
}
void usbspk_room_init(uint32_t empty_buf_len)
{
usbspk_frame_init();
INIT_LIST_HEAD((struct list_head *)&usbspk_free_list);
INIT_LIST_HEAD((struct list_head *)&usbspk_use_list);
if(empty_buf_len == 0)
{
empty_buf_len = 96; //48K采样率
}
empty_buf = (uint8_t*)os_zalloc(empty_buf_len);
if(!empty_buf)
{
os_printf("malloc empty buf err\n");
return;
}
if(check_usbspk_room == 0) {
usbspk_buf = (uint8*)os_zalloc(UAC_FRAME_LEN*UAC_FRAME_NUM);
if(usbspk_buf)
check_usbspk_room = 1;
}
if(!usbspk_buf)
{
os_printf("malloc usbspk room err\n");
return;
}
for(uint8 i=0; i<UAC_FRAME_NUM; i++)
{
usbspk_manage[i].data_addr = usbspk_buf+i*UAC_FRAME_LEN;
list_add_tail((struct list_head *)&usbspk_manage[i].list,(struct list_head *)&usbspk_free_list);
}
os_printf("usbspk_room_init\n");
}
void usbspk_room_del(void)
{
if(usbspk_buf) {
os_free(usbspk_buf);
os_printf("usbspk_room_del\n");
usbspk_buf = NULL;
check_usbspk_room = 0;
}
if(empty_buf) {
os_free(empty_buf);
os_printf("empty buf free\n");
empty_buf = NULL;
}
}
UAC_MANAGE *get_usbmic_new_frame(uint8 grab)
{
UAC_MANAGE *uac_manage = NULL;
if(grab == 0)
{
if(list_empty((const struct list_head *)&usbmic_free_list)){
// os_printf("Not usbmic free frame\n");
return 0;
}
}
else if(grab == 1)
{
if(list_empty((const struct list_head *)&usbmic_free_list)){
list_move_tail((struct list_head *)usbmic_use_list.prev, (struct list_head *)&usbmic_free_list);
}
}
uac_manage = list_entry((struct list_head *)usbmic_free_list.next, UAC_MANAGE, list);
uac_manage->data_len = 0;
uac_manage->respace_len = UAC_FRAME_LEN;
uac_manage->offset = 0;
set_uac_frame_sta(uac_manage, 1);
return uac_manage;
}
UAC_MANAGE *get_usbmic_frame(void)
{
UAC_MANAGE *uac_manage = NULL;
if(list_empty((const struct list_head *)&usbmic_use_list)){
// os_printf("Not usbmic use frame\n");
return 0;
}
uac_manage = list_entry((struct list_head *)usbmic_use_list.next, UAC_MANAGE, list);
set_uac_frame_sta(uac_manage, 3);
return uac_manage;
}
void put_usbmic_frame_to_use(UAC_MANAGE *uac_manage)
{
set_uac_frame_sta(uac_manage, 2);
list_move_tail((struct list_head *)&uac_manage->list, (struct list_head *)&usbmic_use_list);
}
void del_usbmic_frame(UAC_MANAGE *uac_manage)
{
set_uac_frame_sta(uac_manage, 0);
list_move_tail((struct list_head *)&uac_manage->list, (struct list_head *)&usbmic_free_list);
}
UAC_MANAGE *get_usbspk_new_frame(uint8 grab)
{
UAC_MANAGE *uac_manage = NULL;
if(grab == 0)
{
if(list_empty((const struct list_head *)&usbspk_free_list)){
// os_printf("Not usbspk free frame\n");
return 0;
}
}
else if(grab == 1)
{
if(list_empty((const struct list_head *)&usbspk_free_list)){
list_move_tail((struct list_head *)usbspk_use_list.prev, (struct list_head *)&usbspk_free_list);
}
}
uac_manage = list_entry((struct list_head *)usbspk_free_list.next, UAC_MANAGE, list);
uac_manage->data_len = 0;
uac_manage->respace_len = UAC_FRAME_LEN;
uac_manage->offset = 0;
set_uac_frame_sta(uac_manage, 1);
return uac_manage;
}
UAC_MANAGE *get_usbspk_frame(void)
{
UAC_MANAGE *uac_manage = NULL;
if(list_empty((const struct list_head *)&usbspk_use_list)){
// os_printf("Not usbspk use frame\n");
return 0;
}
uac_manage = list_entry((struct list_head *)usbspk_use_list.next, UAC_MANAGE, list);
set_uac_frame_sta(uac_manage, 3);
return uac_manage;
}
void put_usbspk_frame_to_use(UAC_MANAGE *uac_manage)
{
set_uac_frame_sta(uac_manage, 2);
list_move_tail((struct list_head *)&uac_manage->list, (struct list_head *)&usbspk_use_list);
}
void del_usbspk_frame(UAC_MANAGE *uac_manage)
{
set_uac_frame_sta(uac_manage, 0);
list_move_tail((struct list_head *)&uac_manage->list, (struct list_head *)&usbspk_free_list);
}
void force_reset_usbmic_frame()
{
uint8 frame_num = 0;
if(check_usbmic_room) {
for(frame_num=0; frame_num<UAC_FRAME_NUM; frame_num++)
{
del_usbmic_frame((UAC_MANAGE *)&usbmic_manage[frame_num]);
}
}
}
void force_reset_usbspk_frame()
{
uint8 frame_num = 0;
if(check_usbspk_room) {
for(frame_num=0; frame_num<UAC_FRAME_NUM; frame_num++)
{
del_usbspk_frame((UAC_MANAGE *)&usbspk_manage[frame_num]);
}
}
}
static UAC_MANAGE *mic_frame = NULL;
static UAC_MANAGE *spk_frame = NULL;
uint32_t usbmic_rx_cnt = 0;
int usbmic_data_deal(struct hgusb20_dev *p_dev)
{
extern uint32 hgusb20_ep_get_dma_rx_len(struct hgusb20_dev *p_dev, uint8 ep);
uint32 rx_len = hgusb20_ep_get_dma_rx_len(p_dev, UAC_EP);
if(rx_len == 0){
return 0;
}
usbmic_packet_len = rx_len;
return 1;
}
int usbmic_deal(struct hgusb20_dev *p_dev, uint8_t* rx_buff)
{
if(!mic_frame){
mic_frame = get_usbmic_new_frame(1);
}
if(!mic_frame) {
return 0;
}
uint8 *addr = get_uac_frame_data(mic_frame);
os_memcpy(addr+(mic_frame->offset), rx_buff, usbmic_packet_len);
mic_frame->offset += usbmic_packet_len;
mic_frame->respace_len -= usbmic_packet_len;
mic_frame->data_len += usbmic_packet_len;
if(mic_frame->respace_len < usbmic_packet_len)
{
put_usbmic_frame_to_use(mic_frame);
mic_frame = NULL;
usbmic_rx_cnt++;
}
return 1;
}
void usbmic_dma_irq(void *dev, uint8_t* mic_rx_buff)
{
uint32 ret;
struct hgusb20_dev *p_dev = (struct hgusb20_dev *)dev;
if (!p_dev){
return;
}
if(uac_open && uac_run) {
ret = usbmic_data_deal((struct hgusb20_dev *)p_dev);
if(ret == 1){
ret = usbmic_deal((struct hgusb20_dev *)p_dev, (uint8_t*)mic_rx_buff);
}
hgusb20_ep_rx_kick(p_dev, UAC_EP, (uint32)mic_rx_buff, 1024);
}
}
uint32_t usbspk_tx_cnt = 0;
void usbspk_tx(struct hgusb20_dev *p_dev, uint8_t ep, uint32_t len)
{
uint32 packetlen = len;
static uint32_t send_empty_cnt = 0;
uint8 *audio_addr = NULL;
if(send_empty_cnt > 0) {
hgusb20_ep_tx_kick(p_dev, ep, (uint32)empty_buf, packetlen);
send_empty_cnt--;
return;
}
if(!spk_frame) {
spk_frame = get_usbspk_frame();
}
if(!spk_frame)
{
hgusb20_ep_tx_kick(p_dev, ep, (uint32)empty_buf, packetlen);
send_empty_cnt = UAC_FRAME_LEN/packetlen - 1;
}
else {
audio_addr = get_uac_frame_data(spk_frame);
hgusb20_ep_tx_kick(p_dev, ep, (uint32)(audio_addr+(spk_frame->offset)), packetlen);
spk_frame->offset += packetlen;
if(spk_frame->offset >= get_uac_frame_datalen(spk_frame))
{
del_usbspk_frame(spk_frame);
spk_frame = NULL;
usbspk_tx_cnt++;
}
}
}
void usbspk_dma_irq(void *dev)
{
struct hgusb20_dev *p_dev = (struct hgusb20_dev *)dev;
if(uac_open && uac_run) {
usbspk_tx((struct hgusb20_dev *)p_dev, UAC_EP, usbmic_packet_len);
}
}
void uac_stop(void)
{
if(uac_open) {
uac_run = 0;
os_sleep_ms(10);
if(check_usbmic_room) {
os_memset(usbmic_buf, 0, UAC_FRAME_LEN*UAC_FRAME_NUM);
}
if(check_usbspk_room) {
os_memset(usbspk_buf, 0, UAC_FRAME_LEN*UAC_FRAME_NUM);
}
}
}
void uac_start(void *dev, uint8_t* mic_rx_buff)
{
struct hgusb20_dev *p_dev = (struct hgusb20_dev *)dev;
if(uac_open) {
uac_run = 1;
os_sleep_ms(10);
hgusb20_ep_rx_kick(p_dev, UAC_EP, (uint32)mic_rx_buff, 1024);
usbspk_tx((struct hgusb20_dev *)p_dev, UAC_EP, usbmic_packet_len);
}
}
File diff suppressed because it is too large Load Diff