00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #include <unistd.h>
00071 #include <stdio.h>
00072 #include <stdlib.h>
00073 #include <signal.h>
00074 #include <fcntl.h>
00075 #include <sys/uio.h>
00076 #include <errno.h>
00077 #include <sys/types.h>
00078 #include <sys/socket.h>
00079 #include <sys/stat.h>
00080
00081
00082 #include <time.h>
00083 #include <string.h>
00084
00085 #include <netinet/in.h>
00086 #include <sys/mman.h>
00087 #include <sys/ioctl.h>
00088
00089 #include <asm/elphel/c313a.h>
00090
00091 #include <asm/elphel/ext353.h>
00092 #include <asm/byteorder.h>
00093
00094
00095 #include <ogg/ogg.h>
00096 #include "ogmstreams.h"
00097
00098
00099 #include "camogm_ogm.h"
00100 #include "camogm_jpeg.h"
00101 #include "camogm_mov.h"
00102 #include "camogm_kml.h"
00103 #include "camogm.h"
00104
00105 #define TRAILER_SIZE 0x02
00106 #define MAP_OPTIONS MAP_FILE|MAP_PRIVATE
00107
00108 char trailer[TRAILER_SIZE] = {0xff,0xd9};
00109
00110 const char ExifFileName[]="/dev/exif_exif";
00111
00112 const char HeadFileName[]="/dev/jpeghead";
00113 const char ctlFileName[]="/dev/frameparsall";
00114 unsigned long * ccam_dma_buf;
00115
00116 int lastDaemonBit= DAEMON_BIT_CAMOGM;
00117 struct framepars_all_t *frameParsAll;
00118 struct framepars_t *framePars;
00119 unsigned long *globalPars;
00120
00121
00122 int buff_size;
00123
00124 #define DEFAULT_DURATION 60
00125 #define DEFAULT_LENGTH 100000000
00126
00127 #define DEFAULT_FRAMES 16384
00128 #define DEFAULT_FRAMES_PER_CHUNK 10
00129
00130 #define DEFAULT_LENGTH 100000000
00131 #define DEFAULT_EXIF 1
00132
00133 static char cmdbuf[1024];
00134 static int cmdbufp=0;
00135 static int cmdstrt=0;
00136
00137 camogm_state sstate;
00138 camogm_state * state;
00139
00140 int debug_level;
00141 FILE* debug_file;
00142
00143
00144 int camogm_init(void);
00145 int camogm_start(void);
00146
00147
00148
00149
00150
00151
00152 int camogm_stop(void);
00153 int camogm_reset(void);
00154 int camogm_debug(const char * fname);
00155 int camogm_debug_level(int d);
00156 void camogm_set_segment_duration(int sd);
00157 void camogm_set_segment_length(int sl);
00158 void camogm_set_save_gp(int d);
00159 void camogm_set_prefix (const char * p);
00160 void camogm_set_exif(int d);
00161 void camogm_set_timescale(double d);
00162 void camogm_set_frames_skip(int d);
00163 void camogm_set_format(int d);
00164
00165 void camogm_kml_set_enable(int d);
00166 void camogm_kml_set_horHalfFov (double dd);
00167 void camogm_kml_set_vertHalfFov(double dd);
00168 void camogm_kml_set_height_mode(int d);
00169 void camogm_kml_set_height(double dd);
00170 void camogm_kml_set_period(int d);
00171 void camogm_kml_set_near(double dd);
00172
00173
00174 int parse_cmd(FILE* npipe);
00175 char * getLineFromPipe(FILE* npipe);
00176
00177 int sendImageFrame (void);
00178
00179 void camogm_set_max_frames(int d);
00180 void camogm_set_frames_per_chunk(int d);
00181
00182
00184 void put_uint16(void *buf, u_int16_t val)
00185 {
00186 unsigned char *tmp;
00187
00188 tmp = (unsigned char *) buf;
00189
00190 tmp[0] = val & 0xff;
00191 tmp[1] = (val >>= 8) & 0xff;
00192 }
00193
00194 void put_uint32(void *buf, u_int32_t val)
00195 {
00196 unsigned char *tmp;
00197
00198 tmp = (unsigned char *) buf;
00199
00200 tmp[0] = val & 0xff;
00201 tmp[1] = (val >>= 8) & 0xff;
00202 tmp[2] = (val >>= 8) & 0xff;
00203 tmp[3] = (val >>= 8) & 0xff;
00204 }
00205
00206 void put_uint64(void *buf, u_int64_t val)
00207 {
00208 unsigned char *tmp;
00209
00210 tmp = (unsigned char *) buf;
00211
00212 tmp[0] = val & 0xff;
00213 tmp[1] = (val >>= 8) & 0xff;
00214 tmp[2] = (val >>= 8) & 0xff;
00215 tmp[3] = (val >>= 8) & 0xff;
00216 tmp[4] = (val >>= 8) & 0xff;
00217 tmp[5] = (val >>= 8) & 0xff;
00218 tmp[6] = (val >>= 8) & 0xff;
00219 tmp[7] = (val >>= 8) & 0xff;
00220 }
00221
00222 int camogm_init(void) {
00223 const char sserial[]="elp0";
00224 int * ipser= (int*) sserial;
00225 state->running=0;
00226 state->starting=0;
00227 state->vf=NULL;
00228 camogm_set_segment_duration(DEFAULT_DURATION);
00229 camogm_set_segment_length(DEFAULT_LENGTH);
00230 camogm_set_max_frames(DEFAULT_FRAMES);
00231 camogm_set_frames_per_chunk(DEFAULT_FRAMES_PER_CHUNK);
00232 camogm_set_prefix ("\0");
00233 camogm_set_save_gp(0);
00234 camogm_reset();
00235 state->serialno= ipser[0];
00236 state->last= 0;
00237 debug_file= stderr;
00238 camogm_debug_level(1);
00239 strcpy(state->debug_name,"stderr");
00240 camogm_set_timescale(1.0);
00241 camogm_set_frames_skip(0);
00242 camogm_set_format(CAMOGM_FORMAT_OGM);
00243 state->exifSize=0;
00244 state->exif= DEFAULT_EXIF;
00245 state->frame_lengths=NULL;
00246 state->frameno=0;
00247 state->formats=0;
00248
00250 camogm_kml_set_enable(0);
00251 state->kml_file=NULL;
00252 camogm_kml_set_horHalfFov (20.0);
00253 camogm_kml_set_vertHalfFov(15.0);
00254 camogm_kml_set_height_mode(0);
00255 camogm_kml_set_height(10.0);
00256 camogm_kml_set_period(2);
00257 camogm_kml_set_near(40.0);
00258 state->kml_path[0]='\0';
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 return 0;
00284 }
00285
00286
00287 int camogm_debug(const char * fname) {
00288 int none=1;
00289 if (fname && strlen(fname) && strcmp(fname, "none") && strcmp(fname, "null") && strcmp(fname, "/dev/null")) none=0;
00290 if (debug_file){
00291 if (strcmp(state->debug_name, "stdout") && strcmp(state->debug_name, "stderr")) fclose (debug_file);
00292 debug_file=NULL;
00293 state->debug_name[0]='\0';
00294 }
00295 if (!none) {
00296 if (strcmp(fname, "stdout") ==0) debug_file=stdout;
00297 else if (strcmp(fname, "stderr") ==0) debug_file=stderr;
00298 else debug_file=fopen(fname,"w+");
00299 }
00300 if (debug_file) {
00301 strncpy(state->debug_name,fname,sizeof(state->debug_name)-1);
00302 state->debug_name[sizeof(state->debug_name)-1]='\0';
00303 }
00304 return 0;
00305 }
00306
00307 int camogm_debug_level(int d) {
00308 debug_level=d;
00309 return 0;
00310 }
00311
00312
00313
00314
00315 int camogm_start(void) {
00316 int timestamp_start;
00317 int rslt;
00318 int next_metadata_start, next_jpeg_len, fp;
00319 D1(fprintf (debug_file,"Starting recording\n"));
00320 state->frameno=0;
00321 state->timescale= state->set_timescale;
00322
00323 int * ifp = (int *) &(state->frame_params) ;
00324 int * ifp_this = (int *) &(state->this_frame_params) ;
00325 if (state->kml_enable) camogm_init_kml() ;
00326
00327 if (state->format != state->set_format) {
00328 state->format= state->set_format;
00329 switch (state->format) {
00330 case CAMOGM_FORMAT_NONE: rslt= 0; break;
00331 case CAMOGM_FORMAT_OGM: rslt= camogm_init_ogm(); break;
00332 case CAMOGM_FORMAT_JPEG: rslt= camogm_init_jpeg();break;
00333 case CAMOGM_FORMAT_MOV: rslt= camogm_init_mov(); break;
00334 }
00335 state->formats |= 1 << (state->format);
00337 }
00338 state->max_frames= state->set_max_frames;
00339 state->frames_per_chunk= state->frames_per_chunk;
00340 state->starting=1;
00341
00342 D3(fprintf (debug_file,"1: state->cirbuf_rp=0x%x\n",state->cirbuf_rp));
00343 if ((state->cirbuf_rp <0) || (lseek(state->fd_circ,state->cirbuf_rp,SEEK_SET) < 0) || (lseek(state->fd_circ,LSEEK_CIRC_VALID,SEEK_END) < 0 )) {
00344 D3(fprintf (debug_file,"2: state->cirbuf_rp=0x%x\n",state->cirbuf_rp));
00345 state->cirbuf_rp=lseek(state->fd_circ,LSEEK_CIRC_LAST,SEEK_END);
00346 if (((fp=lseek(state->fd_circ,LSEEK_CIRC_PREV,SEEK_END)))>=0) state->cirbuf_rp=fp;
00347 state->buf_overruns++;
00349
00350
00351 state->buf_min=getGPValue(G_FREECIRCBUF);
00352
00353 } else {
00354
00355
00356 if (state->buf_min > getGPValue(G_FREECIRCBUF)) state->buf_min=getGPValue(G_FREECIRCBUF);
00357
00358 }
00359 D3(fprintf (debug_file,"3: state->cirbuf_rp=0x%x\n",state->cirbuf_rp));
00360 D3(fprintf (debug_file,"4:lseek(state->fd_circ,LSEEK_CIRC_READY,SEEK_END)=%d\n",(int) lseek(state->fd_circ,LSEEK_CIRC_READY,SEEK_END)));
00361
00363 if (lseek(state->fd_circ,LSEEK_CIRC_READY,SEEK_END) <0) return -CAMOGM_FRAME_NOT_READY;
00364 D3(fprintf (debug_file,"5: state->cirbuf_rp=0x%x\n",state->cirbuf_rp));
00365 state->metadata_start=(state->cirbuf_rp)-32;
00366 if (state->metadata_start<0) state->metadata_start+=state->circ_buff_size;
00367
00369
00370 memcpy (&(state->frame_params), (unsigned long * ) &ccam_dma_buf[state->metadata_start>>2],32);
00371 state->jpeg_len=state->frame_params.frame_length;
00372
00373
00374 if (state->frame_params.signffff !=0xffff) {
00375 D0(fprintf(debug_file, "%s:%d: wrong signature - %d\r\n",__FILE__,__LINE__,(int) state->frame_params.signffff));
00376 state->cirbuf_rp=-1;
00377 D1(fprintf(debug_file, "state->cirbuf_rp=0x%x\r\n",(int) state->cirbuf_rp));
00378 D1(fprintf(debug_file, "%08x %08x %08x %08x %08x %08x %08x %08x\r\n",ifp[0],ifp[1],ifp[2],ifp[3],ifp[4],ifp[5],ifp[6],ifp[7]));
00379 return -CAMOGM_FRAME_BROKEN;
00380 }
00383 timestamp_start=(state->cirbuf_rp)+((state->jpeg_len+CCAM_MMAP_META+3) & (~0x1f)) + 32 - CCAM_MMAP_META_SEC;
00384 if (timestamp_start >= state->circ_buff_size) timestamp_start-=state->circ_buff_size;
00385 memcpy (&(state->frame_params.timestamp_sec), (unsigned long * ) &ccam_dma_buf[timestamp_start>>2],8);
00386
00388 if ((lseek(state->fd_circ,LSEEK_CIRC_NEXT,SEEK_END) < 0 ) ||
00390 (((fp=lseek(state->fd_circ,LSEEK_CIRC_READY,SEEK_END))) < 0)) {
00391 lseek(state->fd_circ,state->cirbuf_rp,SEEK_SET);
00392 return -CAMOGM_FRAME_NOT_READY;
00393 }
00394 next_metadata_start=fp-32;
00395 if (next_metadata_start<0) next_metadata_start+= state->circ_buff_size;
00396 memcpy (&(state->this_frame_params), (unsigned long * ) &ccam_dma_buf[next_metadata_start>>2],32);
00397 next_jpeg_len=state->this_frame_params.frame_length;
00398 if (state->this_frame_params.signffff !=0xffff) {
00399 D0(fprintf(debug_file, "%s:%d: wrong signature - %d\r\n",__FILE__,__LINE__,(int) state->this_frame_params.signffff));
00400 D1(fprintf(debug_file, "fp=0x%x\r\n",(int) fp));
00401 D1(fprintf(debug_file, "%08x %08x %08x %08x %08x %08x %08x %08x\r\n",ifp_this[0],ifp_this[1],ifp_this[2],ifp_this[3],ifp_this[4],ifp_this[5],ifp_this[6],ifp_this[7]));
00402
00403
00404
00405 state->cirbuf_rp=-1;
00406 return -CAMOGM_FRAME_BROKEN;
00407 }
00409 timestamp_start=fp+((next_jpeg_len+CCAM_MMAP_META+3) & (~0x1f)) + 32 - CCAM_MMAP_META_SEC;
00410 if (timestamp_start >= state->circ_buff_size) timestamp_start-=state->circ_buff_size;
00411 memcpy (&(state->this_frame_params.timestamp_sec), (unsigned long * ) &ccam_dma_buf[timestamp_start>>2],8);
00413 if ((state->frame_params.width != state->this_frame_params.width) ||
00414 (state->frame_params.height != state->this_frame_params.height)) {
00416 state->cirbuf_rp=fp;
00417 return -CAMOGM_FRAME_CHANGED;
00418 }
00420 state->frame_period=(state->this_frame_params.timestamp_usec - state->frame_params.timestamp_usec)+
00421 1000000*(state->this_frame_params.timestamp_sec - state->frame_params.timestamp_sec);
00422
00424 state->frames_skip= state->set_frames_skip;
00425 if (state->frames_skip > 0) {
00426 state->frames_skip_left=0;
00427 state->frame_period *= (state->frames_skip+1);
00428
00429 } else if (state->frames_skip < 0) {
00430 state->frame_period=-(state->frames_skip) ;
00431 state->frames_skip_left=state->frame_params.timestamp_sec;
00432 }
00433 state->time_unit= (ogg_int64_t) (((double) state-> frame_period) * ((double) 10) / ((double) state-> timescale));
00434 state->width=state->frame_params.width;
00435 state->height=state->frame_params.height;
00436
00439 lseek(state->fd_head,state->cirbuf_rp+1,SEEK_END);
00440 state->head_size=lseek(state->fd_head,0,SEEK_END);
00441 if (state->head_size>JPEG_HEADER_MAXSIZE) {
00442 D0(fprintf (debug_file,"%s:%d: Too big JPEG header (%d > %d)",__FILE__,__LINE__,state->head_size, JPEG_HEADER_MAXSIZE ));
00443 return -2;
00444 }
00446 lseek(state->fd_head,0,0);
00447 read (state->fd_head,state->jpegHeader,state->head_size);
00449 lseek(state->fd_circ,state->cirbuf_rp,SEEK_SET);
00450
00452 switch (state->format) {
00453 case CAMOGM_FORMAT_NONE: rslt= 0; break;
00454 case CAMOGM_FORMAT_OGM: rslt= camogm_start_ogm(); break;
00455 case CAMOGM_FORMAT_JPEG: rslt= camogm_start_jpeg(); break;
00456 case CAMOGM_FORMAT_MOV: rslt= camogm_start_mov(); break;
00457 default: rslt=0;
00458 }
00459 if (rslt) return rslt;
00460 if (state->kml_enable) rslt=camogm_start_kml() ;
00461 if (rslt) return rslt;
00462 state->running=1;
00463 state->starting=0;
00464 D1(fprintf (debug_file,"Started OK\n"));
00465 return 0;
00466 }
00467
00468
00469 int sendImageFrame (void) {
00470 int rslt;
00471
00472
00473 unsigned char frame_packet_type = PACKET_IS_SYNCPOINT;
00474
00475
00476
00477 int timestamp_start;
00479
00480 int * ifp_this = (int *) &(state->this_frame_params) ;
00481
00483 if (state->frameno >= (state->max_frames)) return -CAMOGM_FRAME_CHANGED;
00485
00486
00487 if (state->format != state->set_format) return -CAMOGM_FRAME_CHANGED;
00489 if ((state->vf) && (state->segment_length >=0) && (ftell(state->vf) > state->segment_length)) return -CAMOGM_FRAME_CHANGED;
00491 if (((state->ivf)>=0) && (state->segment_length >=0) && (lseek(state->ivf, 0, SEEK_CUR) > state->segment_length)) return -CAMOGM_FRAME_CHANGED;
00493 if (lseek(state->fd_circ,state->cirbuf_rp,SEEK_SET) <0) return -CAMOGM_FRAME_INVALID;
00494
00495 if (lseek(state->fd_circ,LSEEK_CIRC_READY,SEEK_END) <0) return -CAMOGM_FRAME_NOT_READY;
00496
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00510 if ( (state->frames_skip > 0) && (state->frames_skip_left > 0 )) {
00511 state->cirbuf_rp=lseek(state->fd_circ,LSEEK_CIRC_NEXT,SEEK_END);
00513 if (state->save_gp) lseek(state->fd_circ,LSEEK_CIRC_SETP,SEEK_END);
00514 state->frames_skip_left--;
00515 return -CAMOGM_FRAME_NOT_READY;
00516 }
00517
00519
00520 state->metadata_start=state->cirbuf_rp-32;
00521 if (state->metadata_start<0) state->metadata_start+=state->circ_buff_size;
00522 memcpy (&(state->this_frame_params), (unsigned long * ) &ccam_dma_buf[state->metadata_start>>2],32);
00523 state->jpeg_len=state->this_frame_params.frame_length;
00524 if (state->this_frame_params.signffff !=0xffff) {
00525 D0(fprintf(debug_file, "%s:%d: wrong signature - %d\r\n",__FILE__,__LINE__,(int) state->this_frame_params.signffff));
00526 D1(fprintf(debug_file, "state->cirbuf_rp=0x%x\r\n",(int) state->cirbuf_rp));
00527 D1(fprintf(debug_file, "%08x %08x %08x %08x %08x %08x %08x %08x\r\n",ifp_this[0],ifp_this[1],ifp_this[2],ifp_this[3],ifp_this[4],ifp_this[5],ifp_this[6],ifp_this[7]));
00528
00529
00530 return -CAMOGM_FRAME_BROKEN;
00531 }
00532
00534 timestamp_start=state->cirbuf_rp+((state->jpeg_len+CCAM_MMAP_META+3) & (~0x1f)) + 32 - CCAM_MMAP_META_SEC;
00535 if (timestamp_start >= state->circ_buff_size) timestamp_start-=state->circ_buff_size;
00536
00537 memcpy (&(state->this_frame_params.timestamp_sec), (unsigned long * ) &ccam_dma_buf[timestamp_start>>2],8);
00539 if ((state->frame_params.width != state->this_frame_params.width) ||
00540 (state->frame_params.height != state->this_frame_params.height)) return -CAMOGM_FRAME_CHANGED;
00541
00542 if ((state->segment_duration > 0) &&
00543 ((state->this_frame_params.timestamp_sec-state->frame_params.timestamp_sec) > state->segment_duration))
00544 return -CAMOGM_FRAME_CHANGED;
00545
00547 if ((state->frames_skip < 0) && (state->frames_skip_left > state->this_frame_params.timestamp_sec) ) {
00548 state->cirbuf_rp=lseek(state->fd_circ,LSEEK_CIRC_NEXT,SEEK_END);
00550 if (state->save_gp) lseek(state->fd_circ,LSEEK_CIRC_SETP,SEEK_END);
00551 return -CAMOGM_FRAME_NOT_READY;
00552 }
00553
00554
00555
00556 if (state->exif) {
00557 D3(fprintf (debug_file,"_5_"));
00559
00560 state->exifSize=lseek(state->fd_exif,1,SEEK_END);
00561
00562 if (state->exifSize > 0) {
00563
00564 lseek(state->fd_exif,state->this_frame_params.meta_index,SEEK_END);
00565 rslt=read (state->fd_exif, state->ed, state->exifSize);
00566 if (rslt<0) rslt=0;
00567 state->exifSize=rslt;
00568 } else state->exifSize=0;
00569 } else state->exifSize=0;
00570
00571
00572
00574 state->chunk_index=0;
00575 state->packetchunks[state->chunk_index ].bytes=1;
00576 state->packetchunks[state->chunk_index++].chunk=&frame_packet_type;
00577 if (state->exif>0) {
00578
00579 state->packetchunks[state->chunk_index ].bytes=2;
00580 state->packetchunks[state->chunk_index++].chunk=state->jpegHeader;
00581 state->packetchunks[state->chunk_index ].bytes=state->exifSize;
00582 state->packetchunks[state->chunk_index++].chunk= state->ed;
00583 state->packetchunks[state->chunk_index ].bytes=state->head_size-2;
00584 state->packetchunks[state->chunk_index++].chunk= &(state->jpegHeader[2]);
00585 } else {
00586
00587 state->packetchunks[state->chunk_index ].bytes=state->head_size;
00588 state->packetchunks[state->chunk_index++].chunk= state->jpegHeader;
00589 }
00590
00591
00593
00594 if ((state->cirbuf_rp + state->jpeg_len) > state->circ_buff_size) {
00595
00596
00597
00598
00599 state->packetchunks[state->chunk_index ].bytes=state->circ_buff_size-state->cirbuf_rp;
00600 state->packetchunks[state->chunk_index++].chunk= (unsigned char*) &ccam_dma_buf[state->cirbuf_rp>>2];
00602
00603 state->packetchunks[state->chunk_index ].bytes=state->jpeg_len - (state->circ_buff_size-state->cirbuf_rp);
00604 state->packetchunks[state->chunk_index++].chunk= (unsigned char*) &ccam_dma_buf[0];
00605 } else {
00606
00607
00609
00610 state->packetchunks[state->chunk_index ].bytes=state->jpeg_len;
00611 state->packetchunks[state->chunk_index++].chunk= (unsigned char*) &ccam_dma_buf[state->cirbuf_rp>>2];
00612 }
00613
00614 state->packetchunks[state->chunk_index ].bytes=2;
00615 state->packetchunks[state->chunk_index++].chunk= (unsigned char*) trailer;
00616
00617 switch (state->format) {
00618 case CAMOGM_FORMAT_NONE: rslt=0; break;
00619 case CAMOGM_FORMAT_OGM: rslt=camogm_frame_ogm(); break;
00620 case CAMOGM_FORMAT_JPEG: rslt=camogm_frame_jpeg(); break;
00621 case CAMOGM_FORMAT_MOV: rslt=camogm_frame_mov(); break;
00622 default: rslt=0;
00623 }
00624 if (rslt) return rslt;
00625 if (state->kml_used) rslt=camogm_frame_kml() ;
00626 if (rslt) return rslt;
00627
00628
00630 state->frameno++;
00631 state->cirbuf_rp=lseek(state->fd_circ,LSEEK_CIRC_NEXT,SEEK_END);
00633 if (state->save_gp) lseek(state->fd_circ,LSEEK_CIRC_SETP,SEEK_END);
00634
00635
00636
00637 if (state->frames_skip > 0) {
00638 state->frames_skip_left= state->frames_skip;
00639 } else if (state->frames_skip < 0) {
00640 state->frames_skip_left+= -(state->frames_skip);
00641 }
00642 return 0;
00643 }
00644
00645
00646
00647 int camogm_stop(void) {
00648 int rslt=0;
00649 if (!state->running) {
00650 if (!state->starting) {
00651 D2(fprintf (debug_file,"Recording was not running, nothing to stop\n"));
00652 } else {
00653 state->starting=0;
00654 D1(fprintf (debug_file,"Dropping attempt to start\n"));
00655 }
00656 return 0;
00657 }
00658 D1(fprintf (debug_file,"Ending recording\n"));
00659 if (state->kml_used) camogm_end_kml() ;
00660 switch (state->format) {
00661 case CAMOGM_FORMAT_NONE: rslt= 0; break;
00662 case CAMOGM_FORMAT_OGM: rslt= camogm_end_ogm(); break;
00663 case CAMOGM_FORMAT_JPEG: rslt= camogm_end_jpeg();break;
00664 case CAMOGM_FORMAT_MOV: rslt= camogm_end_mov(); break;
00666 }
00668 if (state->vf) fclose (state->vf);
00669 state->vf=NULL;
00670 if (rslt) return rslt;
00671 state->last=1;
00673 state->running=0;
00674 state->starting=0;
00675 return 0;
00676 }
00677
00678 void camogm_free() {
00679 int f;
00681
00682 for (f=0;f<31;f++) {
00683 if (state->formats & ( 1 << (state->format))) {
00684 switch (f) {
00685 case CAMOGM_FORMAT_NONE: break;
00686 case CAMOGM_FORMAT_OGM: camogm_free_ogm(); break;
00687 case CAMOGM_FORMAT_JPEG: camogm_free_jpeg();break;
00688 case CAMOGM_FORMAT_MOV: camogm_free_mov(); break;
00689 }
00690 }
00691 }
00692 state->formats=0;
00693 }
00694
00695 int camogm_reset(void) {
00696 state->cirbuf_rp=-1;
00697 state->buf_overruns=-1;
00698 return 0;
00699 }
00700
00702 void camogm_kml_set_enable(int d) {
00703 state->kml_enable=d;
00704 }
00705 void camogm_kml_set_horHalfFov (double dd) {
00706 state->kml_horHalfFov=dd;
00707 }
00708 void camogm_kml_set_vertHalfFov(double dd) {
00709 state->kml_vertHalfFov=dd;
00710 }
00711 void camogm_kml_set_height_mode(int d) {
00712 state->kml_height_mode=d;
00713 }
00714 void camogm_kml_set_height(double dd) {
00715 state->kml_height=dd;
00716 }
00717 void camogm_kml_set_period(int d) {
00718 state->kml_period=d;
00719 state->kml_last_ts=0;
00720 state->kml_last_uts=0;
00721 }
00722 void camogm_kml_set_near(double dd) {
00723 state->kml_near=dd;
00724 }
00725
00726
00727 void camogm_set_segment_duration(int sd) {
00728 state->segment_duration=sd;
00729 }
00730 void camogm_set_segment_length(int sl) {
00731 state->segment_length= sl;
00732 }
00733 void camogm_set_save_gp(int d) {
00734 state->save_gp= d;
00735 }
00736 void camogm_set_exif(int d) {
00737 state->exif= d;
00738 }
00739
00740 void camogm_set_prefix (const char * p) {
00741 strncpy(state->path_prefix, p, sizeof(state->path_prefix)-1);
00742 state->path_prefix[sizeof(state->path_prefix)-1]='\0';
00743 }
00744
00745 void camogm_set_timescale(double d) {
00746 state->set_timescale= d;
00747 if ((state->running==0) && (state->starting==0)) {
00748 state->timescale=state->set_timescale;
00749 }
00750 }
00751
00752 void camogm_set_frames_skip(int d) {
00753 state->set_frames_skip= d;
00754 if ((state->running==0) && (state->starting==0)) {
00755 state->frames_skip= state->set_frames_skip;
00756
00757 state->frames_skip_left= 0;
00758 }
00759 }
00760
00761
00762 void camogm_set_format(int d) {
00763 int rslt=0;
00764 state->set_format= d;
00765 if ((state->running==0) && (state->starting==0)) {
00766 state->format= state->set_format;
00767 switch (state->format) {
00768 case CAMOGM_FORMAT_NONE: rslt= 0; break;
00769 case CAMOGM_FORMAT_OGM: rslt= camogm_init_ogm(); break;
00770 case CAMOGM_FORMAT_JPEG: rslt= camogm_init_jpeg();break;
00771 case CAMOGM_FORMAT_MOV: rslt= camogm_init_mov(); break;
00772 }
00773 if (rslt) {
00774 D0(fprintf (debug_file,"%s:%d: Error setting format to=%d\n",__FILE__,__LINE__, state->format));
00775 }
00776 state->formats |= 1 << (state->format);
00777 }
00778 }
00780 void camogm_set_max_frames(int d) {
00781 state->set_max_frames= d;
00782 if ((state->running==0) && (state->starting==0)) state->max_frames= d;
00783 }
00784 void camogm_set_frames_per_chunk(int d) {
00785 state->set_frames_per_chunk= d;
00786 if ((state->running==0) && (state->starting==0)) state->frames_per_chunk= d;
00787 }
00788 void camogm_status(char * fn, int xml) {
00789 int _len=0;
00790 int _dur,_udur;
00791
00792 FILE* f;
00793 char *_state, *_output_format, *_using_exif, *_using_global_pointer, *_compressor_state;
00794 int _b_free, _b_used;
00795 int _frames_remain=0;
00796 int _sec_remain=0;
00797 int _frames_skip=0;
00798 int _sec_skip=0;
00799 char *_kml_enable, *_kml_used, *_kml_height_mode;
00800
00801 _kml_enable= state->kml_enable?"yes":"no";
00802 _kml_used= state->kml_used?"yes":"no";
00803 _kml_height_mode= state->kml_height_mode?"GPS altitude":"map ground level";
00804
00805
00806 _b_free=getGPValue(G_FREECIRCBUF);
00807 _b_used=getGPValue(G_CIRCBUFSIZE)-getGPValue(G_FREECIRCBUF);
00808
00809 if (!fn) f=stdout;
00810 else if (strcmp(fn, "stdout")==0) f=stdout;
00811 else if (strcmp(fn, "stderr")==0) f=stderr;
00812 else {
00813 if (!((f=fopen (fn,"w")))) {
00814 D0(fprintf (debug_file,"Error opening %s\n", fn));
00815 return;
00816 }
00817 }
00818 if (state->vf) _len=ftell(state->vf);
00819 else if ((state->ivf)>=0) _len=lseek(state->ivf, 0, SEEK_CUR);
00820 _dur= state->this_frame_params.timestamp_sec-state->frame_params.timestamp_sec;
00821 _udur=state->this_frame_params.timestamp_usec-state->frame_params.timestamp_usec;
00822 if (_udur<0) {
00823 _dur-=1;
00824 _udur+=1000000;
00825 } else if (_udur>=1000000) {
00826 _dur+=1;
00827 _udur-=1000000;
00828 }
00829 _state= state->running? "running":(state->starting?"starting":"stopped");
00830 _output_format= state->format?((state->format==CAMOGM_FORMAT_OGM)?"ogm":
00831 ((state->format==CAMOGM_FORMAT_JPEG)?"jpeg":
00832 ((state->format==CAMOGM_FORMAT_MOV)?"mov":
00833 "other"))):"none";
00834 _using_exif= state->exif?"yes":"no";
00835 _using_global_pointer=state->save_gp?"yes":"no";
00836 _compressor_state=(getGPValue(P_COMPRESSOR_RUN)==2)?"running":"stoppped";
00837 if ( state->frames_skip >0 ) {
00838 _frames_remain= state->frames_skip_left;
00839 _frames_skip=state->frames_skip;
00840 } else if ( state->frames_skip <0 ) {
00841 _sec_remain= (state->frames_skip_left - state->this_frame_params.timestamp_sec);
00842 _sec_skip=-(state->frames_skip);
00843 }
00844
00845
00846 if (xml) {
00847 fprintf (f,"<?xml version=\"1.0\"?>\n" \
00848 "<camogm_state>\n" \
00849 " <state>\"%s\"</state>\n" \
00850 " <compressor_state>\"%s\"</compressor_state>\n" \
00851 " <file_name>\"%s\"</file_name>\n" \
00852 " <frame_number>%d</frame_number>\n" \
00853 " <file_duration>%d.%06d</file_duration>\n" \
00854 " <file_length>%d</file_length>\n" \
00855 " <frame_period>%d</frame_period>\n" \
00856 " <frames_skip>%d</frames_skip>\n" \
00857 " <seconds_skip>%d</seconds_skip>\n" \
00858 " <frames_skip_left>%d</frames_skip_left>\n" \
00859 " <seconds_skip_left>%d</seconds_skip_left>\n" \
00860 " <frame_width>%d</frame_width>\n" \
00861 " <frame_height>%d</frame_height>\n" \
00862 " <format>\"%s\"</format>\n" \
00863 " <exif>\"%s\"</exif>\n" \
00864 " <prefix>\"%s\"</prefix>\n" \
00865 " <max_duration>%d</max_duration>\n" \
00866 " <max_length>%d</max_length>\n" \
00867 " <max_frames>%d</max_frames>\n" \
00868 " <timescale>%f</timescale>\n" \
00869 " <frames_per_chunk>%d</frames_per_chunk>\n" \
00870 " <buffer_overruns>%d</buffer_overruns>\n" \
00871 " <buffer_minimal>%d</buffer_minimal>\n" \
00872 " <buffer_free>%d</buffer_free>\n" \
00873 " <buffer_used>%d</buffer_used>\n" \
00874 " <circbuf_rp>%d</circbuf_rp>\n" \
00875 " <debug_output>\"%s\"</debug_output>\n" \
00876 " <debug_level>%d</debug_level>\n" \
00877 " <use_global_rp>\"%s\"</use_global_rp>\n" \
00878 " <kml_enable>\"%s\"</kml_enable>\n" \
00879 " <kml_used>\"%s\"</kml_used>\n" \
00880 " <kml_path>\"%s\"</kml_path>\n" \
00881 " <kml_horHalfFov>\"%f\"</kml_horHalfFov>\n" \
00882 " <kml_vertHalfFov>\"%f\"</kml_vertHalfFov>\n" \
00883 " <kml_near>\"%f\"</kml_near>\n" \
00884 " <kml_height_mode>\"%s\"</kml_height_mode>\n" \
00885 " <kml_height>\"%f\"</kml_height>\n" \
00886 " <kml_period>%d</kml_period>\n" \
00887 " <kml_last_ts>%d.%06d</kml_last_ts>\n" \
00888 "</camogm_state>\n",
00889 _state,_compressor_state,state->path,state->frameno,_dur,_udur,_len,state->frame_period, \
00890 _frames_skip,_sec_skip,_frames_remain, _sec_remain, \
00891 state->width,state->height,_output_format,_using_exif, \
00892 state->path_prefix, state->segment_duration, state->segment_length, state->max_frames, state->timescale, \
00893 state->frames_per_chunk, state->buf_overruns, state->buf_min, _b_free, _b_used, state->cirbuf_rp, \
00894 state->debug_name, debug_level, _using_global_pointer, \
00895 _kml_enable,_kml_used,state->kml_path,state->kml_horHalfFov,state->kml_vertHalfFov,state->kml_near,\
00896 _kml_height_mode,state->kml_height,state->kml_period,state->kml_last_ts,state->kml_last_uts);
00897 } else {
00898 fprintf (f,"state %s\n", _state);
00899 fprintf (f,"compressor state %s\n", _compressor_state);
00900 fprintf (f,"file %s\n", state->path);
00901 fprintf (f,"frame %d\n", state->frameno);
00902 fprintf (f,"file duration %d.%06d sec\n",_dur,_udur);
00903 fprintf (f,"file length %d B\n", _len);
00904 fprintf (f,"frame period %d (0x%x)\n", state->frame_period,state->frame_period);
00905 if ( _frames_skip >0 ) fprintf (f,"frames to skip %d (left %d)\n",_frames_skip, _frames_remain);
00906 if ( _sec_skip <0 ) fprintf (f,"timelapse period %d sec (remaining %d sec)\n", _sec_skip, _sec_remain);
00907 fprintf (f,"width %d (0x%x)\n", state->width,state->width);
00908 fprintf (f,"height %d (0x%x)\n", state->height,state->height);
00909 fprintf (f,"\n");
00910 fprintf (f,"output format %s\n", _output_format);
00911 fprintf (f,"using exif %s\n", _using_exif);
00912 fprintf (f,"path prefix: %s\n", state->path_prefix);
00913 fprintf (f,"max file duration: %d sec\n", state->segment_duration);
00914 fprintf (f,"max file length: %d B\n", state->segment_length);
00915 fprintf (f,"max frames %d\n", state->max_frames);
00916 fprintf (f,"timescale %f\n", state->timescale);
00917 fprintf (f,"frames per chunk %d\n", state->frames_per_chunk);
00918 fprintf (f,"\n");
00919 fprintf (f,"buffer overruns %d\n", state->buf_overruns);
00920 fprintf (f,"buffer minimal %d\n", state->buf_min);
00921 fprintf (f,"buffer free %d\n", _b_free);
00922 fprintf (f,"buffer used %d\n", _b_used);
00923 fprintf (f,"circbuf_rp %d (0x%x)\n", state->cirbuf_rp,state->cirbuf_rp);
00924 fprintf (f,"\n");
00925 fprintf (f,"debug output to %s\n", state->debug_name);
00926 fprintf (f,"debug level %d\n", debug_level);
00927 fprintf (f,"use global pointer %s\n", _using_global_pointer);
00928 fprintf (f,"\n\n");
00929 fprintf (f,"kml_enable %s\n", _kml_enable);
00930 fprintf (f,"kml_used %s\n", _kml_used);
00931 fprintf (f,"kml_path %s\n", state->kml_path);
00932 fprintf (f,"kml_horHalfFov %f degrees\n",state->kml_horHalfFov);
00933 fprintf (f,"kml_vertHalfFov %f degrees\n",state->kml_vertHalfFov);
00934 fprintf (f,"kml_near %f m\n", state->kml_near);
00935 fprintf (f,"kml height mode %s\n", _kml_height_mode);
00936 fprintf (f,"kml_height (extra) %f m\n", state->kml_height);
00937 fprintf (f,"kml_period %d\n", state->kml_period);
00938 fprintf (f,"kml_last_ts %d.%06d\n", state->kml_last_ts,state->kml_last_uts);
00939 fprintf (f,"\n\n");
00940
00941 }
00942 if ((f!=stdout) && (f!=stderr)) fclose (f);
00943 if (state->buf_overruns>=0) state->buf_overruns=0;
00944 state->buf_min=_b_free;
00945 }
00946
00948 char * getLineFromPipe(FILE* npipe) {
00949 int fl;
00950 char * nlp;
00952 if (cmdstrt > 0) {
00954 memmove(cmdbuf, &cmdbuf[cmdstrt], sizeof(cmdbuf)- cmdstrt);
00955 cmdbufp-=cmdstrt;
00956 cmdstrt=0;
00957 }
00959 if (!cmdbufp) cmdbuf[cmdbufp]=0;
00960
00961 nlp= strpbrk(cmdbuf,";\n");
00962 if (!nlp) {
00963 fl=fread(&cmdbuf[cmdbufp], 1,sizeof(cmdbuf)-cmdbufp-1,npipe);
00964 cmdbuf[cmdbufp+fl]=0;
00966
00967 nlp= strpbrk(&cmdbuf[cmdbufp],";\n");
00968 cmdbufp+=fl;
00969 }
00970 if (nlp) {
00971
00972 nlp[0]=0;
00973 cmdstrt=nlp-cmdbuf+1;
00974
00975
00976 for (fl=0; cmdbuf[fl] && strchr(" \t",cmdbuf[fl]); fl++);
00977
00978 return &cmdbuf[fl];
00979 } else {
00980
00981 return NULL;
00982 }
00983 }
00984
00985 int parse_cmd(FILE* npipe) {
00986 char * cmd;
00987 char * args;
00988 char * argse;
00989 int d;
00990 double dd;
00991
00993 while(((cmd=getLineFromPipe(npipe))) && !cmd[0]) ;
00994 if (!cmd) return 0;
00995
00996 args=strpbrk(cmd,"= \t");
00998 if (args) {
00999 args[0]=0;
01000 args++;
01001 while (strchr("= \t",args[0])) args++;
01002 if (args[0]) {
01004 for (argse=strchr(args,'\0')-1; strchr("= \t",argse[0]);argse--) argse[0]='\0';
01005 }
01006 if (!args[0]) args=NULL;
01007 }
01009 if (strcmp(cmd, "start")==0) {
01010 camogm_start();
01011 return 1;
01012 } else if (strcmp(cmd, "reset")==0) {
01013 camogm_reset();
01014 return 2;
01015 } else if (strcmp(cmd, "stop")==0) {
01016 camogm_stop();
01017 return 3;
01018 } else if (strcmp(cmd, "exit")==0) {
01019 camogm_stop();
01020 camogm_free();
01021 exit (0);
01022 } else if (strcmp(cmd, "duration")==0) {
01023 if (!(args) || (((d= strtol(args, NULL, 10)))<=0)) d=DEFAULT_DURATION;
01024 camogm_set_segment_duration(d);
01025 return 4;
01026 } else if (strcmp(cmd, "length")==0) {
01027 if (!(args) || (((d= strtol(args, NULL, 10)))<=0)) d=DEFAULT_LENGTH;
01028 camogm_set_segment_length(d);
01029 return 5;
01030 } else if (strcmp(cmd, "prefix")==0) {
01031 if (args) camogm_set_prefix (args);
01032 return 6;
01033 } else if (strcmp(cmd, "status")==0) {
01034 camogm_status(args, 0);
01035 return 7;
01036 } else if (strcmp(cmd, "xstatus")==0) {
01037 camogm_status(args, 1);
01038 return 7;
01039 } else if (strcmp(cmd, "save_gp")==0) {
01040 if ((args) && (((d= strtol(args, NULL, 10)))>=0)) camogm_set_save_gp(d);
01041 return 8;
01042 } else if (strcmp(cmd, "exif")==0) {
01043 if ((args) && (((d= strtol(args, NULL, 10)))>=0)) camogm_set_exif(d);
01044 return 8;
01045 } else if (strcmp(cmd, "debug")==0) {
01046 camogm_debug(args);
01047 return 9;
01048 } else if (strcmp(cmd, "timescale")==0) {
01049 dd= strtod(args,NULL);
01050 camogm_set_timescale(dd?dd:1.0);
01051 return 10;
01054
01055
01056 } else if (strcmp(cmd, "frameskip")==0) {
01057 d= strtol(args, NULL, 10);
01058 camogm_set_frames_skip(d);
01059 return 11;
01060 } else if (strcmp(cmd, "timelapse")==0) {
01061 d= strtol(args, NULL, 10);
01062 camogm_set_frames_skip(-d);
01063 return 11;
01064 } else if (strcmp(cmd, "format")==0) {
01065 if (args) {
01066 if (strcmp(args, "none")==0) camogm_set_format(0);
01067 else if ((strcmp(args, "ogm" )==0) || (strcmp(args, "ogg")==0)) camogm_set_format(CAMOGM_FORMAT_OGM);
01068 else if ((strcmp(args, "jpeg")==0) || (strcmp(args, "jpg")==0)) camogm_set_format(CAMOGM_FORMAT_JPEG);
01069 else if (strcmp(args, "mov" )==0) camogm_set_format(CAMOGM_FORMAT_MOV);
01070 }
01071 return 12;
01072 } else if (strcmp(cmd, "debuglev")==0) {
01073 d= strtol(args, NULL, 10);
01074 camogm_debug_level(d?d:0);
01075 return 13;
01076 } else if (strcmp(cmd, "kml")==0) {
01077 if ((args) && (((d= strtol(args, NULL, 10)))>=0)) camogm_kml_set_enable(d);
01078 return 14;
01079 } else if (strcmp(cmd, "kml_hhf")==0) {
01080 dd= strtod(args,NULL);
01081 camogm_kml_set_horHalfFov(dd);
01082 return 15;
01083 } else if (strcmp(cmd, "kml_vhf")==0) {
01084 dd= strtod(args,NULL);
01085 camogm_kml_set_vertHalfFov(dd);
01086 return 16;
01087 } else if (strcmp(cmd, "kml_near")==0) {
01088 dd= strtod(args,NULL);
01089 camogm_kml_set_near(dd);
01090 return 17;
01091 } else if (strcmp(cmd, "kml_alt")==0) {
01092 if (args) {
01093 if (strcmp(args, "gps" )==0) camogm_kml_set_height_mode(1);
01094 else if (strcmp(args, "ground")==0) camogm_kml_set_height_mode(0);
01095 }
01096 return 18;
01097 } else if (strcmp(cmd, "kml_height")==0) {
01098 dd= strtod(args,NULL);
01099 camogm_kml_set_height(dd);
01100 return 19;
01101 } else if (strcmp(cmd, "kml_period")==0) {
01102 d= strtol(args, NULL, 10);
01103 camogm_kml_set_period(d?d:1);
01104 return 20;
01105 }
01106
01107 return -1;
01108 }
01109
01110 int main(int argc, char *argv[])
01111 {
01112 const char circbufFileName[]="/dev/circbuf";
01113
01114 FILE * cmd_file;
01115 const char usage[]= "This program allows recording of the video/images acquired by Elphel camera to the storage media.\n" \
01116 "It is designed to run in the background and accept commands through a named pipe.\n\n" \
01117 "Usage:\n\n" \
01118 "%s <named_pipe_name>\n\n" \
01119 "i.e.:\n\n" \
01120 "%s /var/state/camogm_cmd\n\n" \
01121 "When the program is runninig you may send commands by writing strings to the command file\n" \
01122 "(/var/state/camogm_cmd in the example above). The complete list of available commands is available\n" \
01123 "on Elphel Wiki (http://wiki.elphel.com/index.php?title=Camogm), here is the example of usage\n" \
01124 "from the shell prompt in the camera:\n\n" \
01125 "echo \"status; exif=1; format=jpeg;status=/var/tmp/camogm.status\" > /var/state/camogm_cmd\n\n" \
01126 "That will print status information on the standard output (may not be visible if the program was not\n" \
01127 "started from the same session), set exif mode on (each frame will have the full Exif header including\n" \
01128 "a precise time stamp), set output format to a series of individual JPEG files, and then send status\n" \
01129 "information to a file /var/tmp/camogm.status in the camera file system.\n\n" \
01130 "This program does not control the process of acquisition of the video/images to the camera internal\n" \
01131 "buffer, it only retrieves that data from the buffer (waiting when needed), packages it to selected\n" \
01132 "format and stores the result files.\n\n";
01133 int go=1;
01134 int cmd;
01135 int i,rslt;
01136 state= &sstate;
01138 if ((argc < 2) || (argv[1][1]=='-')) {
01139 printf (usage,argv[0],argv[0]);
01140 return 0;
01141 }
01142 camogm_init();
01143
01145 state->fd_exif = open(ExifFileName, O_RDONLY);
01146 if (state->fd_exif<0) {
01147 D0(fprintf (debug_file,"Error opening %s\n", ExifFileName));
01148 return -1;
01149 }
01150
01152 state->fd_head = open(HeadFileName, O_RDWR);
01153 if (state->fd_head<0) {
01154 D0(fprintf (debug_file,"Error opening %s\n", HeadFileName));
01155 return -1;
01156 }
01157 state->head_size=lseek(state->fd_head,0,SEEK_END);
01158 if (state->head_size>JPEG_HEADER_MAXSIZE) {
01159 D0(fprintf (debug_file,"%s:%d: Too big JPEG header (%d > %d)",__FILE__,__LINE__,state->head_size, JPEG_HEADER_MAXSIZE ));
01160 return -2;
01161 }
01162
01164 state->fd_circ = open(circbufFileName, O_RDWR);
01165 if (state->fd_circ<0) {
01166 D0(fprintf (debug_file,"Error opening %s\n", circbufFileName));
01167 return -2;
01168 }
01170 state->circ_buff_size=lseek(state->fd_circ,0,SEEK_END);
01171 ccam_dma_buf = (unsigned long *) mmap(0, state->circ_buff_size, PROT_READ, MAP_SHARED, state->fd_circ, 0);
01172 if((int)ccam_dma_buf == -1) {
01173 D0(fprintf (debug_file,"Error in mmap of %s\n",circbufFileName));
01174
01175 close(state->fd_circ);
01176 return -3;
01177 }
01178
01180
01182 state->fd_fparmsall = open(ctlFileName, O_RDWR);
01183 if (state->fd_fparmsall<0) {
01184 D0(fprintf (debug_file,"%s:%d:%s: Error opening %s\n",__FILE__,__LINE__,__FUNCTION__, ctlFileName));
01185 return -2;
01186 }
01187
01189 frameParsAll = (struct framepars_all_t *) mmap(0, sizeof (struct framepars_all_t) , PROT_READ, MAP_SHARED, state->fd_fparmsall, 0);
01190 if((int)frameParsAll == -1) {
01191 D0(fprintf(debug_file,"%s:%d:%s: Error in mmap in %s\n",__FILE__,__LINE__,__FUNCTION__,ctlFileName));
01192 close(state->fd_fparmsall);
01193 close(state->fd_circ);
01194 return -3;
01195 }
01196 framePars=frameParsAll->framePars;
01197 globalPars=frameParsAll->globalPars;
01198
01201 i=unlink (argv[1]);
01202 if (i) {
01203 D1(fprintf (debug_file,"Unlink %s returned %d, errno=%d \n", argv[1], i, errno));
01204 }
01205 i=mkfifo(argv[1], 0777);
01207 if (i) {
01208 if (errno==EEXIST) {
01209 D1(fprintf (debug_file,"Named pipe %s already exists, will use it.\n", argv[1]));
01210 } else {
01211 D0(fprintf (debug_file,"Can not create a named pipe %s, errno=%d \n", argv[1], errno));
01212 return -4;
01213 }
01214 }
01215
01218 if (!((cmd_file=fopen(argv[1],"r")))) {
01219 D0(fprintf (debug_file,"Can not open command file %s\n",argv[1]));
01220 return -5;
01221 }
01222 D1(fprintf (debug_file,"Pipe %s open for reading\n",argv[1]));
01223
01225 #define COMMAND_LOOP_DELAY 500000 //0.5sec
01226
01227 while (go) {
01228
01229
01231 cmd=parse_cmd(cmd_file);
01232 if (cmd) {
01233 if (cmd<0) D0(fprintf (debug_file,"Unrecognized command\n"));
01234 } else if (state->running) {
01235
01236
01237 switch ((rslt=-sendImageFrame ())) {
01238 case 0:
01239
01240
01241
01242
01243 break;
01244 case CAMOGM_FRAME_NOT_READY:
01245
01246
01247
01248
01249
01250
01251
01252
01253 lseek(state->fd_circ,LSEEK_CIRC_WAIT,SEEK_END);
01254 break;
01255 case CAMOGM_FRAME_CHANGED:
01256 case CAMOGM_FRAME_NEXTFILE:
01257 case CAMOGM_FRAME_INVALID:
01258 case CAMOGM_FRAME_BROKEN:
01259
01260
01261 camogm_stop();
01262 camogm_start();
01263 break;
01264 case CAMOGM_FRAME_FILE_ERR:
01265 case CAMOGM_FRAME_OTHER:
01266 D0(fprintf (debug_file,"%s:line %d - error=%d\n",__FILE__,__LINE__,rslt));
01267 break;
01268 default:
01269 D0(fprintf (debug_file,"%s:line %d - should not get here (rslt=%d)\n",__FILE__,__LINE__,rslt));
01270 exit (-1);
01271 }
01272 } else if (state->starting) {
01273
01274
01276 switch ((rslt=-camogm_start())) {
01277 case 0: break;
01278 case CAMOGM_FRAME_NOT_READY:
01279
01280
01281
01282 case CAMOGM_FRAME_CHANGED:
01283 case CAMOGM_FRAME_NEXTFILE:
01284 case CAMOGM_FRAME_INVALID:
01285 case CAMOGM_FRAME_BROKEN:
01286
01287 usleep( COMMAND_LOOP_DELAY) ;
01288 break;
01289 case CAMOGM_FRAME_FILE_ERR:
01290 case CAMOGM_FRAME_OTHER:
01291 D0(fprintf (debug_file,"%s:line %d - error=%d\n",__FILE__,__LINE__,rslt));
01292 break;
01293 default:
01294 D0(fprintf (debug_file,"%s:line %d - should not get here (rslt=%d)\n",__FILE__,__LINE__,rslt));
01295 exit (-1);
01296 }
01297 } else {
01298 usleep( COMMAND_LOOP_DELAY) ;
01299 }
01300 }
01301 return 0;
01302 }
01309 unsigned long getGPValue(unsigned long GPNumber) {
01310 return (GPNumber>=FRAMEPAR_GLOBALS)?
01311 GLOBALPARS(GPNumber):
01312 framePars[GLOBALPARS(G_THIS_FRAME) & PARS_FRAMES_MASK].pars[GPNumber];
01313 }
01314
01320 void setGValue(unsigned long GNumber, unsigned long value) {
01321 GLOBALPARS(GNumber)=value;
01322 }
01323
01330 int waitDaemonEnabled(int daemonBit) {
01331 if ((daemonBit>=0) && (daemonBit<32)) lastDaemonBit=daemonBit;
01332 unsigned long this_frame=this_frame=GLOBALPARS(G_THIS_FRAME);
01335 lseek(state->fd_circ, LSEEK_DAEMON_CIRCBUF+lastDaemonBit, SEEK_END);
01336 if (this_frame==GLOBALPARS(G_THIS_FRAME)) return 1;
01337 return 0;
01338 }
01339
01345 int isDaemonEnabled(int daemonBit) {
01346 if ((daemonBit>=0) && (daemonBit<32)) lastDaemonBit=daemonBit;
01347 return ((framePars[GLOBALPARS(G_THIS_FRAME) & PARS_FRAMES_MASK].pars[P_DAEMON_EN] & (1 <<lastDaemonBit))!=0);
01348 }