--- camserv-0.353.orig/camserv/main_loop.c Sat Nov 6 12:26:36 1999 +++ camserv-0.353/camserv/main_loop.c Sun Nov 21 22:23:59 1999 @@ -172,7 +172,8 @@ return -1; } - if( command == 0 ) { +/* printf("dispatch channel %d\n", command); */ + if( (command >= 0) && (command <= 2) ) { /* dichro */ char *new_picture_data; int nbytes; @@ -183,7 +184,8 @@ } memcpy( new_picture_data, picture_mem, nbytes ); - if( manager_new_picture( new_picture_data, nbytes, 100 ) == -1 ){ + + if( manager_new_picture( new_picture_data, nbytes, 100, command ) == -1 ){ /* dichro */ camserv_log( MODNAME, "Unable to manage picture!"); free( new_picture_data ); return -1; @@ -192,7 +194,7 @@ camserv_log( MODNAME, "Unknown pictaker dispatch command: %d", command ); return -1; } - return 0; + return command; /* dichro */ } static @@ -222,7 +224,7 @@ } } - cinfo->management_data = manager_new_client(&pic_data, &pic_size, &pic_id); + cinfo->management_data = manager_new_client(&pic_data, &pic_size, &pic_id, 0); if( cinfo->management_data == NULL ){ camserv_log( MODNAME, "Error managing proxy! (Picture may not be " "taken yet)"); @@ -253,6 +255,7 @@ static int write_regular_client( ClientInfo *cinfo, SockSet *writeset ){ +/* printf("writing client\n"); */ switch(databuf_write( cinfo->writebuf, socket_query_fd( cinfo->socket ))) { case -1 : /* Error */ @@ -266,13 +269,16 @@ size_t pic_size; int pic_id; +/* printf("into man_new_cli: %d\n", cinfo->socket->vidchan); */ cinfo->management_data = manager_new_client( &pic_data, &pic_size, - &pic_id ); + &pic_id, cinfo->socket->vidchan ); /* dichro */ +/* printf("out of man_new_cli\n"); */ if( cinfo->management_data == NULL ){ camserv_log( MODNAME, "Error managing client! (Picture may not" " be taken yet)"); /* Wait for the next successful picture to come around */ sockset_hold( writeset, cinfo->socket ); +/* printf("finished writing 3\n"); */ return 0; } @@ -281,6 +287,7 @@ cinfo->management_data = NULL; /* Whoa boy! Hold on a second! */ sockset_hold( writeset, cinfo->socket ); +/* printf("finished writing 2\n"); */ return 0; } @@ -332,6 +339,7 @@ case 1: /* Keep feeding data to the client */ break; } +/* printf("finished writing\n"); */ return 0; } @@ -364,11 +372,11 @@ } int main_loop( CamConfig *ccfg, Socket *picture_sock, char *picture_mem ){ - Socket *listen_socket; + Socket *listen_socket[3]; /* dichro */ SockSet *readset = NULL, *writeset = NULL; list_t *client_sockets; lnode_t *node; - int cfg_listen_port, highest_fd, num_clients, picture_client_ready; + int cfg_listen_port, highest_fd, num_clients, i, picture_client_ready[3]; /* dichro */ ClientInfo *clientinfo, *clientinfo2; if( (client_sockets = list_create( -1 )) == NULL) @@ -388,23 +396,29 @@ return -1; } - if((listen_socket = socket_serve_tcp( NULL, cfg_listen_port, 100 )) == NULL ) - { - camserv_log( MODNAME, "Error setting up socket on port \"%d\". Exiting", - cfg_listen_port ); - list_destroy( client_sockets ); - sockset_dest( readset ); - sockset_dest( writeset ); - return -1; + for(i = 0; i < 3; i++) { /* dichro */ + if((listen_socket[i] = socket_serve_tcp( NULL, cfg_listen_port + i, 100 )) == NULL ) + { + camserv_log( MODNAME, "Error setting up socket on port \"%d\". Exiting", + cfg_listen_port ); + list_destroy( client_sockets ); + sockset_dest( readset ); + sockset_dest( writeset ); + return -1; + } + listen_socket[i]->vidchan = i; } - highest_fd = MAX( socket_query_fd( listen_socket ), - socket_query_fd( picture_sock )); - clientinfo = clientinfo_new( listen_socket ); + for(i = 0; i < 3; i++) { /* dichro */ + highest_fd = MAX( socket_query_fd( listen_socket[i] ), + socket_query_fd( picture_sock )); + clientinfo = clientinfo_new( listen_socket[i] ); + sockset_add_fd( readset, listen_socket[i], clientinfo ); + } + clientinfo2 = clientinfo_new( picture_sock ); - if( !clientinfo || !clientinfo2 || - sockset_add_fd( readset, listen_socket, clientinfo ) == -1 || + if( !clientinfo || !clientinfo2 || /* dichro */ sockset_add_fd( readset, picture_sock, clientinfo2 ) == -1 ) { camserv_log( MODNAME, "Error adding initial sockets to sockset!"); @@ -417,7 +431,8 @@ } num_clients = 0; - picture_client_ready = 1; + for(i = 0; i < 3; i++) + picture_client_ready[i] = 1; /* dichro */ setup_signals(); Abort = 0; @@ -425,9 +440,18 @@ int sel_res, i, nset_socks; void **set_socks; - if( num_clients > 0 && picture_client_ready == 1 ){ - send( socket_query_fd( picture_sock ), "0", sizeof( "0" ), 0 ); - picture_client_ready = 0; + if( num_clients > 0){ /* dichro */ + for(i = 0; i < 3; i++) { + char buf[8]; + + if(!picture_client_ready[i]) + continue; + memset(buf, 0, 8); + sprintf(buf, "%d", i << 8); + send( socket_query_fd( picture_sock ), buf, strlen(buf) + 1, 0 ); + picture_client_ready[i] = 0; +/* printf("sending request for %d\n", i); */ + } } sockset_reset( readset ); @@ -451,10 +475,13 @@ clientinfo = set_socks[ i ]; - if( clientinfo->socket == listen_socket ) { +/* printf("readable %d\n", socket_query_fd(clientinfo->socket)); */ + if( clientinfo->socket == listen_socket[0] || /* dichro */ + clientinfo->socket == listen_socket[1] || + clientinfo->socket == listen_socket[2] ) { /* New client */ - if( (new_cinfo = accept_client( listen_socket )) == NULL ) + if( (new_cinfo = accept_client( clientinfo->socket )) == NULL ) continue; if( (node = lnode_create( new_cinfo )) == NULL ){ @@ -507,10 +534,12 @@ num_clients--; } else { if( clientinfo->socket == picture_sock ) { - if( dispatch_pictaker( cmdbuf, picture_mem ) == -1 ) + if( (i = dispatch_pictaker( cmdbuf, picture_mem )) == -1 ) { /* dichro */ camserv_log( MODNAME, "Pictaker dispatch failure!"); - sockset_unhold_all( writeset ); - picture_client_ready = 1; + } else { + sockset_unhold_all( writeset ); + picture_client_ready[i] = 1; + } } else { /* Information from a regular client */ cmdbuf[ readlen ] = '\0'; @@ -611,7 +640,7 @@ list_destroy_nodes( client_sockets ); list_destroy( client_sockets ); - socket_dest( listen_socket ); + /* socket_dest( listen_socket ); */ /* dichro */ return 0; } diff -ru camserv-0.353.orig/camserv/picture_loop.c camserv-0.353/camserv/picture_loop.c --- camserv-0.353.orig/camserv/picture_loop.c Sat Nov 6 16:17:27 1999 +++ camserv-0.353/camserv/picture_loop.c Sun Nov 21 22:26:36 1999 @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include "camconfig.h" #include "camshm.h" @@ -23,6 +25,37 @@ #define MODNAME "picloop" +typedef struct video_v4l_st { + char section_name[ MAX_SECTION_NAME + 1 ]; + struct video_capability vidcaps; + struct video_window vidwin; + struct video_tuner vidtuner; + struct video_channel vidchan; + struct video_mbuf vidmbuf; + struct video_mmap vidmmap; + struct video_audio vidaudio; + struct video_picture vidpict; + + int current_frame; + int video_fd; + char *video_buffer; /* mmap()ed buffer */ + size_t video_buffer_size; /* Size of mmap()ed buffer */ + int initialized; + int width, height; /* Width & height of the video */ + int uses_mbuf; + int is_black_white; /* TRUE of black and white, else FALSE */ + + int autobright; /* 0 if autobright is turned off, else the # + of frames in between brightness adjustments */ + int brightmean; /* The mean value of the brightness 'goal' when + doing autobrightness adjustments */ + int autoleft; /* # of frames left until next auto bright */ + int brightx1, brighty1, + brightx2, brighty2; /* Points giving rectangle of which to calculate + the 'mean' pixel value, which is then used + to modify the whole image. */ +} Video_V4L; + /* * report_picsnap: Report a snapped picture to the parent process. * @@ -31,10 +64,11 @@ */ static -void report_picsnap( Socket *server_sock, int bytes ){ +void report_picsnap( Socket *server_sock, int bytes, int chan ){ /* dichro */ char buf[ 1024 ]; - sprintf( buf, "%d %d", 0, bytes ); +/* printf("report %d %d\n", chan, bytes); */ + sprintf( buf, "%d %d", chan, bytes ); send( socket_query_fd( server_sock ), buf, strlen( buf ) + 1, 0 ); } @@ -399,10 +433,22 @@ continue; } - if( dispatch_id == 0 ){ /* Snap a picture */ +/* printf("received req %d in pic_loop\n", dispatch_id); */ + if( (dispatch_id & 0xff) == 0 ){ /* Snap a picture */ char *pic_snap; int nsnaps; + static int lastchan = -1; /* dichro */ + dispatch_id >>= 8; + if(lastchan != dispatch_id) { + struct video_channel vc; + + vc.channel = dispatch_id; + vc.norm = VIDEO_MODE_PAL; + if(ioctl(((Video_V4L *)vid_device)->video_fd, VIDIOCSCHAN, &vc)) + perror("VIDIOSCHAN"); + lastchan = dispatch_id; + } for( nsnaps=0; nsnaps < MAX_CONSEC_BAD_SNAPS; nsnaps++ ){ if( memhack_buf ) pic_snap = memhack_buf; else pic_snap = picture_memory; @@ -437,7 +483,7 @@ filter_list_process( filters, pic_snap, picture_memory, &vinfo, &out_vinfo ); - report_picsnap( server_sock, out_vinfo.nbytes ); + report_picsnap( server_sock, out_vinfo.nbytes, dispatch_id ); time( &cur_time ); if( cur_time - last_cur_time > 10 ) /* Fudge factor */{ time( &start_time ); diff -ru camserv-0.353.orig/camserv/video_v4l.c camserv-0.353/camserv/video_v4l.c --- camserv-0.353.orig/camserv/video_v4l.c Sat Nov 6 12:22:29 1999 +++ camserv-0.353/camserv/video_v4l.c Sun Nov 21 22:26:33 1999 @@ -751,12 +751,36 @@ } +volatile int channel = 0; +volatile int urk = 0; +int fish = 0; + +static void rotchan(int dummy) { + channel++; + channel %= 3; + urk = 1; +} + static int mbuf_snapshot( Video_V4L *vid_dev, char *place_buffer ){ /* XXX -- Apparently the v4linux stuff can sometimes hang on a VIDIOCSYNC call .. *sigh* -- SO we simply bail out when the alarm rings */ + if(!fish) { + signal(SIGUSR1, rotchan); + fish++; +/* printf("%d here I am!\n", getpid()); */ + } + if(urk) { + struct video_channel vc; + + vc.channel = channel; + vc.norm = VIDEO_MODE_PAL; + if(ioctl(vid_dev->video_fd, VIDIOCSCHAN, &vc)) + perror("VIDIOSCHAN"); + urk = 0; + } alarm( SYNC_FAILURE_ALARM ); if( ioctl( vid_dev->video_fd, VIDIOCSYNC, &vid_dev->current_frame) == -1 ){ perror( "VIDIOSYNC" ); diff -ru camserv-0.353.orig/common/manager.c camserv-0.353/common/manager.c --- camserv-0.353.orig/common/manager.c Wed Nov 3 15:27:28 1999 +++ camserv-0.353/common/manager.c Sun Nov 21 22:31:23 1999 @@ -28,6 +28,7 @@ size_t picture_size; int picture_id; int nClients; /* # of clients using the bin */ + int chan; /* dichro */ } Picture_Bin; /* @@ -60,6 +61,7 @@ res->picture_size = 0; res->nClients = 0; res->picture_id = 0; + res->chan = 0; return res; } @@ -93,10 +95,11 @@ */ int -manager_new_picture( char *picture_data, size_t pic_size, int max_clients ){ +manager_new_picture( char *picture_data, size_t pic_size, int max_clients, int channel ){ /* dichro */ Picture_Bin *new_bin; lnode_t *binlist_node, *node_next; +/* printf("new pic channel %d\n", channel); */ if( (new_bin = picture_bin_new( max_clients )) == NULL ){ return -1; } @@ -104,6 +107,7 @@ new_bin->picture_data = picture_data; new_bin->picture_size = pic_size; new_bin->picture_id = Current_Picture_Id++; + new_bin->chan = channel; if( (binlist_node = lnode_create( new_bin )) == NULL ){ fprintf( stderr, "Manager; Couldn't allocate lnode!\n"); @@ -136,7 +140,7 @@ /* If the bin doesn't have any clients, just delete it */ - if( node_data->nClients == 0 ){ + if( (node_data->nClients == 0) && (node_data->chan == channel) ){ /* dichro */ list_delete( Manager_BinList, binlist_node ); picture_bin_dest( node_data ); lnode_destroy( binlist_node ); @@ -170,17 +174,28 @@ */ void *manager_new_client( char **pic_data, size_t *pic_size, - int *pic_id ) + int *pic_id, int channel ) /* dichro */ { - lnode_t *binlist_head_node; + lnode_t *binlist_head_node, *start; Picture_Bin *pic_bin; +/* printf("manager client for chan %d\n", channel); */ if( Manager_BinList == NULL ) return NULL; - binlist_head_node = list_first( Manager_BinList ); - if( binlist_head_node == NULL ){ - return NULL; + start = binlist_head_node = list_first( Manager_BinList ); + while(1) { + if( binlist_head_node == NULL ){ + return NULL; + } +/* printf("looping %p, found %d, looking for %d\n", */ +/* binlist_head_node, ((Picture_Bin *)binlist_head_node->data)->chan, channel); */ + if(((Picture_Bin *)binlist_head_node->data)->chan == channel) /* dichro */ + break; +/* binlist_head_node = binlist_head_node->next; */ + binlist_head_node = list_next(Manager_BinList, binlist_head_node); + if(binlist_head_node == start) + return NULL; } pic_bin = binlist_head_node->data; @@ -190,6 +205,7 @@ *pic_id = pic_bin->picture_id; pic_bin->nClients++; +/* printf("exiting client for chan %d\n", channel); */ return binlist_head_node; } diff -ru camserv-0.353.orig/common/socket.c camserv-0.353/common/socket.c --- camserv-0.353.orig/common/socket.c Thu Nov 4 18:24:26 1999 +++ camserv-0.353/common/socket.c Sun Nov 21 20:52:16 1999 @@ -25,15 +25,6 @@ #include "socket.h" -#define BAD_SOCKET -1 -#define BAD_PORT -1 -#define MAX_SOCKET_REMOTE_NAME 512 - -struct socket_st { - int fd; - char remote_name[ MAX_SOCKET_REMOTE_NAME ]; /* hostname of remote */ - short port; -}; /* * socket_zero: Zero out a socket structure @@ -45,6 +36,7 @@ sock->fd = BAD_SOCKET; sock->port = BAD_PORT; strcpy( sock->remote_name, "** Disconnected **" ); + sock->vidchan = 0; /* dichro */ } /* @@ -203,11 +195,13 @@ Socket *sockres; struct sockaddr_in sin; int val; + long opt = 1; if( (sockres = socket_new()) == NULL ) return NULL; sockres->port = port; + sockres->vidchan = port - 9192; /* dichro */ if( (sockres->fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP )) < 0 ){ perror( "socket()" ); @@ -229,6 +223,8 @@ } } + if(setsockopt(sockres->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) + perror("setsockopt(SO_REUSEADDR)"); if( bind( sockres->fd, (struct sockaddr *)&sin, sizeof( sin )) < 0 ) { perror( "bind()" ); socket_dest( sockres ); @@ -279,6 +275,7 @@ new_socket->fd = accres; new_socket->port = sin->sin_port; + new_socket->vidchan = listen_sock->vidchan; /* dichro */ socket_set_remote_name( new_socket, inet_ntoa( sin->sin_addr )); return new_socket; } diff -ru camserv-0.353.orig/include/config.h camserv-0.353/include/config.h --- camserv-0.353.orig/include/config.h Sat Nov 6 17:42:50 1999 +++ camserv-0.353/include/config.h Thu Nov 11 18:21:35 1999 @@ -37,7 +37,7 @@ #define HAVE_STRERROR 1 /* Define if you have the header file. */ -#define HAVE_IMLIB2_H 1 +/* #undef HAVE_IMLIB2_H */ /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 diff -ru camserv-0.353.orig/include/manager.h camserv-0.353/include/manager.h --- camserv-0.353.orig/include/manager.h Wed Oct 27 14:11:13 1999 +++ camserv-0.353/include/manager.h Sun Nov 21 20:46:29 1999 @@ -2,10 +2,10 @@ #define MANAGER_DOT_H extern void *manager_new_client( char **pic_data, - size_t *pic_size, int *pic_id ); + size_t *pic_size, int *pic_id, int channel ); extern int manager_dest_client( void *reset_data ); extern int manager_new_picture( char *picture_data, size_t pic_size, - int max_clients ); + int max_clients, int channel ); /* dichro */ #endif diff -ru camserv-0.353.orig/include/socket.h camserv-0.353/include/socket.h --- camserv-0.353.orig/include/socket.h Wed Oct 27 13:57:23 1999 +++ camserv-0.353/include/socket.h Sun Nov 21 20:51:58 1999 @@ -10,6 +10,19 @@ #include #include +/* dichro - boggle */ + +#define BAD_SOCKET -1 +#define BAD_PORT -1 +#define MAX_SOCKET_REMOTE_NAME 512 + +struct socket_st { + int fd; + char remote_name[ MAX_SOCKET_REMOTE_NAME ]; /* hostname of remote */ + short port; + int vidchan; /* dichro */ +}; + typedef struct socket_st Socket; extern Socket *socket_serve_tcp( const char *hname, int port, int backlog );