248 lines
6.3 KiB
C
248 lines
6.3 KiB
C
#include "stream_frame.h"
|
|
#include "utlist.h"
|
|
#include "osal/work.h"
|
|
#include "jpgdef.h"
|
|
#include "custom_mem/custom_mem.h"
|
|
#include "lib/video/uvc/hg_usb_device.h"
|
|
#include "osal/irq.h"
|
|
|
|
|
|
|
|
//需要获取usb的句柄
|
|
#include "list.h"
|
|
#include "dev.h"
|
|
#include "devid.h"
|
|
|
|
#include "dev/usb/hgusb20_v1_dev_api.h"
|
|
#include "dev/usb/uvc_host.h"
|
|
static stream *g_usb_to_lcd_s = NULL;
|
|
uint8_t dispuvc = 0;
|
|
extern uint8 uvc_dpi;
|
|
extern uint8_t uvc_open;
|
|
extern volatile uint8 scale2_finish;
|
|
extern void uvc_reset_dev(uint8_t en);
|
|
extern void uvc_stream_open(struct hgusb20_dev *p_dev,uint8 enable);
|
|
void jpg_decode_to_lcd(uint32 photo,uint32 jpg_w,uint32 jpg_h,uint32 video_w,uint32 video_h);
|
|
int32_t usb_to_lcd_work(struct os_work *work);
|
|
struct usb_to_lcd_s
|
|
{
|
|
struct os_work work;
|
|
struct data_structure *get_f;
|
|
struct data_structure *get_f_tmp;
|
|
};
|
|
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:
|
|
{
|
|
|
|
s->priv = custom_malloc(sizeof(struct usb_to_lcd_s));
|
|
memset(s->priv,0,sizeof(struct usb_to_lcd_s));
|
|
enable_stream(s,1);
|
|
#if RTT_USB_EN
|
|
|
|
#else
|
|
void *dev = (struct usb_device *)dev_get(HG_USBDEV_DEVID);
|
|
//hgusb20_host_reset_phy(dev);
|
|
uvc_reset_dev_mjpeg(1);
|
|
uvc_stream_open((struct hgusb20_dev *)dev,1);
|
|
#endif
|
|
|
|
//启动workqueue中usb_to_lcd事件
|
|
{
|
|
struct usb_to_lcd_s *usb_to_lcd = (struct usb_to_lcd_s*)s->priv;
|
|
OS_WORK_INIT(&usb_to_lcd->work, usb_to_lcd_work, 0);
|
|
os_run_work_delay(&usb_to_lcd->work, 1);
|
|
}
|
|
}
|
|
break;
|
|
case STREAM_OPEN_FAIL:
|
|
break;
|
|
case STREAM_CLOSE_EXIT:
|
|
{
|
|
if(s->priv)
|
|
{
|
|
struct usb_to_lcd_s *usb_to_lcd = (struct usb_to_lcd_s*)s->priv;
|
|
os_work_cancle2(&usb_to_lcd->work,1);
|
|
|
|
if(usb_to_lcd->get_f)
|
|
{
|
|
free_data(usb_to_lcd->get_f);
|
|
usb_to_lcd->get_f = NULL;
|
|
}
|
|
|
|
if(usb_to_lcd->get_f_tmp)
|
|
{
|
|
free_data(usb_to_lcd->get_f_tmp);
|
|
usb_to_lcd->get_f_tmp = NULL;
|
|
}
|
|
custom_free(usb_to_lcd);
|
|
s->priv = NULL;
|
|
}
|
|
|
|
#if RTT_USB_EN
|
|
|
|
#else
|
|
void *dev = (struct usb_device *)dev_get(HG_USBDEV_DEVID);
|
|
uvc_stream_open((struct hgusb20_dev *)dev,0);
|
|
uvc_reset_dev_mjpeg(0);
|
|
#endif
|
|
}
|
|
break;
|
|
default:
|
|
//默认都返回成功
|
|
break;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t usb_to_lcd_work(struct os_work *work)
|
|
{
|
|
stream *s = g_usb_to_lcd_s;
|
|
static uint32_t old_time;
|
|
static uint32_t timeout;
|
|
struct usb_to_lcd_s* usb_to_lcd = (struct usb_to_lcd_s*)s->priv;
|
|
struct stream_jpeg_data_s *dest_list;
|
|
struct stream_jpeg_data_s *dest_list_tmp;
|
|
uint32_t total_len;
|
|
uint32_t uint_len;
|
|
static uint8_t count = 0;
|
|
struct stream_jpeg_data_s *el,*tmp;
|
|
uint8_t *jpeg_buf_addr = NULL;
|
|
static uint32_t wait_time = 0;
|
|
|
|
if((os_jiffies() - old_time) > 1000){
|
|
old_time = os_jiffies();
|
|
dispuvc = count;
|
|
count = 0;
|
|
}else{
|
|
if(os_jiffies() < old_time){ //os_jiffies 溢出处理
|
|
old_time = os_jiffies();
|
|
}
|
|
}
|
|
|
|
|
|
if(usb_to_lcd->get_f == NULL)
|
|
{
|
|
usb_to_lcd->get_f = recv_real_data(s);
|
|
}
|
|
|
|
|
|
//准备解码下一帧,释放上一次的
|
|
if((os_jiffies() - timeout) > 200){
|
|
if(usb_to_lcd->get_f_tmp )
|
|
{
|
|
free_data(usb_to_lcd->get_f_tmp);
|
|
usb_to_lcd->get_f_tmp = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if(usb_to_lcd->get_f)
|
|
{
|
|
|
|
if(!scale2_finish)
|
|
{
|
|
wait_time++;
|
|
if(wait_time > 100)
|
|
{
|
|
_os_printf("Dcod err\r\n");
|
|
scale2_finish = 1;
|
|
wait_time = 0;
|
|
}
|
|
goto usb_to_lcd_work_end;
|
|
}
|
|
dest_list = (struct stream_jpeg_data_s *)get_stream_real_data(usb_to_lcd->get_f);
|
|
dest_list_tmp = dest_list;
|
|
total_len = get_stream_real_data_len(usb_to_lcd->get_f);
|
|
uint_len = stream_data_custom_cmd_func(usb_to_lcd->get_f,CUSTOM_GET_NODE_LEN,NULL);
|
|
count++;
|
|
//准备解码下一帧,释放上一次的
|
|
if(usb_to_lcd->get_f_tmp )
|
|
{
|
|
free_data(usb_to_lcd->get_f_tmp);
|
|
usb_to_lcd->get_f_tmp = NULL;
|
|
}
|
|
usb_to_lcd->get_f_tmp = usb_to_lcd->get_f;
|
|
timeout = os_jiffies();
|
|
|
|
LL_FOREACH_SAFE(dest_list,el,tmp)
|
|
{
|
|
if(dest_list_tmp == el)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//读取完毕删除
|
|
//图片保存起来
|
|
//理论这里就是一张图片,由于这里是节点形式,所以这里暂时先去实现,后续获取一张图片形式显示
|
|
|
|
jpeg_buf_addr = (uint8_t *)stream_data_custom_cmd_func(usb_to_lcd->get_f,CUSTOM_GET_NODE_BUF,el->data);//GET_JPG_SELF_BUF(data,el->data);
|
|
scale2_finish = 0;
|
|
_os_printf("M");
|
|
#if RTT_USB_EN
|
|
jpg_decode_to_lcd((uint32)jpeg_buf_addr,640,480,320,240);
|
|
#else
|
|
if(uvc_dpi == 1){
|
|
jpg_decode_to_lcd((uint32)jpeg_buf_addr,640,480,160,120);
|
|
}else if(uvc_dpi == 2){
|
|
jpg_decode_to_lcd((uint32)jpeg_buf_addr,1280,720,160,120);
|
|
}
|
|
#endif
|
|
|
|
//jpg_decode_to_lcd((uint32)jpeg_buf_addr,1280,720,160,120);
|
|
//DEL_JPEG_NODE(usb_to_lcd->get_f,el);
|
|
break;
|
|
}
|
|
wait_time = 0;
|
|
//读取图片,显示在lcd
|
|
//free_data(usb_to_lcd->get_f);
|
|
usb_to_lcd->get_f = NULL;
|
|
}
|
|
|
|
|
|
usb_to_lcd_work_end:
|
|
os_run_work_delay(work, 1);
|
|
return 0;
|
|
}
|
|
|
|
|
|
uint8_t enable_video_usb_to_lcd(uint8_t enable)
|
|
{
|
|
if(enable)
|
|
{
|
|
stream *s = NULL;
|
|
s = open_stream_available(R_JPEG_TO_LCD,0,8,opcode_func,NULL);
|
|
g_usb_to_lcd_s = s;
|
|
if(s)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int res;
|
|
if(g_usb_to_lcd_s)
|
|
{
|
|
res = close_stream(g_usb_to_lcd_s);
|
|
if(!res)
|
|
{
|
|
g_usb_to_lcd_s = NULL;
|
|
os_printf("%s close end\n",__FUNCTION__);
|
|
}
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|