采集YUYV422/ jpeg 数据
jpeg是编码压缩后的格式,在获取buf中的数据时,一定要是实际的大小:
v4l2_buffer --> buf.bytesused
1 #include <errno.h> 2 #include <fcntl.h> 3 #include <linux/videodev2.h> 4 #include <pthread.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <sys/ioctl.h> 9 #include <sys/mman.h> 10 #include <sys/prctl.h> 11 #include <sys/stat.h> 12 #include <sys/types.h> 13 #include <unistd.h> 14 15 16 #define VIDEO_NAME "/dev/video0" 17 #define TEST_STREAM_SAVE_PATH "/customer/nfs" 18 #define BUFFER_NUM (4) 19 #define V4L2_BUF_TYPE (V4L2_BUF_TYPE_VIDEO_CAPTURE) 20 #define V4L2_PIX_FORMAT (V4L2_PIX_FMT_MJPEG) //or V4L2_PIX_FMT_YUYV 21 static int g_video_fd; 22 23 typedef struct { 24 void *start; 25 int length; 26 } BUFTYPE; 27 28 BUFTYPE *usr_buf; 29 static unsigned int n_buffer = 0; 30 31 static int camera_Open(void) { 32 struct v4l2_input inp; 33 int i = 0; 34 int ret = -1; 35 g_video_fd = open(VIDEO_NAME, O_RDWR | O_NONBLOCK, 0); 36 if (g_video_fd < 0) { 37 printf("%s open failed ! \n", VIDEO_NAME); 38 return ret; 39 }; 40 41 for (i = 0; i < 16; i++) { 42 inp.index = i; 43 if (-1 == ioctl(g_video_fd, VIDIOC_S_INPUT, &inp)) { 44 printf("VIDIOC_S_INPUT failed %d !\n", i); 45 } else { 46 printf("VIDIOC_S_INPUT success %d !\n", i); 47 ret = 0; 48 break; 49 } 50 } 51 52 return ret; 53 } 54 55 // close 56 void camera_Close(int video_fd) { 57 unsigned int i; 58 59 for (i = 0; i < n_buffer; i++) { 60 if (-1 == munmap(usr_buf[i].start, usr_buf[i].length)) { 61 exit(-1); 62 } 63 } 64 65 if (NULL != usr_buf) free(usr_buf); 66 67 if (video_fd > 0) close(video_fd); 68 69 return; 70 } 71 72 /*set video capture ways(mmap)*/ 73 int init_mmap(int fd) { 74 /*to request frame cache, contain requested counts*/ 75 struct v4l2_requestbuffers reqbufs; 76 77 memset(&reqbufs, 0, sizeof(reqbufs)); 78 reqbufs.count = BUFFER_NUM; /*the number of buffer*/ 79 reqbufs.type = V4L2_BUF_TYPE; 80 reqbufs.memory = V4L2_MEMORY_MMAP; 81 82 if (-1 == ioctl(fd, VIDIOC_REQBUFS, &reqbufs)) { 83 perror("Fail to ioctl 'VIDIOC_REQBUFS'"); 84 return -1; 85 } 86 87 n_buffer = reqbufs.count; 88 printf("n_buffer = %d\n", n_buffer); 89 usr_buf = calloc(reqbufs.count, sizeof(BUFTYPE)); 90 if (usr_buf == NULL) { 91 printf("Out of memory\n"); 92 return -1; 93 } 94 95 /*map kernel cache to user process*/ 96 for (n_buffer = 0; n_buffer < reqbufs.count; n_buffer++) { 97 // stand for a frame 98 struct v4l2_buffer buf; 99 memset(&buf, 0, sizeof(buf)); 100 buf.type = V4L2_BUF_TYPE; 101 buf.memory = V4L2_MEMORY_MMAP; 102 buf.index = n_buffer; 103 104 /*check the information of the kernel cache requested*/ 105 if (-1 == ioctl(fd, VIDIOC_QUERYBUF, &buf)) { 106 perror("Fail to ioctl : VIDIOC_QUERYBUF"); 107 return -1; 108 } 109 printf("buf length = %d",buf.length); 110 111 usr_buf[n_buffer].length = buf.length; 112 usr_buf[n_buffer].start = 113 (char *)mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, 114 fd, buf.m.offset); 115 116 if (MAP_FAILED == usr_buf[n_buffer].start) { 117 perror("Fail to mmap"); 118 return -1; 119 } 120 } 121 122 return 0; 123 } 124 125 static int set_Format(int video_fd) { 126 struct v4l2_format tv_fmt; /* frame format */ 127 128 /*set the form of camera capture data*/ 129 tv_fmt.type = V4L2_BUF_TYPE; /*v4l2_buf_typea,camera must use 130 V4L2_BUF_TYPE_VIDEO_CAPTURE*/ 131 tv_fmt.fmt.pix.width = 1280; 132 tv_fmt.fmt.pix.height = 720; 133 tv_fmt.fmt.pix.pixelformat = V4L2_PIX_FORMAT; 134 tv_fmt.fmt.pix.field = V4L2_FIELD_NONE; /*V4L2_FIELD_NONE*/ 135 if (ioctl(video_fd, VIDIOC_S_FMT, &tv_fmt) < 0) { 136 fprintf(stderr, "VIDIOC_S_FMT set err\n"); 137 return -1; 138 } 139 return 0; 140 } 141 static int init_Camera(int video_fd) { 142 struct v4l2_capability cap; /* decive fuction, such as video input */ 143 struct v4l2_fmtdesc fmtdesc; /* detail control value */ 144 145 int ret = 0; 146 if (video_fd <= 0) return -1; 147 148 /*show all the support format*/ 149 memset(&fmtdesc, 0, sizeof(fmtdesc)); 150 fmtdesc.index = 0; /* the number to check */ 151 fmtdesc.type = V4L2_BUF_TYPE; 152 153 /* check video decive driver capability */ 154 if (ret = ioctl(video_fd, VIDIOC_QUERYCAP, &cap) < 0) { 155 fprintf(stderr, "fail to ioctl VIDEO_QUERYCAP \n"); 156 return -1; 157 } 158 159 /*judge wherher or not to be a video-get device*/ 160 if (!(cap.capabilities & V4L2_BUF_TYPE)) { 161 fprintf(stderr, "The Current device is not a video capture device \n"); 162 return -1; 163 } 164 165 /*judge whether or not to supply the form of video stream*/ 166 if (!(cap.capabilities & V4L2_CAP_STREAMING)) { 167 printf("The Current device does not support streaming i/o\n"); 168 return -1; 169 } 170 171 printf("\ncamera driver name is : %s\n", cap.driver); 172 printf("camera device name is : %s\n", cap.card); 173 printf("camera bus information: %s\n", cap.bus_info); 174 175 /*display the format device support*/ 176 printf("\n"); 177 while (ioctl(video_fd, VIDIOC_ENUM_FMT, &fmtdesc) != -1) { 178 printf("support device %d.%s\n", fmtdesc.index + 1, 179 fmtdesc.description); 180 fmtdesc.index++; 181 } 182 printf("\n"); 183 184 return 0; 185 } 186 187 int start_capture(int fd) { 188 unsigned int i; 189 enum v4l2_buf_type type; 190 191 /*place the kernel cache to a queue*/ 192 for (i = 0; i < n_buffer; i++) { 193 struct v4l2_buffer buf; 194 memset(&buf, 0, sizeof(buf)); 195 buf.type = V4L2_BUF_TYPE; 196 buf.memory = V4L2_MEMORY_MMAP; 197 buf.index = i; 198 199 if (-1 == ioctl(fd, VIDIOC_QBUF, &buf)) { 200 perror("Fail to ioctl 'VIDIOC_QBUF'"); 201 exit(EXIT_FAILURE); 202 } 203 } 204 205 type = V4L2_BUF_TYPE; 206 if (-1 == ioctl(fd, VIDIOC_STREAMON, &type)) { 207 printf("i=%d.\n", i); 208 perror("VIDIOC_STREAMON"); 209 close(fd); 210 exit(EXIT_FAILURE); 211 } 212 213 return 0; 214 } 215 216 int process_image(void *addr, int length) { 217 FILE *fp; 218 static int num = 0; 219 char image_name[64] = {0}; 220 221 sprintf(image_name, TEST_STREAM_SAVE_PATH "/%d.jpeg", num++); 222 if ((fp = fopen(image_name, "w")) == NULL) { 223 perror("Fail to fopen \n"); 224 exit(EXIT_FAILURE); 225 } 226 fwrite(addr, length, 1, fp); 227 usleep(500); 228 fclose(fp); 229 230 return 0; 231 } 232 233 int read_frame(int fd) { 234 struct v4l2_buffer buf; 235 236 memset(&buf, 0, sizeof(buf)); 237 buf.type = V4L2_BUF_TYPE; 238 buf.memory = V4L2_MEMORY_MMAP; 239 240 // put cache from queue 241 if (-1 == ioctl(fd, VIDIOC_DQBUF, &buf)) { 242 perror("Fail to ioctl 'VIDIOC_DQBUF'"); 243 return -1; 244 } 245 if (buf.index >= n_buffer) return -1; 246 // printf("length=%d", usr_buf[buf.index].length); 247 printf("bytesused=%d, buf length=%d", buf.bytesused, buf.length); 248 if(V4L2_PIX_FORMAT == V4L2_PIX_FMT_MJPEG){ 249 usr_buf[buf.index].length = buf.bytesused; 250 } 251 // read process space's data to a file 252 process_image(usr_buf[buf.index].start, usr_buf[buf.index].length); 253 254 if (-1 == ioctl(fd, VIDIOC_QBUF, &buf)) { 255 perror("Fail to ioctl 'VIDIOC_QBUF'"); 256 return -1; 257 } 258 259 return 0; 260 } 261 262 static int stop_Capture(int fd) { 263 enum v4l2_buf_type type; 264 type = V4L2_BUF_TYPE; 265 if (-1 == ioctl(fd, VIDIOC_STREAMOFF, &type)) { 266 perror("Fail to ioctl 'VIDIOC_STREAMOFF' \n"); 267 return -1; 268 } 269 return 0; 270 } 271 272 int mainloop(int fd) { 273 int count = 10; 274 while (count-- > 0) { 275 while (1) { 276 fd_set fds; 277 struct timeval tv; 278 int r; 279 280 FD_ZERO(&fds); 281 FD_SET(fd, &fds); 282 283 /*Timeout*/ 284 tv.tv_sec = 2; 285 tv.tv_usec = 0; 286 r = select(fd + 1, &fds, NULL, NULL, &tv); 287 288 if (-1 == r) { 289 if (EINTR == errno) continue; 290 perror("Fail to select \n"); 291 return -1; 292 } 293 if (0 == r) { 294 fprintf(stderr, "select Timeout \n"); 295 return -1; 296 } 297 298 if (read_frame(fd) == 0) break; 299 } 300 } 301 return 0; 302 } 303 304 int UVC_Init(void) { 305 int s32Ret = 0; 306 307 // 1 open device 308 s32Ret = camera_Open(); 309 if (s32Ret < 0) { 310 printf("HI_PDT_Camera_Open failed ! \n"); 311 return -1; 312 } 313 314 // Check and set device properties set frame 315 s32Ret = init_Camera(g_video_fd); 316 if (s32Ret < 0) { 317 printf("HI_PDT_Camera_Open failed ! \n"); 318 camera_Close(g_video_fd); 319 return -1; 320 } 321 322 set_Format(g_video_fd); 323 324 // Apply for a video buffer 325 init_mmap(g_video_fd); 326 start_capture(g_video_fd); 327 mainloop(g_video_fd); 328 return 0; 329 } 330 331 int UVC_DeInit(void) { 332 stop_Capture(g_video_fd); 333 camera_Close(g_video_fd); 334 return 0; 335 } 336 337 int main() { 338 UVC_Init(); 339 UVC_DeInit(); 340 return 0; 341 }