📄 spcaview.c
字号:
/****************************************************************************# spcaview: Sdl video recorder and viewer with sound. ##This package work with the spca5xx based webcam with the raw jpeg feature. ##All the decoding is in user space with the help of libjpeg. ##. ## Copyright (C) 2003 2004 2005 Michel Xhaard ## ## 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 <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/file.h>#include <string.h>#include <pthread.h>#include <SDL/SDL.h>#include <SDL/SDL_thread.h>#include <SDL/SDL_audio.h>#include <SDL/SDL_timer.h>#include <linux/videodev.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <errno.h>#include <fcntl.h>#include <time.h>#include <sys/time.h>#include <signal.h>#include "SDL_audioin.h"#include "jconfig.h"#include "avilib.h"#include "dpsh.h"#include "utils.h"#include "tcputils.h"#include "spcaframe.h"#include "version.h"#define WAVE_AUDIO_PCM 1#define CHANNELS 1#define AUDIO_SAMPLERATE 22050 // 44100 // 11025 // 8000 // 22050#define AUDIO_SAMPLES 512 // 1024#define AUDIO_FORMAT AUDIO_S16#define AUDIOSIZE 2#define NUM_CHUNCK 64 // 256 a large ring buffer #define MAXBUFFERSIZE (AUDIO_SAMPLES*AUDIOSIZE*NUM_CHUNCK)#define HELPBUFFERSIZE (AUDIO_SAMPLES*AUDIOSIZE)// INIT_BRIGHT is the initial brightness level// BRIGHTMEAN is the goal mean brightness for the // auto adjustment.// SPRING_CONSTANT determines the restoring force// for the auto adjust// BRIGHT_WINDOW is the window around the goal mean// in which no adjustment is to occur#define V4L_BRIGHT_MIN 0#define V4L_BRIGHT_MAX 50000 //65000#define BRIGHTMEAN 128 //145#define SPRING_CONSTANT 25#define BRIGHTWINDOW 10/* pictFlag should be set by the hardware or the timer *//* call_back function need to reset the flag */static int totmean;int interval = 0;volatile int pictFlag = 0;static int Oneshoot = 1;static int numshoot = 0;static int modshoot = 0;static videoOk = 0;/* picture structure */typedef struct pictstruct{ unsigned char *data; int sizeIn; int width; int height; int formatIn; int mode; avi_t *out_fd; pthread_mutex_t mutex; pthread_cond_t cond;} pictstruct;void *waitandshoot(void* ptr);/* sound buffer */struct Rbuffer { Uint8 buffer[MAXBUFFERSIZE]; Uint8 helpbuffer[HELPBUFFERSIZE]; int ptread ; int ptwrite; }; Uint32 GetVideoBpp (void); static Uint32 callback_timer (Uint32 interval){ pictFlag = 1; //printf("TIMER ON !!!!\n"); return interval;}void callback_record(void *userdata, Uint8 *stream, int len){ int part1 =0; int part2 =0; struct Rbuffer *mybuf=(struct Rbuffer*) userdata; if ((mybuf->ptwrite + len) > MAXBUFFERSIZE){ part1=MAXBUFFERSIZE-mybuf->ptwrite; part2 = len-part1; memcpy (mybuf->buffer+mybuf->ptwrite,stream,part1); memcpy (mybuf->buffer,stream+part1,part2); } else { memcpy(mybuf->buffer+mybuf->ptwrite,stream,len); } mybuf->ptwrite = (mybuf->ptwrite +len) % MAXBUFFERSIZE; //fprintf(stderr,"callback_record(%p,%d,%d %d)\n",userdata,mybuf->ptwrite,part1,part2); }void callback_play(void *userdata, Uint8 *stream, int len){ struct Rbuffer *mybuf=(struct Rbuffer*) userdata; int ptwrite=mybuf->ptwrite ; int ptread =mybuf->ptread; int part1 =0; int part2 =0; int delta =0; delta = ptwrite-ptread; if(delta < 0){ if (((MAXBUFFERSIZE + delta) >= len)){ part1=MAXBUFFERSIZE-ptread; if (part1 >=len){ part1 = len; part2 = 0 ; } else { part2 = len-part1; } //fprintf(stderr,"callback_playT part1 %d part2 %d \n",part1,part2); memcpy (mybuf->helpbuffer,mybuf->buffer+ptread,part1); if (part2) memcpy (mybuf->helpbuffer+part1,mybuf->buffer,part2); SDL_MixAudio(stream,mybuf->helpbuffer, len, SDL_MIX_MAXVOLUME); mybuf->ptread = (mybuf->ptread +len) % MAXBUFFERSIZE; //fprintf(stderr,"callback_playT ptread %d ptwrite %d \n",ptread,ptwrite); } else { //fprintf(stderr,"Waiting for dataT to Play Ptread %dPtwrite %d !! \n",ptread,ptwrite); } } else { if (delta >= len){ memcpy (mybuf->helpbuffer,mybuf->buffer+ptread,len); SDL_MixAudio(stream,mybuf->helpbuffer, len, SDL_MIX_MAXVOLUME); mybuf->ptread = (mybuf->ptread +len) % MAXBUFFERSIZE; //fprintf(stderr,"callback_playF ptread %d ptwrite %d \n",ptread,ptwrite); } else { //fprintf(stderr,"Waiting for dataF to Play Ptread %d Ptwrite %d !! \n",ptread,ptwrite); } } } static int clip_to(int x, int low, int high);//void equalize (unsigned char *src, int width, int height, int format);static int adjust_bright( struct video_picture *videopict, int fd);static int get_pic_mean ( int width, int height, const unsigned char *buffer, int is_rgb,int startx, int starty, int endx, int endy );static int setVideoPict (struct video_picture *videopict, int fd);static int isSpcaChip (const char *BridgeName);/* return Bridge otherwhise -1 */static int getStreamId (const char * BridgeName);/* return Stream_id otherwhise -1 */static int probeSize (const char *BridgeName, int *width, int *height); /* return 1->ok otherwhise -1 */voidresize (unsigned char *dst,unsigned char *src, int Wd,int Hd,int Ws,int Hs) ;static intreadFrame (avi_t *out_fd,long i,unsigned char **jpegData, int * jpegSize, struct Rbuffer *RingBuffer, int maxsound, int *audiolen, int *soundbytes, int isaudio, int updown, int compress);static voidrefresh_screen (unsigned char *src, unsigned char *pict, int format, int width, int height,int owidth ,int oheight, int size, int autobright); int spcaClient (char *Ip, short port,int owidth, int oheight ,int statOn);int spcaPlay (char* inputfile, int width, int height);int spcaGrab (char *outputfile,char fourcc[4] , const char *videodevice, int image_width,int image_height, int format, int owidth, int oheight, int grabMethod,int videoOn,int audioout,int videocomp,int autobright,int statOn,int decodeOn); void *waitandshoot(void* ptr){ pictstruct *mypict = (pictstruct *) ptr; int width = mypict->width; int height = mypict->height; int format = mypict->formatIn; int size = mypict->sizeIn; int mode = mypict->mode; avi_t *fd = mypict->out_fd; int status;while(1){ status = pthread_mutex_lock (&mypict->mutex); if (status != 0) {fprintf(stderr,"Lock error!\n"); exit(-1);} while (pictFlag == 0) { /* Set predicate */ status = pthread_cond_wait(&mypict->cond, &mypict->mutex); if (status != 0) {fprintf(stderr,"Wait error!\n"); exit(-1);} } pictFlag = 0; getJpegPicture(mypict->data,width,height,format,size,mode,fd); if (modshoot) if (!(--numshoot)) Oneshoot = 0; status = pthread_mutex_unlock (&mypict->mutex); if (status != 0) {fprintf(stderr,"Unlock error!\n"); exit(-1);} /******* EXIT the MONITOR ************///printf("Condition was accept, data.value=%d\n",pictFlag);} return NULL; }void init_callbackmessage(struct client_t* callback){ char key[4] ={'O','K','\0','\0'} ; int x = 128; int y = 128; unsigned char sleepon=0; unsigned char bright=0; unsigned char contrast =0; unsigned char exposure = 0; unsigned char colors = 0; unsigned char size = 0; unsigned char fps = 0; memcpy(callback->message,key,4); callback->x = x; callback->y = y; callback->updobright=bright; callback->updocontrast=contrast; callback->updoexposure = exposure; callback->updocolors = colors; callback->sleepon=sleepon; callback->updosize = size; callback->fps = fps; }/* callback spec updobright = 1 increase bright updobright = 0 nothing todo updobright = 2 decrease bright same for all updocontrast updosize sleepon =1 ask the server for no frame on wakeup sleepon is cleared server will send frame and client should display sleepon =2 ask the server to send a 100ms pulse on pin 14 pin 14 is inverted always 1 pulse 0*/void reset_callbackmessage(struct client_t* callback){ callback->updobright= 0; callback->updocontrast= 0; callback->updoexposure = 0; callback->updocolors = 0; callback->sleepon= 0; callback->updosize = 0; callback->fps = 0; } intmain (int argc, char *argv[]){ /* Timing value used for statistic */ const char *videodevice = NULL; /* default mmap */ int grabMethod = 1; int format = VIDEO_PALETTE_YUV420P; /******** output screen pointer ***/ int image_width = IMAGE_WIDTH; int image_height = IMAGE_HEIGHT; int owidth = 0; int oheight = 0; /**********************************/ /* avi parametres */ char *inputfile = NULL; char *outputfile = NULL; char fourcc[4] = "MJPG"; char *sizestring = NULL; int use_libjpeg = 1; char *separateur; char *mode = NULL; /*********************************/ /* Starting Flags */ int i; int videoOn = 1; int decodeOn =1 ; int statOn = 0; int audioout = 0; int videocomp = 0; int channel = 0; int norme = 0; int autobright = 0; /*********************************/ char *AdIpPort; char AdIp[]= "000.000.000.000"; unsigned short ports = 0; /*********************************/ SPCASTATE funct; /* init default bytes per pixels for VIDEO_PALETTE_RAW_JPEG */ /* FIXME bpp is used as byte per pixel for the ouput screen */ /* we need also a bpp_in for the input stream as spcaview */ /* can convert stream That will be a good idea to have 2 struct */ /* with all global data one for input the other for output */ bpp = 3; funct = GRABBER; printf(" %s \n",version); /* check arguments */ for (i = 1; i < argc; i++) { /* skip bad arguments */ if (argv[i] == NULL || *argv[i] == 0 || *argv[i] != '-') { continue; } if (strcmp (argv[i], "-d") == 0) { if (i + 1 >= argc) { printf ("No parameter specified with -d, aborting.\n"); exit (1); } videodevice = strdup (argv[i + 1]); } if (strcmp (argv[i], "-n") == 0) { if (i + 1 >= argc) { printf ("No parameter specified with -n, aborting.\n"); exit (1); } norme = atoi (argv[i + 1]); if (norme < 0 || norme > 4) printf ("Norme should be between 0..4 Read the readme !.\n"); } if (strcmp (argv[i], "-c") == 0) { if (i + 1 >= argc) { printf ("No parameter specified with -c, aborting.\n"); exit (1); } channel = atoi (argv[i + 1]); if (channel < 0 || channel > 9) printf ("Channel should be between [0..3] || [6..9] Read the readme !.\n"); } if (strcmp (argv[i], "-v") == 0) { videoOn = 0; } if (strcmp (argv[i], "-j") == 0) { decodeOn = 0; } if (strcmp (argv[i], "-t") == 0) { statOn = 1; } if (strcmp (argv[i], "-z") == 0) { videocomp = 1; } if (strcmp (argv[i], "-b") == 0) { autobright = 1; } if (strcmp (argv[i], "-f") == 0) { if (i + 1 >= argc) { printf ("No parameter specified with -f, aborting.\n"); exit (1); } mode = strdup (argv[i + 1]); if (strncmp (mode, "r32", 3) == 0) { format = VIDEO_PALETTE_RGB32; bpp = 4; snprintf (fourcc, 5, "RGB4"); } else if (strncmp (mode, "r24", 3) == 0) { format = VIDEO_PALETTE_RGB24; bpp = 3; snprintf (fourcc, 5, "RGB3"); } else if (strncmp (mode, "r16", 3) == 0) { format = VIDEO_PALETTE_RGB565; bpp = 2; snprintf (fourcc, 5, "RGB2"); } else if (strncmp (mode, "yuv", 3) == 0) { format = VIDEO_PALETTE_YUV420P; bpp = 3; snprintf (fourcc, 5, "I420"); } else if (strncmp (mode, "jpg", 3) == 0) { format = VIDEO_PALETTE_JPEG; bpp = 3; snprintf (fourcc, 5, "MJPG"); }else { format = VIDEO_PALETTE_YUV420P; bpp = 3; snprintf (fourcc, 5, "I420"); } } if (strcmp (argv[i], "-i") == 0) { if (i + 1 >= argc) { printf ("No parameter specified with -i, aborting.\n"); exit (1); } inputfile = strdup (argv[i + 1]); funct = PLAYER ; } if (strcmp (argv[i], "-g") == 0) { /* Ask for read instead default mmap */ grabMethod = 0; } if (strcmp (argv[i], "-a") == 0) { if (i + 1 >= argc) { printf ("No parameter specified with -a, aborting.\n"); exit (1); } audioout = atoi (argv[i + 1]); if ((audioout < 0) || (audioout > 2)) { audioout = 0; } printf ("audio channel %d\n", audioout); } if (strcmp (argv[i], "-o") == 0) { if (i + 1 >= argc) { printf ("No parameter specified with -o, aborting.\n"); exit (1); } outputfile = strdup (argv[i + 1]); } /* custom ? */ if (strcmp (argv[i], "-s") == 0) { if (i + 1 >= argc) { printf ("No parameter specified with -s, aborting.\n"); exit (1); } sizestring = strdup (argv[i + 1]); image_width = strtoul (sizestring, &separateur, 10); if (*separateur != 'x') { printf ("Error in size use -s widthxheight \n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -