firewire.cpp
Go to the documentation of this file.
00001 /* This file is part of the Pangolin Project.
00002  * http://github.com/stevenlovegrove/Pangolin
00003  *
00004  * Copyright (c) 2011 Steven Lovegrove
00005  *
00006  * Permission is hereby granted, free of charge, to any person
00007  * obtaining a copy of this software and associated documentation
00008  * files (the "Software"), to deal in the Software without
00009  * restriction, including without limitation the rights to use,
00010  * copy, modify, merge, publish, distribute, sublicense, and/or sell
00011  * copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following
00013  * conditions:
00014  *
00015  * The above copyright notice and this permission notice shall be
00016  * included in all copies or substantial portions of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00019  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
00020  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00021  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
00022  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
00023  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00024  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00025  * OTHER DEALINGS IN THE SOFTWARE.
00026  */
00027 
00028 #include "firewire.h"
00029 
00030 #include <stdio.h>
00031 #include <stdint.h>
00032 #include <stdlib.h>
00033 #include <inttypes.h>
00034 
00035 using namespace std;
00036 
00037 namespace pangolin
00038 {
00039 
00040 void FirewireVideo::init_camera(
00041     uint64_t guid, int dma_frames,
00042     dc1394speed_t iso_speed,
00043     dc1394video_mode_t video_mode,
00044     dc1394framerate_t framerate
00045 )
00046 {
00047 
00048     if(video_mode>=DC1394_VIDEO_MODE_FORMAT7_0)
00049         throw VideoException("format7 modes need to be initialized through the constructor that allows for specifying the roi");
00050 
00051     camera = dc1394_camera_new (d, guid);
00052     if (!camera)
00053         throw VideoException("Failed to initialize camera");
00054 
00055     // Attempt to stop camera if it is already running
00056     dc1394switch_t is_iso_on = DC1394_OFF;
00057     dc1394_video_get_transmission(camera, &is_iso_on);
00058     if (is_iso_on==DC1394_ON)
00059     {
00060         dc1394_video_set_transmission(camera, DC1394_OFF);
00061     }
00062 
00063 
00064     cout << "Using camera with GUID " << camera->guid << endl;
00065 
00066     //-----------------------------------------------------------------------
00067     //  setup capture
00068     //-----------------------------------------------------------------------
00069 
00070     if( iso_speed >= DC1394_ISO_SPEED_800)
00071     {
00072         err=dc1394_video_set_operation_mode(camera, DC1394_OPERATION_MODE_1394B);
00073         if( err != DC1394_SUCCESS )
00074             throw VideoException("Could not set DC1394_OPERATION_MODE_1394B");
00075     }
00076 
00077     err=dc1394_video_set_iso_speed(camera, iso_speed);
00078     if( err != DC1394_SUCCESS )
00079         throw VideoException("Could not set iso speed");
00080 
00081     err=dc1394_video_set_mode(camera, video_mode);
00082     if( err != DC1394_SUCCESS )
00083         throw VideoException("Could not set video mode");
00084 
00085     err=dc1394_video_set_framerate(camera, framerate);
00086     if( err != DC1394_SUCCESS )
00087         throw VideoException("Could not set framerate");
00088 
00089     err=dc1394_capture_setup(camera,dma_frames, DC1394_CAPTURE_FLAGS_DEFAULT);
00090     if( err != DC1394_SUCCESS )
00091         throw VideoException("Could not setup camera - check settings");
00092 
00093     //-----------------------------------------------------------------------
00094     //  initialise width and height from mode
00095     //-----------------------------------------------------------------------
00096     dc1394_get_image_size_from_video_mode(camera, video_mode, &width, &height);
00097 
00098     Start();
00099 }
00100 
00101 
00102 // Note:
00103 // the following was tested on a IIDC camera over USB therefore might not work as
00104 // well on a camera over proper firewire transport
00105 void FirewireVideo::init_format7_camera(
00106     uint64_t guid, int dma_frames,
00107     dc1394speed_t iso_speed,
00108     dc1394video_mode_t video_mode,
00109     int framerate,
00110     uint32_t width, uint32_t height,
00111     uint32_t left, uint32_t top, bool reset_at_boot
00112 )
00113 {
00114 
00115     if(video_mode< DC1394_VIDEO_MODE_FORMAT7_0)
00116         throw VideoException("roi can be specified only for format7 modes");
00117 
00118     camera = dc1394_camera_new (d, guid);
00119     if (!camera)
00120         throw VideoException("Failed to initialize camera");
00121 
00122     // Attempt to stop camera if it is already running
00123     dc1394switch_t is_iso_on = DC1394_OFF;
00124     dc1394_video_get_transmission(camera, &is_iso_on);
00125     if (is_iso_on==DC1394_ON)
00126     {
00127         dc1394_video_set_transmission(camera, DC1394_OFF);
00128     }
00129 
00130     cout << "Using camera with GUID " << camera->guid << endl;
00131 
00132     if(reset_at_boot)
00133     {
00134         dc1394_camera_reset(camera);
00135     }
00136 
00137     //-----------------------------------------------------------------------
00138     //  setup mode and roi
00139     //-----------------------------------------------------------------------
00140 
00141     if(iso_speed >= DC1394_ISO_SPEED_800)
00142     {
00143         err=dc1394_video_set_operation_mode(camera, DC1394_OPERATION_MODE_1394B);
00144         if( err != DC1394_SUCCESS )
00145             throw VideoException("Could not set DC1394_OPERATION_MODE_1394B");
00146     }
00147 
00148     err=dc1394_video_set_iso_speed(camera, iso_speed);
00149     if( err != DC1394_SUCCESS )
00150         throw VideoException("Could not set iso speed");
00151 
00152     // check that the required mode is actually supported
00153     dc1394format7mode_t format7_info;
00154 
00155     err = dc1394_format7_get_mode_info(camera, video_mode, &format7_info);
00156     if( err != DC1394_SUCCESS )
00157         throw VideoException("Could not get format7 mode info");
00158 
00159     // safely set the video mode
00160     err=dc1394_video_set_mode(camera, video_mode);
00161     if( err != DC1394_SUCCESS )
00162         throw VideoException("Could not set format7 video mode");
00163 
00164     // set position to 0,0 so that setting any size within min and max is a valid command
00165     err = dc1394_format7_set_image_position(camera, video_mode,0,0);
00166     if( err != DC1394_SUCCESS )
00167         throw VideoException("Could not set format7 image position");
00168 
00169     // work out the desired image size
00170     width = nearest_value(width, format7_info.unit_pos_x, 0, format7_info.max_size_x - left);
00171     height = nearest_value(height, format7_info.unit_pos_y, 0, format7_info.max_size_y - top);
00172 
00173     // set size
00174     err = dc1394_format7_set_image_size(camera,video_mode,width,height);
00175     if( err != DC1394_SUCCESS )
00176         throw VideoException("Could not set format7 size");
00177 
00178     // get the info again since many parameters depend on image size
00179     err = dc1394_format7_get_mode_info(camera, video_mode, &format7_info);
00180     if( err != DC1394_SUCCESS )
00181         throw VideoException("Could not get format7 mode info");
00182 
00183     // work out position of roi
00184     left = nearest_value(left, format7_info.unit_size_x, format7_info.unit_size_x, format7_info.max_size_x - width);
00185     top = nearest_value(top, format7_info.unit_size_y, format7_info.unit_size_y, format7_info.max_size_y - height);
00186 
00187     // set roi position
00188     err = dc1394_format7_set_image_position(camera,video_mode,left,top);
00189     if( err != DC1394_SUCCESS )
00190         throw VideoException("Could not set format7 size");
00191 
00192     this->width = width;
00193     this->height = height;
00194     this->top = top;
00195     this->left = left;
00196 
00197     cout<<"roi: "<<left<<" "<<top<<" "<<width<<" "<<height<<"  ";
00198 
00199 
00200     //-----------------------------------------------------------------------
00201     //  setup frame rate
00202     //-----------------------------------------------------------------------
00203 
00204     if((framerate == MAX_FR)||(framerate == EXT_TRIG))
00205     {
00206 
00207         err=dc1394_format7_set_packet_size(camera,video_mode, format7_info.max_packet_size);
00208         if( err != DC1394_SUCCESS )
00209             throw VideoException("Could not set format7 packet size");
00210 
00211     }
00212     else
00213     {
00214 
00215         // setting packet size to get the desired frame rate according to the libdc docs
00216         // does not do the trick, so for now we support only max frame rate
00217 
00218         throw VideoException("In format 7 only max frame rate is currently supported");
00219         //      uint32_t depth;
00220         //      err = dc1394_format7_get_data_depth(camera, video_mode, &depth);
00221         //      if( err != DC1394_SUCCESS )
00222         //        throw VideoException("Could not get format7 depth");
00223         //
00224         //      // the following is straight from the libdc docs
00225         //      double bus_period = bus_period_from_iso_speed(iso_speed);
00226         //
00227         //      // work out the max number of packets that the bus can deliver
00228         //      int num_packets = (int) (1.0/(bus_period*framerate) + 0.5);
00229         //
00230         //      if((num_packets > 4095)||(num_packets < 0))
00231         //        throw VideoException("number of format7 packets out of range");
00232         //
00233         //      // work out what the packet size should be for the requested size and framerate
00234         //      uint32_t packet_size = (width*964*depth + (num_packets*8) - 1)/(num_packets*8);
00235         //      packet_size = nearest_value(packet_size,format7_info.unit_packet_size,format7_info.unit_packet_size,format7_info.max_packet_size);
00236         //
00237         //      if(packet_size > format7_info.max_packet_size){
00238         //        throw VideoException("format7 requested frame rate and size exceed bus bandwidth");
00239         //      }
00240         //
00241         //      err=dc1394_format7_set_packet_size(camera,video_mode, packet_size);
00242         //      if( err != DC1394_SUCCESS ){
00243         //        throw VideoException("Could not set format7 packet size");
00244         //      }
00245     }
00246 
00247     // ask the camera what is the resulting framerate (this assume that such a rate is actually
00248     // allowed by the shutter time)
00249     err = dc1394_feature_set_power(camera,DC1394_FEATURE_FRAME_RATE,DC1394_OFF);
00250     if( err != DC1394_SUCCESS )
00251         throw VideoException("Could not turn off frame rate");
00252 
00253     float value;
00254     err=dc1394_feature_get_absolute_value(camera,DC1394_FEATURE_FRAME_RATE,&value);
00255     if( err != DC1394_SUCCESS )
00256         throw VideoException("Could not get framerate");
00257 
00258     cout<<" framerate(shutter permitting):"<<value<<endl;
00259 
00260     //-----------------------------------------------------------------------
00261     //  setup capture
00262     //-----------------------------------------------------------------------
00263 
00264     err=dc1394_capture_setup(camera,dma_frames, DC1394_CAPTURE_FLAGS_DEFAULT);
00265     if( err != DC1394_SUCCESS )
00266         throw VideoException("Could not setup camera - check settings");
00267 
00268     Start();
00269 
00270 }
00271 
00272 
00273 std::string Dc1394ColorCodingToString(dc1394color_coding_t coding)
00274 {
00275     switch(coding)
00276     {
00277     case DC1394_COLOR_CODING_RGB8 :
00278         return "RGB24";
00279     case DC1394_COLOR_CODING_MONO8 :
00280         return "GRAY8";
00281 
00282 //        case DC1394_COLOR_CODING_MONO16 :  return "GRAY16LE";
00283 //        case DC1394_COLOR_CODING_RGB16 :   return "RGB48LE";
00284 //        case DC1394_COLOR_CODING_MONO16S : return "GRAY16BE";
00285 //        case DC1394_COLOR_CODING_RGB16S :  return "RGB48BE";
00286 
00287 //        case DC1394_COLOR_CODING_YUV411 :  return "YUV411P";
00288 //        case DC1394_COLOR_CODING_YUV422 :  return "YUV422P";
00289 //        case DC1394_COLOR_CODING_YUV444 :  return "YUV444P";
00290 //        case DC1394_COLOR_CODING_RAW8 :    return "RAW8";
00291 //        case DC1394_COLOR_CODING_RAW16 :   return "RAW16";
00292     default:
00293         throw VideoException("Unknown colour coding");
00294     }
00295 }
00296 
00297 dc1394color_coding_t Dc1394ColorCodingFromString(std::string coding)
00298 {
00299     if(     !coding.compare("RGB24"))    return DC1394_COLOR_CODING_RGB8;
00300     else if(!coding.compare("GRAY8"))    return DC1394_COLOR_CODING_MONO8;
00301 
00302 //    else if(!coding.compare("GRAY16LE")) return DC1394_COLOR_CODING_MONO16;
00303 //    else if(!coding.compare("RGB48LE"))  return DC1394_COLOR_CODING_RGB16;
00304 //    else if(!coding.compare("GRAY16BE")) return DC1394_COLOR_CODING_MONO16S;
00305 //    else if(!coding.compare("RGB48BE"))  return DC1394_COLOR_CODING_RGB16S;
00306 
00307 //    else if(!coding.compare("YUV411P"))  return DC1394_COLOR_CODING_YUV411;
00308 //    else if(!coding.compare("YUV422P"))  return DC1394_COLOR_CODING_YUV422;
00309 //    else if(!coding.compare("YUV444P"))  return DC1394_COLOR_CODING_YUV444;
00310 //    else if(!coding.compare("RAW8"))     return DC1394_COLOR_CODING_RAW8;
00311 //    else if(!coding.compare("RAW16"))    return DC1394_COLOR_CODING_RAW16;
00312     throw VideoException("Unknown colour coding");
00313 }
00314 
00315 void Dc1394ModeDetails(dc1394video_mode_t mode, unsigned& w, unsigned& h, string& format )
00316 {
00317     switch( mode )
00318     {
00319         // RGB Modes
00320     case DC1394_VIDEO_MODE_1024x768_RGB8:
00321         w=1024;
00322         h=768;
00323         format = "RGB24";
00324         break;
00325     case DC1394_VIDEO_MODE_640x480_RGB8:
00326         w=640;
00327         h=480;
00328         format = "RGB24";
00329         break;
00330     case DC1394_VIDEO_MODE_800x600_RGB8:
00331         w=800;
00332         h=600;
00333         format = "RGB24";
00334         break;
00335     case DC1394_VIDEO_MODE_1280x960_RGB8:
00336         w=1280;
00337         h=960;
00338         format = "RGB24";
00339         break;
00340     case DC1394_VIDEO_MODE_1600x1200_RGB8:
00341         w=1600;
00342         h=1200;
00343         format = "RGB24";
00344         break;
00345 
00346         // Greyscale modes
00347     case DC1394_VIDEO_MODE_640x480_MONO8:
00348         w=640;
00349         h=480;
00350         format = "GRAY8";
00351         break;
00352     case DC1394_VIDEO_MODE_800x600_MONO8:
00353         w=800;
00354         h=600;
00355         format = "GRAY8";
00356         break;
00357     case DC1394_VIDEO_MODE_1024x768_MONO8:
00358         w=1024;
00359         h=768;
00360         format = "GRAY8";
00361         break;
00362     case DC1394_VIDEO_MODE_1280x960_MONO8:
00363         w=1280;
00364         h=960;
00365         format = "GRAY8";
00366         break;
00367     case DC1394_VIDEO_MODE_1600x1200_MONO8:
00368         w=1600;
00369         h=1200;
00370         format = "GRAY8";
00371         break;
00372     case DC1394_VIDEO_MODE_640x480_MONO16:
00373         w=640;
00374         h=480;
00375         format = "GRAY16";
00376         break;
00377     case DC1394_VIDEO_MODE_800x600_MONO16:
00378         w=800;
00379         h=600;
00380         format = "GRAY16";
00381         break;
00382     case DC1394_VIDEO_MODE_1024x768_MONO16:
00383         w=1024;
00384         h=768;
00385         format = "GRAY16";
00386         break;
00387     case DC1394_VIDEO_MODE_1280x960_MONO16:
00388         w=1280;
00389         h=960;
00390         format = "GRAY16";
00391         break;
00392     case DC1394_VIDEO_MODE_1600x1200_MONO16:
00393         w=1600;
00394         h=1200;
00395         format = "GRAY16";
00396         break;
00397 
00398         // Chrome modes
00399     case DC1394_VIDEO_MODE_640x480_YUV411:
00400         w=640;
00401         h=480;
00402         format = "YUV411P";
00403         break;
00404     case DC1394_VIDEO_MODE_160x120_YUV444:
00405         w=160;
00406         h=120;
00407         format = "YUV444P";
00408         break;
00409     case DC1394_VIDEO_MODE_320x240_YUV422:
00410         w=320;
00411         h=240;
00412         format = "YUV422P";
00413         break;
00414     case DC1394_VIDEO_MODE_640x480_YUV422:
00415         w=640;
00416         h=480;
00417         format = "YUV422P";
00418         break;
00419     case DC1394_VIDEO_MODE_800x600_YUV422:
00420         w=800;
00421         h=600;
00422         format = "YUV422P";
00423         break;
00424     case DC1394_VIDEO_MODE_1024x768_YUV422:
00425         w=1024;
00426         h=768;
00427         format = "YUV422P";
00428         break;
00429     case DC1394_VIDEO_MODE_1600x1200_YUV422:
00430         w=1600;
00431         h=1200;
00432         format = "YUV422P";
00433         break;
00434     case DC1394_VIDEO_MODE_1280x960_YUV422:
00435         w=1280;
00436         h=960;
00437         format = "YUV422P";
00438         break;
00439     default:
00440         throw VideoException("Unknown colour coding");
00441     }
00442 }
00443 
00444 std::string FirewireVideo::PixFormat() const
00445 {
00446     dc1394video_mode_t video_mode;
00447     dc1394color_coding_t color_coding;
00448     dc1394_video_get_mode(camera,&video_mode);
00449     dc1394_get_color_coding_from_video_mode(camera,video_mode,&color_coding);
00450     return Dc1394ColorCodingToString(color_coding);
00451 }
00452 
00453 size_t FirewireVideo::SizeBytes() const
00454 {
00455     return (Width() * Height() * VideoFormatFromString(PixFormat()).bpp) / 8;
00456 }
00457 
00458 void FirewireVideo::Start()
00459 {
00460     if( !running )
00461     {
00462         err=dc1394_video_set_transmission(camera, DC1394_ON);
00463         if( err != DC1394_SUCCESS )
00464             throw VideoException("Could not start camera iso transmission");
00465         running = true;
00466     }
00467 }
00468 
00469 void FirewireVideo::Stop()
00470 {
00471     if( running )
00472     {
00473         // Stop transmission
00474         err=dc1394_video_set_transmission(camera,DC1394_OFF);
00475         if( err != DC1394_SUCCESS )
00476             throw VideoException("Could not stop the camera");
00477         running = false;
00478     }
00479 }
00480 
00481 FirewireVideo::FirewireVideo(
00482     Guid guid,
00483     dc1394video_mode_t video_mode,
00484     dc1394framerate_t framerate,
00485     dc1394speed_t iso_speed,
00486     int dma_buffers
00487 ) :running(false),top(0),left(0)
00488 {
00489     d = dc1394_new ();
00490     if (!d)
00491         throw VideoException("Failed to get 1394 bus");
00492 
00493     init_camera(guid.guid,dma_buffers,iso_speed,video_mode,framerate);
00494 }
00495 
00496 FirewireVideo::FirewireVideo(
00497     Guid guid,
00498     dc1394video_mode_t video_mode,
00499     int framerate,
00500     uint32_t width, uint32_t height,
00501     uint32_t left, uint32_t top,
00502     dc1394speed_t iso_speed,
00503     int dma_buffers, bool reset_at_boot
00504 ) :running(false)
00505 {
00506     d = dc1394_new ();
00507     if (!d)
00508         throw VideoException("Failed to get 1394 bus");
00509 
00510     init_format7_camera(guid.guid,dma_buffers,iso_speed,video_mode,framerate,width,height,left,top, reset_at_boot);
00511 }
00512 
00513 FirewireVideo::FirewireVideo(
00514     unsigned deviceid,
00515     dc1394video_mode_t video_mode,
00516     dc1394framerate_t framerate,
00517     dc1394speed_t iso_speed,
00518     int dma_buffers
00519 ) :running(false),top(0),left(0)
00520 {
00521     d = dc1394_new ();
00522     if (!d)
00523         throw VideoException("Failed to get 1394 bus");
00524 
00525     err=dc1394_camera_enumerate (d, &list);
00526     if( err != DC1394_SUCCESS )
00527         throw VideoException("Failed to enumerate cameras");
00528 
00529     if (list->num == 0)
00530         throw VideoException("No cameras found");
00531 
00532     if( deviceid >= list->num )
00533         throw VideoException("Invalid camera index");
00534 
00535     const uint64_t guid = list->ids[deviceid].guid;
00536 
00537     dc1394_camera_free_list (list);
00538 
00539     init_camera(guid,dma_buffers,iso_speed,video_mode,framerate);
00540 
00541 }
00542 
00543 FirewireVideo::FirewireVideo(
00544     unsigned deviceid,
00545     dc1394video_mode_t video_mode,
00546     int framerate,
00547     uint32_t width, uint32_t height,
00548     uint32_t left, uint32_t top,
00549     dc1394speed_t iso_speed,
00550     int dma_buffers, bool reset_at_boot
00551 ) :running(false)
00552 {
00553     d = dc1394_new ();
00554     if (!d)
00555         throw VideoException("Failed to get 1394 bus");
00556 
00557     err=dc1394_camera_enumerate (d, &list);
00558     if( err != DC1394_SUCCESS )
00559         throw VideoException("Failed to enumerate cameras");
00560 
00561     if (list->num == 0)
00562         throw VideoException("No cameras found");
00563 
00564     if( deviceid >= list->num )
00565         throw VideoException("Invalid camera index");
00566 
00567     const uint64_t guid = list->ids[deviceid].guid;
00568 
00569     dc1394_camera_free_list (list);
00570 
00571     init_format7_camera(guid,dma_buffers,iso_speed,video_mode,framerate,width,height,left,top, reset_at_boot);
00572 
00573 }
00574 
00575 bool FirewireVideo::GrabNext( unsigned char* image, bool wait )
00576 {
00577     const dc1394capture_policy_t policy =
00578         wait ? DC1394_CAPTURE_POLICY_WAIT : DC1394_CAPTURE_POLICY_POLL;
00579 
00580     dc1394video_frame_t *frame;
00581     dc1394_capture_dequeue(camera, policy, &frame);
00582     if( frame )
00583     {
00584         memcpy(image,frame->image,frame->image_bytes);
00585         dc1394_capture_enqueue(camera,frame);
00586         return true;
00587     }
00588     return false;
00589 }
00590 
00591 bool FirewireVideo::GrabNewest( unsigned char* image, bool wait )
00592 {
00593     dc1394video_frame_t *f;
00594     dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_POLL, &f);
00595 
00596     if( f )
00597     {
00598         while( true )
00599         {
00600             dc1394video_frame_t *nf;
00601             dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_POLL, &nf);
00602             if( nf )
00603             {
00604                 err=dc1394_capture_enqueue(camera,f);
00605                 f = nf;
00606             }
00607             else
00608             {
00609                 break;
00610             }
00611         }
00612         memcpy(image,f->image,f->image_bytes);
00613         err=dc1394_capture_enqueue(camera,f);
00614         return true;
00615     }
00616     else if(wait)
00617     {
00618         return GrabNext(image,true);
00619     }
00620     return false;
00621 }
00622 
00623 FirewireFrame FirewireVideo::GetNext(bool wait)
00624 {
00625     const dc1394capture_policy_t policy =
00626         wait ? DC1394_CAPTURE_POLICY_WAIT : DC1394_CAPTURE_POLICY_POLL;
00627 
00628     dc1394video_frame_t *frame;
00629     dc1394_capture_dequeue(camera, policy, &frame);
00630     return FirewireFrame(frame);
00631 }
00632 
00633 FirewireFrame FirewireVideo::GetNewest(bool wait)
00634 {
00635     dc1394video_frame_t *f;
00636     dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_POLL, &f);
00637 
00638     if( f )
00639     {
00640         while( true )
00641         {
00642             dc1394video_frame_t *nf;
00643             dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_POLL, &nf);
00644             if( nf )
00645             {
00646                 err=dc1394_capture_enqueue(camera,f);
00647                 f = nf;
00648             }
00649             else
00650             {
00651                 break;
00652             }
00653         }
00654         return FirewireFrame(f);
00655     }
00656     else if(wait)
00657     {
00658         return GetNext(true);
00659     }
00660     return FirewireFrame(0);
00661 }
00662 
00663 void FirewireVideo::PutFrame(FirewireFrame& f)
00664 {
00665     if( f.frame )
00666     {
00667         dc1394_capture_enqueue(camera,f.frame);
00668         f.frame = 0;
00669     }
00670 }
00671 
00672 void FirewireVideo::SetShutterTimeQuant(int shutter)
00673 {
00674     // TODO: Set mode as well
00675 
00676     err = dc1394_feature_set_value(camera,DC1394_FEATURE_SHUTTER,shutter);
00677 
00678     if( err != DC1394_SUCCESS )
00679         throw VideoException("Failed to set shutter");
00680 }
00681 
00682 float FirewireVideo::GetGain() const
00683 {
00684     float gain;
00685     err = dc1394_feature_get_absolute_value(camera,DC1394_FEATURE_GAIN,&gain);
00686     if( err != DC1394_SUCCESS )
00687         throw VideoException("Failed to read gain");
00688 
00689     return gain;
00690 
00691 }
00692 
00693 void FirewireVideo::SetAutoGain()
00694 {
00695 
00696     dc1394error_t err = dc1394_feature_set_mode(camera, DC1394_FEATURE_GAIN, DC1394_FEATURE_MODE_AUTO);
00697     if (err < 0)
00698     {
00699         throw VideoException("Could not set auto gain mode");
00700     }
00701 }
00702 
00703 
00704 float FirewireVideo::GetShutterTime() const
00705 {
00706     float shutter;
00707     err = dc1394_feature_get_absolute_value(camera,DC1394_FEATURE_SHUTTER,&shutter);
00708     if( err != DC1394_SUCCESS )
00709         throw VideoException("Failed to read shutter");
00710 
00711     return shutter;
00712 }
00713 
00714 
00715 void FirewireVideo::SetGain(float val)
00716 {
00717 
00718     dc1394error_t err = dc1394_feature_set_mode(camera, DC1394_FEATURE_GAIN, DC1394_FEATURE_MODE_MANUAL);
00719     if (err < 0)
00720     {
00721         throw VideoException("Could not set manual gain mode");
00722     }
00723 
00724     err = dc1394_feature_set_absolute_control(camera, DC1394_FEATURE_GAIN, DC1394_ON);
00725     if (err < 0)
00726     {
00727         throw VideoException("Could not set absolute control for gain");
00728     }
00729 
00730     err = dc1394_feature_set_absolute_value(camera, DC1394_FEATURE_GAIN, val);
00731     if (err < 0)
00732     {
00733         throw VideoException("Could not set gain value");
00734     }
00735 }
00736 
00737 void FirewireVideo::SetAutoShutterTime()
00738 {
00739 
00740     dc1394error_t err = dc1394_feature_set_mode(camera, DC1394_FEATURE_SHUTTER, DC1394_FEATURE_MODE_AUTO);
00741     if (err < 0)
00742     {
00743         throw VideoException("Could not set auto shutter mode");
00744     }
00745 }
00746 
00747 void FirewireVideo::SetShutterTime(float val)
00748 {
00749 
00750     dc1394error_t err = dc1394_feature_set_mode(camera, DC1394_FEATURE_SHUTTER, DC1394_FEATURE_MODE_MANUAL);
00751     if (err < 0)
00752     {
00753         throw VideoException("Could not set manual shutter mode");
00754     }
00755 
00756     err = dc1394_feature_set_absolute_control(camera, DC1394_FEATURE_SHUTTER, DC1394_ON);
00757     if (err < 0)
00758     {
00759         throw VideoException("Could not set absolute control for shutter");
00760     }
00761 
00762     err = dc1394_feature_set_absolute_value(camera, DC1394_FEATURE_SHUTTER, val);
00763     if (err < 0)
00764     {
00765         throw VideoException("Could not set shutter value");
00766     }
00767 }
00768 
00769 float FirewireVideo::GetGamma() const
00770 {
00771     float gamma;
00772     err = dc1394_feature_get_absolute_value(camera,DC1394_FEATURE_GAMMA,&gamma);
00773     if( err != DC1394_SUCCESS )
00774         throw VideoException("Failed to read gamma");
00775     return gamma;
00776 }
00777 
00778 void FirewireVideo::SetInternalTrigger()
00779 {
00780     dc1394error_t err = dc1394_external_trigger_set_power(camera, DC1394_OFF);
00781     if (err < 0)
00782     {
00783         throw VideoException("Could not set internal trigger mode");
00784     }
00785 }
00786 
00787 void FirewireVideo::SetExternalTrigger(dc1394trigger_mode_t mode, dc1394trigger_polarity_t polarity, dc1394trigger_source_t source)
00788 {
00789     dc1394error_t err = dc1394_external_trigger_set_polarity(camera, polarity);
00790     if (err < 0)
00791     {
00792         throw VideoException("Could not set external trigger polarity");
00793     }
00794 
00795     err = dc1394_external_trigger_set_mode(camera, mode);
00796     if (err < 0)
00797     {
00798         throw VideoException("Could not set external trigger mode");
00799     }
00800 
00801     err = dc1394_external_trigger_set_source(camera, source);
00802     if (err < 0)
00803     {
00804         throw VideoException("Could not set external trigger source");
00805     }
00806 
00807     err = dc1394_external_trigger_set_power(camera, DC1394_ON);
00808     if (err < 0)
00809     {
00810         throw VideoException("Could not set external trigger power");
00811     }
00812 }
00813 
00814 
00815 FirewireVideo::~FirewireVideo()
00816 {
00817     Stop();
00818 
00819     // Close camera
00820     dc1394_video_set_transmission(camera, DC1394_OFF);
00821     dc1394_capture_stop(camera);
00822     dc1394_camera_free(camera);
00823     dc1394_free (d);
00824 }
00825 
00826 
00827 int FirewireVideo::nearest_value(int value, int step, int min, int max)
00828 {
00829 
00830     int low, high;
00831 
00832     low=value-(value%step);
00833     high=value-(value%step)+step;
00834     if (low<min)
00835         low=min;
00836     if (high>max)
00837         high=max;
00838 
00839     if (abs(low-value)<abs(high-value))
00840         return low;
00841     else
00842         return high;
00843 }
00844 
00845 double FirewireVideo::bus_period_from_iso_speed(dc1394speed_t iso_speed)
00846 {
00847     double bus_period;
00848 
00849     switch(iso_speed)
00850     {
00851     case DC1394_ISO_SPEED_3200:
00852         bus_period = 15.625e-6;
00853         break;
00854     case DC1394_ISO_SPEED_1600:
00855         bus_period = 31.25e-6;
00856         break;
00857     case DC1394_ISO_SPEED_800:
00858         bus_period = 62.5e-6;
00859         break;
00860     case DC1394_ISO_SPEED_400:
00861         bus_period = 125e-6;
00862         break;
00863     case DC1394_ISO_SPEED_200:
00864         bus_period = 250e-6;
00865         break;
00866     case DC1394_ISO_SPEED_100:
00867         bus_period = 500e-6;
00868         break;
00869     default:
00870         throw VideoException("iso speed not valid");
00871     }
00872 
00873     return bus_period;
00874 }
00875 
00876 }
00877 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


pangolin_wrapper
Author(s): Todor Stoyanov
autogenerated on Wed Feb 13 2013 14:03:25