77#include <rtdevice.h>
88#include "usbh_uvc_stream.h"
99
10+ #ifdef BSP_USING_DEEPCRAFT_AI
11+ #include "uvc_ai_app.h"
12+ #else
13+ static void uvc_ai_app_enforce_mode (uint8_t * fmt , uint16_t * width , uint16_t * height )
14+ {
15+ (void )fmt ;
16+ (void )width ;
17+ (void )height ;
18+ }
19+
20+ static int uvc_ai_app_start (uint16_t src_width , uint16_t src_height )
21+ {
22+ (void )src_width ;
23+ (void )src_height ;
24+ return 0 ;
25+ }
26+
27+ static void uvc_ai_app_process_frame (const struct usbh_videoframe * frame )
28+ {
29+ (void )frame ;
30+ }
31+
32+ static void uvc_ai_app_stop (void )
33+ {
34+ }
35+ #endif
36+
1037#undef USB_DBG_TAG
1138#define USB_DBG_TAG "uvc_app"
1239#include "usb_log.h"
@@ -32,10 +59,44 @@ static volatile uint8_t uvc_app_running;
3259static volatile uint32_t g_uvc_display_fps ;
3360static volatile uint32_t g_uvc_display_drop_count ;
3461
62+ static void uvc_filter_empty_formats (struct usbh_video * video_class )
63+ {
64+ uint8_t read_idx ;
65+ uint8_t write_idx ;
66+
67+ if (video_class == RT_NULL ) {
68+ return ;
69+ }
70+
71+ /*
72+ * Some cameras expose an extra VS format entry with zero frames.
73+ * Keep CherryUSB core unchanged and compact valid entries here,
74+ * so usbh_video_open() does not pick an empty format.
75+ */
76+ write_idx = 0U ;
77+ for (read_idx = 0U ; read_idx < video_class -> num_of_formats ; read_idx ++ ) {
78+ if (video_class -> format [read_idx ].num_of_frames == 0U ) {
79+ continue ;
80+ }
81+
82+ if (write_idx != read_idx ) {
83+ video_class -> format [write_idx ] = video_class -> format [read_idx ];
84+ }
85+ write_idx ++ ;
86+ }
87+
88+ if (write_idx != video_class -> num_of_formats ) {
89+ USB_LOG_WRN ("UVC filter empty format: %u -> %u\r\n" ,
90+ video_class -> num_of_formats , write_idx );
91+ video_class -> num_of_formats = write_idx ;
92+ }
93+ }
94+
3595/* ---------- CherryUSB video class callbacks ---------- */
3696
3797void usbh_video_run (struct usbh_video * video_class )
3898{
99+ uvc_filter_empty_formats (video_class );
39100 USB_LOG_INFO ("UVC device connected\r\n" );
40101 usbh_video_list_info (video_class );
41102}
@@ -52,15 +113,6 @@ void usbh_video_stop(struct usbh_video *video_class)
52113extern volatile uint32_t g_uvc_fps ;
53114extern volatile uint32_t uvc_transfer_count ;
54115extern volatile uint32_t video_complete_count ;
55- extern volatile uint32_t uvc_dbg_eof_count ;
56- extern volatile uint32_t uvc_dbg_fid_toggle ;
57- extern volatile uint32_t uvc_dbg_empty_pkt ;
58- extern volatile uint32_t uvc_dbg_data_pkt ;
59- extern volatile uint32_t uvc_dbg_last_eof_offset ;
60- extern volatile uint32_t uvc_dbg_frame_done ;
61- extern volatile uint32_t uvc_dbg_err_bit ;
62- extern volatile uint32_t uvc_dbg_payload_bytes ;
63- extern volatile uint32_t uvc_dbg_hdronly_pkt ;
64116
65117static void uvc_display_fps_record (void )
66118{
@@ -104,16 +156,10 @@ static void uvc_frame_keep_latest(struct usbh_videoframe **frame)
104156static void uvc_fps_thread_entry (void * arg )
105157{
106158 while (uvc_app_running ) {
107- USB_LOG_INFO ("UVC fps:%d disp:%d drop:%u urb:%d eof:%d fid:%d err:%d empty:%d data:%d hdronly:%d payload:%d done:%d last_off:%u \r\n" ,
159+ USB_LOG_INFO ("UVC fps:%d disp:%d drop:%u urb:%d\r\n" ,
108160 (int )g_uvc_fps , (int )g_uvc_display_fps ,
109161 (unsigned )g_uvc_display_drop_count ,
110- (int )video_complete_count ,
111- (int )uvc_dbg_eof_count , (int )uvc_dbg_fid_toggle ,
112- (int )uvc_dbg_err_bit , (int )uvc_dbg_empty_pkt ,
113- (int )uvc_dbg_data_pkt ,
114- (int )uvc_dbg_hdronly_pkt , (int )uvc_dbg_payload_bytes ,
115- (int )uvc_dbg_frame_done ,
116- (unsigned )uvc_dbg_last_eof_offset );
162+ (int )video_complete_count );
117163 rt_thread_mdelay (3000 );
118164 }
119165}
@@ -132,6 +178,7 @@ static void uvc_frame_thread_entry(void *arg)
132178
133179 /* initialise display output */
134180 uvc_display_init ();
181+ (void )uvc_ai_app_start (uvc_cam_w , uvc_cam_h );
135182
136183 while (uvc_app_running ) {
137184 ret = usbh_video_stream_dequeue (& frame , RT_TICK_PER_SECOND );
@@ -149,6 +196,7 @@ static void uvc_frame_thread_entry(void *arg)
149196 }
150197
151198 usbh_video_stream_get_info (& stream_w , & stream_h , RT_NULL );
199+ uvc_ai_app_process_frame (frame );
152200
153201 /* render frame to LCD */
154202 uvc_display_frame (frame ,
@@ -158,14 +206,18 @@ static void uvc_frame_thread_entry(void *arg)
158206
159207 usbh_video_stream_enqueue (frame );
160208 }
209+
210+ uvc_ai_app_stop ();
161211}
162212
163213/* ---------- msh commands ---------- */
164214
165215static int cmd_usbh_uvc_start (int argc , char * * argv )
166216{
167217 uint8_t fmt = USBH_VIDEO_FORMAT_UNCOMPRESSED ; /* default: YUYV */
168- uint16_t w = 640 , h = 480 ;
218+ uint16_t w = 320 ;
219+ uint16_t h = 240 ;
220+ uint32_t frame_bufsize = UVC_FRAME_BUF_SIZE ;
169221 int ret ;
170222
171223 if (uvc_app_running ) {
@@ -181,14 +233,27 @@ static int cmd_usbh_uvc_start(int argc, char **argv)
181233 h = atoi (argv [3 ]);
182234 }
183235
236+ uvc_ai_app_enforce_mode (& fmt , & w , & h );
237+
184238 USB_LOG_INFO ("UVC start: %ux%u format=%s\r\n" , w , h ,
185239 fmt == USBH_VIDEO_FORMAT_MJPEG ? "mjpeg" : "yuyv" );
186240
241+ if (fmt == USBH_VIDEO_FORMAT_UNCOMPRESSED ) {
242+ uint32_t yuyv_size = (uint32_t )w * (uint32_t )h * 2U ;
243+
244+ if ((w == 0U ) || (h == 0U ) || (yuyv_size > UVC_FRAME_BUF_SIZE )) {
245+ USB_LOG_ERR ("Invalid YUYV frame size: %ux%u (%lu)\r\n" ,
246+ w , h , (unsigned long )yuyv_size );
247+ return - RT_EINVAL ;
248+ }
249+ frame_bufsize = yuyv_size ;
250+ }
251+
187252 /* initialise frame pool */
188253 {
189254 for (uint32_t i = 0 ; i < UVC_FRAME_BUF_COUNT ; i ++ ) {
190255 frame_pool [i ].frame_buf = frame_buffer [i ];
191- frame_pool [i ].frame_bufsize = UVC_FRAME_BUF_SIZE ;
256+ frame_pool [i ].frame_bufsize = frame_bufsize ;
192257 }
193258 }
194259
@@ -213,7 +278,7 @@ static int cmd_usbh_uvc_start(int argc, char **argv)
213278 if (t ) rt_thread_startup (t );
214279
215280 t = rt_thread_create ("uvc_frm" , uvc_frame_thread_entry , NULL ,
216- 8192 , 22 , 10 );
281+ 65536 , 22 , 10 );
217282 if (t ) rt_thread_startup (t );
218283
219284 /* start the video stream (frames are queued inside stream_start) */
0 commit comments