ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

在V4l2框架下采集UVC摄像头的YUV与JPEG数据

2021-12-23 11:34:09  阅读:308  来源: 互联网

标签:return int JPEG YUV VIDIOC fd video UVC buf


#include <errno.h> #include <fcntl.h> #include <linux/videodev2.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <sys/prctl.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h>

#define VIDEO_NAME "/dev/video0" #define TEST_STREAM_SAVE_PATH "/customer/nfs" #define BUFFER_NUM (4) #define V4L2_BUF_TYPE (V4L2_BUF_TYPE_VIDEO_CAPTURE) static int g_video_fd;
typedef struct { void *start; int length; } BUFTYPE;
BUFTYPE *usr_buf; static unsigned int n_buffer = 0;
static int camera_Open(void) { struct v4l2_input inp; int i = 0; int ret = -1; g_video_fd = open(VIDEO_NAME, O_RDWR | O_NONBLOCK, 0); if (g_video_fd < 0) { printf("%s open failed ! \n", VIDEO_NAME); return ret; };
for (i = 0; i < 16; i++) { inp.index = i; if (-1 == ioctl(g_video_fd, VIDIOC_S_INPUT, &inp)) { printf("VIDIOC_S_INPUT failed %d !\n", i); } else { printf("VIDIOC_S_INPUT success %d !\n", i); ret = 0; break; } }
return ret; }
// close void camera_Close(int video_fd) { unsigned int i;
for (i = 0; i < n_buffer; i++) { if (-1 == munmap(usr_buf[i].start, usr_buf[i].length)) { exit(-1); } }
if (NULL != usr_buf) free(usr_buf);
if (video_fd > 0) close(video_fd);
return; }
/*set video capture ways(mmap)*/ int init_mmap(int fd) { /*to request frame cache, contain requested counts*/ struct v4l2_requestbuffers reqbufs;
memset(&reqbufs, 0, sizeof(reqbufs)); reqbufs.count = BUFFER_NUM; /*the number of buffer*/ reqbufs.type = V4L2_BUF_TYPE; reqbufs.memory = V4L2_MEMORY_MMAP;
if (-1 == ioctl(fd, VIDIOC_REQBUFS, &reqbufs)) { perror("Fail to ioctl 'VIDIOC_REQBUFS'"); return -1; }
n_buffer = reqbufs.count; printf("n_buffer = %d\n", n_buffer); usr_buf = calloc(reqbufs.count, sizeof(BUFTYPE)); if (usr_buf == NULL) { printf("Out of memory\n"); return -1; }
/*map kernel cache to user process*/ for (n_buffer = 0; n_buffer < reqbufs.count; n_buffer++) { // stand for a frame struct v4l2_buffer buf; memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE; buf.memory = V4L2_MEMORY_MMAP; buf.index = n_buffer;
/*check the information of the kernel cache requested*/ if (-1 == ioctl(fd, VIDIOC_QUERYBUF, &buf)) { perror("Fail to ioctl : VIDIOC_QUERYBUF"); return -1; } printf("buf length = %d",buf.length);
usr_buf[n_buffer].length = buf.length; usr_buf[n_buffer].start = (char *)mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
if (MAP_FAILED == usr_buf[n_buffer].start) { perror("Fail to mmap"); return -1; } }
return 0; }
static int set_Format(int video_fd) { struct v4l2_format tv_fmt; /* frame format */
/*set the form of camera capture data*/ tv_fmt.type = V4L2_BUF_TYPE; /*v4l2_buf_typea,camera must use V4L2_BUF_TYPE_VIDEO_CAPTURE*/ tv_fmt.fmt.pix.width = 1280; tv_fmt.fmt.pix.height = 720; tv_fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; tv_fmt.fmt.pix.field = V4L2_FIELD_NONE; /*V4L2_FIELD_NONE*/ if (ioctl(video_fd, VIDIOC_S_FMT, &tv_fmt) < 0) { fprintf(stderr, "VIDIOC_S_FMT set err\n"); return -1; } return 0; } static int init_Camera(int video_fd) { struct v4l2_capability cap; /* decive fuction, such as video input */ struct v4l2_fmtdesc fmtdesc; /* detail control value */
int ret = 0; if (video_fd <= 0) return -1;
/*show all the support format*/ memset(&fmtdesc, 0, sizeof(fmtdesc)); fmtdesc.index = 0; /* the number to check */ fmtdesc.type = V4L2_BUF_TYPE;
/* check video decive driver capability */ if (ret = ioctl(video_fd, VIDIOC_QUERYCAP, &cap) < 0) { fprintf(stderr, "fail to ioctl VIDEO_QUERYCAP \n"); return -1; }
/*judge wherher or not to be a video-get device*/ if (!(cap.capabilities & V4L2_BUF_TYPE)) { fprintf(stderr, "The Current device is not a video capture device \n"); return -1; }
/*judge whether or not to supply the form of video stream*/ if (!(cap.capabilities & V4L2_CAP_STREAMING)) { printf("The Current device does not support streaming i/o\n"); return -1; }
printf("\ncamera driver name is : %s\n", cap.driver); printf("camera device name is : %s\n", cap.card); printf("camera bus information: %s\n", cap.bus_info);
/*display the format device support*/ printf("\n"); while (ioctl(video_fd, VIDIOC_ENUM_FMT, &fmtdesc) != -1) { printf("support device %d.%s\n", fmtdesc.index + 1, fmtdesc.description); fmtdesc.index++; } printf("\n");
return 0; }
int start_capture(int fd) { unsigned int i; enum v4l2_buf_type type;
/*place the kernel cache to a queue*/ for (i = 0; i < n_buffer; i++) { struct v4l2_buffer buf; memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i;
if (-1 == ioctl(fd, VIDIOC_QBUF, &buf)) { perror("Fail to ioctl 'VIDIOC_QBUF'"); exit(EXIT_FAILURE); } }
type = V4L2_BUF_TYPE; if (-1 == ioctl(fd, VIDIOC_STREAMON, &type)) { printf("i=%d.\n", i); perror("VIDIOC_STREAMON"); close(fd); exit(EXIT_FAILURE); }
return 0; }
int process_image(void *addr, int length) { FILE *fp; static int num = 0; char image_name[64] = {0};
sprintf(image_name, TEST_STREAM_SAVE_PATH "/%d.jpeg", num++); if ((fp = fopen(image_name, "w")) == NULL) { perror("Fail to fopen \n"); exit(EXIT_FAILURE); } fwrite(addr, length, 1, fp); usleep(500); fclose(fp);
return 0; }
int read_frame(int fd) { struct v4l2_buffer buf;
memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE; buf.memory = V4L2_MEMORY_MMAP;
// put cache from queue if (-1 == ioctl(fd, VIDIOC_DQBUF, &buf)) { perror("Fail to ioctl 'VIDIOC_DQBUF'"); return -1; } if (buf.index >= n_buffer) return -1; // printf("length=%d", usr_buf[buf.index].length); printf("bytesused=%d", buf.bytesused); usr_buf[buf.index].length = buf.bytesused; // read process space's data to a file process_image(usr_buf[buf.index].start, usr_buf[buf.index].length);
if (-1 == ioctl(fd, VIDIOC_QBUF, &buf)) { perror("Fail to ioctl 'VIDIOC_QBUF'"); return -1; }
return 0; }
static int stop_Capture(int fd) { enum v4l2_buf_type type; type = V4L2_BUF_TYPE; if (-1 == ioctl(fd, VIDIOC_STREAMOFF, &type)) { perror("Fail to ioctl 'VIDIOC_STREAMOFF' \n"); return -1; } return 0; }
int mainloop(int fd) { int count = 10; while (count-- > 0) { while (1) { fd_set fds; struct timeval tv; int r;
FD_ZERO(&fds); FD_SET(fd, &fds);
/*Timeout*/ tv.tv_sec = 2; tv.tv_usec = 0; r = select(fd + 1, &fds, NULL, NULL, &tv);
if (-1 == r) { if (EINTR == errno) continue; perror("Fail to select \n"); return -1; } if (0 == r) { fprintf(stderr, "select Timeout \n"); return -1; }
if (read_frame(fd) == 0) break; } } return 0; }
int UVC_Init(void) { int s32Ret = 0;
// 1 open device s32Ret = camera_Open(); if (s32Ret < 0) { printf("HI_PDT_Camera_Open failed ! \n"); return -1; }
// Check and set device properties set frame s32Ret = init_Camera(g_video_fd); if (s32Ret < 0) { printf("HI_PDT_Camera_Open failed ! \n"); camera_Close(g_video_fd); return -1; }
set_Format(g_video_fd);
// Apply for a video buffer init_mmap(g_video_fd); start_capture(g_video_fd); mainloop(g_video_fd); return 0; }
int UVC_DeInit(void) { stop_Capture(g_video_fd); camera_Close(g_video_fd); return 0; }
int main() { UVC_Init(); UVC_DeInit(); return 0; }

标签:return,int,JPEG,YUV,VIDIOC,fd,video,UVC,buf
来源: https://www.cnblogs.com/y4247464/p/15722722.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有