uvc_capture.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /**
  2. * RT-Thread RuiChing
  3. *
  4. * COPYRIGHT (C) 2024-2025 Shanghai Real-Thread Electronic Technology Co., Ltd.
  5. * All rights reserved.
  6. *
  7. * The license and distribution terms for this file may be
  8. * found in the file LICENSE in this distribution.
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <unistd.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include <fcntl.h>
  16. #include <stdio.h>
  17. #define RT_UVC_CTRL_SET_CALLBACK 0x0 /**< set callback control command */
  18. #define RT_UVC_CTRL_START_STREAM 0x1 /**< set start stream control command */
  19. #define RT_UVC_CTRL_STOP_STREAM 0x2 /**< set stop stream control command */
  20. struct usbh_videoframe {
  21. uint8_t *frame_buf;
  22. uint32_t frame_bufsize;
  23. uint32_t frame_format;
  24. uint32_t frame_size;
  25. };
  26. typedef void (*frame_callback_t)(struct usbh_videoframe *frame);
  27. char file_path[50];
  28. static struct rt_semaphore sem_lock;
  29. static bool flag = false;
  30. // 定义回调函数
  31. frame_callback_t uvc_function(struct usbh_videoframe *frame) {
  32. int fd = -1;
  33. if (frame->frame_format == 0 && flag) {
  34. flag = false;
  35. //yuv
  36. char *file = "output.yuv";
  37. strncat( file_path, file, sizeof(file_path) - strlen(file_path) -1 );
  38. fd = open(file_path, O_RDWR | O_CREAT);
  39. rt_kprintf("YUV data saved to %s\r\n",file_path);
  40. } else if (frame->frame_format == 1 && flag){
  41. flag = false;
  42. //mjpeg
  43. char* file = "output.jpg";
  44. strncat( file_path, file, sizeof(file_path) - strlen(file_path) -1 );
  45. fd = open(file_path, O_RDWR | O_CREAT);
  46. rt_kprintf("MJPEG data saved to %s\r\n",file_path);
  47. }
  48. if (!fd){
  49. rt_kprintf("failed to open file %s\r\n",file_path);
  50. return RT_NULL;
  51. }
  52. rt_sem_release(&sem_lock);
  53. rt_kprintf("frame buf:%p,frame len:%d\r\n", frame->frame_buf, frame->frame_size);
  54. write(fd, frame->frame_buf, frame->frame_size);
  55. close(fd);
  56. }
  57. static int uvc_capture(int argc, char *argv[])
  58. {
  59. uint8_t type;
  60. struct rt_device *device = rt_device_find("uvc");
  61. if (!device)
  62. {
  63. rt_kprintf("Can't find device uvc\n");
  64. return (-RT_ERROR);
  65. }
  66. if (argc < 3) {
  67. rt_kprintf("please input correct command: usbh_uvc_start type to file_path\r\n");
  68. rt_kprintf("type 0:yuyv, type 1:mjpeg\r\n");
  69. return (-RT_ERROR);
  70. }
  71. type = atoi(argv[1]);
  72. if (type == 0) {
  73. rt_kprintf("uvc capture yuyv type picture\r\n");
  74. } else if(type == 1) {
  75. rt_kprintf("uvc capture mjpeg type picture\r\n");
  76. } else {
  77. rt_kprintf("uvc capture type is unsupport!\r\n");
  78. return (-RT_ERROR);
  79. }
  80. if (access(argv[2], F_OK) == 0) { // F_OK检查文件路径是否存在
  81. rt_kprintf("file path exist\r\n");
  82. } else {
  83. rt_kprintf("file path does not exist\r\n");
  84. return (-RT_ERROR); // 文件路径无效
  85. }
  86. snprintf(file_path, sizeof(file_path), "%s", argv[2]);
  87. if ((strcmp (file_path , "/data/") == 0) || (strcmp (file_path , "/tmp/") == 0)) {
  88. rt_kprintf("file path exist\r\n");
  89. }
  90. else if ((strcmp (file_path , "/data") == 0) || (strcmp (file_path , "/tmp") == 0)) {
  91. strncat( file_path, "/", sizeof(file_path) - strlen(file_path) -1 );
  92. }
  93. else {
  94. rt_kprintf("file path does not exist\r\n");
  95. rt_kprintf("File paths are only allowed to be created in the /tmp/ or /data/ \r\n");
  96. return (-RT_ERROR); // 文件路径不存在
  97. }
  98. flag = true;
  99. frame_callback_t uvc_callback = uvc_function; // 用户定义的UVC函数
  100. rt_sem_init(&sem_lock, "uvc_lock", 0, RT_IPC_FLAG_PRIO);
  101. rt_device_init(device);
  102. rt_device_open(device, RT_DEVICE_FLAG_RDWR);
  103. rt_device_control(device, RT_UVC_CTRL_SET_CALLBACK, (void *)uvc_callback);
  104. rt_device_control(device, RT_UVC_CTRL_START_STREAM, &type);
  105. rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
  106. rt_device_control(device, RT_UVC_CTRL_STOP_STREAM, NULL);
  107. rt_sem_detach(&sem_lock);
  108. return RT_EOK;
  109. }
  110. MSH_CMD_EXPORT(uvc_capture, uvc capture example);