在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
*
* dotphoenix@qq.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.c
logger//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));