📄 main.c
字号:
/** -*-linux-c-*- * */#include <stdio.h>#include <stdint.h>#include <string.h>#include <ctype.h>#include <sys/time.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <usb.h>#ifndef __user#define __user#endif#include <linux/usbdevice_fs.h>#include "v2u_id.h"#include "v2u_ioctl.h"#include <magick/api.h>// OK error code#define EOK 0#define TRUE 1#define FALSE 0int max(int x, int y) {return x>y ? x : y;}int min(int x, int y) {return x<y ? x : y;}/** * returns 0 if failed */static int save_image(int w, int h, int bpp, const char * pixels, const char * fname) { int res = -EOK; ExceptionInfo exception; Image *image; ImageInfo *image_info; // Initialize the image info structure InitializeMagick(NULL); GetExceptionInfo(&exception); image_info = CloneImageInfo(NULL); if(bpp==16) { unsigned char * pixels24 = malloc(w*h*3); unsigned char * d = pixels24; unsigned short * s = (unsigned short *)pixels; int x, y; for(y=0; y<h; y++) for(x=0; x<w; x++) { const unsigned short p = *s; d[2] = (0x1F & p) << 3; d[1] = ((0x3F << 5) & p) >> 3; d[0] = ((0x1F << 11) & p) >> 8; d+=3; s++; } image = ConstituteImage( w, h, "RGB", CharPixel, pixels24, &exception ); free(pixels24); } else { image = ConstituteImage( w, h, "RGB", CharPixel, pixels, &exception ); } strcpy(image->filename, fname); res = WriteImage(image_info, image); DestroyConstitute(); DestroyImage(image); DestroyImageInfo(image_info); DestroyExceptionInfo(&exception); DestroyMagick(); return res;}/** * */static struct usb_device * find_vga2usb(){ struct usb_bus *busses; usb_init(); usb_find_busses(); usb_find_devices(); busses = usb_get_busses(); struct usb_bus *bus; for (bus = busses; bus; bus = bus->next) { struct usb_device *dev; for (dev = bus->devices; dev; dev = dev->next) { if( dev->descriptor.idVendor == VGA2USB_VENDORID ) { return dev; } } } return NULL;}/** * Perform an ioctl on the device connected on usbfs */static int usbfs_ioctl(int fd, int code, void * data){ struct usbdevfs_ioctl ctrl; ctrl.ifno = 0; ctrl.ioctl_code = code; ctrl.data = data; return ioctl(fd, USBDEVFS_IOCTL, &ctrl);}/** * */static int grab_frame(const int fd, const char * img_file, int doSave, int doSaveRGB, int bpp) { int result = -EOK; struct ioctl_grabframe ioctl_grabframe; ioctl_grabframe.pixbuflen = 2048*1536*3; ioctl_grabframe.bpp = bpp; ioctl_grabframe.pixbuf = malloc(ioctl_grabframe.pixbuflen); if(!ioctl_grabframe.pixbuf) { result = -ENOMEM; goto Exit; } result = usbfs_ioctl(fd, IOCTL_VGA2USB_GRABFRAME, &ioctl_grabframe); if(result>=0 && doSave) { result = save_image(ioctl_grabframe.width, ioctl_grabframe.height, ioctl_grabframe.bpp, ioctl_grabframe.pixbuf, img_file); if(doSaveRGB) { int i,j; char * compbuf = malloc(ioctl_grabframe.pixbuflen); if(!compbuf) { result = -ENOMEM; goto Exit; } for(j=0; j<3; j++) { char fname[64]; snprintf(fname, 64, "%s-%d.png", img_file, j); memset(compbuf,0,ioctl_grabframe.pixbuflen); for(i=0; i<ioctl_grabframe.pixbuflen; i+=3) { compbuf[i+j] = ((char*)ioctl_grabframe.pixbuf)[i+j]; } result = save_image(ioctl_grabframe.width, ioctl_grabframe.height, ioctl_grabframe.bpp, compbuf, fname); } free(compbuf); } } Exit: if(ioctl_grabframe.pixbuf) free(ioctl_grabframe.pixbuf); return result;}/** * */static int get_videomode(const int fd){ int result = 0; struct ioctl_videomode vm = {0,0,0}; if( (result = usbfs_ioctl(fd, IOCTL_VGA2USB_VIDEOMODE, &vm)) < 0 ) { goto Exit; } printf("Videomode: %d x %d @ %d mHz\n", vm.width, vm.height, vm.vfreq); Exit: return result;}/** * */static int get_timings(const int fd){ int result = 0; int i; int msglen; V2U_Property prop; prop.key = V2UKey_ModeMeasurmentsDump; memset(&prop.value, 0, sizeof(prop.value)); if( (result = usbfs_ioctl(fd, IOCTL_VGA2USB_GET_PROPERTY, &prop)) < 0 ) { goto Exit; } msglen = min(prop.value.blob[0],sizeof(prop.value.blob)/sizeof(prop.value.blob[0])); for(i=0; i<msglen; i++) { if (i == 6 || i == 14) { printf("\r\n"); } printf("%02X ",prop.value.blob[i]); } printf("\r\n"); Exit: return result;}/** * Queries capture parameters from the drivers and prints them to stdout. */#define MSGSTR_MANUAL "manual"#define MSGSTR_AUTO "auto "static int get_adjustment (const int d){ struct ioctl_setparams params; memset(¶ms,0,sizeof(params)); int result = usbfs_ioctl(d, IOCTL_VGA2USB_GETPARAMS, ¶ms); if ( result >= 0 ) { printf("VGR2USB capture parameters:\n"); printf(" hshift (%s): %d\n", params.flags & V2U_FLAG_VALID_HSHIFT ? MSGSTR_MANUAL : MSGSTR_AUTO, params.hshift ); printf(" vshift (%s): %d\n", params.flags & V2U_FLAG_VALID_VSHIFT ? MSGSTR_MANUAL : MSGSTR_AUTO, params.vshift); printf(" phase (%s): %u\n", params.flags & V2U_FLAG_VALID_PHASE ? MSGSTR_MANUAL : MSGSTR_AUTO, (unsigned int)params.phase); printf(" pll (%s): %d\n", params.flags & V2U_FLAG_VALID_PLLSHIFT ? MSGSTR_MANUAL : MSGSTR_AUTO, params.pllshift); printf(" offset (%s): R:%u G:%u B:%u\n", params.flags & V2U_FLAG_VALID_OFFSETGAIN ? MSGSTR_MANUAL : MSGSTR_AUTO, (unsigned int)params.offset_r, (unsigned int)params.offset_g, (unsigned int)params.offset_b); printf(" gain (%s): R:%u G:%u B:%u\n", params.flags & V2U_FLAG_VALID_OFFSETGAIN ? MSGSTR_MANUAL : MSGSTR_AUTO, (unsigned int)params.gain_r, (unsigned int)params.gain_g, (unsigned int)params.gain_b); if (params.flags & V2U_FLAG_VALID_GRABFLAGS) { printf(" grab flags : 0x%08x\n",params.grab_flags); if (params.grab_flags & GRAB_BMP_BOTTOM_UP) { printf(" GRAB_BMP_BOTTOM_UP\n"); } if (params.grab_flags & GRAB_PREFER_WIDE_MODE) { printf(" GRAB_PREFER_WIDE_MODE\n"); } } } return result;}/** * */#define ADJ_SEPARATOR ":"#define ADJ_HSHIFT "hs="#define ADJ_VSHIFT "vs="#define ADJ_PHASE "phase="#define ADJ_GAIN "gain="#define ADJ_OFFSET "offset="#define ADJ_PLL "pll="#define ADJ_FLAGS "flags="static int set_adjustment(const int fd, const char * args){ int result = 0; char parambuf[256]; char *token=NULL, *tmp; struct ioctl_setparams adj = {0,0,0}; memset(&adj,0,sizeof(struct ioctl_setparams)); strncpy(parambuf,args,sizeof(parambuf)); parambuf[sizeof(parambuf)-1]=0; token = strtok_r(parambuf, ADJ_SEPARATOR, &tmp); while( token ) { char *nptr; char *eptr; int num; if(!strncmp(token,ADJ_HSHIFT,sizeof(ADJ_HSHIFT)-1)) { num = strtol( (nptr=token+sizeof(ADJ_HSHIFT)-1), &eptr, 10); if(!*eptr) { if(*nptr) { adj.flags |= V2U_FLAG_VALID_HSHIFT; adj.hshift = num; } } else { fprintf(stderr,"Ignoring invalid adjustment %s\n", token); } } else if(!strncmp(token,ADJ_VSHIFT,sizeof(ADJ_VSHIFT)-1)) { num = strtol( (nptr=token+sizeof(ADJ_VSHIFT)-1), &eptr, 10); if(!*eptr) { if(*nptr) { adj.flags |= V2U_FLAG_VALID_VSHIFT; adj.vshift = num; } } else { fprintf(stderr,"Ignoring invalid adjustment %s\n", token); } } else if(!strncmp(token,ADJ_PHASE,sizeof(ADJ_PHASE)-1)) { num = strtol( (nptr=token+sizeof(ADJ_PHASE)-1), &eptr, 10); if(!*eptr) { if(*nptr) { adj.flags |= V2U_FLAG_VALID_PHASE; adj.phase = num; } } else { fprintf(stderr,"Ignoring invalid adjustment %s\n", token); } } else if(!strncmp(token,ADJ_OFFSET,sizeof(ADJ_OFFSET)-1)) { num = strtol( (nptr=token+sizeof(ADJ_OFFSET)-1), &eptr, 10); if(!*eptr) { if(*nptr) { adj.flags |= V2U_FLAG_VALID_OFFSETGAIN; adj.offset_r = adj.offset_g = adj.offset_b = ((unsigned)num) & 0x1F; } } else { fprintf(stderr,"Ignoring invalid adjustment %s\n", token); } } else if(!strncmp(token,ADJ_GAIN,sizeof(ADJ_GAIN)-1)) { num = strtol( (nptr=token+sizeof(ADJ_GAIN)-1), &eptr, 10); if(!*eptr) { if(*nptr) { adj.flags |= V2U_FLAG_VALID_OFFSETGAIN; adj.gain_r = adj.gain_g = adj.gain_b = ((unsigned)num) & 0xFF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -