📄 input-v4l.c
字号:
spook_log( SL_ERR, "v4l: error verifying image parameters" ); return -1; }#ifdef HAVE_PWC_IOCTL_H if( pwc ) { int fps; fps = ( win.flags & PWC_FPS_FRMASK ) >> PWC_FPS_SHIFT; if( fps != conf->fps ) { if( fps == 0 ) { spook_log( SL_ERR, "v4l: kernel webcam drivers too old to set frame rate" ); return -1; } spook_log( SL_INFO, "v4l: camera selected frame rate %d", fps ); conf->fincr = 1; conf->fbase = fps; } }#endif#ifdef VIDIOCPWCGREALSIZE if( pwc && ioctl( conf->fd, VIDIOCPWCGREALSIZE, &pwc_imagesize ) == 0 ) { real_width = pwc_imagesize.width; real_height = pwc_imagesize.height; } else#endif { real_width = win.width; real_height = win.height; } if( real_width != conf->width || real_height != conf->height ) { spook_log( SL_INFO, "v4l: hardware resized frames to %dx%d", real_width, real_height ); conf->width = real_width; conf->height = real_height; win.x = win.y = 0; win.width = conf->width; win.height = conf->height; win.chromakey = 0; win.flags = 0; win.clips = NULL; win.clipcount = 0; if( ioctl( conf->fd, VIDIOCSWIN, &win ) < 0 ) { spook_log( SL_ERR, "v4l: error setting image parameters" ); return -1; } } memset( &conf->vm, 0, sizeof( conf->vm ) );#ifdef HAVE_PWC_IOCTL_H if( pwc && ioctl( conf->fd, VIDIOCPWCSAWB, &conf->pwc_whitebalance ) < 0 ) { spook_log( SL_ERR, "v4l: error setting white balance on Philips webcam" ); return -1; }#endif if( ioctl( conf->fd, VIDIOCGMBUF, &conf->vm ) < 0 ) { spook_log( SL_ERR, "v4l: error configuring driver for DMA" ); return -1; } if( ! ( conf->mmap_buf = (unsigned char *)mmap( NULL, conf->vm.size, PROT_READ, MAP_SHARED, conf->fd, 0 ) ) ) { spook_log( SL_ERR, "v4l: error mapping driver memory" ); return -1; } return 0;}static void get_framerate( struct stream *s, int *fincr, int *fbase ){ struct v4l_input *conf = (struct v4l_input *)s->private; *fincr = conf->fincr; *fbase = conf->fbase;}static void set_running( struct stream *s, int running ){ struct v4l_input *conf = (struct v4l_input *)s->private; conf->running = running;}#if 0void v4l_close( int fd ){ munmap( m, vm.size ); close( fd ); xvid_encore( xvid_handle, XVID_ENC_DESTROY, NULL, NULL );}#endif/************************ CONFIGURATION DIRECTIVES ************************/static void *start_block(void){ struct v4l_input *conf; conf = (struct v4l_input *)malloc( sizeof( struct v4l_input ) ); conf->output = NULL; conf->device[0] = 0; conf->width = 0; conf->height = 0; conf->inputport = -1; conf->inputtype = 0;#ifdef HAVE_PWC_IOCTL_H conf->pwc_whitebalance.mode = PWC_WB_AUTO;#endif conf->fps = -1; conf->fd = -1; conf->running = 0; return conf;}static int end_block( void *d ){ struct v4l_input *conf = (struct v4l_input *)d; int i; if( ! conf->output ) { spook_log( SL_ERR, "v4l: missing output stream name" ); return -1; } if( ! conf->device[0] ) { spook_log( SL_ERR, "v4l: missing V4L device name" ); return -1; } switch( conf->inputtype ) { case 0: spook_log( SL_ERR, "v4l: input type not specified" ); return -1; case INPUTTYPE_NTSC: conf->fincr = 1001; conf->fbase = 30000; if( conf->width == 0 ) { conf->width = 320; conf->height = 240; } break; case INPUTTYPE_PAL: conf->fincr = 1; conf->fbase = 25; if( conf->width == 0 ) { conf->width = 320; conf->height = 240; } break; case INPUTTYPE_WEBCAM: if( conf->fps < 0 ) { spook_log( SL_ERR, "v4l: framerate not specified for webcam" ); return -1; } else if( conf->fps > 0 ) { conf->fincr = 1; conf->fbase = conf->fps; } else spook_log( SL_INFO, "v4l: must figure out framerate, this will take some time..." ); if( conf->inputport < 0 ) conf->inputport = 0; if( conf->width == 0 ) { conf->width = 352; conf->height = 288; } break; } if( v4l_setup( conf ) < 0 ) return -1; conf->ex = new_exchanger( 8, get_back_frame, conf ); for( i = 0; i < 8; ++i ) exchange_frame( conf->ex, new_frame() ); pthread_create( &conf->thread, NULL, capture_loop, conf ); return 0;}static int set_device( int num_tokens, struct token *tokens, void *d ){ struct v4l_input *conf = (struct v4l_input *)d; strcpy( conf->device, tokens[1].v.str ); return 0;}static int set_output( int num_tokens, struct token *tokens, void *d ){ struct v4l_input *conf = (struct v4l_input *)d; conf->output = new_stream( tokens[1].v.str, FORMAT_RAW_UYVY, conf ); if( ! conf->output ) { spook_log( SL_ERR, "v4l: unable to create stream \"%s\"", tokens[1].v.str ); return -1; } conf->output->get_framerate = get_framerate; conf->output->set_running = set_running; return 0;}static int set_framesize( int num_tokens, struct token *tokens, void *d ){ struct v4l_input *conf = (struct v4l_input *)d; conf->width = tokens[1].v.num; conf->height = tokens[2].v.num; return 0;}static int set_inputport( int num_tokens, struct token *tokens, void *d ){ struct v4l_input *conf = (struct v4l_input *)d; conf->inputport = tokens[1].v.num; return 0;}static int set_inputtype( int num_tokens, struct token *tokens, void *d ){ struct v4l_input *conf = (struct v4l_input *)d; if( ! strcasecmp( tokens[1].v.str, "webcam" ) ) conf->inputtype = INPUTTYPE_WEBCAM; else if( ! strcasecmp( tokens[1].v.str, "ntsc" ) ) conf->inputtype = INPUTTYPE_NTSC; else if( ! strcasecmp( tokens[1].v.str, "pal" ) ) conf->inputtype = INPUTTYPE_PAL; else { spook_log( SL_ERR, "v4l: video mode \"%s\" is unsupported; try NTSC, PAL or WEBCAM", tokens[1].v.str ); return -1; } return 0;}static int set_framerate_num( int num_tokens, struct token *tokens, void *d ){ struct v4l_input *conf = (struct v4l_input *)d; if( conf->fps >= 0 ) { spook_log( SL_ERR, "v4l: frame rate has already been set!" ); return -1; } conf->fps = tokens[1].v.num; return 0;}static int set_framerate_str( int num_tokens, struct token *tokens, void *d ){ struct v4l_input *conf = (struct v4l_input *)d; if( strcasecmp( tokens[1].v.str, "auto" ) ) { spook_log( SL_ERR, "v4l: frame rate should be a number or \"auto\"" ); return -1; } conf->fps = 0; return 0;}#ifdef HAVE_PWC_IOCTL_Hstatic int set_pwc_whitebalance_str( int num_tokens, struct token *tokens, void *d ){ struct v4l_input *conf = (struct v4l_input *)d; if( ! strcasecmp( tokens[1].v.str, "auto" ) ) conf->pwc_whitebalance.mode = PWC_WB_AUTO; else if( ! strcasecmp( tokens[1].v.str, "indoor" ) ) conf->pwc_whitebalance.mode = PWC_WB_INDOOR; else if( ! strcasecmp( tokens[1].v.str, "outdoor" ) ) conf->pwc_whitebalance.mode = PWC_WB_OUTDOOR; else if( ! strcasecmp( tokens[1].v.str, "fl" ) ) conf->pwc_whitebalance.mode = PWC_WB_FL; else { spook_log( SL_ERR, "v4l: PWC-WhiteBalance setting \"%s\" is invalid", tokens[1].v.str ); return -1; } return 0;}static int set_pwc_whitebalance_num( int num_tokens, struct token *tokens, void *d ){ struct v4l_input *conf = (struct v4l_input *)d; if( tokens[1].v.num < 0 || tokens[1].v.num > 65535 || tokens[2].v.num < 0 || tokens[2].v.num > 65535 ) { spook_log( SL_ERR, "v4l: PWC-WhiteBalance settings must be in the range 0-65535" ); return -1; } conf->pwc_whitebalance.mode = PWC_WB_MANUAL; conf->pwc_whitebalance.manual_red = tokens[1].v.num; conf->pwc_whitebalance.manual_blue = tokens[2].v.num; return 0;}#endifstatic struct statement config_statements[] = { /* directive name, process function, min args, max args, arg types */ { "device", set_device, 1, 1, { TOKEN_STR } }, { "output", set_output, 1, 1, { TOKEN_STR } }, { "framesize", set_framesize, 2, 2, { TOKEN_NUM, TOKEN_NUM } }, { "inputport", set_inputport, 1, 1, { TOKEN_NUM } }, { "inputtype", set_inputtype, 1, 1, { TOKEN_STR } }, { "framerate", set_framerate_num, 1, 1, { TOKEN_NUM } }, { "framerate", set_framerate_str, 1, 1, { TOKEN_STR } },#ifdef HAVE_PWC_IOCTL_H { "pwc-whitebalance", set_pwc_whitebalance_str, 1, 1, { TOKEN_STR } }, { "pwc-whitebalance", set_pwc_whitebalance_num, 2, 2, { TOKEN_NUM, TOKEN_NUM } },#endif /* empty terminator -- do not remove */ { NULL, NULL, 0, 0, {} }};void v4l_init(void){ register_config_context( "input", "v4l", start_block, end_block, config_statements );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -