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