Files
OpenTXW81X/sdk/app/video_app/video_app_usb_to_lcd.c
2025-08-27 09:51:58 +01:00

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;
}