usb_uvc.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366
  1. #include <string.h>
  2. #include <ctype.h>
  3. #include <stdlib.h>
  4. #include <stdbool.h>
  5. #include "usb_os_adapter.h"
  6. #include "board.h"
  7. #include "video_buf.h"
  8. #ifdef USB_UVC_SUPPORT
  9. #include "ff_stdio.h"
  10. #include "usb.h"
  11. #include "list.h"
  12. #include "semphr.h"
  13. #include "timers.h"
  14. #include "lcd.h"
  15. #include "pxp.h"
  16. #include "timer.h"
  17. #include "cp15/cp15.h"
  18. #include "jpegdecapi.h"
  19. #include "mfcapi.h"
  20. #include "usb_uvc.h"
  21. /* */
  22. #define UVC_STREAM_EOH (1 << 7)
  23. #define UVC_STREAM_ERR (1 << 6)
  24. #define UVC_STREAM_STI (1 << 5)
  25. #define UVC_STREAM_RES (1 << 4)
  26. #define UVC_STREAM_SCR (1 << 3)
  27. #define UVC_STREAM_PTS (1 << 2)
  28. #define UVC_STREAM_EOF (1 << 1)
  29. #define UVC_STREAM_FID (1 << 0)
  30. #define UVC_ALIGN_8(x) ALIGN(x, 8)
  31. #define UVC_ALIGN_4(x) ALIGN(x, 4)
  32. #define UVC_HEADER_LEN 0x0c
  33. #define UVC_MAX_ENDPOINT_LEN 0x2000
  34. #define UVC_VIDEO_WIDTH 1024
  35. #define UVC_VIDEO_HEIGHT 600
  36. #define UVC_JPEG_FIFO_COUNT 4
  37. #define UVC_JPEG_BUF_SIZE (UVC_VIDEO_WIDTH * UVC_VIDEO_HEIGHT)
  38. #define UVC_YUV_BUF_SIZE ((UVC_ALIGN_8(UVC_VIDEO_WIDTH) * UVC_ALIGN_8(UVC_VIDEO_HEIGHT)) * 2)
  39. #define UVC_DATA_RECEIVE_TASK_PRIORITY (configMAX_PRIORITIES - 4)
  40. #define UVC_JPEG_DECODE_TASK_PRIORITY (configMAX_PRIORITIES - 5)
  41. #define UVC_TEST
  42. typedef struct _uvc_video_frame {
  43. ListItem_t entry;
  44. uint8_t *buf;
  45. uint8_t *cur;
  46. unsigned int len;
  47. unsigned int frame_id;
  48. } uvc_video_frame_t;
  49. typedef struct _uvc_disp_area {
  50. uint16_t x;
  51. uint16_t y;
  52. uint16_t w;
  53. uint16_t h;
  54. } uvc_disp_area_t;
  55. typedef struct _uvc_probe_param {
  56. uint16_t bmHint;
  57. uint8_t bFormatIndex;
  58. uint8_t bFrameIndex;
  59. uint32_t dwFrameInterval;
  60. uint16_t wKeyFrameRate;
  61. uint16_t wPFrameRate;
  62. uint16_t wCompQuality;
  63. uint16_t wCompWindowSize;
  64. uint16_t wDelay;
  65. uint32_t dwMaxVideoFrameSize;
  66. uint32_t dwMaxPayloadTransferSize;
  67. } uvc_probe_param_t;
  68. typedef struct _uvc_dev_info {
  69. struct usb_device *dev;
  70. TaskHandle_t dec_task_handle;
  71. TaskHandle_t rcv_task_handle;
  72. List_t frame_free_list;
  73. List_t frame_ready_list;
  74. SemaphoreHandle_t frame_list_mutex;
  75. QueueHandle_t jpeg_frame_queue;
  76. QueueHandle_t exit_queue;
  77. MFCHandle *mfc_handle;
  78. uint8_t *jpeg_buf;
  79. uint8_t *yuv_buf;
  80. #ifdef USB_DMA
  81. uint8_t *dma_buf;
  82. #endif
  83. int32_t pipe;
  84. uint32_t dev_ready;
  85. uint32_t dec_task_start;
  86. uint32_t uvc_start;
  87. uvc_disp_area_t disp_area;
  88. //
  89. struct usb_interface_descriptor pVideoInterface;
  90. struct usb_endpoint_descriptor pVideoEndpoint;
  91. uint8_t num_altsetting;
  92. uint8_t bEndpointNumber;
  93. } uvc_dev_info_t;
  94. static uvc_dev_info_t *g_uvc_info = NULL;
  95. extern void usb_set_maxpacket_ep_ex(struct usb_device *dev, int if_idx, int alt_idx, int ep_idx);
  96. static int uvc_jpeg_decode_and_display(uvc_dev_info_t *uvc, uvc_video_frame_t* frame);
  97. static void uvc_frame_list_reset(uvc_dev_info_t *uvc);
  98. static void uvc_parse_probe_param(uvc_probe_param_t *ProbeParam, uint8_t *pdata)
  99. {
  100. ProbeParam->bmHint = (pdata[1]<<8) | pdata[0];
  101. ProbeParam->bFormatIndex = pdata[2];
  102. ProbeParam->bFrameIndex = pdata[3];
  103. ProbeParam->dwFrameInterval = (pdata[7]<<24)|(pdata[6]<<16)|(pdata[5]<<8) | pdata[4];
  104. ProbeParam->wKeyFrameRate = (pdata[9]<<8) | pdata[8];
  105. ProbeParam->wPFrameRate = (pdata[11]<<8) | pdata[10];
  106. ProbeParam->wCompQuality = (pdata[13]<<8) | pdata[12];
  107. ProbeParam->wCompWindowSize = (pdata[15]<<8) | pdata[14];
  108. ProbeParam->wDelay = (pdata[17]<<8) | pdata[16];
  109. ProbeParam->dwMaxVideoFrameSize = (pdata[21]<<24)|(pdata[20]<<16)|(pdata[19]<<8) | pdata[18];
  110. ProbeParam->dwMaxPayloadTransferSize = (pdata[21]<<25)|(pdata[24]<<16)|(pdata[23]<<8) | pdata[22];
  111. }
  112. static void uvc_dump_probe_param(uvc_probe_param_t *ProbeParam)
  113. {
  114. printf("=== MGC_UvcGetProbeControl ===\r\n");
  115. printf("bmHint = 0x%x\r\n", ProbeParam->bmHint);
  116. printf("bFormatIndex = 0x%x\r\n", ProbeParam->bFormatIndex);
  117. printf("bFrameIndex = 0x%x\r\n", ProbeParam->bFrameIndex);
  118. printf("dwFrameInterval = 0x%x\r\n", ProbeParam->dwFrameInterval);
  119. printf("wKeyFrameRate = 0x%x\r\n", ProbeParam->wKeyFrameRate);
  120. printf("wPFrameRate = 0x%x\r\n", ProbeParam->wPFrameRate);
  121. printf("wCompQuality = 0x%x\r\n", ProbeParam->wCompQuality);
  122. printf("wCompWindowSize = 0x%x\r\n", ProbeParam->wCompWindowSize);
  123. printf("wDelay = 0x%x\r\n", ProbeParam->wDelay);
  124. printf("dwMaxVideoFrameSize = 0x%x\r\n", ProbeParam->dwMaxVideoFrameSize);
  125. printf("dwMaxPayloadTransferSize = 0x%x\r\n", ProbeParam->dwMaxPayloadTransferSize);
  126. }
  127. static void uvc_prepare_probe_data(uvc_probe_param_t *ProbeParam, uint8_t *out)
  128. {
  129. out[0] = ProbeParam->bmHint & 0xff;
  130. out[1] = (ProbeParam->bmHint>>8) & 0xff;
  131. out[2] = ProbeParam->bFormatIndex & 0xff;
  132. out[3] = ProbeParam->bFrameIndex & 0xff;
  133. out[4] = ProbeParam->dwFrameInterval & 0xff;
  134. out[5] = (ProbeParam->dwFrameInterval>>8) & 0xff;
  135. out[6] = (ProbeParam->dwFrameInterval>>16) & 0xff;
  136. out[7] = (ProbeParam->dwFrameInterval>>24) & 0xff;
  137. out[8] = ProbeParam->wKeyFrameRate & 0xff;
  138. out[9] = (ProbeParam->wKeyFrameRate>>8) & 0xff;
  139. out[10] = ProbeParam->wPFrameRate & 0xff;
  140. out[11] = (ProbeParam->wPFrameRate>>8) & 0xff;
  141. out[12] = ProbeParam->wCompQuality & 0xff;
  142. out[13] = (ProbeParam->wCompQuality>>8) & 0xff;
  143. out[14] = ProbeParam->wCompWindowSize & 0xff;
  144. out[15] = (ProbeParam->wCompWindowSize>>8) & 0xff;
  145. out[16] = ProbeParam->wDelay & 0xff;
  146. out[17] = (ProbeParam->wDelay>>8) & 0xff;
  147. out[18] = ProbeParam->dwMaxVideoFrameSize & 0xff;
  148. out[19] = (ProbeParam->dwMaxVideoFrameSize>>8) & 0xff;
  149. out[20] = (ProbeParam->dwMaxVideoFrameSize>>16) & 0xff;
  150. out[21] = (ProbeParam->dwMaxVideoFrameSize>>24) & 0xff;
  151. out[22] = ProbeParam->dwMaxPayloadTransferSize & 0xff;
  152. out[23] = (ProbeParam->dwMaxPayloadTransferSize>>8) & 0xff;
  153. out[24] = (ProbeParam->dwMaxPayloadTransferSize>>16) & 0xff;
  154. out[25] = (ProbeParam->dwMaxPayloadTransferSize>>24) & 0xff;
  155. }
  156. int uvc_select_max_endpoint(uvc_dev_info_t *uvc)
  157. {
  158. struct usb_interface *iface;
  159. struct usb_interface_descriptor *if_desc;
  160. struct usb_endpoint_descriptor *ep_desc;
  161. struct usb_device *dev;
  162. int if_index;
  163. int alt_index;
  164. int ep_index;
  165. int ret = -1;
  166. if (!uvc) {
  167. printf("%s, Invalid uvc.\n", __func__);
  168. return -1;
  169. }
  170. dev = uvc->dev;
  171. uvc->num_altsetting = 0;
  172. uvc->bEndpointNumber = 0;
  173. memset(&uvc->pVideoInterface, 0, sizeof(struct usb_interface_descriptor));
  174. memset(&uvc->pVideoEndpoint, 0, sizeof(struct usb_endpoint_descriptor));
  175. for (if_index = 0; (if_index < dev->config.desc.bNumInterfaces) && (if_index < USB_MAXINTERFACES); if_index++) {
  176. int total_ep_index = 0;
  177. iface = &dev->config.if_desc[if_index];
  178. printf("num_altsetting is 0x%x\n", iface->num_altsetting);
  179. for (alt_index = 0; alt_index < iface->num_altsetting; alt_index++) {
  180. if (iface->num_altsetting > 1)
  181. if_desc = &iface->alt_intf[alt_index].desc;
  182. else
  183. if_desc = &iface->desc;
  184. if ((if_desc->bInterfaceClass == USB_CLASS_VIDEO) ||
  185. (if_desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)) {
  186. #ifdef UVC_TEST
  187. printf("===== video interface index is 0x%x=====\n", if_index);
  188. printf("bLength is 0x%x\n", if_desc->bLength);
  189. printf("bDescriptorType is 0x%x\n", if_desc->bDescriptorType);
  190. printf("bInterfaceNumber is 0x%x\n", if_desc->bInterfaceNumber);
  191. printf("bAlternateSetting is 0x%x\n", if_desc->bAlternateSetting);
  192. printf("bNumEndpoints is 0x%x\n", if_desc->bNumEndpoints);
  193. printf("bInterfaceClass is 0x%x\n", if_desc->bInterfaceClass);
  194. printf("bInterfaceSubClass is 0x%x\n", if_desc->bInterfaceSubClass);
  195. printf("bInterfaceProtocol is 0x%x\n", if_desc->bInterfaceProtocol);
  196. printf("iInterface is 0x%x\n", if_desc->iInterface);
  197. printf("=======================================\n");
  198. #endif
  199. for (ep_index = 0; ep_index < if_desc->bNumEndpoints; ep_index++) {
  200. // if (iface->num_altsetting > 1)
  201. // ep_desc = &iface->alt_intf->ep_desc[ep_index];
  202. // else
  203. //ep_desc = &iface->ep_desc[ep_index];
  204. ep_desc = &iface->ep_desc[total_ep_index++];
  205. if ((ep_desc->wMaxPacketSize <= UVC_MAX_ENDPOINT_LEN) &&
  206. (ep_desc->wMaxPacketSize > uvc->pVideoEndpoint.wMaxPacketSize) &&
  207. ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_CONTROL))
  208. {
  209. uvc->num_altsetting = iface->num_altsetting;
  210. //if
  211. uvc->pVideoInterface.bLength = if_desc->bLength;
  212. uvc->pVideoInterface.bDescriptorType = if_desc->bDescriptorType;
  213. uvc->pVideoInterface.bInterfaceNumber = if_desc->bInterfaceNumber;
  214. uvc->pVideoInterface.bAlternateSetting = if_desc->bAlternateSetting;
  215. uvc->pVideoInterface.bNumEndpoints = if_desc->bNumEndpoints;
  216. uvc->pVideoInterface.bInterfaceClass = if_desc->bInterfaceClass;
  217. uvc->pVideoInterface.bInterfaceSubClass = if_desc->bInterfaceSubClass;
  218. uvc->pVideoInterface.bInterfaceProtocol = if_desc->bInterfaceProtocol;
  219. uvc->pVideoInterface.iInterface = if_desc->iInterface;
  220. //ep
  221. uvc->bEndpointNumber = ep_index;
  222. uvc->pVideoEndpoint.bLength = ep_desc->bLength;
  223. uvc->pVideoEndpoint.bDescriptorType = ep_desc->bDescriptorType;
  224. uvc->pVideoEndpoint.bEndpointAddress = ep_desc->bEndpointAddress;
  225. uvc->pVideoEndpoint.bmAttributes = ep_desc->bmAttributes;
  226. uvc->pVideoEndpoint.wMaxPacketSize = ep_desc->wMaxPacketSize;
  227. uvc->pVideoEndpoint.bInterval = ep_desc->bInterval;
  228. #ifdef UVC_TEST
  229. printf(" =====endpoint index is 0x%x=====\n", ep_index);
  230. printf(" bLength is 0x%x\n", ep_desc->bLength);
  231. printf(" bDescriptorType is 0x%x\n", ep_desc->bDescriptorType);
  232. printf(" bEndpointAddress is 0x%x\n", ep_desc->bEndpointAddress);
  233. printf(" bmAttributes is 0x%x\n", ep_desc->bmAttributes);
  234. printf(" wMaxPacketSize is 0x%x\n", ep_desc->wMaxPacketSize);
  235. printf(" bInterval is 0x%x\n", ep_desc->bInterval);
  236. printf(" =======================================\n");
  237. #endif
  238. ret = 0;
  239. }
  240. }
  241. } else if (if_desc->bInterfaceClass == USB_CLASS_AUDIO) {
  242. }
  243. }
  244. }
  245. return ret;
  246. }
  247. static int uvc_camera_init(uvc_dev_info_t *uvc)
  248. {
  249. struct usb_device *dev;
  250. struct usb_interface *iface;
  251. uvc_probe_param_t ProbeParam = {0};
  252. uint32_t interface_idx, alternate_idx, endpoint_idx;
  253. uint32_t flag_video_ctrl = 0;
  254. uint32_t flag_video_stream = 0;
  255. uint8_t ep_in = 0;
  256. uint8_t probe_buf[128] = {0};
  257. uint8_t *pdata = NULL;
  258. int i, ret = -1;
  259. if (!uvc) {
  260. printf("%s, Invalid uvc\n", __func__);
  261. return -1;
  262. }
  263. dev = uvc->dev;
  264. if (!dev) {
  265. printf("%s, Invalid dev\n", __func__);
  266. return -1;
  267. }
  268. for (i = 0; i < USB_MAXINTERFACES; i++) {
  269. iface = &dev->config.if_desc[i];
  270. if ((iface->desc.bInterfaceClass == USB_CLASS_VIDEO) ||
  271. (iface->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC)) {
  272. if (iface->desc.bInterfaceSubClass == 0x01) {
  273. flag_video_ctrl = 1;
  274. } else if (iface->desc.bInterfaceSubClass == 0x02) {
  275. flag_video_stream = 1;
  276. }
  277. }
  278. }
  279. if (!flag_video_ctrl || !flag_video_stream) {
  280. goto exit;
  281. }
  282. printf("UVC device fond.\n");
  283. ret = uvc_select_max_endpoint(uvc);
  284. if (ret < 0) {
  285. printf("%s, uvc_select_max_endpoint failed\n", __func__);
  286. goto exit;
  287. }
  288. interface_idx = uvc->pVideoInterface.bInterfaceNumber;
  289. alternate_idx = uvc->pVideoInterface.bAlternateSetting;
  290. endpoint_idx = uvc->bEndpointNumber;
  291. printf("uvc camera select: if:%d, alt:%d, ep:%d, wMaxPacketSize:0x%x\n",
  292. interface_idx, alternate_idx, endpoint_idx, uvc->pVideoEndpoint.wMaxPacketSize);
  293. if ((uvc->pVideoEndpoint.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_CONTROL) {
  294. if (uvc->pVideoEndpoint.bEndpointAddress & USB_DIR_IN) {
  295. usb_set_maxpacket_ep_ex(dev, interface_idx, alternate_idx, endpoint_idx);
  296. }
  297. }
  298. if (uvc->num_altsetting == 1) {
  299. ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE,
  300. alternate_idx, interface_idx, NULL, 0, USB_CNTL_TIMEOUT * 5);
  301. } else {
  302. ret = usb_set_interface(dev, 1, 0);
  303. }
  304. if (ret < 0) {
  305. goto exit;
  306. }
  307. mdelay(10);
  308. /* Get Cur */
  309. ret= usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x81, 0xA1, 0x100, 0x1, probe_buf, 0x1A, 3000);
  310. if (ret < 0) {
  311. goto exit;
  312. }
  313. uvc_parse_probe_param(&ProbeParam, probe_buf);
  314. uvc_dump_probe_param(&ProbeParam);
  315. /* 客户设置自己的摄像头参数配置 */
  316. ProbeParam.bFormatIndex = 2; //mjpeg
  317. ProbeParam.bFrameIndex = 2; //1:1280x720; 2:640x480
  318. // ProbeParam.dwMaxVideoFrameSize = 0x003f4800;//0x96000;
  319. // ProbeParam.dwFrameInterval = 0x0007A120;//30fps:0x051615; 20fps:0x0007A120; 10fps:0x000F4240; 5fps:0x001E8480
  320. // ProbeParam.dwMaxPayloadTransferSize = 0x00001400;
  321. /* Set Cur */
  322. pdata = probe_buf;
  323. uvc_prepare_probe_data(&ProbeParam, pdata);
  324. ret= usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x1, 0x21, 0x100, 0x1, pdata, 0x1A, 3000);
  325. if (ret < 0) {
  326. goto exit;
  327. }
  328. /* Get Cur */
  329. ret= usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x81, 0xA1, 0x100, 0x1, probe_buf, 0x1A, 3000);
  330. if (ret < 0) {
  331. goto exit;
  332. }
  333. uvc_parse_probe_param(&ProbeParam, probe_buf);
  334. uvc_dump_probe_param(&ProbeParam);
  335. mdelay(10);
  336. /* Set Commit */
  337. pdata = probe_buf;
  338. uvc_prepare_probe_data(&ProbeParam, pdata);
  339. ret= usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x1, 0x21, 0x200, 0x1, pdata, 0x1A, 10000);
  340. ret= usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x1, 0x21, 0x200, 0x1, pdata, 0x1A, 10000); //avoid abnormal.
  341. if (ret < 0) {
  342. goto exit;
  343. }
  344. mdelay(10);
  345. ret = usb_set_interface(dev, interface_idx, alternate_idx);
  346. if (ret < 0) {
  347. goto exit;
  348. }
  349. ep_in = uvc->pVideoEndpoint.bEndpointAddress;
  350. if ((uvc->pVideoEndpoint.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) {
  351. uvc->pipe = usb_rcvisocpipe(dev, ep_in);
  352. } else if ((uvc->pVideoEndpoint.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
  353. uvc->pipe = usb_rcvbulkpipe(dev, ep_in);
  354. } else if ((uvc->pVideoEndpoint.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
  355. uvc->pipe = usb_rcvintpipe(dev, ep_in);
  356. }
  357. exit:
  358. return ret;
  359. }
  360. static uvc_video_frame_t* uvc_get_free_node(uvc_dev_info_t *uvc)
  361. {
  362. uvc_video_frame_t* frame = NULL;
  363. ListItem_t* item;
  364. xSemaphoreTake(uvc->frame_list_mutex, portMAX_DELAY);
  365. if (listLIST_IS_EMPTY(&uvc->frame_free_list)) {
  366. #ifdef UVC_TEST
  367. printf("### uvc no free node, ready node count:%d\n", uvc->frame_ready_list.uxNumberOfItems);
  368. #endif
  369. #if 0 //reuse ready node.
  370. if (!listLIST_IS_EMPTY(&uvc->frame_ready_list)) {
  371. item = listGET_HEAD_ENTRY(&uvc->frame_ready_list);
  372. uxListRemove(item);
  373. frame = listGET_LIST_ITEM_OWNER(item);
  374. }
  375. #endif
  376. xSemaphoreGive(uvc->frame_list_mutex);
  377. return frame;
  378. }
  379. item = listGET_HEAD_ENTRY(&uvc->frame_free_list);
  380. uxListRemove(item);
  381. frame = listGET_LIST_ITEM_OWNER(item);
  382. xSemaphoreGive(uvc->frame_list_mutex);
  383. return frame;
  384. }
  385. #if 0
  386. /* 采用数据拼接的方式:
  387. * 即直接使用目的缓存接收每一微帧数据,每次接收完一个微帧,备份末尾12个字节(帧格式头长度为12字节),
  388. * 下一微帧直接覆盖上一微帧的末尾12个字节,然后再把上一微帧备份的12字节拷贝回来,这样每一微帧仅拷贝
  389. * 12字节。这种方式可以减少拷贝时间,节省带宽,图像分辨率过大时不易花屏。
  390. */
  391. static int uvc_iso_data_proc(uvc_dev_info_t *uvc)
  392. {
  393. struct usb_device *dev;
  394. uvc_video_frame_t* frame = NULL;
  395. int payload_len = 0, frame_len = 0;
  396. int buf_len = UVC_JPEG_BUF_SIZE;
  397. int8_t header_backup_buf[UVC_HEADER_LEN] = {0};
  398. uint8_t header_len;
  399. uint8_t bfh;
  400. // int8_t fid = -1;
  401. // int jpeg_header_fond = 0;
  402. int ret;
  403. if (!uvc) {
  404. printf("%s, Invalid uvc\n", __func__);
  405. goto exit;
  406. }
  407. dev = uvc->dev;
  408. if (!dev) {
  409. printf("%s, Invalid dev\n", __func__);
  410. goto exit;
  411. }
  412. while (uvc->dev_ready) {
  413. if (!frame) {
  414. frame = uvc_get_free_node(uvc);
  415. if (!frame) {
  416. msleep(30);
  417. continue;
  418. }
  419. frame->cur = frame->buf;
  420. frame->len = 0;
  421. }
  422. #ifdef USB_DMA
  423. uint8_t *align_buffer = frame->cur;
  424. if ((unsigned int)frame->cur & 3) {
  425. if (uvc->dma_buf) {
  426. align_buffer = (uint8_t *)UVC_ALIGN_4((unsigned int)uvc->dma_buf);
  427. }
  428. }
  429. ret = usb_iso_msg(dev, uvc->pipe, (void*)align_buffer, buf_len, &payload_len, pdMS_TO_TICKS(100));
  430. if (((unsigned int)frame->cur & 3) && (payload_len > 0)) {
  431. memcpy(frame->cur, align_buffer, payload_len);
  432. }
  433. #else
  434. ret = usb_iso_msg(dev, uvc->pipe, (void*)frame->cur, buf_len, &payload_len, pdMS_TO_TICKS(100));
  435. #endif
  436. if (ret < 0) {
  437. printf("%s send receive cmd failed.\n", __func__);
  438. goto exit;
  439. }
  440. if (payload_len <= 0) {
  441. msleep(30);
  442. continue;
  443. }
  444. header_len = frame->cur[0];
  445. bfh = frame->cur[1];
  446. #if 0
  447. if ((header_len != UVC_HEADER_LEN) || (payload_len <= header_len) || ((bfh & 0xf0) != 0x80)) {
  448. //max payload len: 0xbfe
  449. if ((payload_len == header_len) && (bfh & UVC_STREAM_EOF)) {
  450. goto end_of_frame;
  451. }
  452. //msleep(1);
  453. continue;
  454. }
  455. if ((bfh & UVC_STREAM_FID) != fid) {
  456. fid = (bfh & UVC_STREAM_FID);
  457. jpeg_header_fond = 1;
  458. printf("### FID: 0x%.2x, 0x%.2x\n", frame->cur[12], frame->cur[13]);
  459. }
  460. frame_len = payload_len - header_len;
  461. if (jpeg_header_fond == 0) {
  462. printf("### uvc drop frame, fid lost.\n");
  463. //msleep(5);
  464. goto end_of_frame;
  465. }
  466. if (frame->len + frame_len > UVC_JPEG_BUF_SIZE) {
  467. printf("### %s, uvc jpeg buf overflow.\n", __func__);
  468. frame->cur = frame->buf;
  469. frame->len = 0;
  470. jpeg_header_fond = 0;
  471. continue;
  472. }
  473. memcpy(frame->cur, header_backup_buf, UVC_HEADER_LEN);
  474. frame->cur += frame_len;
  475. frame->len += frame_len;
  476. memcpy(header_backup_buf, frame->cur, UVC_HEADER_LEN);
  477. end_of_frame:
  478. if (bfh & UVC_STREAM_EOF) {
  479. printf("### EOF\n");
  480. xSemaphoreTake(uvc->frame_list_mutex, portMAX_DELAY);
  481. if ((frame->buf[12] == 0xff) && (frame->buf[13] == 0xd8) &&
  482. (frame->buf[frame->len+10] == 0xff) && (frame->buf[frame->len+11] == 0xd9)) {
  483. CP15_clean_dcache_for_dma((uint32_t)frame->buf, (uint32_t)frame->buf + frame->len + UVC_HEADER_LEN);
  484. vListInsertEnd(&uvc->frame_ready_list, &frame->entry);
  485. xSemaphoreGive(uvc->frame_list_mutex);
  486. xQueueSend(uvc->jpeg_frame_queue, NULL, 0);
  487. } else {
  488. vListInsertEnd(&uvc->frame_free_list, &frame->entry);
  489. xSemaphoreGive(uvc->frame_list_mutex);
  490. }
  491. frame = NULL;
  492. jpeg_header_fond = 0;
  493. }
  494. //msleep(1);
  495. #else
  496. if ((header_len != UVC_HEADER_LEN) || (payload_len <= header_len) || ((bfh & 0xf0) != 0x80)) {
  497. //msleep(1);
  498. continue;
  499. }
  500. if ((frame->cur[12] == 0xff) && (frame->cur[13] == 0xd8)) {
  501. if (frame->cur != frame->buf) {
  502. printf("### %s, uvc lost EOF, drop frame\n", __func__);
  503. memcpy(frame->buf, frame->cur, payload_len);
  504. frame->cur = frame->buf;
  505. frame->len = 0;
  506. }
  507. //printf("### FID\n");
  508. }
  509. frame_len = payload_len - header_len;
  510. if (frame->len + frame_len > UVC_JPEG_BUF_SIZE) {
  511. printf("###### %s, uvc jpeg buf overflow.\n", __func__);
  512. frame->cur = frame->buf;
  513. frame->len = 0;
  514. msleep(5);
  515. continue;
  516. } else if (frame_len > 0) {
  517. memcpy(frame->cur, header_backup_buf, UVC_HEADER_LEN);
  518. frame->cur += frame_len;
  519. frame->len += frame_len;
  520. memcpy(header_backup_buf, frame->cur, UVC_HEADER_LEN);
  521. }
  522. if ((frame->cur[10] == 0xff) && (frame->cur[11] == 0xd9)) {
  523. //printf("### EOF\n");
  524. xSemaphoreTake(uvc->frame_list_mutex, portMAX_DELAY);
  525. if ((frame->buf[12] == 0xff) && (frame->buf[13] == 0xd8)) {
  526. CP15_clean_dcache_for_dma((uint32_t)frame->buf, (uint32_t)frame->buf + frame->len + UVC_HEADER_LEN);
  527. vListInsertEnd(&uvc->frame_ready_list, &frame->entry);
  528. xSemaphoreGive(uvc->frame_list_mutex);
  529. xQueueSend(uvc->jpeg_frame_queue, NULL, 0);
  530. } else {
  531. printf("### %s, uvc lost FID, drop frame\n", __func__);
  532. vListInsertEnd(&uvc->frame_free_list, &frame->entry);
  533. xSemaphoreGive(uvc->frame_list_mutex);
  534. }
  535. frame = NULL;
  536. }
  537. #endif
  538. }
  539. exit:
  540. if (frame) {
  541. frame->cur = frame->buf;
  542. frame->len = 0;
  543. xSemaphoreTake(uvc->frame_list_mutex, portMAX_DELAY);
  544. vListInsertEnd(&uvc->frame_free_list, &frame->entry);
  545. xSemaphoreGive(uvc->frame_list_mutex);
  546. frame = NULL;
  547. }
  548. xQueueSend(uvc->jpeg_frame_queue, NULL, 0);
  549. xQueueSend(uvc->exit_queue, NULL, 0);
  550. printf("%s exit.\n", __func__);
  551. return 0;
  552. }
  553. #else
  554. /* 采用数据拷贝的方式:
  555. * 即对接收到的每一微帧数据都进行拷贝, 然后拼成一帧图片,效率相对较低。
  556. * 图像分辨率过大时,可能会花屏或者闪屏。
  557. */
  558. static int uvc_iso_data_proc(uvc_dev_info_t *uvc)
  559. {
  560. struct usb_device *dev;
  561. uvc_video_frame_t* frame = NULL;
  562. int payload_len = 0, frame_len = 0;
  563. int buf_len = UVC_JPEG_BUF_SIZE;
  564. uint8_t header_len;
  565. uint8_t *dma_buf = NULL;
  566. uint8_t bfh;
  567. int8_t fid = -1;
  568. int ret;
  569. if (!uvc) {
  570. printf("%s, Invalid uvc\n", __func__);
  571. goto exit;
  572. }
  573. dev = uvc->dev;
  574. if (!dev) {
  575. printf("%s, Invalid dev\n", __func__);
  576. goto exit;
  577. }
  578. #ifdef USB_DMA
  579. dma_buf = uvc->dma_buf;
  580. #else
  581. dma_buf = pvPortMalloc(buf_len);
  582. if (dma_buf == NULL) {
  583. printf("%s, malloc dma_buf failed.\n", __func__);
  584. goto exit;
  585. }
  586. #endif
  587. while (uvc->dev_ready) {
  588. if (!frame) {
  589. frame = uvc_get_free_node(uvc);
  590. if (!frame) {
  591. msleep(30);
  592. continue;
  593. }
  594. frame->cur = frame->buf + UVC_HEADER_LEN;
  595. frame->len = 0;
  596. }
  597. ret = usb_iso_msg(dev, uvc->pipe, (void*)dma_buf, buf_len, &payload_len, pdMS_TO_TICKS(100));
  598. if (ret < 0) {
  599. printf("%s send receive cmd failed.\n", __func__);
  600. goto exit;
  601. }
  602. if (payload_len <= 0) {
  603. msleep(1);
  604. continue;
  605. }
  606. header_len = dma_buf[0];
  607. bfh = dma_buf[1];
  608. if ((header_len != UVC_HEADER_LEN) || (payload_len < UVC_HEADER_LEN) || ((bfh & 0xf0) != 0x80)) {
  609. msleep(30);
  610. continue;
  611. }
  612. frame_len = payload_len - UVC_HEADER_LEN;
  613. if (frame->len + frame_len > UVC_JPEG_BUF_SIZE) {
  614. printf("### %s, uvc jpeg buf overflow.\n", __func__);
  615. frame->cur = frame->buf + UVC_HEADER_LEN;
  616. frame->len = 0;
  617. if ((bfh & UVC_STREAM_FID) != fid) {
  618. fid = (bfh & UVC_STREAM_FID);
  619. }
  620. continue;
  621. }
  622. if ((bfh & UVC_STREAM_FID) != fid) {
  623. //printf("### FID\n");
  624. fid = (bfh & UVC_STREAM_FID);
  625. frame->cur = frame->buf + UVC_HEADER_LEN;
  626. frame->len = 0;
  627. }
  628. if (frame_len > 0) {
  629. memcpy(frame->cur, dma_buf+UVC_HEADER_LEN, frame_len);
  630. frame->cur += frame_len;
  631. frame->len += frame_len;
  632. }
  633. if (bfh & UVC_STREAM_EOF) {
  634. //printf("### EOF\n");
  635. xSemaphoreTake(uvc->frame_list_mutex, portMAX_DELAY);
  636. if ((frame->buf[12] == 0xff) && (frame->buf[13] == 0xd8) &&
  637. (frame->buf[frame->len+10] == 0xff) && (frame->buf[frame->len+11] == 0xd9)) {
  638. CP15_clean_dcache_for_dma((uint32_t)frame->buf, (uint32_t)frame->buf + frame->len);
  639. vListInsertEnd(&uvc->frame_ready_list, &frame->entry);
  640. xSemaphoreGive(uvc->frame_list_mutex);
  641. xQueueSend(uvc->jpeg_frame_queue, NULL, 0);
  642. } else {
  643. vListInsertEnd(&uvc->frame_free_list, &frame->entry);
  644. xSemaphoreGive(uvc->frame_list_mutex);
  645. printf("drop one frame\n");
  646. }
  647. frame = NULL;
  648. }
  649. #if 0 //free cpu.
  650. if (frame_len == 0) {
  651. msleep(1);
  652. }
  653. #endif
  654. }
  655. exit:
  656. if (frame) {
  657. frame->cur = frame->buf;
  658. frame->len = 0;
  659. xSemaphoreTake(uvc->frame_list_mutex, portMAX_DELAY);
  660. vListInsertEnd(&uvc->frame_free_list, &frame->entry);
  661. xSemaphoreGive(uvc->frame_list_mutex);
  662. frame = NULL;
  663. }
  664. xQueueSend(uvc->jpeg_frame_queue, NULL, 0);
  665. xQueueSend(uvc->exit_queue, NULL, 0);
  666. #ifndef USB_DMA
  667. if (dma_buf)
  668. vPortFree(dma_buf);
  669. #endif
  670. printf("%s exit.\n", __func__);
  671. return 0;
  672. }
  673. #endif
  674. static int uvc_bulk_msg(struct usb_device *dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout)
  675. {
  676. int err;
  677. #if 1
  678. if (len < 0)
  679. return -1;
  680. dev->status = USB_ST_NOT_PROC; /*not yet processed */
  681. err = submit_bulk_msg(dev, pipe, data, len, actual_length, timeout);
  682. if (err < 0)
  683. return err;
  684. #else
  685. int transfer_len = 0, total_len = 0, act_len = 0;
  686. char *pdata = data;
  687. #if 0
  688. #define BULK_BUF_LEN 4096
  689. ALLOC_CACHE_ALIGN_BUFFER(char, dma_buf, BULK_BUF_LEN);
  690. #else
  691. #define BULK_BUF_LEN 16384
  692. static char *dma_buf = NULL;
  693. if (!dma_buf) {
  694. dma_buf = pvPortMalloc(BULK_BUF_LEN);
  695. }
  696. #endif
  697. if (len < 0)
  698. return -1;
  699. while (len > 0) {
  700. dev->status = USB_ST_NOT_PROC; /*not yet processed */
  701. if (len < BULK_BUF_LEN)
  702. transfer_len = len;
  703. else
  704. transfer_len = BULK_BUF_LEN;
  705. // if (0 == gconnect_flag && dev->parent != NULL) {
  706. // dev->status = -1;
  707. // break;
  708. // }
  709. err = submit_bulk_msg(dev, pipe, dma_buf, transfer_len, &act_len, USB_CNTL_TIMEOUT * 5);
  710. if (err < 0)
  711. break;
  712. memcpy(pdata, dma_buf, act_len);
  713. total_len += act_len;
  714. pdata += act_len;
  715. len -= act_len;
  716. if (act_len != transfer_len) {
  717. break;
  718. }
  719. }
  720. *actual_length = total_len;
  721. #endif
  722. if (dev->status)
  723. return -1;
  724. return 0;
  725. }
  726. static int uvc_bulk_data_proc(uvc_dev_info_t *uvc)
  727. {
  728. #define JPGDEC_AFTER_EOF
  729. struct usb_device *dev;
  730. uvc_video_frame_t *frame = NULL;
  731. int payload_len = 0, frame_len = 0;
  732. const int buf_len = UVC_JPEG_BUF_SIZE;
  733. uint8_t header_backup_buf[12] = {0};
  734. uint8_t header_len;
  735. uint8_t bfh;
  736. uint8_t fid;
  737. int ret;
  738. if (!uvc) {
  739. printf("%s, Invalid uvc\n", __func__);
  740. goto exit;
  741. }
  742. dev = uvc->dev;
  743. if (!dev) {
  744. printf("%s, Invalid dev\n", __func__);
  745. goto exit;
  746. }
  747. while (uvc->dev_ready) {
  748. if (!uvc->uvc_start) {
  749. msleep(100);
  750. continue;
  751. }
  752. if (!frame) {
  753. frame = uvc_get_free_node(uvc);
  754. if (!frame) {
  755. msleep(30);
  756. continue;
  757. }
  758. frame->cur = frame->buf;
  759. frame->len = 0;
  760. }
  761. payload_len = 0;
  762. #ifdef USB_DMA
  763. uint8_t *align_buffer = frame->cur;
  764. if ((unsigned int)frame->cur & 3) {
  765. if (uvc->dma_buf) {
  766. align_buffer = (uint8_t *)UVC_ALIGN_4((unsigned int)uvc->dma_buf);
  767. }
  768. }
  769. ret = uvc_bulk_msg(dev, uvc->pipe, (void*)align_buffer, buf_len, &payload_len, pdMS_TO_TICKS(100));
  770. if (((unsigned int)frame->cur & 3) && (payload_len > 0)) {
  771. memcpy(frame->cur, align_buffer, payload_len);
  772. }
  773. #else
  774. ret = uvc_bulk_msg(dev, uvc->pipe, (void*)frame->cur, buf_len, &payload_len, pdMS_TO_TICKS(100));
  775. #endif
  776. if (ret < 0) {
  777. printf("%s send receive cmd failed.\n", __func__);
  778. goto exit;
  779. }
  780. if (payload_len <= 0) {
  781. //msleep(30);
  782. continue;
  783. }
  784. header_len = frame->cur[0];
  785. bfh = frame->cur[1];
  786. if ((header_len != UVC_HEADER_LEN) || (payload_len < header_len)) {
  787. continue;
  788. }
  789. if ((bfh & UVC_STREAM_FID) != fid) {
  790. fid = (bfh & UVC_STREAM_FID);
  791. //printf("### FID: 0x%.2x, 0x%.2x\n", frame->cur[12], frame->cur[13]);
  792. #if 1
  793. if (frame->cur != frame->buf) {
  794. printf("### uvc lost EOF, drop frame\n");
  795. memcpy(frame->buf, frame->cur, payload_len);
  796. frame->cur = frame->buf;
  797. frame->len = 0;
  798. }
  799. #endif
  800. }
  801. frame_len = payload_len - header_len;
  802. if (frame_len > 0) {
  803. if (frame->len + frame_len > UVC_JPEG_BUF_SIZE) {
  804. printf("### %s, uvc jpeg buf overflow.\n", __func__);
  805. frame->cur = frame->buf;
  806. frame->len = 0;
  807. continue;
  808. }
  809. if (frame->cur != frame->buf)
  810. memcpy(frame->cur, header_backup_buf, UVC_HEADER_LEN);
  811. frame->cur += frame_len;
  812. frame->len += frame_len;
  813. memcpy(header_backup_buf, frame->cur, UVC_HEADER_LEN);
  814. } else {
  815. if (frame->cur != frame->buf)
  816. memcpy(frame->cur, header_backup_buf, UVC_HEADER_LEN);
  817. }
  818. if (bfh & UVC_STREAM_EOF) {
  819. //printf("### EOF\n");
  820. #ifdef JPGDEC_AFTER_EOF
  821. if ((frame->buf[12] == 0xff) && (frame->buf[13] == 0xd8) &&
  822. (frame->buf[frame->len+10] == 0xff) && (frame->buf[frame->len+11] == 0xd9)) {
  823. if (uvc->uvc_start) {
  824. CP15_clean_dcache_for_dma((uint32_t)frame->buf, (uint32_t)frame->buf + frame->len + UVC_HEADER_LEN);
  825. uvc_jpeg_decode_and_display(uvc, frame);
  826. }
  827. } else {
  828. printf("### %s, uvc lost FID or EOF, drop frame\n", __func__);
  829. }
  830. frame->cur = frame->buf;
  831. frame->len = 0;
  832. #else
  833. xSemaphoreTake(uvc->frame_list_mutex, portMAX_DELAY);
  834. if ((frame->buf[12] == 0xff) && (frame->buf[13] == 0xd8) &&
  835. (frame->buf[frame->len+10] == 0xff) && (frame->buf[frame->len+11] == 0xd9)) {
  836. CP15_clean_dcache_for_dma((uint32_t)frame->buf, (uint32_t)frame->buf + frame->len + UVC_HEADER_LEN);
  837. vListInsertEnd(&uvc->frame_ready_list, &frame->entry);
  838. xQueueSend(uvc->jpeg_frame_queue, NULL, 0);
  839. } else {
  840. printf("### %s, uvc lost FID, drop frame\n", __func__);
  841. vListInsertEnd(&uvc->frame_free_list, &frame->entry);
  842. }
  843. xSemaphoreGive(uvc->frame_list_mutex);
  844. frame = NULL;
  845. msleep(20);
  846. #endif
  847. }
  848. }
  849. exit:
  850. if (frame) {
  851. frame->cur = frame->buf;
  852. frame->len = 0;
  853. xSemaphoreTake(uvc->frame_list_mutex, portMAX_DELAY);
  854. vListInsertEnd(&uvc->frame_free_list, &frame->entry);
  855. xSemaphoreGive(uvc->frame_list_mutex);
  856. frame = NULL;
  857. }
  858. xQueueSend(uvc->jpeg_frame_queue, NULL, 0);
  859. xQueueSend(uvc->exit_queue, NULL, 0);
  860. printf("%s exit.\n", __func__);
  861. #undef JPGDEC_AFTER_EOF
  862. return 0;
  863. }
  864. static void uvc_data_receive_task(void *parameters)
  865. {
  866. uvc_dev_info_t *uvc = (uvc_dev_info_t *)parameters;
  867. if (!uvc) {
  868. printf("%s, Invalid uvc\n", __func__);
  869. goto exit;
  870. }
  871. if (!uvc->dev) {
  872. printf("%s, Invalid dev\n", __func__);
  873. goto exit;
  874. }
  875. xSemaphoreTake(uvc->frame_list_mutex, portMAX_DELAY);
  876. uvc_frame_list_reset(uvc);
  877. xSemaphoreGive(uvc->frame_list_mutex);
  878. xQueueReset(uvc->jpeg_frame_queue);
  879. #ifdef UVC_TEST
  880. uvc_start();
  881. #endif
  882. switch (uvc->pVideoEndpoint.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
  883. case USB_ENDPOINT_XFER_ISOC:
  884. uvc_iso_data_proc(uvc);
  885. break;
  886. case USB_ENDPOINT_XFER_BULK:
  887. uvc_bulk_data_proc(uvc);
  888. break;
  889. case USB_ENDPOINT_XFER_INT:
  890. break;
  891. default:
  892. break;
  893. }
  894. #ifdef UVC_TEST
  895. uvc_stop();
  896. #endif
  897. exit:
  898. vTaskDelete(NULL);
  899. }
  900. static int uvc_jpeg_decode_and_display(uvc_dev_info_t *uvc, uvc_video_frame_t* frame)
  901. {
  902. JpegHeaderInfo jpginfo = {0};
  903. uint32_t yaddr, uvaddr, vaddr, dstaddr;
  904. int format;
  905. int ret = -1;
  906. if (xVideoDisplayBufTake(pdMS_TO_TICKS(10)) == pdPASS) {
  907. if (!uvc->mfc_handle)
  908. uvc->mfc_handle = mfc_init(RAW_STRM_TYPE_JPEG);
  909. if (!uvc->mfc_handle) {
  910. printf("%s, mfc_init failed.\n", __func__);
  911. goto done;
  912. }
  913. jpginfo.handle = uvc->mfc_handle;
  914. jpginfo.jpg_addr = (uint32_t)frame->buf + UVC_HEADER_LEN;
  915. jpginfo.jpg_size = frame->len;
  916. jpginfo.dec_addry = (uint32_t)uvc->yuv_buf;
  917. jpginfo.dec_size = UVC_YUV_BUF_SIZE;
  918. ret = mfc_jpegdec(&jpginfo);
  919. if (ret < 0) {
  920. printf("%s, jpgdec failed.\n", __func__);
  921. } else {
  922. yaddr = jpginfo.dec_addry;
  923. uvaddr = jpginfo.dec_addru;
  924. vaddr = jpginfo.dec_addrv;
  925. if (jpginfo.dec_format == JPEGDEC_YCbCr420_SEMIPLANAR) {
  926. format = PXP_S0_FORMAT_YUV2P420;
  927. } else if (jpginfo.dec_format == JPEGDEC_YCbCr422_SEMIPLANAR) {
  928. format = PXP_S0_FORMAT_YUV2P422;
  929. } else {
  930. printf("%s Invalid yuv format.\n", __func__);
  931. ret = -1;
  932. goto done;
  933. }
  934. if (uvc->uvc_start) {
  935. dstaddr = ulVideoDisplayBufGet();
  936. ret = pxp_scaler_rotate(yaddr, uvaddr, vaddr, format, jpginfo.dec_width, jpginfo.dec_height,
  937. dstaddr, 0, PXP_OUT_FORMAT_RGB565, LCD_WIDTH, LCD_HEIGHT, 0);
  938. if (ret) {
  939. goto done;
  940. }
  941. LcdOsdInfo info = {0};
  942. info.x = uvc->disp_area.x;
  943. info.y = uvc->disp_area.y;
  944. info.width = uvc->disp_area.w;
  945. info.height = uvc->disp_area.h;
  946. info.format = LCD_OSD_FORAMT_RGB565;
  947. info.yaddr = dstaddr;
  948. if (!ark_lcd_get_osd_info_atomic_isactive(LCD_VIDEO_LAYER)) {
  949. ark_lcd_wait_for_vsync();
  950. }
  951. ark_lcd_set_osd_info_atomic(LCD_VIDEO_LAYER, &info);
  952. ark_lcd_osd_enable(LCD_VIDEO_LAYER, 1);
  953. ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
  954. ark_lcd_osd_enable(LCD_UI_LAYER, 0);
  955. ark_lcd_set_osd_sync(LCD_UI_LAYER);
  956. vVideoDisplayBufRender(dstaddr);
  957. }
  958. ret = 0;
  959. }
  960. done:
  961. vVideoDisplayBufGive();
  962. }
  963. return ret;
  964. }
  965. static void uvc_jpeg_decode_task(void *parameters)
  966. {
  967. uvc_dev_info_t *uvc = (uvc_dev_info_t *)parameters;
  968. uvc_video_frame_t* frame;
  969. ListItem_t* item;
  970. if (!uvc) {
  971. printf("%s, Invalid uvc\n", __func__);
  972. vTaskDelete(NULL);
  973. return;
  974. }
  975. while (uvc->dec_task_start) {
  976. xQueueReceive(uvc->jpeg_frame_queue, NULL, portMAX_DELAY);
  977. if (uvc->dec_task_start == 0) {
  978. break;
  979. }
  980. xSemaphoreTake(uvc->frame_list_mutex, portMAX_DELAY);
  981. if (listLIST_IS_EMPTY(&uvc->frame_ready_list)) {
  982. xSemaphoreGive(uvc->frame_list_mutex);
  983. continue;
  984. }
  985. item = listGET_HEAD_ENTRY(&uvc->frame_ready_list);
  986. uxListRemove(item);
  987. frame = listGET_LIST_ITEM_OWNER(item);
  988. xSemaphoreGive(uvc->frame_list_mutex);
  989. if (uvc->uvc_start) {
  990. uvc_jpeg_decode_and_display(uvc, frame);
  991. frame->buf[12] = frame->buf[13] = 0;
  992. frame->buf[frame->len-1] = frame->buf[frame->len-2] = 0;
  993. }
  994. xSemaphoreTake(uvc->frame_list_mutex, portMAX_DELAY);
  995. frame->cur = frame->buf;
  996. frame->len = 0;
  997. vListInsertEnd(&uvc->frame_free_list, &frame->entry);
  998. xSemaphoreGive(uvc->frame_list_mutex);
  999. }
  1000. if (uvc->mfc_handle) {
  1001. mfc_uninit(uvc->mfc_handle);
  1002. uvc->mfc_handle = NULL;
  1003. }
  1004. printf("%s exit.\n", __func__);
  1005. vTaskDelete(NULL);
  1006. }
  1007. static void uvc_frame_list_reset(uvc_dev_info_t *uvc)
  1008. {
  1009. uvc_video_frame_t* frame = NULL;
  1010. ListItem_t *pxListItem;
  1011. list_for_each_entry(pxListItem, frame, &uvc->frame_ready_list) {
  1012. ListItem_t * item = listGET_HEAD_ENTRY(&uvc->frame_ready_list);
  1013. uxListRemove(item);
  1014. frame->cur = frame->buf;
  1015. frame->len = 0;
  1016. vListInsertEnd(&uvc->frame_free_list, &frame->entry);
  1017. }
  1018. list_for_each_entry(pxListItem, frame, &uvc->frame_free_list) {
  1019. frame->cur = frame->buf;
  1020. frame->len = 0;
  1021. }
  1022. }
  1023. static int uvc_frame_buf_init(uvc_dev_info_t *uvc)
  1024. {
  1025. static uvc_video_frame_t jpeg_fifos[UVC_JPEG_FIFO_COUNT] = {0};
  1026. static int g_uvc_init_flag = 0;
  1027. uvc_video_frame_t *buffer;
  1028. int i;
  1029. if (!uvc) {
  1030. printf("%s, Invalid uvc\n", __func__);
  1031. return 0;
  1032. }
  1033. if (g_uvc_init_flag) {
  1034. return 0;
  1035. }
  1036. #ifdef USB_DMA
  1037. uvc->dma_buf = pvPortMalloc(UVC_JPEG_BUF_SIZE);
  1038. if (uvc->dma_buf == NULL) {
  1039. printf("%s, pvPortMalloc jpeg buf failed.\n", __func__);
  1040. }
  1041. #endif
  1042. uvc->yuv_buf = pvPortMalloc(UVC_YUV_BUF_SIZE);
  1043. if (!uvc->yuv_buf) {
  1044. printf("%s, pvPortMalloc jpeg yuv buf failed\n", __func__);
  1045. goto exit;
  1046. }
  1047. memset((void *)uvc->yuv_buf, 0, UVC_YUV_BUF_SIZE);
  1048. uvc->jpeg_buf = pvPortMalloc(UVC_JPEG_FIFO_COUNT * UVC_JPEG_BUF_SIZE);
  1049. if (uvc->jpeg_buf == NULL) {
  1050. printf("%s, pvPortMalloc jpeg buf failed.\n", __func__);
  1051. goto exit;
  1052. }
  1053. memset((void *)uvc->jpeg_buf, 0, UVC_JPEG_FIFO_COUNT * UVC_JPEG_BUF_SIZE);
  1054. vListInitialise(&uvc->frame_free_list);
  1055. vListInitialise(&uvc->frame_ready_list);
  1056. buffer = (uvc_video_frame_t *)jpeg_fifos;
  1057. for (i = 0; i < UVC_JPEG_FIFO_COUNT; i++) {
  1058. buffer->buf = (uint8_t *)UVC_ALIGN_4(((unsigned int)uvc->jpeg_buf + i * UVC_JPEG_BUF_SIZE));
  1059. buffer->cur = buffer->buf;
  1060. buffer->len = 0;
  1061. buffer->frame_id = i;
  1062. vListInitialiseItem(&buffer->entry);
  1063. vListInsertEnd(&uvc->frame_free_list, &buffer->entry);
  1064. listSET_LIST_ITEM_OWNER(&buffer->entry, buffer);
  1065. buffer++;
  1066. }
  1067. g_uvc_init_flag = 0;
  1068. return 0;
  1069. exit:
  1070. #ifdef USB_DMA
  1071. if (uvc->dma_buf) {
  1072. vPortFree(uvc->dma_buf);
  1073. uvc->dma_buf = NULL;
  1074. }
  1075. #endif
  1076. if (uvc->yuv_buf) {
  1077. vPortFree(uvc->yuv_buf);
  1078. uvc->yuv_buf = NULL;
  1079. }
  1080. if (uvc->jpeg_buf) {
  1081. vPortFree(uvc->jpeg_buf);
  1082. uvc->jpeg_buf = NULL;
  1083. }
  1084. return -1;
  1085. }
  1086. static int usb_uvc_probe(struct usb_device *dev)
  1087. {
  1088. uvc_dev_info_t *uvc = g_uvc_info;
  1089. int ret;
  1090. if (!uvc) {
  1091. printf("%s, Invalid uvc\n", __func__);
  1092. return 0;
  1093. }
  1094. uvc->dev = dev;
  1095. ret = uvc_camera_init(uvc);
  1096. if (ret < 0) {
  1097. return 0;
  1098. }
  1099. uvc->dev_ready = 1;
  1100. xTaskCreate(uvc_data_receive_task, "uvc_data_receive_task", configMINIMAL_STACK_SIZE * 4,
  1101. (void*)uvc, UVC_DATA_RECEIVE_TASK_PRIORITY, &uvc->rcv_task_handle);
  1102. return 1;
  1103. }
  1104. int uvc_set_disp_pos(int x, int y)
  1105. {
  1106. uvc_dev_info_t *uvc = g_uvc_info;
  1107. if (uvc) {
  1108. if ((x < LCD_WIDTH) && (y < LCD_HEIGHT)) {
  1109. uvc->disp_area.x = x;
  1110. uvc->disp_area.y = y;
  1111. } else {
  1112. printf("%s, Invalid x:%d or y:%d\n", __func__, x, y);
  1113. return -1;
  1114. }
  1115. }
  1116. return 0;
  1117. }
  1118. int uvc_set_disp_size(int width, int height)
  1119. {
  1120. uvc_dev_info_t *uvc = g_uvc_info;
  1121. if (uvc) {
  1122. if (((uint32_t)width <= LCD_WIDTH) && ((uint32_t)height <= LCD_HEIGHT)) {
  1123. uvc->disp_area.w = width;
  1124. uvc->disp_area.h = height;
  1125. //uvc->disp_area.w -= width;
  1126. //uvc->disp_area.h -= height;
  1127. } else {
  1128. printf("%s, Invalid width:%d or height:%d\n", __func__, width, height);
  1129. return -1;
  1130. }
  1131. }
  1132. return 0;
  1133. }
  1134. int uvc_start(void)
  1135. {
  1136. uvc_dev_info_t *uvc = g_uvc_info;
  1137. if (uvc) {
  1138. uvc->uvc_start = 1;
  1139. return 0;
  1140. }
  1141. return -1;
  1142. }
  1143. int uvc_stop(void)
  1144. {
  1145. uvc_dev_info_t *uvc = g_uvc_info;
  1146. int ret = -1;
  1147. if (uvc) {
  1148. uvc->uvc_start = 0;
  1149. ret = 0;
  1150. }
  1151. //test and wait for display done.
  1152. if (xVideoDisplayBufTake(pdMS_TO_TICKS(1000)) == pdPASS) {
  1153. vVideoDisplayBufGive();
  1154. }
  1155. //osd layer switch.
  1156. ark_lcd_osd_enable(LCD_VIDEO_LAYER, 0);
  1157. ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
  1158. ark_lcd_osd_enable(LCD_UI_LAYER, 1);
  1159. ark_lcd_set_osd_sync(LCD_UI_LAYER);
  1160. return ret;
  1161. }
  1162. int usb_uvc_scan(void)
  1163. {
  1164. struct usb_device *dev;
  1165. int ret = 0;
  1166. int i;
  1167. for (i = 0; i < USB_MAX_DEVICE; i++) {
  1168. dev = usb_get_dev_index(i);
  1169. if (!dev) {
  1170. continue;
  1171. }
  1172. if (usb_uvc_probe(dev)) {
  1173. ret = 1;
  1174. break;
  1175. }
  1176. }
  1177. return ret;
  1178. }
  1179. void usb_uvc_disconnect(void)
  1180. {
  1181. uvc_dev_info_t *uvc = g_uvc_info;
  1182. if (!uvc) {
  1183. printf("%s, Invalid uvc\n", __func__);
  1184. return;
  1185. }
  1186. printf("%s exit +++.\n", __func__);
  1187. if (uvc->dev_ready != 0) {
  1188. uvc->dev_ready = 0;
  1189. xQueueReceive(uvc->exit_queue, NULL, portMAX_DELAY);
  1190. }
  1191. xQueueReset(uvc->exit_queue);
  1192. printf("%s exit ---.\n", __func__);
  1193. }
  1194. int usb_uvc_init(void)
  1195. {
  1196. uvc_dev_info_t *uvc;
  1197. int ret;
  1198. uvc = pvPortMalloc(sizeof(uvc_dev_info_t));
  1199. if (!uvc) {
  1200. printf("%s uvc pvPortMalloc failed\n", __func__);
  1201. return -1;
  1202. }
  1203. memset(uvc, 0, sizeof(uvc_dev_info_t));
  1204. ret = uvc_frame_buf_init(uvc);
  1205. if (ret < 0) {
  1206. printf("%s, uvc_frame_buf_init failed, uvc exit.\n", __func__);
  1207. vPortFree(uvc);
  1208. return -1;
  1209. }
  1210. uvc->frame_list_mutex = xSemaphoreCreateMutex();
  1211. uvc->jpeg_frame_queue = xQueueCreate(UVC_JPEG_FIFO_COUNT, 0);
  1212. uvc->exit_queue = xQueueCreate(1, 0);
  1213. uvc->dec_task_start = 1;
  1214. uvc->disp_area.x = 0;
  1215. uvc->disp_area.y = 0;
  1216. uvc->disp_area.w = LCD_WIDTH;
  1217. uvc->disp_area.h = LCD_HEIGHT;
  1218. g_uvc_info = uvc;
  1219. ret = xTaskCreate(uvc_jpeg_decode_task, "uvc_jpeg_decode_task", configMINIMAL_STACK_SIZE,
  1220. (void *)uvc, UVC_JPEG_DECODE_TASK_PRIORITY, &uvc->dec_task_handle);
  1221. return ret;
  1222. }
  1223. #endif