/* flag ignored, for arg compatibility w/ xmit_data */ void _xmit_img_file(QSP_ARG_DECL Port *mpp,Image_File *ifp,int flag) /** send a file header */ { int32_t len; int32_t code; #ifdef SIGPIPE // We used to call a handler (if_pipe) that performed // a fatal error exit. Now we would like to recover // a little more gracefully. That means that put_port_int32 etc // can return after the port is closed. signal(SIGPIPE,SIG_IGN); #endif /* SIGPIPE */ code=P_IMG_FILE; if( put_port_int32(mpp,code) == (-1) ){ warn("xmit_file: error sending code"); return; } len=(int32_t)strlen(ifp->if_name)+1; /* we don't send the file data, just the header data */ /* We need to send: * * name * if_nfrms (frms written/read) * if_type (file format) * (file type specific header?) * if_flags * (dp ptr to obj with dimensions?) * (if_pathname) (don't really care since file is on remot sys) */ if( put_port_int32(mpp,len) == -1 ){ warn("xmit_file: error writing name length word"); return; } if( put_port_int32(mpp, ifp->if_nfrms) == -1 || put_port_int32(mpp, FT_CODE(IF_TYPE(ifp)) ) == -1 || put_port_int32(mpp, ifp->if_flags ) == -1 ){ warn("error sending image file header data"); return; } if( write_port(mpp,ifp->if_name,len) == (-1) ){ warn("xmit_file: error writing image file name"); return; } /* now send the associated data_obj header... */ assert( ifp->if_dp != NULL ); xmit_obj(mpp,ifp->if_dp,0); }
static COMMAND_FUNC( do_delete_imgfile ) { Image_File *ifp; ifp = PICK_IMG_FILE(""); if( ifp == NO_IMAGE_FILE ) return; if( FT_CODE(IF_TYPE(ifp)) != IFT_RV ){ sprintf(ERROR_STRING, "Use \"close\" for image file %s, not \"delete\"", ifp->if_name); WARN(ERROR_STRING); return; } delete_image_file(QSP_ARG ifp); }
void v4l2_stream_record(QSP_ARG_DECL Image_File *ifp,long n_frames,int n_cameras, Video_Device **vd_tbl) { #ifdef HAVE_RAWVOL int fd_arr[MAX_DISKS]; int ndisks, which_disk; uint32_t blocks_per_frame; Shape_Info shp1; Shape_Info *shpp=(&shp1); RV_Inode *inp; struct v4l2_buffer *bufp; int i; if( record_state != NOT_RECORDING ){ sprintf(ERROR_STRING, "v4l2_stream_record: can't record file %s until previous record completes", ifp->if_name); WARN(ERROR_STRING); return; } /* grabber dependent? */ blocks_per_frame = get_blocks_per_frame(); n_to_write = blocks_per_frame * BLOCK_SIZE; //n_to_write>>=2; /* write quarter for testing */ if( FT_CODE(IF_TYPE(ifp)) != IFT_RV ){ sprintf(ERROR_STRING, "stream record: image file %s (type %s) should be type %s", ifp->if_name, FT_NAME(IF_TYPE(ifp)), FT_NAME(FILETYPE_FOR_CODE(IFT_RV)) ); WARN(ERROR_STRING); return; } inp = (RV_Inode *) ifp->if_hdr_p; ndisks = queue_rv_file(QSP_ARG inp,fd_arr); #ifdef CAUTIOUS if( ndisks < 1 ){ sprintf(ERROR_STRING, "Bad number (%d) of raw volume disks",ndisks); WARN(ERROR_STRING); return; } #endif /* CAUTIOUS */ /* meteor_get_geometry(&_geo); */ SET_SHP_FLAGS(shpp, 0); SET_SHP_ROWS(shpp, 480); /* BUG don't hard code */ SET_SHP_COLS(shpp, 640); /* BUG don't hard code */ /* should get bytes per pixel from _geo... */ SET_SHP_COMPS(shpp, DEFAULT_BYTES_PER_PIXEL); SET_SHP_FRAMES(shpp, n_frames); SET_SHP_SEQS(shpp, 1); SET_SHP_PREC_PTR(shpp, PREC_FOR_CODE(PREC_UBY) ); set_shape_flags(shpp,NO_OBJ,AUTO_SHAPE); rv_set_shape(QSP_ARG ifp->if_name,shpp); /* We write an entire frame to each disk in turn... */ #ifdef RECORD_TIMESTAMPS if( stamping ) init_stamps(n_frames); #endif /* RECORD_TIMESTAMPS */ record_state = RECORDING; /* stuff from video_reader */ for(i=0;i<n_cameras;i++) start_capturing(QSP_ARG vd_tbl[i]); n_so_far = 0; which_disk=0; bufp=next_frame(QSP_ARG n_cameras,vd_tbl); while( bufp != NULL ){ int n_written; /* write the frame to disk */ if( really_writing ){ if( (n_written = write(fd_arr[which_disk],vd_tbl[which_device]->vd_buf_tbl[ bufp->index ].mb_start,n_to_write)) != n_to_write ){ sprintf(ERROR_STRING,"write (frm %ld, fd=%d)",n_so_far,ifp->if_fd); perror(ERROR_STRING); sprintf(ERROR_STRING, "%ld requested, %d written", n_to_write,n_written); WARN(ERROR_STRING); return; } which_disk = (which_disk+1) % ndisks; } n_so_far++; /* QBUG releases this buffer to be used again */ if( xioctl(vd_tbl[which_device]->vd_fd, VIDIOC_QBUF, bufp) < 0 ) ERRNO_WARN ("v4l2_stream_record: error queueing frame"); if( n_so_far >= n_frames ) bufp = NULL; else bufp=next_frame(QSP_ARG n_cameras,vd_tbl); } if( bufp != NULL ){ if( xioctl(vd_tbl[which_device]->vd_fd, VIDIOC_QBUF, bufp) < 0 ) ERRNO_WARN ("v4l2_stream_record: error queueing frame"); } for(i=0;i<n_cameras;i++) stop_capturing(QSP_ARG vd_tbl[i]); rv_sync(SINGLE_QSP_ARG); /* we used to disable real-time scheduling here, but * when video_reader executes as a separate thread there * is no point, because it won't affect the main process! */ recording_in_process = 0; record_state=NOT_RECORDING; #ifdef RECORD_TIMESTAMPS n_stored_times = n_so_far; #endif #ifdef CAUTIOUS if( ifp == NO_IMAGE_FILE ){ WARN("CAUTIOUS: v4l2_stream_record: ifp is NULL!?"); return; } #endif /* CAUTIOUS */ v4l2_finish_recording( QSP_ARG ifp ); /* Because the disk writers don't use the fileio library, * the ifp doesn't know how many frames have been written. */ ifp->if_nfrms = n_frames; /* BUG? is this really what happened? */ #else // ! HAVE_RAWVOL WARN("v4l2_stream_record: Program not compiled with raw volume support, can't record!?"); #endif // ! HAVE_RAWVOL } /* end v4l2_stream_record */