虚拟机调用摄像头设备一直 select timeout问题的解决

在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));

       
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值