#define PROG_NAME "capture_cam_firewire" #define PROG_DESC "capture uncompressed images from Firewire cameras using dc1394" #define PROG_VERS "1.0" #define PROG_HELP \ " " PROG_NAME " \\\n" \ " -prefix {PREFIX} \\\n" \ " -deviceNum {DEVICE NUMBER}\\\n" \ " -numPictures {NUMBER}\\\n" \ " [-format {0-7} ] \\\n" \ " (only for format 7)[ -mode {0-7} -roi {W}{H}{X}{Y} ] \\\n" \ " [-coding {MONO|RGB|YUV|RAW} ] \\\n" \ " [-depth {8|16 (for MONO,RGB,RAW) 411|422|444 (for YUV)}] \\\n" \ " [-framerate {1.875|3.75|7.5|15|30|60|120|240}] \\\n" \ " [-isoSpeed {100|200|400|800} ] \\\n" \ " [-resetDevice] \\\n" \ " [-justPreview] \\\n" \ " [-showPreview] \\\n" \ " [-resetAllDevices] \\\n" \ " [-listAllDevices] \\\n" \ " [-timeInterval {TIMEINTERVAL} ]" #define PROG_INFO \ "NAME\n" \ " " PROG_NAME " - " PROG_DESC "\n" \ "\n" \ "SYNOPSIS\n" \ PROG_HELP "\n" \ "\n" \ "\n" \ argparser_help_info_HELP_INFO "\n" \ "\n" \ "AUTHOR\n" \ " Created 2010-05-24 by Rafael Saracchini, UNICAMP.\n" \ "MODIFICATION HISTORY\n" \ " 2010-05-25 by R. Saracchini, IC-UNICAMP/MVL-UWE: introduced arg parsing and advanced options.\n" \ "\n" \ "WARRANTY\n" \ argparser_help_info_NO_WARRANTY "\n" \ argparser_help_info_STANDARD_RIGHTS #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct options_t{ int deviceNum; char* prefix; dc1394video_mode_t videoMode; dc1394color_coding_t colorCoding; r2_t* roiDimensions; r2_t* roiPosition; dc1394framerate_t framerate; dc1394speed_t isoSpeed; double timeInterval; int autoSetup; int numPictures; bool_t resetDevice; bool_t resetAllDevices; bool_t listAllDevices; bool_t showPreview; bool_t justPreview; }; typedef struct options_t options_t; options_t* parse_options(int argc, char** argv); options_t* parse_options(int argc, char** argv){ options_t* o = (options_t*)malloc(sizeof(options_t)); argparser_t *pp = argparser_new(stderr, argc, argv); argparser_set_help(pp, PROG_NAME " version " PROG_VERS ", usage:\n" PROG_HELP); argparser_set_info(pp, PROG_INFO); argparser_process_help_info_options(pp); o->resetDevice = argparser_keyword_present(pp,"-resetDevice"); o->resetAllDevices = argparser_keyword_present(pp,"-resetAllDevices") ; o->listAllDevices= argparser_keyword_present(pp,"-listAllDevices") ; o->showPreview = argparser_keyword_present(pp,"-showPreview") ; o->justPreview = argparser_keyword_present(pp,"-justPreview") ; if((!o->resetDevice ) && (!o->resetAllDevices) && (!o->listAllDevices) ){ argparser_get_keyword(pp, "-prefix"); o->prefix = argparser_get_next(pp); argparser_get_keyword(pp, "-numPictures"); o->numPictures = argparser_get_next_int(pp, 1, 100000); } if((!o->resetAllDevices) && (!o->listAllDevices) ){ argparser_get_keyword(pp, "-deviceNum"); o->deviceNum = argparser_get_next_int(pp, 0, 1000); } //The video mode options arent know by advance... o->videoMode = DC1394_VIDEO_MODE_MAX+1; o->roiDimensions = NULL; o->roiPosition = NULL; o->colorCoding = DC1394_COLOR_CODING_MAX +1; o->autoSetup = 1; int format,mode; format = mode = -1; if(argparser_keyword_present(pp,"-format")){ o->autoSetup = 0; format = argparser_get_next_int(pp, 0, 7); if(format == 7 ){ mode = 0; if(argparser_keyword_present(pp,"-mode")){ mode = argparser_get_next_int(pp, 0, 7); } if(argparser_keyword_present(pp,"-roi")){ o->roiDimensions = (r2_t*)malloc(sizeof(r2_t)); o->roiPosition = (r2_t*)malloc(sizeof(r2_t)); o->roiDimensions->c[0] = argparser_get_next_int(pp, 0, 100000); o->roiDimensions->c[1] = argparser_get_next_int(pp, 0, 100000); o->roiPosition->c[0] = argparser_get_next_int(pp, 0, 100000); o->roiPosition->c[1] = argparser_get_next_int(pp, 0, 100000); } } } int coding = -1; int depth = -1; if(argparser_keyword_present(pp,"-coding")){ o->autoSetup = 0; char* txt_coding = argparser_get_next(pp); char* valid_codings[] = {"MONO","RGB","RAW","YUV"}; int i; for(i = 0; i < 4; i++){ if(strcmp(valid_codings[i],txt_coding) == 0){ coding = i; break; } } if(coding == 4){ argparser_error(pp,"No valid coding selected"); } argparser_get_keyword(pp,"-depth"); if(i < 3){ depth = argparser_get_next_int(pp,8,16); if((depth != 8) && (depth != 16)){ fprintf(stderr,"Wrong Value to depth (%d).",depth); argparser_error(pp,"Depth for MONO,RGB or RAW should be 8 or 16"); } }else{ depth = argparser_get_next_int(pp,411,444); if((depth != 411) && (depth != 422) && (depth != 444)){ argparser_error(pp,"Depth for YUV should be 411, 422 or 444"); } } } //We will come back to video modes later ! int isospeed; o->isoSpeed = DC1394_ISO_SPEED_400; if(argparser_keyword_present(pp,"-isoSpeed")){ isospeed = argparser_get_next_int(pp, 0, 3200); switch (isospeed){ case 100: o->isoSpeed = DC1394_ISO_SPEED_100; break; case 200: o->isoSpeed = DC1394_ISO_SPEED_200; break; case 400: o->isoSpeed = DC1394_ISO_SPEED_400; break; case 800: o->isoSpeed = DC1394_ISO_SPEED_800; break; case 1600: o->isoSpeed = DC1394_ISO_SPEED_1600; break; case 3200: o->isoSpeed = DC1394_ISO_SPEED_3200; break; default: argparser_error(pp,"Invalid value for ISO speed"); } } o->framerate = DC1394_FRAMERATE_7_5; double framerate ; if(argparser_keyword_present(pp,"-framerate")){ framerate = argparser_get_next_double(pp, 1.875, 240); if( framerate == 1.875){ o->framerate = DC1394_FRAMERATE_1_875; }else if( framerate == 3.75 ){ o->framerate = DC1394_FRAMERATE_3_75; }else if( framerate == 7.5){ o->framerate = DC1394_FRAMERATE_7_5; }else if( framerate == 15){ o->framerate = DC1394_FRAMERATE_15; }else if( framerate == 30){ o->framerate = DC1394_FRAMERATE_30; }else if( framerate == 60){ o->framerate = DC1394_FRAMERATE_60; }else if( framerate == 120){ o->framerate = DC1394_FRAMERATE_120; }else if( framerate == 240){ o->framerate = DC1394_FRAMERATE_240; }else{ argparser_error(pp,"Invalid value for framerate"); } } o->timeInterval = 3.0; if(argparser_keyword_present(pp,"-timeInterval")){ o->timeInterval = argparser_get_next_double(pp,0,1000000); } /*Then we will check now the combination of format, coding and depth*/ if(o->autoSetup != 1){ if(!determine_videomode(format,mode,coding,depth,&(o->videoMode),&(o->colorCoding))){ argparser_error(pp,"The format,coding and depth configuration is not compatible with DC1394 videomodes"); } } /*Just preview overhides all caoture settings*/ if(o->justPreview){ o->timeInterval = INT_MAX; o->numPictures = INT_MAX; } argparser_finish(pp); return o; } uint32_t get_num_pixels(dc1394camera_t *camera, uint32_t format ); /*----------------------------------------------------------------------- * Returns the number of pixels in the image based upon the format *-----------------------------------------------------------------------*/ uint32_t get_num_pixels(dc1394camera_t *camera, uint32_t format ) { uint32_t w,h; dc1394_get_image_size_from_video_mode(camera, format,&w,&h); return w*h; } void beep(void); void beep(void){ system("printf \"\x07\""); } /*Clock control */ double user_cpu_time_usec(void); double user_cpu_time_usec(void){ // struct tms buf; // (void)times(&buf); // return(1000000.0 * ((double) buf.tms_utime)/((double)sysconf(_SC_CLK_TCK))); struct timespec start; clock_gettime(CLOCK_MONOTONIC, &start); double time = start.tv_sec + ((start.tv_nsec)/1000000000.0); return time; } int main(int argc, char *argv[]) { options_t* o = parse_options(argc,argv); dc1394error_t err; dc1394_t * d = session_init(); if (!d){ fprintf(stderr,"Failed to Init DC1394 session !\n"); return 1; } if(o->resetDevice){ session_reset_device(d,o->deviceNum); fprintf(stderr,"Device %d was reseted. Exiting.\n",o->deviceNum); session_close(d); return 0; } if(o->resetAllDevices){ session_reset_all_devices(d); fprintf(stderr,"All Devices where reseted. Exiting.\n"); session_close(d); return 0; } if(o->listAllDevices){ int i; int num_devices = session_get_num_devices(d); fprintf(stderr,"%d devices found\n",num_devices); for(i = 0; i < num_devices; i++){ dc1394camera_t* curr_camera = camera_get_device(d,i); if(curr_camera != NULL){ fprintf(stderr,"Listing Device %d capabilities.\n",i); camera_print_capabilities(curr_camera,stderr); camera_release(curr_camera); }else{ fprintf(stderr,"Could not get access to Device %d\n",i); } } session_close(d); return 0; } /*Start the job: get access to the camera, init it with parameters*/ dc1394camera_t *camera = camera_get_device(d,o->deviceNum); if(camera == NULL){ fprintf(stderr,"Could not get access to Device %d.Exiting.\n",o->deviceNum); return 1; }; fprintf(stderr,"Using camera with GUID %"PRIx64"\n", camera->guid); if(o->autoSetup){ err = camera_auto_init(camera); DC1394_ERR_RTN(err,"Error in auto initialization of camera."); }else{ err = camera_init(camera, o->videoMode, o->colorCoding, o->isoSpeed, o->framerate, o->roiDimensions, o->roiPosition); DC1394_ERR_RTN(err,"Error in the initialization of camera."); } fprintf(stderr,"Camera had been initialized. \n"); camera_print_settings(camera,stderr); int capturedFrames = 0; double starting_time = user_cpu_time_usec(); double last_capture_time = starting_time; double already_beep = 0; fprintf(stderr,"Pre-alocating buffers.\n"); dc1394video_frame_t* framebuffer = calloc(o->numPictures,sizeof(dc1394video_frame_t)); dc1394video_frame_t* frame = calloc(1,sizeof(dc1394video_frame_t)) ; fprintf(stderr,"Capturing.\n"); /* err=dc1394_video_set_transmission(camera, DC1394_OFF); DC1394_ERR_CLN_RTN(err,cleanup_and_exit(camera),"Could not stop camera for initialization\n"); err = camera_flush_DMA(camera); */ sdl_screen_t* ss = NULL; if(o->showPreview){ ss = InitSDLScreen(camera); assert(ss != NULL); } err=dc1394_video_set_transmission(camera, DC1394_ON); uint32_t bits_camera; dc1394_get_color_coding_data_depth(o->colorCoding,&bits_camera); int done = 0; while((capturedFrames < o->numPictures) && (done == 0)){ /*Capture a frame anyway*/ err=dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_POLL, &frame); DC1394_ERR_CLN_RTN(err,cleanup_and_exit(camera),"Could not capture a frame\n"); /*Event treatment here.. i dont want it freezing*/ SDL_Event event; while (SDL_PollEvent (&event)){ switch (event.type){ case SDL_QUIT: done = 1; break; case SDL_KEYDOWN: break; default: break; }; } /*--------------------*/ double current_time = user_cpu_time_usec(); double time_diff = current_time - last_capture_time; if(o->justPreview){ time_diff = 0; } if(o->timeInterval > 1.0){ if(!already_beep){ if(time_diff > (o->timeInterval-2)){ already_beep= 1; beep(); fprintf(stderr,"BEEEP at %lf (%lf)\n",time_diff,current_time); } } } if ((err==DC1394_SUCCESS)&&(frame!=NULL)) { /*Security Check verify consistency between frames*/ if(frame->color_coding != o->colorCoding){ err = DC1394_FAILURE; fprintf(stderr,"FATAL ERROR: Inconsistent frame coding !\n"); fprintf(stderr,"Camera has: %s\n",camfirewire_color_coding_name(o->colorCoding)); fprintf(stderr,"Frame has: %s\n",camfirewire_color_coding_name(frame->color_coding)); DC1394_ERR_CLN_RTN(err,cleanup_and_exit(camera),"Could not capture a frame\n"); } /*Exibit image if needed*/ if(o->showPreview){ displayFrame(ss,frame); } /*Return frame to ring*/ if( time_diff >= o->timeInterval ){ beep(); camera_copy_frame(frame,&(framebuffer[capturedFrames])); already_beep = 0; last_capture_time = user_cpu_time_usec(); fprintf(stderr,"Frame %d captured at %f\n",capturedFrames, last_capture_time); capturedFrames++; } err = dc1394_capture_enqueue(camera,frame); DC1394_ERR_CLN_RTN(err,cleanup_and_exit(camera),"Could not release a frame\n"); /*Reset everything else*/ } } /*----------------------------------------------------------------------- * stop data transmission *-----------------------------------------------------------------------*/ /*Turn off display*/ if(o->showPreview){ releaseSDLScreen(ss); } err=dc1394_video_set_transmission(camera,DC1394_OFF); DC1394_ERR_CLN_RTN(err,cleanup_and_exit(camera),"Could not stop the camera?\n"); /*----------------------------------------------------------------------- * Save stored frames *-----------------------------------------------------------------------*/ int i; fprintf(stderr,"Saving frames.\n"); for(i = 0; i < capturedFrames; i++){ char* file_prefix = NULL; asprintf(&file_prefix,"%s_%03d",o->prefix,i); fprintf(stderr,"Frame color coding is %s.\n",camfirewire_color_coding_name(framebuffer[i].color_coding)); fprintf(stderr,"Saving frame %d...",i); save_frame(file_prefix,camera,&(framebuffer[i])); fprintf(stderr,"OK\n"); free(framebuffer[i].image); } /*Release frame*/ // fprintf(stderr,"releasing frame\n"); // free(frame); fprintf(stderr,"releasing buffer\n"); free(framebuffer); /*----------------------------------------------------------------------- * close camera *-----------------------------------------------------------------------*/ // free(new_frame->image); // free(new_frame); // dc1394_video_set_transmission(camera, DC1394_OFF); // dc1394_capture_stop(camera); // dc1394_camera_free(camera); // dc1394_free (d); fprintf(stderr,"Exiting.\n"); camera_release(camera); session_close(d); return 0; }