企业手机网站建设信息,网页设计作品源代码下载,比较好的网站建设论坛,南京网站建设培训在VMware里面调用v4l2-ctl捕获图像#xff0c;或者opencv的VideoCapture(0)捕获图像#xff0c;或者直接调用v4l2的函数#xff0c;在streamon后#xff0c;调用select读取数据#xff0c;均会一直提示select timeout的问题#xff0c;大概率是由于USB版本的兼容性造成的…在VMware里面调用v4l2-ctl捕获图像或者opencv的VideoCapture(0)捕获图像或者直接调用v4l2的函数在streamon后调用select读取数据均会一直提示select timeout的问题大概率是由于USB版本的兼容性造成的做如下设置基本能够解决。 另外附上一个完整的例子
/** V4L2 video capture example*** This program is a plus version of program provided with the V4L2 API* * dotphoenixqq.com* */#include stdio.h
#include stdlib.h
#include string.h
#include assert.h#include getopt.h /* getopt_long() */#include fcntl.h /* low-level i/o */
#include unistd.h
#include errno.h
#include sys/stat.h
#include sys/types.h
#include sys/time.h
#include sys/mman.h
#include sys/ioctl.h
#include stdarg.h
#include unistd.h
#include time.h
#include linux/videodev2.h//gcc -g -Wall -o capture_v4l2 capture_v4l2.clogger//Synsynchronization is not considered///typedef struct {FILE * (*fopen)(char const * const filename, char const * const mode);int (*fprintf)(FILE *fp, char const * const fmt, ...);int (*vfprintf)(FILE *fp, char const * const fmt, va_list argp);int (*fclose)(FILE* fp);
} std_file_t;void std_file_init(std_file_t * const std_file) {std_file-fopen fopen;std_file-fprintf fprintf;std_file-vfprintf vfprintf;std_file-fclose fclose;
}typedef enum {OFF,DEBUG,INFO,WARNING,ERROR
} logger_level_t;typedef struct {logger_level_t level;int write_to_file ;FILE *fp;std_file_t *std_file;
} logger_t;static logger_t* logger;static void logger_format_current_time(char* ts) {time_t rawtime;struct tm *info;time( rawtime );info localtime( rawtime );strftime(ts, 80, %Y-%m-%d %H:%M:%S, info);
}static const char* logger_format_level(int level) {switch (level){case DEBUG:return [DEBUG];case INFO:return [INFO];case WARNING:return [WARNING];case ERROR:return [ERROR]; default:return [UNKNOWN];}
}void logger_log(logger_level_t const level, char const * const file, size_t const line, char const * const fmt, ...) {if (level logger-level) {return;}char ts[64] {0};logger_format_current_time(ts);logger-std_file-fprintf(logger-fp, %s %s %s: %lu: , logger_format_level(level), ts, file, line);va_list argp;va_start(argp, fmt);logger-std_file-vfprintf(logger-fp, fmt, argp);va_end(argp); logger-std_file-fprintf(logger-fp, \n);
}#define log_debug(...) logger_log(DEBUG, __FILE__, __LINE__, __VA_ARGS__)
#define log_info(...) logger_log(INFO, __FILE__, __LINE__, __VA_ARGS__)
#define log_warn(...) logger_log(WARNING, __FILE__, __LINE__, __VA_ARGS__)
#define log_error(...) logger_log(ERROR, __FILE__, __LINE__, __VA_ARGS__)static int logger_init(logger_level_t const level, char const * const filename, int const write_to_file
) {std_file_t* std_file (std_file_t*)malloc(sizeof(std_file_t));logger (logger_t*)malloc(sizeof(logger_t));std_file_init(std_file);logger-level level;logger-write_to_file write_to_file;logger-std_file std_file;if (logger-write_to_file) {logger-fp logger-std_file-fopen(filename, a);if (logger-fp NULL) {fprintf(stderr, append log file %s failed, error %d, %s\n, filename, errno, strerror(errno));return -1;}} else {logger-fp stderr;}char ts[128] {0};logger_format_current_time(ts);strcat(ts, start new logger -------------------\n);log_warn(ts);return 0;
}void logger_uninit() {if(logger NULL) {return;}if(logger-write_to_file) {if(logger-fp ! NULL) {logger-std_file-fclose(logger-fp);logger-fp NULL;}}free(logger-std_file);free(logger);
}//
#define CLEAR(x) memset((x), 0, sizeof(x))enum io_method_t {IO_METHOD_READ,IO_METHOD_MMAP,IO_METHOD_USERPTR,
};struct buffer_t {void *start;size_t length;
};static char *dev_name;
static enum io_method_t io_method IO_METHOD_MMAP;
static int fd -1;
struct buffer_t *buffers;
static unsigned int n_buffers;
static int save_to_file 1; //save to file
static int force_format_yuyv 1; //force to use yuyv format
static int force_format_mjpeg 0;//force to use mjpeg
static int frame_count 30 * 2; //total save frame count
static int req_width 640;
static int req_height 480;
static int req_rate_numerator 30;
static int req_rate_denominator 1;static int frame_index 0;static void errno_exit(const char *s)
{fprintf(stderr, %s error %d, %s\n, s, errno, strerror(errno));log_error(%s error %d, %s\n, s, errno, strerror(errno));logger_uninit();exit(EXIT_FAILURE);
}static void general_exit_v(char const * const fmt, ...)
{char msg[512] {0};va_list argp;va_start(argp, fmt);vsprintf(msg, fmt, argp);va_end(argp); strcat(msg, \n);fprintf(stderr, %s, msg);log_error(msg);logger_uninit();exit(EXIT_FAILURE);
}static int xioctl(int fh, int request, void *arg)
{int r;do {r ioctl(fh, request, arg);} while (-1 r EINTR errno);return r;
}static void generate_save_to_fullpath(char* fullpath, const char*postfix, int file_index)
{char cwd[256] {0};getcwd(cwd, 255);sprintf(fullpath, %s/pictures/%06d.%s, cwd, file_index, postfix);
}static void process_image(const void *p, int size)
{frame_index;//mark one frame on the consolefprintf(stderr, .);fflush(stderr);if(save_to_file 1) {char fullpath[128] {0};if(force_format_mjpeg 1) {generate_save_to_fullpath(fullpath, jpg, frame_index);}else {generate_save_to_fullpath(fullpath, yuyv, frame_index);}FILE *fp fopen(fullpath, wb);if(fp NULL) {fprintf(stderr, create file failed, file %s, error %d, %s\n, fullpath, errno, strerror(errno));log_error(create file failed, file %s, error %d, %s\n, fullpath, errno, strerror(errno));return; } else {fwrite(p, size, 1, fp);fflush(fp);fclose(fp);log_debug(one frame coming and save to file, size%d, path%s \n, size, fullpath);}}else {log_debug(one frame coming and not save to file, size%d \n, size);}}static int read_frame(void)
{struct v4l2_buffer buf;unsigned int i;switch (io_method) {case IO_METHOD_READ:if (-1 read(fd, buffers[0].start, buffers[0].length)) {switch (errno) {case EAGAIN:return 0;case EIO:/* Could ignore EIO, see spec. *//* fall through */default:errno_exit(read);}}process_image(buffers[0].start, buffers[0].length);break;case IO_METHOD_MMAP:CLEAR(buf);buf.type V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory V4L2_MEMORY_MMAP;if (-1 xioctl(fd, VIDIOC_DQBUF, buf)) {switch (errno) {case EAGAIN:return 0;case EIO:/* Could ignore EIO, see spec. *//* fall through */default:errno_exit(VIDIOC_DQBUF);}}assert(buf.index n_buffers);process_image(buffers[buf.index].start, buf.bytesused);if (-1 xioctl(fd, VIDIOC_QBUF, buf))errno_exit(VIDIOC_QBUF);break;case IO_METHOD_USERPTR:CLEAR(buf);buf.type V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory V4L2_MEMORY_USERPTR;if (-1 xioctl(fd, VIDIOC_DQBUF, buf)) {switch (errno) {case EAGAIN:return 0;case EIO:/* Could ignore EIO, see spec. *//* fall through */default:errno_exit(VIDIOC_DQBUF);}}for (i 0; i n_buffers; i)if (buf.m.userptr (unsigned long)buffers[i].start buf.length buffers[i].length)break;assert(i n_buffers);process_image((void *)buf.m.userptr, buf.bytesused);if (-1 xioctl(fd, VIDIOC_QBUF, buf))errno_exit(VIDIOC_QBUF);break;}return 1;
}static void mainloop(void)
{unsigned int count;count frame_count;while (count-- 0) {for (;;) {fd_set fds;struct timeval tv;int r;FD_ZERO(fds);FD_SET(fd, fds);/* Timeout. */tv.tv_sec 30;tv.tv_usec 0;r select(fd 1, fds, NULL, NULL, tv);if (-1 r) {if (EINTR errno)continue;errno_exit(select);}if (0 r) {general_exit_v(select timeout);}if (read_frame())break;/* EAGAIN - continue select loop. */}}
}static void stop_capturing(void)
{enum v4l2_buf_type type;switch (io_method) {case IO_METHOD_READ:/* Nothing to do. */break;case IO_METHOD_MMAP:case IO_METHOD_USERPTR:type V4L2_BUF_TYPE_VIDEO_CAPTURE;if (-1 xioctl(fd, VIDIOC_STREAMOFF, type))errno_exit(VIDIOC_STREAMOFF);break;}
}static void start_capturing(void)
{unsigned int i;enum v4l2_buf_type type;switch (io_method) {case IO_METHOD_READ:/* Nothing to do. */break;case IO_METHOD_MMAP:for (i 0; i n_buffers; i) {struct v4l2_buffer buf;CLEAR(buf);buf.type V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory V4L2_MEMORY_MMAP;buf.index i;if (-1 xioctl(fd, VIDIOC_QBUF, buf))errno_exit(VIDIOC_QBUF);}type V4L2_BUF_TYPE_VIDEO_CAPTURE;if (-1 xioctl(fd, VIDIOC_STREAMON, type))errno_exit(VIDIOC_STREAMON);log_info(%s stream on, dev_name);break;case IO_METHOD_USERPTR:for (i 0; i n_buffers; i) {struct v4l2_buffer buf;CLEAR(buf);buf.type V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory V4L2_MEMORY_USERPTR;buf.index i;buf.m.userptr (unsigned long)buffers[i].start;buf.length buffers[i].length;if (-1 xioctl(fd, VIDIOC_QBUF, buf))errno_exit(VIDIOC_QBUF);}type V4L2_BUF_TYPE_VIDEO_CAPTURE;if (-1 xioctl(fd, VIDIOC_STREAMON, type))errno_exit(VIDIOC_STREAMON);log_info(%s stream on, dev_name);break;}
}static void uninit_device(void)
{unsigned int i;switch (io_method) {case IO_METHOD_READ:free(buffers[0].start);break;case IO_METHOD_MMAP:for (i 0; i n_buffers; i)if (-1 munmap(buffers[i].start, buffers[i].length))errno_exit(munmap);break;case IO_METHOD_USERPTR:for (i 0; i n_buffers; i)free(buffers[i].start);break;}free(buffers);
}static void init_read(unsigned int buffer_size)
{buffers calloc(1, sizeof(*buffers));if (!buffers) {general_exit_v(Out of memory);}buffers[0].length buffer_size;buffers[0].start malloc(buffer_size);if (!buffers[0].start) {general_exit_v(Out of memory);}log_info(initialize readwrite method of %s successfully);
}static void init_mmap(void)
{struct v4l2_requestbuffers req;CLEAR(req);req.count 8;req.type V4L2_BUF_TYPE_VIDEO_CAPTURE;req.memory V4L2_MEMORY_MMAP;if (-1 xioctl(fd, VIDIOC_REQBUFS, req)) {if (EINVAL errno) {general_exit_v(%s does not support memory mappingn, dev_name);} else {errno_exit(VIDIOC_REQBUFS);}}if (req.count 2) {general_exit_v(Insufficient buffer_t memory on %s, dev_name);}buffers calloc(req.count, sizeof(*buffers));if (!buffers) {general_exit_v(Out of memory);}for (n_buffers 0; n_buffers req.count; n_buffers) {struct v4l2_buffer buf;CLEAR(buf);buf.type V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory V4L2_MEMORY_MMAP;buf.index n_buffers;if (-1 xioctl(fd, VIDIOC_QUERYBUF, buf))errno_exit(VIDIOC_QUERYBUF);buffers[n_buffers].length buf.length;buffers[n_buffers].start mmap(NULL /* start anywhere */,buf.length,PROT_READ | PROT_WRITE /* required */,MAP_SHARED /* recommended */,fd, buf.m.offset);if (MAP_FAILED buffers[n_buffers].start)errno_exit(mmap);}log_info(initialize mmap method of %s successfully, dev_name);}static void init_userp(unsigned int buffer_size)
{struct v4l2_requestbuffers req;CLEAR(req);req.count 4;req.type V4L2_BUF_TYPE_VIDEO_CAPTURE;req.memory V4L2_MEMORY_USERPTR;if (-1 xioctl(fd, VIDIOC_REQBUFS, req)) {if (EINVAL errno) {general_exit_v(%s does not support user pointer i/o, dev_name);} else {errno_exit(VIDIOC_REQBUFS);}}buffers calloc(4, sizeof(*buffers));if (!buffers) {general_exit_v(Out of memory);}for (n_buffers 0; n_buffers 4; n_buffers) {buffers[n_buffers].length buffer_size;buffers[n_buffers].start malloc(buffer_size);if (!buffers[n_buffers].start) {general_exit_v(Out of memory);}}log_info(initialize userp method of %s successfully, dev_name);}static int check_fmt(int fd, __u32 fmt)
{struct v4l2_format v4l2_fmt;CLEAR(v4l2_fmt);v4l2_fmt.type V4L2_BUF_TYPE_VIDEO_CAPTURE;if (ioctl (fd, VIDIOC_G_FMT, v4l2_fmt) -1) {log_error(ERROR camera VIDIOC_G_FMT Failed.);return -1;}if (v4l2_fmt.fmt.pix.pixelformat fmt) {return 1;}else {log_error(ERROR camera VIDIOC_S_FMT Failed, %u vs %u., v4l2_fmt.fmt.pix.pixelformat, fmt);return -1;}
}static void init_device(void)
{struct v4l2_capability cap;struct v4l2_cropcap cropcap;struct v4l2_crop crop;struct v4l2_format fmt;struct v4l2_streamparm streamparm;unsigned int min;if (-1 xioctl(fd, VIDIOC_QUERYCAP, cap)) {if (EINVAL errno) {general_exit_v(%s is no V4L2 device, dev_name);} else {errno_exit(VIDIOC_QUERYCAP);}}if (!(cap.capabilities V4L2_CAP_VIDEO_CAPTURE)) {general_exit_v(%s is no video capture device,dev_name);}switch (io_method) {case IO_METHOD_READ:if (!(cap.capabilities V4L2_CAP_READWRITE)) {general_exit_v(%s does not support read i/o,dev_name);}log_info(%s supports read and write, dev_name);break;case IO_METHOD_MMAP:case IO_METHOD_USERPTR:if (!(cap.capabilities V4L2_CAP_STREAMING)) {general_exit_v(%s does not support streaming i/o,dev_name);}log_info(%s supports streaming, dev_name);break;}/* Select video input, video standard and tune here. */CLEAR(cropcap);cropcap.type V4L2_BUF_TYPE_VIDEO_CAPTURE;if (0 xioctl(fd, VIDIOC_CROPCAP, cropcap)) {crop.type V4L2_BUF_TYPE_VIDEO_CAPTURE;crop.c cropcap.defrect; /* reset to default */if (-1 xioctl(fd, VIDIOC_S_CROP, crop)) {switch (errno) {case EINVAL:/* Cropping not supported. */break;default:/* Errors ignored. */break;}}} else {/* Errors ignored. */}CLEAR(streamparm);streamparm.type V4L2_BUF_TYPE_VIDEO_CAPTURE;if (-1 xioctl(fd, VIDIOC_G_PARM, streamparm))errno_exit(VIDIOC_G_PARM);if (streamparm.parm.capture.capability V4L2_CAP_TIMEPERFRAME) {struct v4l2_fract *tpf (streamparm.parm.capture.timeperframe);// Swap numerator and denominator: rate is an inverted frame time :-)tpf-numerator req_rate_denominator;tpf-denominator req_rate_numerator;if (-1 xioctl(fd, VIDIOC_S_PARM, streamparm))errno_exit(VIDIOC_S_PARM);if (tpf-numerator ! req_rate_denominator ||tpf-denominator ! req_rate_numerator) {log_error( the driver changed the time per frame from %d/%d to %d/%d failed,req_rate_denominator, req_rate_numerator,tpf-numerator, tpf-denominator);}else {log_info( the driver changed the time per frame from %d/%d to %d/%d successfully,req_rate_denominator, req_rate_numerator,tpf-numerator, tpf-denominator);}} else {log_error(the driver does not allow to change time per frame);}CLEAR(fmt);fmt.type V4L2_BUF_TYPE_VIDEO_CAPTURE;if (force_format_yuyv) {fmt.fmt.pix.width req_width;fmt.fmt.pix.height req_height;fmt.fmt.pix.pixelformat V4L2_PIX_FMT_YUYV;fmt.fmt.pix.field V4L2_FIELD_ANY;if (-1 xioctl(fd, VIDIOC_S_FMT, fmt))errno_exit(VIDIOC_S_FMT);assert(check_fmt(fd, V4L2_PIX_FMT_YUYV) 1);log_info(set format of %s to %u successfully, dev_name, fmt.fmt.pix.pixelformat);/* Note VIDIOC_S_FMT may change width and height. */} else if (force_format_mjpeg) {fmt.fmt.pix.width req_width;fmt.fmt.pix.height req_height;fmt.fmt.pix.pixelformat V4L2_PIX_FMT_MJPEG;fmt.fmt.pix.field V4L2_FIELD_ANY;if (-1 xioctl(fd, VIDIOC_S_FMT, fmt))errno_exit(VIDIOC_S_FMT);assert(check_fmt(fd, V4L2_PIX_FMT_MJPEG) 1);log_info(set format of %s to %u successfully, dev_name, fmt.fmt.pix.pixelformat);/* Note VIDIOC_S_FMT may change width and height. */} else {/* Preserve original settings as set by v4l2-ctl for example */if (-1 xioctl(fd, VIDIOC_G_FMT, fmt))errno_exit(VIDIOC_G_FMT);log_info(format of %s is %u , dev_name, fmt.fmt.pix.pixelformat);}/* Buggy driver paranoia. */min fmt.fmt.pix.width * 2;if (fmt.fmt.pix.bytesperline min)fmt.fmt.pix.bytesperline min;min fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;if (fmt.fmt.pix.sizeimage min)fmt.fmt.pix.sizeimage min;switch (io_method) {case IO_METHOD_READ:init_read(fmt.fmt.pix.sizeimage);break;case IO_METHOD_MMAP:init_mmap();break;case IO_METHOD_USERPTR:init_userp(fmt.fmt.pix.sizeimage);break;}
}static void close_device(void)
{if (-1 close(fd))errno_exit(close);fd -1;
}static void open_device(void)
{struct stat st;if (-1 stat(dev_name, st)) {general_exit_v(Cannot identify device %s: %d, %s,dev_name, errno, strerror(errno));}if (!S_ISCHR(st.st_mode)) {general_exit_v(%s is no device, dev_name);}fd open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);if (-1 fd) {general_exit_v(Cannot open %s: %d, %s,dev_name, errno, strerror(errno));}else {log_info(Open device %s successfully., dev_name);}
}static void usage(FILE *fp, int argc, char **argv)
{fprintf(fp,Usage: %s [options]\\n\\nVersion 1.3\\nOptions:\\n-d | --device name Video device name [%s]n-h | --help Print this messagen-m | --mmap Use memory mapped buffers [default]n-r | --read Use read() callsn-u | --userp Use application allocated buffersn-s | --save Save stream to file-f | --format Force format to 640x480 YUYVn-c | --count Number of frames to grab [%i]n,argv[0], dev_name, frame_count);
}static const char short_options[] d:hmruofc:;static const struct option
long_options[] {{ device, required_argument, NULL, d },{ help, no_argument, NULL, h },{ mmap, no_argument, NULL, m },{ read, no_argument, NULL, r },{ userp, no_argument, NULL, u },{ save, no_argument, NULL, s },{ format, no_argument, NULL, f },{ count, required_argument, NULL, c },{ 0, 0, 0, 0 }
};int main(int argc, char **argv)
{dev_name /dev/video0;char log_filename[256] {0};char cwd[256] {0};getcwd(cwd, 255);sprintf(log_filename, %s/v4l2_log.txt, cwd);logger_init(DEBUG, log_filename, 1);for (;;) {int idx;int c;c getopt_long(argc, argv,short_options, long_options, idx);if (-1 c)break;switch (c) {case 0: /* getopt_long() flag */break;case d:dev_name optarg;break;case h:usage(stdout, argc, argv);exit(EXIT_SUCCESS);case m:io_method IO_METHOD_MMAP;break;case r:io_method IO_METHOD_READ;break;case u:io_method IO_METHOD_USERPTR;break;case s:save_to_file 1;break;case j:force_format_mjpeg 1;break;case n:force_format_yuyv 1;break;case y:errno 0;frame_count strtol(optarg, NULL, 0);if (errno)errno_exit(optarg);break;default:usage(stderr, argc, argv);exit(EXIT_FAILURE);}}open_device();init_device();start_capturing();mainloop();stop_capturing();uninit_device();close_device();logger_uninit(logger);return 0;
}