📄 gqcam.c
字号:
/* gqcam.c - The frontend to Gqcam, a GTK based QuickPict clone. Copyright (C) 1999 Cory Lueninghoener (cluenin1@bigred.unl.edu) 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 */#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <getopt.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <fcntl.h>#include <pthread.h>#include <semaphore.h>#include <gtk/gtk.h>#include <linux/types.h> #include <linux/videodev.h>#include <signal.h>#include <png.h>#include "gqcam.h"#include "frontend.h"#include "save.h"#include "filters.h"char version[] = VERSION;void init_cam(struct Camera *camera){ camera->greyscale = 0; camera->pic = NULL; camera->picbuff = NULL; camera->draw = 0; camera->pixmap = NULL; camera->frozen = 0; camera->update_camera = 0; camera->saving = 0; camera->savetype = PNG; camera->capture = 1; camera->dev = 0; strcpy(camera->devname, "/dev/video"); camera->docked = 1; camera->dump=0; camera->speed_fastest = 0; camera->currentsavepage = NULL; camera->timeout = 100; camera->on_timer = 0; camera->timer_struct.unit = SECONDS; camera->timer_struct.iscommand = 0; camera->swapcolors = 0; camera->save_struct.isinfo = 0; pthread_mutex_init( &camera->pref_mutex, NULL ); /* to modify pref/setting */ pthread_mutex_init( &camera->freeze_mutex, NULL ); /* to freeze display */ pthread_mutex_init( &camera->iscam_mutex, NULL ); /* is there an open cam? */}sem_t s_draw;sem_t s_grab1, s_grab2;int plsquit = 0;int x_frames = 0;int y_frames = 0;void set_cam_info(struct Camera *camera){ if (ioctl (camera->dev, VIDIOCSPICT, &camera->vid_pic) == -1) { perror ("ioctl (VIDIOCSPICT)"); } if (ioctl (camera->dev, VIDIOCSWIN, &camera->vid_win) == -1) { perror ("ioctl (VIDIOCSWIN)"); }}void get_cam_info(struct Camera *camera){ int i; struct video_clip vid_clips[32]; ioctl(camera->dev, VIDIOCGCAP, &camera->vid_caps); ioctl(camera->dev, VIDIOCGWIN, &camera->vid_win); ioctl(camera->dev, VIDIOCGPICT, &camera->vid_pic); for (i = 0; i < 32; i++) { vid_clips[i].x = 0; vid_clips[i].y = 0; vid_clips[i].width = 0; vid_clips[i].height = 0; } camera->vid_win.clips = vid_clips; camera->vid_win.clipcount = 0; if (camera->vid_caps.type & VID_TYPE_MONOCHROME) { camera->greyscale = 1; camera->pic = realloc( camera->pic, camera->vid_caps.maxwidth*camera->vid_caps.maxheight); camera->picbuff = realloc( camera->picbuff, camera->vid_caps.maxwidth*camera->vid_caps.maxheight ); } else { camera->greyscale = 0; camera->pic = realloc(camera->pic, camera->vid_caps.maxwidth*camera->vid_caps.maxheight*3); camera->picbuff = realloc(camera->pic, camera->vid_caps.maxwidth*camera->vid_caps.maxheight*3); }}void print_cam_info(struct Camera *camera){ printf("Name: %s\n", camera->vid_caps.name); printf("Type: %i\n", camera->vid_caps.type); if (camera->vid_caps.type & VID_TYPE_CAPTURE) { printf("\tCan capture\n"); } if (camera->vid_caps.type & VID_TYPE_TUNER) { printf("\tCan tune\n"); } if (camera->vid_caps.type & VID_TYPE_TELETEXT) { printf("\tDoes teletext\n"); } if (camera->vid_caps.type & VID_TYPE_OVERLAY) { printf("\tOverlay onto frame buffer\n"); } if (camera->vid_caps.type & VID_TYPE_CHROMAKEY) { printf("\tOverlay by chromakey\n"); } if (camera->vid_caps.type & VID_TYPE_CLIPPING) { printf("\tCan clip\n"); } if (camera->vid_caps.type & VID_TYPE_FRAMERAM) { printf("\tUses the frame buffer memory\n"); } if (camera->vid_caps.type & VID_TYPE_SCALES) { printf("\tScalable\n"); } if (camera->vid_caps.type & VID_TYPE_MONOCHROME) { printf("\tMonochrome only\n"); } if (camera->vid_caps.type & VID_TYPE_SUBCAPTURE) { printf("\tCan capture subareas of the image\n"); } printf("Channels: %i\n", camera->vid_caps.channels); printf("Audios: %i\n", camera->vid_caps.audios); printf("Maxwidth: %i\n", camera->vid_caps.maxwidth); printf("Maxheight: %i\n", camera->vid_caps.maxheight); printf("Minwidth: %i\n", camera->vid_caps.minwidth); printf("Minheight: %i\n", camera->vid_caps.minheight); printf("---------\n"); printf("X: %i\n", camera->vid_win.x); printf("Y: %i\n", camera->vid_win.y); printf("Width: %i\n", camera->vid_win.width); printf("Height: %i\n", camera->vid_win.height); printf("Chromakey: %i\n", camera->vid_win.chromakey); printf("Flags: %i\n", camera->vid_win.flags);/* printf("Clips: %i\n", camera.vid_win.clips); printf("Clipcound: %i\n", camera.vid_win.clipcount);*/ printf("---------\n"); printf("Brightness:\t%i (%i)\n", camera->vid_pic.brightness, camera->vid_pic.brightness/256); printf("Hue:\t\t%i (%i)\n", camera->vid_pic.hue, camera->vid_pic.hue/256); printf("Color:\t\t%i (%i)\n", camera->vid_pic.colour, camera->vid_pic.colour/256); printf("Contrast:\t%i (%i)\n", camera->vid_pic.contrast, camera->vid_pic.contrast/256); printf("Whiteness:\t%i (%i)\n", camera->vid_pic.whiteness, camera->vid_pic.whiteness/256); printf("Depth:\t\t%i\n", camera->vid_pic.depth); printf("Palette:\t%i\n", camera->vid_pic.palette); return;}void open_cam(struct Camera *camera) { if((camera->dev<=0)){ camera->dev = open(camera->devname, O_RDWR); // printf("Opening: %d\n", camera->dev); if (camera->dev < 0) { perror("/dev/video"); exit(1); } } pthread_mutex_unlock( &camera->iscam_mutex );}void close_cam(struct Camera *camera, int quiting){ int debug = 0; pthread_mutex_lock( &camera->iscam_mutex ); if(camera->dev > 0){ close(camera->dev); camera->dev = 0; }}void display(struct Camera *camera) { GdkDrawable *drawable; int xpos=0, ypos=0; GdkRectangle update_rec; char tbuff[1024]; while( !plsquit ) { if( !sem_wait( &s_draw ) ) { unsigned char *tmp; tmp = camera->pic; camera->pic = camera->picbuff; camera->picbuff = tmp; sem_post( &s_grab1 ); update_rec.x = 0; update_rec.y = 0; update_rec.width = camera->vid_caps.maxwidth; update_rec.height = camera->vid_caps.maxheight; xpos = (camera->vid_caps.maxwidth - camera->vid_win.width)/2; ypos = (camera->vid_caps.maxheight - camera->vid_win.height)/2; drawable = camera->drawing_area->window; gdk_threads_enter(); /* Run filters */ if (camera->swapcolors) swap_rgb24(camera); if (camera->autobright) auto_bright(camera); if (camera->greyscale) gdk_draw_gray_image (camera->pixmap, camera->drawing_area->style->white_gc, xpos, ypos, camera->vid_win.width, camera->vid_win.height, GDK_RGB_DITHER_NORMAL, camera->pic, camera->vid_win.width); else gdk_draw_rgb_image (camera->pixmap, camera->drawing_area->style->white_gc, xpos, ypos, camera->vid_win.width, camera->vid_win.height, GDK_RGB_DITHER_NORMAL, camera->pic, camera->vid_win.width*3); gdk_threads_leave(); gdk_threads_enter(); gtk_statusbar_pop( GTK_STATUSBAR( camera->statusbar ), 12 ); sprintf( tbuff, "Speed (fps) - Average: %d Current: %d", camera->fps_avg, camera->fps_current ); gtk_statusbar_push( GTK_STATUSBAR( camera->statusbar ), 12, tbuff ); gtk_widget_draw (camera->drawing_area, &update_rec); gdk_threads_leave(); } x_frames++; y_frames++; } return;}void grab_image(struct Camera *camera){ int len; GdkRectangle update_rec; GdkEventExpose *event; get_cam_info(camera); update_rec.x = 0; update_rec.y = 0; update_rec.width = camera->vid_caps.maxheight; update_rec.height = camera->vid_caps.maxwidth; while ( !plsquit ) { // order matters! the sem_waits MUST be before the mutex lock if( !sem_wait( &s_grab1 ) && ( camera->speed_fastest || !sem_wait( &s_grab2 ) ) && !pthread_mutex_lock( &camera->freeze_mutex ) && !pthread_mutex_lock( &camera->iscam_mutex )){ pthread_mutex_lock( &camera->pref_mutex ); if (camera->update_camera){ set_cam_info(camera); get_cam_info(camera); camera->update_camera = 0; } pthread_mutex_unlock( &camera->pref_mutex ); if( camera->dev ) len = read (camera->dev, camera->picbuff, camera->vid_caps.maxwidth * camera->vid_caps.maxheight*3); if (len <= 0) fprintf(stderr, "Error reading image...\n"); } pthread_mutex_unlock( &camera->freeze_mutex ); pthread_mutex_unlock( &camera->iscam_mutex );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -