📄 testquickcam.c
字号:
/* * Test quickcam: Logitech QuickCam Express Video Camera driver test tool. * Copyright (C) 2001 Nikolas Zimmermann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * <wildfox@kde.org> * */#include <sys/ioctl.h>#include <sys/mman.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include "testquickcam.h"#define VERSION "$Id: testquickcam.c,v 1.3 2004/07/28 10:13:12 tuukkat Exp $"int resolution = -1;int open_camera(const char *devicename){ device_fd = open(devicename, O_RDWR); if(device_fd <= 0) { printf("Device %s couldn't be opened\n", devicename); return 0; } return 1;}void close_camera(void){ close(device_fd);}void get_camera_info(void){ ioctl(device_fd, VIDIOCGCAP, &vidcap); ioctl(device_fd, VIDIOCGWIN, &vidwin); ioctl(device_fd, VIDIOCGPICT, &vidpic); vidwin.clips = vidclips; vidwin.clipcount = 0;}void print_camera_info(void){ printf(" *** Camera Info ***\n"); printf("Name: %s\n", vidcap.name); printf("Type: %d\n", vidcap.type); printf("Minimum Width: %d\n", vidcap.minwidth); printf("Maximum Width: %d\n", vidcap.maxwidth); printf("Minimum Height: %d\n", vidcap.minheight); printf("Maximum Height: %d\n", vidcap.maxheight); printf("X: %d\n", vidwin.x); printf("Y: %d\n", vidwin.y); printf("Width: %d\n", vidwin.width); printf("Height: %d\n", vidwin.height); printf("Depth: %d\n", vidpic.depth); if(vidcap.type & VID_TYPE_MONOCHROME) printf("Color false\n"); else printf("Color true\n"); printf("Version: %s\n", VERSION);}static void save_ppm(struct video_mmap *vm, const unsigned char *data){ FILE *fp; int len, rc; int pos, i; len = vm->width * vm->height * 3; printf("Save file in %dx%d (len=%d)\n", vm->width, vm->height, len); fp = fopen("pic.ppm", "w"); if(!fp) return; fprintf(fp, "P6\n%3d %3d\n255\n", vm->width, vm->height);#if 0 for(i=0; i<vm->width * vm->height;) { rc = 0; pos = i; rc |= fwrite(&data[pos], 1, 1, fp); pos = i+ (vm->width * vm->height); rc |= fwrite(&data[pos], 1, 1, fp); pos = i+ (vm->width * vm->height)*2; rc |= fwrite(&data[pos], 1, 1, fp); if(rc <= 0) printf("error %d\n", rc); i++; }#endif#if 1 { char *p = malloc(len); for(i=0; i<len;i+=3) { p[i+0] = data[i+2]; p[i+1] = data[i+1]; p[i+2] = data[i]; } rc = fwrite(p, len, 1, fp); free(p); if(rc < 0) printf("error %d\n", rc); }#else rc = fwrite(data, len, 1, fp); if(rc < 0) printf("error %d\n", rc);#endif fclose(fp);}static void hexdump_data(const unsigned char *data, int len){ const int bytes_per_line = 32; char tmp[128]; int i = 0, k = 0; for(i = 0; len > 0; i++, len--) { if(i > 0 && ((i % bytes_per_line) == 0)) { printf("%s\n", tmp); k = 0; } if ((i % bytes_per_line) == 0) k += sprintf(&tmp[k], "[%04x]: ", i); k += sprintf(&tmp[k], "%02x ", data[i]); } if (k > 0) printf("%s\n", tmp);}set_res(struct video_mmap *vm){ struct video_channel vidchan; int r; switch(resolution) { case 0: vm->width = 324; vm->height = 248; break; case 1: vm->width = 320; vm->height = 240; break; case 2: vm->width = 248; vm->height = 162; vm->width = 352; vm->height = 288; break; case 3: vm->width = 324; vm->height = 124; break; case 4: vm->width = 162; vm->height = 248; break; case 5: vm->width = 162; vm->height = 124; break; default: vm->width = 324; vm->height = 248; break; } printf("%d,%d resolution\n", vm->width,vm->height); ioctl(device_fd, VIDIOCGCAP, &vidcap); memset(&vidwin, 0, sizeof(vidwin)); vidwin.width = vm->width; vidwin.height = vm->height; if((vidwin.width > vidcap.maxwidth) || (vidwin.height > vidcap.maxheight)) { vidwin.width = vidcap.maxwidth; vidwin.height = vidcap.maxheight; } r=ioctl(device_fd, VIDIOCSWIN, &vidwin); if (r!=0) { perror("ioctl VIDIOCSWIN"); exit(1); } r=ioctl(device_fd, VIDIOCGWIN, &vidwin); if (r!=0) { perror("ioctl VIDIOCGWIN"); exit(1); } vm->width = vidwin.width; vm->height = vidwin.height; vidchan.channel = 0; r=ioctl(device_fd, VIDIOCGCHAN, &vidchan); if (r!=0) { perror("ioctl VIDIOCGCHAN"); exit(1); } r=ioctl(device_fd, VIDIOCSCHAN, &vidchan); if (r!=0) { perror("ioctl VIDIOCSCHAN"); exit(1); } r=ioctl(device_fd, VIDIOCGPICT, &vidpic); if (r!=0) { perror("ioctl VIDIOCGPICT"); exit(1); } vidpic.depth = 24; vidpic.palette = VIDEO_PALETTE_RGB24; r=ioctl(device_fd, VIDIOCSPICT, &vidpic); if (r!=0) { perror("ioctl VIDIOCSPICT"); exit(1); } r=ioctl(device_fd, VIDIOCGPICT, &vidpic); if (r!=0) { perror("ioctl VIDIOCGPICT"); exit(1); } print_camera_info();}void read_test(int quiet){ unsigned char *buffer; struct video_mmap vm; int len = 0; set_res(&vm); buffer = malloc(vm.width * vm.height * 3); len = read(device_fd, buffer, vm.width * vm.height * 3); if(!quiet) { printf(" *** read() test ***\n"); printf("Read length: %d\n", len); //printf("Raw data: \n\n"); //hexdump_data(buffer, len); save_ppm(&vm, buffer); } free(buffer);}void mmap_test(int quiet){ struct video_mbuf vidbuf; struct video_mmap vm; int numframe = 0; unsigned char *buffer; ioctl(device_fd, VIDIOCGMBUF, &vidbuf); buffer = mmap(NULL, vidbuf.size, PROT_READ, MAP_SHARED, device_fd, 0); vm.format = VIDEO_PALETTE_RGB24; vm.frame = 0; set_res(&vm); if(ioctl(device_fd, VIDIOCMCAPTURE, &vm) < 0) { printf("Error in VIDIOCMCAPTURE\n"); } if(ioctl(device_fd, VIDIOCSYNC, &numframe) < 0) { printf("Error in VIDIOCSYNC\n"); } if(!quiet) { printf(" *** mmap() test ***\n"); printf("Read length: %d\n", vidbuf.size); //printf("Raw data: \n\n"); //hexdump_data(buffer, vidbuf.size); save_ppm(&vm, buffer); }}void read_loop(void){ int loop = 0; while(1) { loop++; read_test(1); printf("*** Read frames: %d times!\n", loop); }}int main(int argc, char *argv[]){ char *switchtwo = ""; char *switchthree = ""; char *switchfour = ""; if(argc == 1) { printf(" *** Usage ***\n"); printf("./testquickcam DEVICE [ -r | -m | -l ] [ -0 | -1 | -2 | -3 | -4 | -5 ]\n\n"); printf(" -r reads one frame via read() from the camera\n"); printf(" -m reads one frame via mmap() from the camera\n"); printf(" -l read() loop...good for debugging gain etc \n"); printf(" -0-5 set resulution\n"); exit(1); } if(argc >= 3) switchtwo = argv[2]; if(argc >= 4) switchthree = argv[3]; if(argc >= 5) switchfour = argv[4]; //printf("switchfour=[%s]\n", switchfour); if(open_camera(argv[1]) == 1) { get_camera_info(); print_camera_info(); if(strcmp(switchthree, "-0") == 0) resolution = 0; if(strcmp(switchthree, "-1") == 0) resolution = 1; if(strcmp(switchthree, "-2") == 0) resolution = 2; if(strcmp(switchthree, "-3") == 0) resolution = 3; if(strcmp(switchthree, "-4") == 0) resolution = 4; if(strcmp(switchthree, "-5") == 0) resolution = 5; if(strcmp(switchfour, "-0") == 0) resolution = 0; if(strcmp(switchfour, "-1") == 0) resolution = 1; if(strcmp(switchfour, "-2") == 0) resolution = 2; if(strcmp(switchfour, "-3") == 0) resolution = 3; if(strcmp(switchfour, "-4") == 0) resolution = 4; if(strcmp(switchfour, "-5") == 0) resolution = 5; if(strcmp(switchtwo, "-r") == 0) read_test(0); if(strcmp(switchtwo, "-m") == 0) mmap_test(0); if(strcmp(switchtwo, "-l") == 0) read_loop(); if(strcmp(switchthree, "-r") == 0) read_test(0); if(strcmp(switchthree, "-m") == 0) mmap_test(0); if(strcmp(switchthree, "-l") == 0) read_loop(); printf("resolution=%d\n", resolution); close_camera(); } exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -