Files
OpenTXW81X/sdk/lib/video/dvp/jpeg/jpg_v2.c
T
2025-08-27 09:51:58 +01:00

1486 lines
37 KiB
C

#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 "devid.h"
#include "osal/irq.h"
#include "osal/string.h"
#include "lib/video/dvp/jpeg/jpg.h"
#include "hal/jpeg.h"
#include "dev/scale/hgscale.h"
#include "osal/semaphore.h"
#include "openDML.h"
#include "osal/mutex.h"
#include "custom_mem/custom_mem.h"
//#include "media.h"
//#include "lib/common/common.h"
#include "stream_frame.h"
#include "utlist.h"
#include "jpgdef.h"
#if PRC_EN
#include "hal/prc.h"
#endif
#include "osal/task.h"
extern struct os_mutex m2m1_mutex;
extern void soft_to_jpg_cfg(uint32 w,uint32 h);
/* soft to jpg run*/
static volatile uint8 stjr_itk=0;
#if PRC_EN
static uint32 sw_jpg_w, sw_jpg_h;
static uint32 stjr_linebuf;
static uint32 stjr_yuvbuf;
static volatile uint32 stjr_tick;
static struct prc_device *stjr_prc_dev;
static struct jpg_device *stjr_jpeg_dev;
#endif
extern volatile uint8_t vfx_open;
#if JPG_EN
static uint8_t *global_jpg0_buf = NULL;
static uint8_t *global_jpg1_buf = NULL;
extern struct dvp_device *dvp_test;
extern uint8_t qc_mode;
extern Vpp_stream photo_msg;
extern uint8 *yuvbuf;
extern FIL fp_jpg;
struct list_head* get_frame(uint8 jpgid);
uint8 *psram_jpg0_buf;
uint8 *psram_jpg1_buf;
struct os_semaphore *jpg_sema_pd = NULL;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define JPEG_FRAME_NUM 2
volatile struct list_head free_tab[JPG_NUM]; //空闲列表,存放空间节点
volatile struct list_head *jpg_p[JPG_NUM]; //jpg模块的节点指针
volatile struct list_head *usr_p[JPG_NUM]; //应用的节点指针
volatile jpeg_frame jpg_frame[JPG_NUM][JPEG_FRAME_NUM]; //最大frame数量
volatile struct list_head* jpg_f_p[JPG_NUM]; //当前jpg所使用的frame
volatile mjpeg_node jpg0_node_src[JPG0_NODE];
volatile mjpeg_node jpg1_node_src[JPG1_NODE];
volatile uint32 outbuff_isr[JPG_NUM] = {0x0,0x0};
volatile int8 default_qt[JPG_NUM] = {0xf, 0xf};
struct jpg_device *jpeg_dev_global[JPG_NUM];
volatile uint8 psram_example_buf[38548] __attribute__ ((aligned(4),section(".psram.src")));
extern uint8 psram_ybuf_src[IMAGE_H*IMAGE_W+IMAGE_H*IMAGE_W/2];
volatile int8_t g_dqtable_index = DQT_DEF;
/**@brief
* 将传入的frame根节点下的buf池都送回空间池(free_tab)中
*/
bool free_get_node_list(volatile struct list_head *head,volatile struct list_head *free){
if(list_empty((struct list_head *)head)){
return 0;
}
list_splice_init((struct list_head *)head,(struct list_head *)free);
return 1;
}
/**@brief
* 从初始化的frame根节点中抽取其中一个空闲的根节点进行使用,并标记frame的使用状态为正在使用
* @param 是否开启抢占模式,如果开启,则将上一帧已完成的帧节点删掉,并返回
*/
volatile struct list_head* get_new_frame_head(uint8 jpgnum,int grab){
uint8 frame_num = 0;
for(frame_num = 0;frame_num < JPEG_FRAME_NUM;frame_num++){
if(jpg_frame[jpgnum][frame_num].usable == 0){
jpg_frame[jpgnum][frame_num].usable = 1;
return &jpg_frame[jpgnum][frame_num].list;
}
}
if(grab) //是否开启抢占模式,开启抢占后,肯定有frame返回,上一帧没使用的frame肯定usable为2
{
for(frame_num = 0;frame_num < JPEG_FRAME_NUM;frame_num++){
if(jpg_frame[jpgnum][frame_num].usable == 2){
jpg_frame[jpgnum][frame_num].usable = 1;
free_get_node_list(&jpg_frame[jpgnum][frame_num].list,&free_tab[jpgnum]);
return &jpg_frame[jpgnum][frame_num].list;
}
}
}
return 0;
}
/**@brief
* 获取当前frame根节点中保存成功的frame,返回根节点以供链表查询
*/
extern struct list_head *get_node(volatile struct list_head *head,volatile struct list_head *del);
extern uint32 get_addr(volatile struct list_head *list);
void set_frame_ready(jpeg_frame *jf){
jf->usable = 2;
}
/**@brief
* 将传入的frame根节点状态调整为空闲,以供下次重新获取
*/
void del_frame(uint8 jpg_num,volatile struct list_head* frame_list)
{
jpeg_frame* fl;
uint32_t flags;
if(list_empty((struct list_head *)frame_list) != TRUE){
//NVIC_DisableIRQ(MJPEG01_IRQn);
flags = disable_irq();
free_get_node_list(frame_list,&free_tab[jpg_num]);
fl = list_entry((struct list_head *)frame_list,jpeg_frame,list);
fl->usable = 0;
//NVIC_EnableIRQ(MJPEG01_IRQn);
enable_irq(flags);
return;
}else{
//NVIC_DisableIRQ(MJPEG01_IRQn);
flags = disable_irq();
fl = list_entry((struct list_head *)frame_list,jpeg_frame,list);
fl->usable = 0;
enable_irq(flags);
//NVIC_EnableIRQ(MJPEG01_IRQn);
return;
}
}
/**@brief
* 初始化free_tab池,将mjpeg_node的节点都放到空闲池中,供frame后面提取使用
* @param ftb 空闲池头指针
* @param jpn mjpeg_node节点源
* @param use_num mjpeg_node的数量,即多少个mjpeg_node放到空闲池
* @param addr mjpeg_node的总buf起始地址
* @param buf_len 每个mjpeg_node所关联到的数据量
*/
void free_table_init(uint8 jpgnum,volatile struct list_head *ftb, volatile mjpeg_node* jpn,int use_num,uint32 addr,uint32 buf_len){
int itk;
for(itk = 0;itk < use_num;itk++){
if(jpgnum == 0)
jpn->buf_addr = (uint8*)(addr + itk*(buf_len+JPG0_TAIL_RESERVER)+JPG0_HEAD_RESERVER);
else
jpn->buf_addr = (uint8*)(addr + itk*(buf_len+JPG1_TAIL_RESERVER)+JPG1_HEAD_RESERVER);
list_add_tail((struct list_head *)&jpn->list,(struct list_head *)ftb);
jpn++;
}
}
/**@brief
* 从空间池中提取一个节点,放到队列中,并将此节点作为返回值返回
*/
struct list_head *get_node(volatile struct list_head *head,volatile struct list_head *del){
if(list_empty((struct list_head *)del)){
return 0;
}
list_move((struct list_head *)del->next,(struct list_head *)head);
return head->next; //返回最新的位置
}
int get_node_count(volatile 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; //返回最新的位置
}
/**@brief
* 从当前使用的节点回放到消息池中
*/
bool put_node(volatile struct list_head *head,volatile struct list_head *del){
//portINIT_CRITICAL();
if(list_empty((struct list_head *)del)){
return 0;
}
uint32_t flags;
flags = disable_irq();
//NVIC_DisableIRQ(MJPEG01_IRQn);
list_move(del->next,(struct list_head *)head);
enable_irq(flags);
//NVIC_EnableIRQ(MJPEG01_IRQn);
return 1;
}
/**@brief
* 获取当前jpeg节点buf地址进行返回
*/
uint32 get_addr(volatile struct list_head *list){
mjpeg_node* mjn;
mjn = list_entry((struct list_head *)list,mjpeg_node,list);
return (uint32)mjn->buf_addr;
}
void jpg_DQT_updata(struct jpg_device *p_jpg, uint8 upOdown, uint8 diff)
{
uint32 *ptable;
static int8 pdqt_tab = DQT_DEF;
if (upOdown == 1)
{
pdqt_tab -= diff;
if (pdqt_tab < 0)
pdqt_tab = 0;
}
else
{
pdqt_tab += diff;
if (pdqt_tab > DQT_MAX_INDEX)
pdqt_tab = DQT_MAX_INDEX;
}
g_dqtable_index = pdqt_tab;
ptable = (uint32 *)quality_tab[pdqt_tab];
jpg_updata_dqt(p_jpg, ptable);
}
int jpg_quality_pidCtrl(int diff, int p, int i, int d)
{
static int diff_prev = 0;
static int diff_sum = 0;
int res = 0;
res = p * diff + i * diff_sum + d * (diff - diff_prev);
diff_sum += diff;
diff_prev = diff;
res = res>>16;
res = LIMITING(res, 120, -120);
diff_sum = LIMITING(diff_sum, 2000, -2000);
//_os_printf("diff_sum:%d\n",diff_sum);
return res;
}
extern volatile uint32 hs_isr;
volatile uint8 rtp_speed = 0; // 1:降低 2:提升
uint8 jpg_quality_tidy(uint8 jpgnum, uint32 len, uint8 *dqt_index_diff)
{
uint8 updata_dqt = 0;
if (qc_mode)
{
if (len >= 15 * 1024)
{
default_qt[jpgnum]++;
if (default_qt[jpgnum] == 0x10)
{
default_qt[jpgnum] = 0x8;
updata_dqt = 2;
}
}
else if (len <= 5 * 1024)
{
default_qt[jpgnum]--;
if (default_qt[jpgnum] == 0)
{
default_qt[jpgnum] = 8;
updata_dqt = 1;
}
}
return updata_dqt;
}
#if 0
if(len >= 25*1024){
default_qt[jpgnum]++;
if(default_qt[jpgnum] == 0x10){
if(g_dqtable_index < DQT_MAX_INDEX) {
default_qt[jpgnum] = 0x8;
updata_dqt = 2;
}
else
default_qt[jpgnum] = 0xf;
}
}else if(len <= 15*1024){
default_qt[jpgnum]--;
if(default_qt[jpgnum] == 0){
if(g_dqtable_index > 0) {
default_qt[jpgnum] = 8;
updata_dqt = 1;
}
else
default_qt[jpgnum] = 0x1;
}
}
*dqt_index_diff = 1;
#elif 1
int jpg_len_diff = len - TARGET_JPG_LEN;
int res = jpg_quality_pidCtrl(jpg_len_diff, QUALITY_CTRL_P, QUALITY_CTRL_I, QUALITY_CTRL_D);
uint8 qt_diff = os_abs(res) % 0x10;
uint8 qt_index_diff = os_abs(res) / 0x10;
*dqt_index_diff = qt_index_diff;
if (res > 0)
{
if (qt_diff + default_qt[jpgnum] > 0xf)
{
if ((g_dqtable_index + qt_index_diff + 1 + (qt_diff - (0xf - default_qt[jpgnum]))/8) > DQT_MAX_INDEX)
{
*dqt_index_diff = DQT_MAX_INDEX - g_dqtable_index;
default_qt[jpgnum] = 0xf;
}
else
{
default_qt[jpgnum] = 0x8 + (qt_diff - (0xf - default_qt[jpgnum]))%8;
*dqt_index_diff = qt_index_diff + 1 + (qt_diff - (0xf - default_qt[jpgnum]))/8;
}
}
else
default_qt[jpgnum] += qt_diff;
if ((*dqt_index_diff) >= 1 && g_dqtable_index < DQT_MAX_INDEX)
{
*dqt_index_diff = ((*dqt_index_diff) > (DQT_MAX_INDEX - g_dqtable_index)) ? (DQT_MAX_INDEX - g_dqtable_index) : (*dqt_index_diff);
updata_dqt = 2;
}
}
else if(res < 0)
{
if (default_qt[jpgnum] - qt_diff < 0)
{
if ((g_dqtable_index - (qt_index_diff + 1 + (qt_diff-default_qt[jpgnum])/8)) < 0)
{
*dqt_index_diff = g_dqtable_index;
default_qt[jpgnum] = 0;
}
else
{
default_qt[jpgnum] = 0x8 - (qt_diff - default_qt[jpgnum])%8; //(qt_diff-default_qt[jpgnum]) maybe > 0x8
*dqt_index_diff = qt_index_diff + 1 + (qt_diff-default_qt[jpgnum])/8;
}
}
else
default_qt[jpgnum] -= qt_diff;
if ((*dqt_index_diff) >= 1 && g_dqtable_index > 0)
{
*dqt_index_diff = ((*dqt_index_diff) > (g_dqtable_index)) ? g_dqtable_index : (*dqt_index_diff);
updata_dqt = 1;
}
}
if(updata_dqt == 0)
*dqt_index_diff = 0;
// _os_printf("pid res:%d %d %d %d %d %d\n", jpg_len_diff, res, qt_diff, qt_index_diff, *dqt_index_diff, updata_dqt);
#else
if (len >= 35 * 1024)
{
default_qt++;
if (default_qt == 0x10)
{
default_qt = 0x8;
updata_dqt = 2;
}
}
else
{
if (rtp_speed == 1)
{
default_qt++;
if (default_qt == 0x10)
{
default_qt = 0x8;
updata_dqt = 2;
}
}
else if (rtp_speed == 2)
{
default_qt--;
if (default_qt == 0)
{
default_qt = 8;
updata_dqt = 1;
}
}
rtp_speed = 0;
}
#endif
return updata_dqt;
}
//获取实际内容buf的长度
int get_jpg_node_len(uint8 jpg_num)
{
if(jpg_num == 0)
{
return JPG0_BUF_LEN-JPG0_HEAD_RESERVER;
}
else
{
return JPG1_BUF_LEN-JPG1_HEAD_RESERVER;
}
}
uint32 get_jpg_node_len_new(void *get_f)
{
jpeg_frame* jpg_frame = (jpeg_frame*)get_f;
if(jpg_frame->jpg_num == 0)
return JPG0_BUF_LEN-JPG0_HEAD_RESERVER;
else
return JPG1_BUF_LEN-JPG1_HEAD_RESERVER;
}
extern volatile uint8 scale_take_photo;
#if 0
extern uint8 video_psram_mem[616320];
extern uint8 video_psram_mem1[616320];
void location_reset(uint8_t *inbuf,uint8_t *outbuf,int x,int y,int w){
int xn,yn;
uint8_t yd,ud,vd;
//float angle;
//angle = (30*3.14)/180;
y = y*-1;
xn = (x * 866 - y * 499)/1000;
yn = (x * 499 + y * 866)/1000;
yn = yn*-1;
if(xn < 0){
return;
}
if(xn > 640){
return;
}
if(yn < 0){
return;
}
//yd = inbuf[x+y*w];
//ud = inbuf[307200+x/2+(y/2)*320];
//vd = inbuf[384000+x/2+(y/2)*320];
outbuf[xn+yn*w] = inbuf[x+y*w];
outbuf[307200+xn/2+(yn/2)*320]= inbuf[307200+x/2+(y/2)*320];
outbuf[384000+xn/2+(yn/2)*320]= inbuf[384000+x/2+(y/2)*320];
//if(xn+1 < 640)
{
if((unsigned char)outbuf[xn+1+yn*w] == 0x80){
outbuf[xn+1+(int)yn*w] = inbuf[x+y*w];
//if((xn+1)%2 == 0){
// outbuf[307200+xn/2+1+(yn/2)*320] = ud;
// outbuf[384000+xn/2+1+(yn/2)*320]= vd;
//}
}
}
}
#endif
#if 0
//认证或者用户学习使用
void jpeg_user(uint32* pixel_itp) //应用层
{
//#define TAKE_PHOTO_HIGH 1080//1080//2560//4320
//#define TAKE_PHOTO_WIDTH 1920//1920//3840//7680
uint16_t itp_w,itp_h;
uint8_t continous_spon;
struct scale_device *scale_dev;
struct lcdc_device *lcd_dev;
struct vpp_device *vpp_dev;
uint8 jpg_chose;
uint32 pingpang = 0;
uint32 count = 0;
uint32 flen;
uint32 itk;
struct list_head* get_f;
mjpeg_node* mjn;
jpeg_frame* jpf;
uint8 printf_dat = 0;
struct jpg_device *jpeg_dev;
jpeg_dev = (struct jpg_device *)dev_get(HG_JPG0_DEVID);
scale_dev = (struct scale_device *)dev_get(HG_SCALE1_DEVID);
lcd_dev = (struct lcdc_device *)dev_get(HG_LCDC_DEVID);
vpp_dev = (struct vpp_device *)dev_get(HG_VPP_DEVID);
itp_w = pixel_itp[0]&0xffff;
itp_h = (pixel_itp[0]>>16)&0xffff;
continous_spon = pixel_itp[1];
scale_close(scale_dev);
jpg_close(jpeg_dev);
os_sleep_ms(100);
jpg_cfg(HG_JPG0_DEVID,SCALER_DATA);
_os_printf("itp_w:%d itp_h:%d continous_spon:%d\r\n",itp_w,itp_h,continous_spon);
photo_msg.out0_w = itp_w;
photo_msg.out0_h = itp_h;
jpg_start(HG_JPG0_DEVID);
if(itp_h <= 720){
scale_from_vpp_to_jpg(scale_dev,yuvbuf,photo_msg.in_w,photo_msg.in_h,itp_w,itp_h);
}
while(1){
if(itp_h > 720){
if(m2m1_mutex.magic == 0xa8b4c2d5)
os_mutex_lock(&m2m1_mutex,osWaitForever);
lcdc_video_enable_auto_ks(lcd_dev,1);
scale_from_soft_to_jpg(scale_dev,psram_ybuf_src,photo_msg.in_w,photo_msg.in_h,itp_w,itp_h);
scale_take_photo = 0;
while(scale_take_photo == 0){
os_sleep_ms(2);
}
if(m2m1_mutex.magic == 0xa8b4c2d5)
os_mutex_unlock(&m2m1_mutex);
os_sleep_ms(10);
lcdc_video_enable_auto_ks(lcd_dev,0);
vpp_open(vpp_dev);
}
get_f = get_frame(HG_JPG0_DEVID);
jpg_chose = 0;
if(get_f){
fatfs_create_jpg();
_os_printf("usr(%d)====>get_f:%x\r\n",jpg_chose,(uint32)get_f);
count++;
usr_p[jpg_chose] = get_f;
jpf = list_entry(get_f,jpeg_frame,list);
flen = jpf->frame_len;
_os_printf("flen_write:%d\r\n",flen);
while(list_empty((struct list_head *)usr_p[jpg_chose]) != TRUE)
{
mjn = list_entry((struct list_head *)usr_p[jpg_chose]->next,mjpeg_node,list);
//_os_printf("mjn:%x\r\n",mjn);
/*
此处使用当前mjn,获取节点对应的buf数据位置,对数据进行处理
*/
if(jpg_chose){
if(flen > JPG1_BUF_LEN){
//fatfs_write_data(mjn->buf_addr,JPG1_BUF_LEN);
osal_fwrite(mjn->buf_addr,1,JPG1_BUF_LEN,&fp_jpg);
flen -= get_jpg_node_len(jpg_chose);
}
else{
//for(itk = 0;itk < flen+JPG1_HEAD_RESERVER;itk++){
// _os_printf("%02x ",mjn->buf_addr[itk-JPG1_HEAD_RESERVER]);
//}
//fatfs_write_data(mjn->buf_addr,flen);
osal_fwrite(mjn->buf_addr,1,flen,&fp_jpg);
flen = 0;
}
}else{
if(flen > JPG0_BUF_LEN){
//for(itk = 0;itk < JPG0_BUF_LEN;itk++){
// _os_printf("%02x ",mjn->buf_addr[itk-JPG0_HEAD_RESERVER]);
//}
//fatfs_write_data(mjn->buf_addr,JPG0_BUF_LEN);
osal_fwrite(mjn->buf_addr,1,JPG0_BUF_LEN,&fp_jpg);
flen -= get_jpg_node_len(jpg_chose);
}
else{
//for(itk = 0;itk < flen+JPG0_HEAD_RESERVER;itk++){
// _os_printf("%02x ",mjn->buf_addr[itk-JPG0_HEAD_RESERVER]);
//}
//fatfs_write_data(mjn->buf_addr,flen);
osal_fwrite(mjn->buf_addr,1,flen,&fp_jpg);
flen = 0;
}
}
put_node(&free_tab[jpg_chose],usr_p[jpg_chose]); //节点归还到free_tab,边处理边给下一帧释放空间
}
_os_printf("flen_write_end:%d\r\n",flen);
del_frame(jpg_chose,usr_p[jpg_chose]); //删除frame
fatfs_close_jpg();
if(count == continous_spon)
break;
}
}
csi_kernel_task_del(csi_kernel_task_get_cur());
}
#endif
extern void take_photo_thread(void *d);
uint32_t takephoto_arg[3] = {0};
void take_photo_thread_init(uint16_t w,uint16_t h,uint8_t continuous_spot){
takephoto_arg[0] = (w&0xffff) | ((h<<16)&0xffff0000);
takephoto_arg[1] = continuous_spot;
takephoto_arg[2] = 1;
os_task_create("take_photo_thread", take_photo_thread, (void*)&takephoto_arg, OS_TASK_PRIORITY_NORMAL, 0, NULL, 1024);
}
uint32_t get_takephoto_thread_status()
{
return takephoto_arg[2];
}
void jpg_room_init(uint8 jpgnum){
//INIT_LIST_HEAD(&jpg_node);
uint8 *buf;
if(jpgnum == 0)
{
if(global_jpg0_buf)
{
os_printf("0please custom_free jpg_buf when custom_malloc again\n");
return ;
}
#ifdef PSRAM_HEAP
buf = (uint8*)custom_malloc_psram(JPG0_NODE*(JPG0_BUF_LEN+JPG0_TAIL_RESERVER));
#else
buf = (uint8*)custom_malloc(JPG0_NODE*(JPG0_BUF_LEN+JPG0_TAIL_RESERVER));
#endif
global_jpg0_buf = buf;
//sys_dcache_clean_invalid_range((void *)buf, JPG0_NODE*(JPG0_BUF_LEN+JPG0_TAIL_RESERVER));
}
else
{
if(global_jpg1_buf)
{
os_printf("1please custom_free jpg_buf when custom_malloc again\n");
return ;
}
#ifdef PSRAM_HEAP
buf = (uint8*)custom_malloc_psram(JPG1_NODE*(JPG1_BUF_LEN+JPG1_TAIL_RESERVER));
#else
buf = (uint8*)custom_malloc(JPG1_NODE*(JPG1_BUF_LEN+JPG1_TAIL_RESERVER));
#endif
global_jpg1_buf = buf;
//sys_dcache_clean_invalid_range((void *)buf, JPG1_NODE*(JPG1_BUF_LEN+JPG1_TAIL_RESERVER));
}
while(!buf)
{
os_printf("%s:%d\n",__FUNCTION__,__LINE__);
os_sleep_ms(1000);
}
INIT_LIST_HEAD((struct list_head *)&jpg_frame[jpgnum][0].list);
INIT_LIST_HEAD((struct list_head *)&jpg_frame[jpgnum][1].list);
INIT_LIST_HEAD((struct list_head *)&free_tab[jpgnum]);
if(jpgnum == 0)
free_table_init(jpgnum,&free_tab[jpgnum],(mjpeg_node*)&jpg0_node_src,JPG0_NODE,(uint32)buf,JPG0_BUF_LEN);
else
free_table_init(jpgnum,&free_tab[jpgnum],(mjpeg_node*)&jpg1_node_src,JPG1_NODE,(uint32)buf,JPG1_BUF_LEN);
jpg_frame[jpgnum][0].usable = 0;
jpg_frame[jpgnum][1].usable = 0;
jpg_frame[jpgnum][0].jpg_num = jpgnum;
jpg_frame[jpgnum][1].jpg_num = jpgnum;
jpg_f_p[jpgnum] = get_new_frame_head(jpgnum,1); //预先分配第一frame,待帧结束的时候再分配下一frame
jpg_p[jpgnum] = jpg_f_p[jpgnum];
}
uint8_t jpg_room_deinit(uint8 jpgnum)
{
if(jpgnum == 0)
{
if(global_jpg0_buf)
{
#ifndef PSRAM_HEAP
custom_free(global_jpg0_buf);
#else
custom_free_psram(global_jpg0_buf);
#endif
global_jpg0_buf = NULL;
}
}
else if(jpgnum == 1)
{
if(global_jpg1_buf)
{
#ifndef PSRAM_HEAP
custom_free(global_jpg1_buf);
#else
custom_free_psram(global_jpg1_buf);
#endif
global_jpg1_buf = NULL;
}
}
return TRUE;
}
/*********************************
获取分辨率
0:无效
1:vga(640x480)
2:720p(1280x720)
*********************************/
uint8 get_camera_dpi()
{
return 1;
}
void jpg_outbuff_full_isr(uint32 irq_flag,uint32 irq_data,uint32 param1,uint32 param2){
uint8 jpg_chose;
uint32 addr;
struct jpg_device *p_jpg = (struct jpg_device *)irq_data;
if(p_jpg == jpeg_dev_global[0]){
jpg_chose = 0;
}else{
jpg_chose = 1;
}
if(outbuff_isr[jpg_chose] != 0xff)
outbuff_isr[jpg_chose]++;
else
return;
jpg_p[jpg_chose] = get_node(jpg_p[jpg_chose],&free_tab[jpg_chose]);
if(jpg_p[jpg_chose] == NULL){
outbuff_isr[jpg_chose] = 0xff;
return;
}
// if((jpg_addr_num%2) == 0){
// data_cmp_u32(jpg_addr0,psram_example_buf+1284*jpg_addr_num,1284);
// }else{
// data_cmp_u32(jpg_addr1,psram_example_buf+1284*jpg_addr_num,1284);
// }
// jpg_addr_num++;
addr = get_addr(jpg_p[jpg_chose]);
jpg_set_addr(p_jpg,addr,get_jpg_node_len(jpg_chose));
sys_dcache_clean_invalid_range((uint32_t *)addr, get_jpg_node_len(jpg_chose));
//os_printf("OF-%x \r\n",addr);
// if((jpg_addr_num%2) == 1){
// jpg_addr0 = addr;
// }else{
// jpg_addr1 = addr;
// }
}
void jpg_buf_err(uint32 irq_flag,uint32 irq_data,uint32 param1,uint32 param2){
uint8 jpg_chose;
struct scale_device *scale_dev;
uint32 addr;
struct jpg_device *p_jpg = (struct jpg_device *)irq_data;
scale_dev = (struct scale_device *)dev_get(HG_SCALE1_DEVID);
if(p_jpg == jpeg_dev_global[0]){
jpg_chose = 0;
}else{
jpg_chose = 1;
}
jpg_close(p_jpg);
if(jpg_chose == 0)
scale_close(scale_dev);
// dvp_close(dvp_test);
_os_printf("(%d)?\r\n",jpg_chose);
del_frame(jpg_chose,jpg_f_p[jpg_chose]);
jpg_f_p[jpg_chose] = get_new_frame_head(jpg_chose,1);
jpg_p[jpg_chose] = jpg_f_p[jpg_chose];
outbuff_isr[jpg_chose] = 0;
jpg_p[jpg_chose] = get_node(jpg_p[jpg_chose],&free_tab[jpg_chose]); //预分配的两个buf地址,帧结束的时候要去掉一个预分配节点
if(jpg_p[jpg_chose] == NULL){
_os_printf("need more node for new frame start1\r\n");
while(1);
}
//p_jpg->DMA_TADR0 = get_addr(jpg_p);
addr = get_addr(jpg_p[jpg_chose]);
//jpg_set_addr0(p_jpg,addr);
jpg_set_addr(p_jpg,addr,get_jpg_node_len(jpg_chose));
sys_dcache_clean_invalid_range((uint32_t *)addr, get_jpg_node_len(jpg_chose));
jpg_p[jpg_chose] = get_node(jpg_p[jpg_chose],&free_tab[jpg_chose]);
if(jpg_p[jpg_chose] == NULL){
_os_printf("need more node for new frame start2\r\n");
while(1);
}
//p_jpg->DMA_TADR1 = get_addr(jpg_p);
addr = get_addr(jpg_p[jpg_chose]);
//jpg_set_addr1(p_jpg,addr);
jpg_set_addr(p_jpg,addr,get_jpg_node_len(jpg_chose));
sys_dcache_clean_invalid_range((uint32_t *)addr, get_jpg_node_len(jpg_chose));
jpg_open(p_jpg);
if(jpg_chose == 0)
scale_open(scale_dev);
// dvp_open(dvp_test);
}
void jpg_done_isr(uint32 irq_flag,uint32 irq_data,uint32 param1,uint32 param2){
uint8 jpg_chose;
struct jpg_device *p_jpg = (struct jpg_device *)irq_data;
uint32 addr;
jpeg_frame* jf;
uint8 out_buf_num_err = 0;
uint8 updata_dqt = 0;
uint8 default_qt_last;
uint32 jpg_len;
uint8 dqt_index_diff = 0;
if(p_jpg == jpeg_dev_global[0]){
jpg_chose = 0;
}else{
jpg_chose = 1;
}
jpg_len = param1;//jpg_get_len(p_jpg);
//os_printf("len(%d)=>:%d ",jpg_chose,jpg_len);
//if(outbuff_isr != jpg_get_outbuf_num(p_jpg))
if(param2||(outbuff_isr[jpg_chose] == 255)){
os_printf("jpg done len err:%d\r\n",outbuff_isr[jpg_chose]);
out_buf_num_err = 1;
}
default_qt_last = default_qt[jpg_chose];
// os_printf("jpglen:%d %d %d\n", jpg_len, default_qt[jpg_chose], g_dqtable_index);
updata_dqt = jpg_quality_tidy(jpg_chose, jpg_len, &dqt_index_diff);
if (default_qt_last != default_qt[jpg_chose])
{
jpg_set_qt(p_jpg, default_qt[jpg_chose]);
}
// os_printf("quality res:%d %s%d\n", default_qt[jpg_chose], ((updata_dqt>1)?"+":"-"),dqt_index_diff);
if (get_node_count(&free_tab[jpg_chose]) < 2)
{
outbuff_isr[jpg_chose] = 0xff;
}
/**/
if(jpg_len < outbuff_isr[jpg_chose] * get_jpg_node_len(jpg_chose)){
os_printf("BUF len err:%d %d\r\n",jpg_len,outbuff_isr[jpg_chose] * get_jpg_node_len(jpg_chose));
del_frame(jpg_chose,jpg_f_p[jpg_chose]);
}else if(outbuff_isr[jpg_chose] == 0xff){
os_printf("outbuff_isr err,no room\r\n");
del_frame(jpg_chose,jpg_f_p[jpg_chose]);
}else if(out_buf_num_err){
os_printf("out_buf_num_err happen\r\n");
del_frame(jpg_chose,jpg_f_p[jpg_chose]);
}
else{
//帧OK
jf = list_entry((struct list_head *)jpg_f_p[jpg_chose],jpeg_frame,list);
jf->frame_len = jpg_len;
//因为有预分配机制,所以要先去掉最后一个节点
put_node(&free_tab[jpg_chose],jpg_p[jpg_chose]->prev);
set_frame_ready(jf);
//os_printf("jf_ready:%x jpg_chose:%d\r\n",jf,jpg_chose);
}
jpg_f_p[jpg_chose] = get_new_frame_head(jpg_chose,1);
//os_printf("jpg_f_p[jpg_chose]:%X\n",jpg_f_p[jpg_chose]);
jpg_p[jpg_chose] = jpg_f_p[jpg_chose];
outbuff_isr[jpg_chose] = 0;
//再设置DMA地址
jpg_p[jpg_chose] = get_node(jpg_p[jpg_chose],&free_tab[jpg_chose]); //预分配的两个buf地址,帧结束的时候要去掉一个预分配节点
if(jpg_p[jpg_chose] == NULL){
_os_printf("need more node for new frame start1\r\n");
while(1);
}
//p_jpg->DMA_TADR0 = get_addr(jpg_p);
addr = get_addr(jpg_p[jpg_chose]);
jpg_set_addr(p_jpg,addr,get_jpg_node_len(jpg_chose));
sys_dcache_clean_invalid_range((uint32_t *)addr, get_jpg_node_len(jpg_chose));
jpg_p[jpg_chose] = get_node(jpg_p[jpg_chose],&free_tab[jpg_chose]);
if(jpg_p[jpg_chose] == NULL){
_os_printf("need more node for new frame start2\r\n");
while(1);
}
//os_printf("addr:%x \r\n",addr);
addr = get_addr(jpg_p[jpg_chose]);
jpg_set_addr(p_jpg,addr,get_jpg_node_len(jpg_chose));
sys_dcache_clean_invalid_range((uint32_t *)addr, get_jpg_node_len(jpg_chose));
if (updata_dqt)
jpg_DQT_updata(p_jpg, updata_dqt, dqt_index_diff);
}
volatile uint8_t pixel_done = 0;
#if PRC_EN
void jpg_pixel_done(uint32 irq_flag,uint32 irq_data,uint32 param1,uint32 param2){
pixel_done = 1;
//为了旧版本兼容,暂时用宏隔离
#if DVP_EN
if(!vfx_open) {
return;
}
#else
if(0)
{
}
#endif
else {
if(stjr_itk < 30) {
hw_memcpy((void*)stjr_linebuf,(void*)(stjr_yuvbuf+stjr_itk*16* sw_jpg_w), sw_jpg_w*16);
prc_set_yaddr(stjr_prc_dev,(uint32)stjr_linebuf);
hw_memcpy((void*)(stjr_linebuf+ sw_jpg_w*16),(void*)(stjr_yuvbuf+ sw_jpg_w*sw_jpg_h+stjr_itk*4* sw_jpg_w), sw_jpg_w*4);
prc_set_uaddr(stjr_prc_dev,(uint32)(stjr_linebuf+ sw_jpg_w*16));
hw_memcpy((void*)(stjr_linebuf+ sw_jpg_w*16+4*sw_jpg_w),(void*)(stjr_yuvbuf+ sw_jpg_w*sw_jpg_h+ sw_jpg_w*sw_jpg_h/4+stjr_itk*4* sw_jpg_w), sw_jpg_w*4);
prc_set_vaddr(stjr_prc_dev,(uint32)(stjr_linebuf+ sw_jpg_w*16+4* sw_jpg_w));
jpg_soft_kick(stjr_jpeg_dev,1);
stjr_itk++;
} else {
os_sema_up(jpg_sema_pd);
stjr_itk = 0;
}
}
}
#endif
void jpg_config_addr(struct jpg_device *p_jpg,uint8 jpgnum){
uint32 addr;
jpg_p[jpgnum] = get_node(jpg_p[jpgnum],&free_tab[jpgnum]); //预分配的两个buf地址,帧结束的时候要去掉一个预分配节点
addr = get_addr(jpg_p[jpgnum]);
jpg_set_addr(p_jpg,addr,get_jpg_node_len(jpgnum));
sys_dcache_clean_invalid_range((uint32_t *)addr, get_jpg_node_len(jpgnum));
jpg_p[jpgnum] = get_node(jpg_p[jpgnum],&free_tab[jpgnum]);
addr = get_addr(jpg_p[jpgnum]);
jpg_set_addr(p_jpg,addr,get_jpg_node_len(jpgnum));
sys_dcache_clean_invalid_range((uint32_t *)addr, get_jpg_node_len(jpgnum));
}
void jpg_isr_init(struct jpg_device *p_jpg){
jpg_request_irq(p_jpg,(jpg_irq_hdl )&jpg_outbuff_full_isr,JPG_IRQ_FLAG_JPG_BUF_FULL,p_jpg);
jpg_request_irq(p_jpg,(jpg_irq_hdl )&jpg_buf_err,JPG_IRQ_FLAG_ERROR,p_jpg);
jpg_request_irq(p_jpg,(jpg_irq_hdl )&jpg_done_isr,JPG_IRQ_FLAG_JPG_DONE,p_jpg);
#if PRC_EN
jpg_request_irq(p_jpg,(jpg_irq_hdl )&jpg_pixel_done,JPG_IRQ_FLAG_PIXEL_DONE,p_jpg);
#endif
NVIC_EnableIRQ(MJPEG01_IRQn);
}
//专门为从yuv在psram,然后编码成jpg的模式
//利用prc模块寄存器但不属于prc功能
//为了兼容,仅仅对JPG_IRQ_FLAG_PIXEL_DONE的done的参数修改,其他不变
typedef int32_t (*jpg_pixel_done_prc)(uint32 irq_flag,uint32 irq_data,uint32 param1,uint32 param2);
void jpg_isr_init_prc(struct jpg_device *p_jpg,jpg_pixel_done_prc done_prc,void *param){
jpg_request_irq(p_jpg,(jpg_irq_hdl )&jpg_outbuff_full_isr,JPG_IRQ_FLAG_JPG_BUF_FULL,p_jpg);
jpg_request_irq(p_jpg,(jpg_irq_hdl )&jpg_buf_err,JPG_IRQ_FLAG_ERROR,p_jpg);
jpg_request_irq(p_jpg,(jpg_irq_hdl )&jpg_done_isr,JPG_IRQ_FLAG_JPG_DONE,p_jpg);
jpg_request_irq(p_jpg,done_prc,JPG_IRQ_FLAG_PIXEL_DONE,param);
NVIC_EnableIRQ(MJPEG01_IRQn);
}
//不需要JPG_IRQ_FLAG_PIXEL_DONE中断
void jpg_isr_init_vpp(struct jpg_device *p_jpg){
jpg_request_irq(p_jpg,(jpg_irq_hdl )&jpg_outbuff_full_isr,JPG_IRQ_FLAG_JPG_BUF_FULL,p_jpg);
jpg_request_irq(p_jpg,(jpg_irq_hdl )&jpg_buf_err,JPG_IRQ_FLAG_ERROR,p_jpg);
jpg_request_irq(p_jpg,(jpg_irq_hdl )&jpg_done_isr,JPG_IRQ_FLAG_JPG_DONE,p_jpg);
jpg_request_irq(p_jpg,(jpg_irq_hdl)NULL,JPG_IRQ_FLAG_PIXEL_DONE,NULL);
NVIC_EnableIRQ(MJPEG01_IRQn);
}
void jpg_cfg_prc(uint8 jpgid,enum JPG_SRC_FROM src_from,jpg_pixel_done_prc done_prc,void *dev_id){
uint8 jpg_chose;
//uint32 itk,jtk;
_os_printf("JPG start:%d\r\n",src_from);
struct jpg_device *jpeg_dev;
if(jpgid == HG_JPG0_DEVID)
jpg_chose = 0;
else
jpg_chose = 1;
jpeg_dev = (struct jpg_device *)dev_get(jpgid);
jpeg_dev_global[jpg_chose] = jpeg_dev;
//jpg table init
jpg_init(jpeg_dev,DQT_DEF,default_qt[jpg_chose]);
jpg_set_data_from(jpeg_dev,src_from);
jpg_set_hw_check(jpeg_dev,1);
jpg_isr_init_prc(jpeg_dev,done_prc,dev_id);
jpg_set_init_finish(jpeg_dev,1);
}
void jpg_cfg(uint8 jpgid,enum JPG_SRC_FROM src_from){
uint8 jpg_chose;
//uint32 itk,jtk;
_os_printf("JPG start\r\n");
struct jpg_device *jpeg_dev;
if(jpgid == HG_JPG0_DEVID)
jpg_chose = 0;
else
jpg_chose = 1;
jpeg_dev = (struct jpg_device *)dev_get(jpgid);
jpeg_dev_global[jpg_chose] = jpeg_dev;
//jpg table init
jpg_init(jpeg_dev,DQT_DEF,default_qt[jpg_chose]);
jpg_set_data_from(jpeg_dev,src_from);
jpg_set_hw_check(jpeg_dev,1);
jpg_isr_init(jpeg_dev);
jpg_set_init_finish(jpeg_dev,1);
}
void jpg_cfg_vpp(uint8 jpgid,enum JPG_SRC_FROM src_from){
uint8 jpg_chose;
//uint32 itk,jtk;
_os_printf("JPG start\r\n");
struct jpg_device *jpeg_dev;
if(jpgid == HG_JPG0_DEVID)
jpg_chose = 0;
else
jpg_chose = 1;
jpeg_dev = (struct jpg_device *)dev_get(jpgid);
jpeg_dev_global[jpg_chose] = jpeg_dev;
//jpg table init
jpg_init(jpeg_dev,DQT_DEF,default_qt[jpg_chose]);
jpg_set_data_from(jpeg_dev,src_from);
jpg_set_hw_check(jpeg_dev,1);
jpg_isr_init_vpp(jpeg_dev);
jpg_set_init_finish(jpeg_dev,1);
}
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;
}
uint32_t get_jpg_default_dpi(uint8_t id)
{
if(id == 0)
{
return (photo_msg.out0_w<<16 | photo_msg.out0_h);
}
else
{
return (photo_msg.out1_w<<16 | photo_msg.out1_h);
}
}
extern uint8_t vga_room[2][640*480+640*480/2];
//uint8_t soft_linebuf[16*640+8*640]__attribute__ ((aligned(4)));
void soft_to_jpg_cfg(uint32 w,uint32 h){
photo_msg.out0_h = h;
photo_msg.out0_w = w;
jpg_cfg(HG_JPG0_DEVID,SOFT_DATA);
if(jpg_sema_pd == NULL)
{
jpg_sema_pd = os_malloc(sizeof(struct os_semaphore));
os_sema_init(jpg_sema_pd, 0);
}
else
{
os_sema_del(jpg_sema_pd);
os_sema_init(jpg_sema_pd, 0);
}
}
#if PRC_EN
void soft_to_jpg_run(uint32 yuvbuf,uint32 linebuf,uint32 w,uint32 h){
stjr_prc_dev = (struct prc_device*)dev_get(HG_PRC_DEVID);
stjr_jpeg_dev = (struct jpg_device *)dev_get(HG_JPG0_DEVID);
stjr_linebuf = linebuf;
stjr_yuvbuf = yuvbuf;
sw_jpg_w = w;
sw_jpg_h = h;
stjr_itk = 0;
stjr_tick = os_jiffies();
hw_memcpy((void*)(stjr_linebuf),(void*)(stjr_yuvbuf+stjr_itk*16* sw_jpg_w), sw_jpg_w*16);
prc_set_yaddr(stjr_prc_dev,(uint32)stjr_linebuf);
hw_memcpy((void*)(stjr_linebuf+ sw_jpg_w*16),(void*)(stjr_yuvbuf+ sw_jpg_w*sw_jpg_h+stjr_itk*4* sw_jpg_w), sw_jpg_w*4);
prc_set_uaddr(stjr_prc_dev,(uint32)(stjr_linebuf+ sw_jpg_w*16));
hw_memcpy((void*)(stjr_linebuf+ sw_jpg_w*16+4*sw_jpg_w),(void*)(stjr_yuvbuf+ sw_jpg_w*sw_jpg_h+ sw_jpg_w*sw_jpg_h/4+stjr_itk*4* sw_jpg_w), sw_jpg_w*4);
prc_set_vaddr(stjr_prc_dev,(uint32)(stjr_linebuf+ sw_jpg_w*16+4* sw_jpg_w));
stjr_itk++;
pixel_done = 0;
jpg_soft_kick(stjr_jpeg_dev,1);
os_sema_down(jpg_sema_pd, 50);
}
extern void yuv_add_time_watermark(uint8_t *src,uint32_t w,uint32_t h,uint8_t cw,uint8_t ch,uint32_t x_s,uint32_t y_s,uint32_t year,uint8_t month,uint8_t day,uint8_t hour,uint8_t min,uint8_t sec);
extern uint8_t *vfx_linebuf;
void start_jpeg();
void soft_to_jpg_thread(){
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 *jpeg_buf_addr = NULL;
os_sleep_ms(1000);
s = open_stream_available(R_RTP_JPEG,0,8,opcode_func,NULL);
soft_to_jpg_cfg(640,480);
if(vfx_linebuf == NULL)
vfx_linebuf = os_malloc(16*640+8*640);
if(vfx_linebuf == NULL){
os_printf("error....vfx malloc...\r\n");
}
vfx_open = 1;
start_jpeg();
while(1){
get_f = recv_real_data(s);
if(get_f){
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);
free_data(get_f);
get_f = NULL;
}else{
os_sleep_ms(15);
yuv_add_time_watermark((uint8_t *)vga_room,640,480,12,32,400,440,2001,12,1,13,1,59);
soft_to_jpg_run((uint32)vga_room,(uint32)vfx_linebuf,640,480);
}
}
}
void softjpg_thread_init(){
os_task_create("handle_softjpg", soft_to_jpg_thread, (void*)NULL, OS_TASK_PRIORITY_NORMAL, 0, NULL, 1024);
}
#endif
#if 0
void jpg_soft_run_demo(){
struct data_structure *get_f = NULL;
struct stream_jpeg_data_s *dest_list;
struct stream_jpeg_data_s *dest_list_tmp;
struct stream_jpeg_data_s *el,*tmp;
stream *s = NULL;
uint32_t node_len;
uint32_t flen;
uint32_t num = 0;
uint8_t *jpeg_buf_addr = NULL;
void *fp;
os_sleep_ms(1000);
s = open_stream_available(R_RTP_JPEG,0,8,opcode_func,NULL);
soft_to_jpg_cfg(640,480);
start_jpeg();
while(1){
get_f = recv_real_data(s);
if(get_f){
os_printf("JPG gen\r\n");
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("jpeg_buf_addr:%x len:%d\r\n",jpeg_buf_addr,node_len);
free_data(get_f);
get_f = NULL;
}else{
os_sleep_ms(15);
soft_to_jpg_run(decode_vga,640,480);
}
}
}
#endif
//jpg重新配置,如果设备处于休眠状态,则可能需要等待休眠结束才可以重新启动mjpeg
void jpg_recfg(uint8 jpg_num)
{
uint32_t jpg_id;
uint32_t count = 0;
jpg_id = jpg_num + HG_JPG0_DEVID;
struct jpg_device *jpeg_dev;
jpeg_dev = (struct jpg_device *)dev_get(jpg_id);
//第二bit代表jpg初始化完成
while(!(jpg_get_init_flag(jpeg_dev)) && count++<3000)
{
os_sleep_ms(1);
}
os_printf("jpg_is_online(jpeg_dev):%X\n",jpg_is_online(jpeg_dev));
jpg_room_init(jpg_num);
jpg_config_addr(jpeg_dev,jpg_num);
}
void jpg_start(uint8 jpg_num){
struct jpg_device *jpeg_dev;
uint32_t jpgid;
jpgid = jpg_num + HG_JPG0_DEVID;
jpeg_dev = (struct jpg_device *)dev_get(jpgid);
//jpg csr config
if(jpgid == HG_JPG0_DEVID){
#if BBM_DEMO
jpg_set_size(jpeg_dev,photo_msg.out1_h,photo_msg.out1_w);
#else
jpg_set_size(jpeg_dev,photo_msg.out0_h,photo_msg.out0_w);
#endif
}
else{
jpg_set_size(jpeg_dev,photo_msg.out0_h,photo_msg.out0_w);
}
jpg_open(jpeg_dev);
os_printf("mj1 open\r\n");
}
//w和h 设置0,代表和源头分辨率一致
void set_jpg_w_h(uint8 jpg_num,uint16_t w,uint16_t h)
{
if(jpg_num == 0)
{
if(w == 0 && h == 0)
{
photo_msg.out0_w = photo_msg.in_w;
photo_msg.out0_h = photo_msg.in_h;
}
else
{
photo_msg.out0_w = w;
photo_msg.out0_h = h;
}
}
else
{
if(w == 0 && h == 0)
{
photo_msg.out1_w = photo_msg.in_w;
photo_msg.out1_h = photo_msg.in_h;
}
else
{
photo_msg.out1_w = w;
photo_msg.out1_h = h;
}
}
}
void jpg_start_dpi(uint8 jpg_num,uint16_t w,uint16_t h){
struct jpg_device *jpeg_dev;
uint32_t jpgid;
jpgid = jpg_num + HG_JPG0_DEVID;
jpeg_dev = (struct jpg_device *)dev_get(jpgid);
if(jpg_num == 0)
{
photo_msg.out0_w = w;
photo_msg.out0_h = h;
}
else
{
photo_msg.out1_w = w;
photo_msg.out1_h = h;
}
os_printf("w:%d\th:%d\n",w,h);
//jpg csr config
if(jpeg_dev)
{
jpg_set_size(jpeg_dev,h,w);
jpg_open(jpeg_dev);
}
os_printf("mj1 open\r\n");
}
void jpg_stop(uint32_t jpg_num)
{
uint32_t jpg_id;
jpg_id = jpg_num + HG_JPG0_DEVID;
struct jpg_device *jpeg_dev;
jpeg_dev = (struct jpg_device *)dev_get(jpg_id);
jpg_close(jpeg_dev);
jpg_room_deinit(jpg_num);
}
void jpg_clear_init_flag(uint32_t jpg_num)
{
uint32_t jpg_id;
struct jpg_device *jpeg_dev;
jpg_id = jpg_num + HG_JPG0_DEVID;
jpeg_dev = (struct jpg_device *)dev_get(jpg_id);
jpg_set_init_finish(jpeg_dev,0);
}
void del_jpeg_frame(void *d)
{
jpeg_frame* get_f = (jpeg_frame*)d;
del_frame(get_f->jpg_num,(struct list_head*)get_f);
}
struct list_head* get_frame(uint8 jpgid)
{
uint8 frame_num = 0;
uint8 jpg_chose;
if(jpgid == HG_JPG0_DEVID)
jpg_chose = 0;
else
jpg_chose = 1;
for(frame_num = 0;frame_num < JPEG_FRAME_NUM;frame_num++){
if(jpg_frame[jpg_chose][frame_num].usable == 2){
jpg_frame[jpg_chose][frame_num].usable = 1;
return (struct list_head *)&jpg_frame[jpg_chose][frame_num].list;
}
}
return NULL;
}
uint32 get_jpeg_len(void *d)
{
uint32 flen;
struct list_head* get_f = (struct list_head*)d;
jpeg_frame* jpf;
jpf = list_entry(get_f,jpeg_frame,list);
flen = jpf->frame_len;
//_os_printf("%s:%d\tflen:%d\n",__FUNCTION__,__LINE__,flen);
return flen;
}
void *get_jpeg_first_buf(void *d)
{
struct list_head* get_f = (struct list_head*)d;
mjpeg_node* mjn;
mjn = list_entry(get_f->next,mjpeg_node,list);
if(mjn)
{
return mjn->buf_addr;
}
return NULL;
}
int del_jpeg_first_node(void *d)
{
jpeg_frame* get_f = (jpeg_frame*)d;
put_node(&free_tab[get_f->jpg_num],(struct list_head*)get_f);
return 0;
}
void *get_jpeg_node_buf(void *d)
{
struct list_head* get_f = (struct list_head*)d;
mjpeg_node* mjn;
mjn = list_entry(get_f,mjpeg_node,list);
if(mjn)
{
return mjn->buf_addr;
}
return NULL;
}
//删除节点,是实际节点
void del_jpeg_node(void *d,uint32_t jpg_num)
{
uint32_t flags;
struct list_head* get_f = (struct list_head *)d;
flags = disable_irq();
list_add_tail(get_f,(struct list_head*)&free_tab[jpg_num]);
enable_irq(flags);
}
#endif