/* * * webcam.c - part of Danovitsch Webcam * * Copyright (C) 2001, 2003 by Daan Vreeken * * Published under the terms of the GNU Public License 2.0 * (or any later version) * */ #include #include #include #include #include #include #include #include #include #include "general.h" #include "io.h" #include "capture.h" #include "overlay.h" #include "display.h" #include "compress.h" #include "server.h" #include "http.h" #include "webcam.h" int PleaseDie = 0; int WantX; int TooOld(struct timeval *Object, long Sec, long USec) { struct timeval Temp = *Object; struct timeval Now; Temp.tv_sec+=Sec; Temp.tv_usec+=USec; while (Temp.tv_usec>=1000*1000) { Temp.tv_usec-=1000*1000; Temp.tv_sec++; } gettimeofday(&Now,NULL); if (Temp.tv_secClose=1; return; } else Error("EEEK! Fixme!! Received SIGPIPE!!"); PleaseDie=1; } void Translate(unsigned char *Dst, unsigned char *Src, int Bpp, int Depth) { int X,Y; unsigned char *DstC = Dst; unsigned short *DstW = (unsigned short *)Dst; unsigned char *SrcC = Src; long C; int Diff; int Plus; unsigned char Cnt; unsigned char Cnt2; switch (Depth) { case 16: for (Y=0; Y>3)<<0; //B C+=((*SrcC++)>>2)<<5; //G C+=((*SrcC++)>>3)<<11; //R SrcC++; *DstW++=C; } break; case 24: case 32: for (Y=0; Y0) { Readed=fread(Buf,1,sizeof(Buf),OverlayTxt); for (Cnt=0; Cnt=argc) Error="Missing argument for -jpegquality"; else { if (!sscanf(argv[Cnt],"%d",&JPEGQuality)) Error="Invalid argument for -jpegquality"; else { if ((JPEGQuality<0) || (JPEGQuality>100)) Error="Argument for -jpegquality out of range"; } Debug(30,"JPEGQuality set to: %d",JPEGQuality); } ArgOK=1; } if (!ArgOK) { printf("unknown option '%s', try -help\n",argv[Cnt]); exit(0); } if (Error!=NULL) { printf("error:\n"); printf("%s!\n",Error); exit(0); } } if (WantHelp) CommandlineHelp(); } int main(int argc, char *argv[]) { XWnd *Wnd; char ListenAddr[20]; struct sockaddr_in Addr; int Len; int NewConn; int FDMax; fd_set ReadMask; fd_set WriteMask; struct timeval MaxWait; unsigned char Nop; int Cnt; struct Connection *C; enum ConnState State; struct Capture_SettingsArr *Arr = &Capture_Settings[0]; time_t GMTime; struct tm *Time; signal(SIGTERM,&DeadHandler); signal(SIGTSTP,&DeadHandler); signal(SIGABRT,&DeadHandler); signal(SIGQUIT,&DeadHandler); signal(SIGHUP,&DeadHandler); signal(SIGINT,&DeadHandler); signal(SIGPIPE,&DeadHandler); ParseCommandline(argc,argv); if (WantX) Display_Init(); IO_Init(); Server_Init(); Compress_Init(); if (WantX) { Wnd=Display_CreateWindow(); if (Wnd==NULL) ExitFatal("Could not create window!"); Display_CreateImage(Wnd,ImageWidth,ImageHeight); Display_ResizeWindow(Wnd,ImageWidth+10,ImageHeight+10); } pipe(&Capture_Fifo[0]); MaxWait.tv_sec=0; MaxWait.tv_usec=MainLoop_msec*1000; Capture_Device=open("/dev/bktr0",O_RDONLY); //Capture_Device=open("/dev/bktr1",O_RDONLY); if (Capture_Device==-1) ExitFatal("Could not open capture device!"); Capture_SetFormat(); Capture_SetSource(); Capture_Setup(); Capture_Single(); ///Set all settings to default setting.. // while (Arr->ID!=NoID) { Capture_Set(Arr,NULL,Arr->NumValue,Arr->OrgValue); Arr++; } sprintf(ListenAddr,Server_ListenAddr); memset(&(Addr.sin_zero),0,8); Addr.sin_family=AF_INET; Addr.sin_port=htons(Server_Port); Addr.sin_addr.s_addr=inet_addr(ListenAddr); Len=sizeof(Addr); AcceptSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); Cnt=1; setsockopt(AcceptSock,SOL_SOCKET,SO_REUSEADDR,(char *)&Cnt,sizeof(Cnt)); if (bind(AcceptSock,(struct sockaddr *)&Addr,Len)==-1) ExitFatal("Could not bind socket!"); if (listen(AcceptSock,5)==-1) ExitFatal("Socket error!"); while (!PleaseDie) { /// Check age of frame buffer // if (TooOld(&FrameTime,FrameTimeout)) Capture_Single(); /// Dump dead connections // for (Cnt=0; Cnt=0; Cnt--) if (Client[Cnt].Close) Server_CloseConnection(Cnt); FD_ZERO(&ReadMask); FD_ZERO(&WriteMask); FD_SET(AcceptSock,&ReadMask); FD_SET(Capture_Fifo[1],&ReadMask); FDMax=AcceptSock; if (Capture_Fifo[1]>FDMax) FDMax=Capture_Fifo[1]; for (Cnt=0; CntFDMax) FDMax=Client[Cnt].FD; } if (State==Response) { FD_SET(Client[Cnt].FD,&WriteMask); if (Client[Cnt].FD>FDMax) FDMax=Client[Cnt].FD; } } /// Wait for data to get available (anywhere) // if (select(FDMax+1,&ReadMask,&WriteMask,NULL,&MaxWait)<=0) { continue; } /// New connection? // if (FD_ISSET(AcceptSock,&ReadMask)) { NewConn=accept(AcceptSock,NULL,NULL); if (NewConn==-1) ExitFatal("Hugh? accept returned an error!"); //fcntl(NewConn,F_SETFD,O_NONBLOCK); if (ClientsFD=NewConn; C->Close=0; C->State=GetRequest; C->Mode=LineMode; C->Line=NULL; C->Length=0; C->Request=NULL; C->PostData=NULL; C->PostLength=0; C->ContentLength=0; C->Error=0; gettimeofday(&C->ConnectTime,NULL); Clients++; } else { Debug(80,"Server full... (dropping new connection)"); close(NewConn); } } /// Check client connections for activity... // for (Cnt=0; Cnttm_hour,Time->tm_min,Time->tm_sec,Time->tm_zone); if (WantX) { Translate((unsigned char *)Wnd->Buffer,(unsigned char *)FrameBuffer,Wnd->Bpp,Wnd->MyDepth); //memcpy(Wnd->Buffer,FrameBuffer,4*ImageWidth*ImageHeight); Display_UpdateImage(Wnd); } NewFrame=0; } } Output("\n\nSomeone wants us to die!"); Server_Shutdown(); Capture_Shutdown(); if (WantX) { Display_DestroyImage(Wnd); Display_Kill(Wnd); } Output("\nMoo,\n]:8)"); return 0; }