Home | History | Annotate | Download | only in src
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                        Intel License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
     14 // Third party copyrights are property of their respective owners.
     15 //
     16 // Redistribution and use in source and binary forms, with or without modification,
     17 // are permitted provided that the following conditions are met:
     18 //
     19 //   * Redistribution's of source code must retain the above copyright notice,
     20 //     this list of conditions and the following disclaimer.
     21 //
     22 //   * Redistribution's in binary form must reproduce the above copyright notice,
     23 //     this list of conditions and the following disclaimer in the documentation
     24 //     and/or other materials provided with the distribution.
     25 //
     26 //   * The name of Intel Corporation may not be used to endorse or promote products
     27 //     derived from this software without specific prior written permission.
     28 //
     29 // This software is provided by the copyright holders and contributors "as is" and
     30 // any express or implied warranties, including, but not limited to, the implied
     31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     32 // In no event shall the Intel Corporation or contributors be liable for any direct,
     33 // indirect, incidental, special, exemplary, or consequential damages
     34 // (including, but not limited to, procurement of substitute goods or services;
     35 // loss of use, data, or profits; or business interruption) however caused
     36 // and on any theory of liability, whether in contract, strict liability,
     37 // or tort (including negligence or otherwise) arising in any way out of
     38 // the use of this software, even if advised of the possibility of such damage.
     39 //
     40 //M*/
     41 
     42 #include "precomp.hpp"
     43 
     44 #ifdef HAVE_DC1394_2
     45 
     46 #include <unistd.h>
     47 #include <stdint.h>
     48 #ifdef WIN32
     49   // On Windows, we have no sys/select.h, but we need to pick up
     50   // select() which is in winsock2.
     51   #ifndef __SYS_SELECT_H__
     52     #define __SYS_SELECT_H__ 1
     53     #include <winsock2.h>
     54   #endif
     55 #else
     56   #include <sys/select.h>
     57 #endif /*WIN32*/
     58 #include <dc1394/dc1394.h>
     59 #include <stdlib.h>
     60 #include <string.h>
     61 
     62 static dc1394error_t adaptBufferStereoLocal(dc1394video_frame_t *in, dc1394video_frame_t *out)
     63 {
     64     uint32_t bpp;
     65 
     66     // buffer position is not changed. Size is boubled in Y
     67     out->size[0] = in->size[0];
     68     out->size[1] = in->size[1] * 2;
     69     out->position[0] = in->position[0];
     70     out->position[1] = in->position[1];
     71 
     72     // color coding is set to mono8 or raw8.
     73     switch (in->color_coding)
     74     {
     75     case DC1394_COLOR_CODING_RAW16:
     76         out->color_coding = DC1394_COLOR_CODING_RAW8;
     77         break;
     78     case DC1394_COLOR_CODING_MONO16:
     79     case DC1394_COLOR_CODING_YUV422:
     80         out->color_coding = DC1394_COLOR_CODING_MONO8;
     81         break;
     82     default:
     83         return DC1394_INVALID_COLOR_CODING;
     84     }
     85 
     86     // keep the color filter value in all cases. if the format is not raw it will not be further used anyway
     87     out->color_filter = in->color_filter;
     88 
     89     // the output YUV byte order must be already set if the buffer is YUV422 at the output
     90     // if the output is not YUV we don't care about this field.
     91     // Hence nothing to do.
     92     // we always convert to 8bits (at this point) we can safely set this value to 8.
     93     out->data_depth = 8;
     94 
     95     // don't know what to do with stride... >>>> TODO: STRIDE SHOULD BE TAKEN INTO ACCOUNT... <<<<
     96     // out->stride=??
     97     // the video mode should not change. Color coding and other stuff can be accessed in specific fields of this struct
     98     out->video_mode = in->video_mode;
     99 
    100     // padding is kept:
    101     out->padding_bytes = in->padding_bytes;
    102 
    103     // image bytes changes:    >>>> TODO: STRIDE SHOULD BE TAKEN INTO ACCOUNT... <<<<
    104     dc1394_get_color_coding_bit_size(out->color_coding, &bpp);
    105     out->image_bytes = (out->size[0] * out->size[1] * bpp) / 8;
    106 
    107     // total is image_bytes + padding_bytes
    108     out->total_bytes = out->image_bytes + out->padding_bytes;
    109 
    110     // bytes-per-packet and packets_per_frame are internal data that can be kept as is.
    111     out->packet_size  = in->packet_size;
    112     out->packets_per_frame = in->packets_per_frame;
    113 
    114     // timestamp, frame_behind, id and camera are copied too:
    115     out->timestamp = in->timestamp;
    116     out->frames_behind = in->frames_behind;
    117     out->camera = in->camera;
    118     out->id = in->id;
    119 
    120     // verify memory allocation:
    121     if (out->total_bytes > out->allocated_image_bytes)
    122     {
    123         free(out->image);
    124         out->image = (uint8_t*)malloc(out->total_bytes * sizeof(uint8_t));
    125         out->allocated_image_bytes = out->total_bytes;
    126     }
    127 
    128     // Copy padding bytes:
    129     memcpy(&(out->image[out->image_bytes]), &(in->image[in->image_bytes]), out->padding_bytes);
    130     out->little_endian = DC1394_FALSE; // not used before 1.32 is out.
    131     out->data_in_padding = DC1394_FALSE; // not used before 1.32 is out.
    132     return DC1394_SUCCESS;
    133 }
    134 
    135 static dc1394error_t dc1394_deinterlace_stereo_frames_fixed(dc1394video_frame_t *in,
    136     dc1394video_frame_t *out, dc1394stereo_method_t method)
    137 {
    138     if((in->color_coding == DC1394_COLOR_CODING_RAW16) ||
    139        (in->color_coding == DC1394_COLOR_CODING_MONO16) ||
    140        (in->color_coding == DC1394_COLOR_CODING_YUV422))
    141     {
    142         switch (method)
    143         {
    144 
    145         case DC1394_STEREO_METHOD_INTERLACED:
    146             adaptBufferStereoLocal(in, out);
    147 //FIXED by AB:
    148 //          dc1394_deinterlace_stereo(in->image, out->image, in->size[0], in->size[1]);
    149             dc1394_deinterlace_stereo(in->image, out->image, out->size[0], out->size[1]);
    150             break;
    151 
    152         case DC1394_STEREO_METHOD_FIELD:
    153             adaptBufferStereoLocal(in, out);
    154             memcpy(out->image, in->image, out->image_bytes);
    155             break;
    156         }
    157 
    158         return DC1394_INVALID_STEREO_METHOD;
    159     }
    160     else
    161         return DC1394_FUNCTION_NOT_SUPPORTED;
    162 }
    163 
    164 static uint32_t getControlRegister(dc1394camera_t *camera, uint64_t offset)
    165 {
    166     uint32_t value = 0;
    167     dc1394error_t err = dc1394_get_control_register(camera, offset, &value);
    168 
    169     assert(err == DC1394_SUCCESS);
    170     return err == DC1394_SUCCESS ? value : 0xffffffff;
    171 }
    172 
    173 struct CvDC1394
    174 {
    175     CvDC1394();
    176     ~CvDC1394();
    177 
    178     dc1394_t* dc;
    179     fd_set camFds;
    180 };
    181 
    182 CvDC1394::CvDC1394()
    183 {
    184     dc = dc1394_new();
    185     FD_ZERO(&camFds);
    186 }
    187 
    188 CvDC1394::~CvDC1394()
    189 {
    190     if (dc)
    191         dc1394_free(dc);
    192     dc = 0;
    193 }
    194 
    195 static CvDC1394 dc1394;
    196 
    197 class CvCaptureCAM_DC1394_v2_CPP : public CvCapture
    198 {
    199 public:
    200     static int dc1394properties[CV_CAP_PROP_MAX_DC1394];
    201     CvCaptureCAM_DC1394_v2_CPP();
    202     virtual ~CvCaptureCAM_DC1394_v2_CPP()
    203     {
    204         close();
    205     }
    206 
    207     virtual bool open(int index);
    208     virtual void close();
    209 
    210     virtual double getProperty(int) const;
    211     virtual bool setProperty(int, double);
    212     virtual bool grabFrame();
    213     virtual IplImage* retrieveFrame(int);
    214     virtual int getCaptureDomain() { return CV_CAP_DC1394; } // Return the type of the capture object: CV_CAP_VFW, etc...
    215 
    216 
    217 protected:
    218     virtual bool startCapture();
    219     virtual bool getVidereCalibrationInfo( char* buf, int bufSize );
    220     virtual bool initVidereRectifyMaps( const char* info, IplImage* ml[2], IplImage* mr[2] );
    221 
    222     uint64_t guid;
    223     dc1394camera_t* dcCam;
    224     int isoSpeed;
    225     int videoMode;
    226     int frameWidth, frameHeight;
    227     double fps;
    228     int nDMABufs;
    229     bool started;
    230     int userMode;
    231 
    232     enum { VIDERE = 0x5505 };
    233 
    234     int cameraId;
    235     bool colorStereo;
    236     dc1394bayer_method_t bayer;
    237     dc1394color_filter_t bayerFilter;
    238 
    239     enum { NIMG = 2 };
    240     IplImage *img[NIMG];
    241     dc1394video_frame_t* frameC;
    242     int nimages;
    243 
    244     bool rectify;
    245     bool init_rectify;
    246     IplImage *maps[NIMG][2];
    247     dc1394featureset_t feature_set;
    248 };
    249 //mapping CV_CAP_PROP_ to DC1394_FEATUREs
    250 int CvCaptureCAM_DC1394_v2_CPP::dc1394properties[CV_CAP_PROP_MAX_DC1394] = {
    251 -1, //no corresponding feature for CV_CAP_PROP_POS_MSEC
    252 -1,-1,-1,-1,
    253 DC1394_FEATURE_FRAME_RATE, //CV_CAP_PROP_FPS - fps can be set for format 7 only!
    254 -1,-1,-1,-1,
    255 DC1394_FEATURE_BRIGHTNESS, //CV_CAP_PROP_BRIGHTNESS 10
    256 -1,
    257 DC1394_FEATURE_SATURATION, //CV_CAP_PROP_SATURATION
    258 DC1394_FEATURE_HUE,
    259 DC1394_FEATURE_GAIN,
    260 DC1394_FEATURE_SHUTTER, //CV_CAP_PROP_EXPOSURE
    261 -1, //CV_CAP_PROP_CONVERT_RGB
    262 DC1394_FEATURE_WHITE_BALANCE, //corresponds to CV_CAP_PROP_WHITE_BALANCE_BLUE_U and CV_CAP_PROP_WHITE_BALANCE_RED_V, see set function to check these props are set
    263 -1,-1,
    264 DC1394_FEATURE_SHARPNESS, //20
    265 DC1394_FEATURE_EXPOSURE, //CV_CAP_PROP_AUTO_EXPOSURE - this is auto exposure according to the IIDC standard
    266 DC1394_FEATURE_GAMMA, //CV_CAP_PROP_GAMMA
    267 DC1394_FEATURE_TEMPERATURE, //CV_CAP_PROP_TEMPERATURE
    268 DC1394_FEATURE_TRIGGER, //CV_CAP_PROP_TRIGGER
    269 DC1394_FEATURE_TRIGGER_DELAY, //CV_CAP_PROP_TRIGGER_DELAY
    270 DC1394_FEATURE_WHITE_BALANCE, //CV_CAP_PROP_WHITE_BALANCE_RED_V
    271 DC1394_FEATURE_ZOOM, //CV_CAP_PROP_ZOOM
    272 DC1394_FEATURE_FOCUS, //CV_CAP_PROP_FOCUS
    273 -1 //CV_CAP_PROP_GUID
    274 };
    275 CvCaptureCAM_DC1394_v2_CPP::CvCaptureCAM_DC1394_v2_CPP()
    276 {
    277     guid = 0;
    278     dcCam = 0;
    279     isoSpeed = 400;
    280     fps = 15;
    281     // Resetted the value here to 1 in order to ensure only a single frame is stored in the buffer!
    282     nDMABufs = 8;
    283     started = false;
    284     cameraId = 0;
    285     colorStereo = false;
    286     bayer = DC1394_BAYER_METHOD_BILINEAR;
    287     bayerFilter = DC1394_COLOR_FILTER_GRBG;
    288     frameWidth = 640;
    289     frameHeight = 480;
    290 
    291     for (int i = 0; i < NIMG; i++)
    292         img[i] = maps[i][0] = maps[i][1] = 0;
    293     frameC = 0;
    294     nimages = 1;
    295     rectify = false;
    296     userMode = -1;
    297 }
    298 
    299 
    300 bool CvCaptureCAM_DC1394_v2_CPP::startCapture()
    301 {
    302     int i;
    303     int code = 0;
    304     if (!dcCam)
    305         return false;
    306     if (isoSpeed > 0)
    307     {
    308         // if capable set operation mode to 1394b for iso speeds above 400
    309         if (isoSpeed > 400 && dcCam->bmode_capable == DC1394_TRUE)
    310         {
    311             dc1394_video_set_operation_mode(dcCam, DC1394_OPERATION_MODE_1394B);
    312         }
    313         code = dc1394_video_set_iso_speed(dcCam,
    314                                           isoSpeed <= 100 ? DC1394_ISO_SPEED_100 :
    315                                           isoSpeed <= 200 ? DC1394_ISO_SPEED_200 :
    316                                           isoSpeed <= 400 ? DC1394_ISO_SPEED_400 :
    317                                           isoSpeed <= 800 ? DC1394_ISO_SPEED_800 :
    318                                           isoSpeed == 1600 ? DC1394_ISO_SPEED_1600 :
    319                                           DC1394_ISO_SPEED_3200);
    320     }
    321 
    322     // should a specific mode be used
    323     if (userMode >= 0)
    324 
    325     {
    326         dc1394video_mode_t wantedMode;
    327         dc1394video_modes_t videoModes;
    328         dc1394_video_get_supported_modes(dcCam, &videoModes);
    329 
    330         //set mode from number, for example the second supported mode, i.e userMode = 1
    331 
    332         if (userMode < (int)videoModes.num)
    333         {
    334             wantedMode = videoModes.modes[userMode];
    335         }
    336 
    337         //set modes directly from DC134 constants (from dc1394video_mode_t)
    338         else if ((userMode >= DC1394_VIDEO_MODE_MIN) && (userMode <= DC1394_VIDEO_MODE_MAX ))
    339         {
    340             //search for wanted mode, to check if camera supports it
    341             int j = 0;
    342             while ((j< (int)videoModes.num) && videoModes.modes[j]!=userMode)
    343             {
    344                 j++;
    345             }
    346 
    347             if ((int)videoModes.modes[j]==userMode)
    348             {
    349                 wantedMode = videoModes.modes[j];
    350             }
    351             else
    352             {
    353                 userMode = -1;  // wanted mode not supported, search for best mode
    354             }
    355         }
    356         else
    357         {
    358             userMode = -1;      // wanted mode not supported, search for best mode
    359         }
    360         //if userMode is available: set it and update size
    361         if (userMode != -1)
    362         {
    363             code = dc1394_video_set_mode(dcCam, wantedMode);
    364             uint32_t width, height;
    365             dc1394_get_image_size_from_video_mode(dcCam, wantedMode, &width, &height);
    366             frameWidth  = (int)width;
    367             frameHeight = (int)height;
    368         }
    369     }
    370 
    371     if (userMode == -1 && (frameWidth > 0 || frameHeight > 0))
    372     {
    373         dc1394video_mode_t bestMode = (dc1394video_mode_t) - 1;
    374         dc1394video_modes_t videoModes;
    375         dc1394_video_get_supported_modes(dcCam, &videoModes);
    376         for (i = 0; i < (int)videoModes.num; i++)
    377         {
    378             dc1394video_mode_t mode = videoModes.modes[i];
    379             if (mode >= DC1394_VIDEO_MODE_FORMAT7_MIN && mode <= DC1394_VIDEO_MODE_FORMAT7_MAX)
    380                 continue;
    381             int pref = -1;
    382             dc1394color_coding_t colorCoding;
    383             dc1394_get_color_coding_from_video_mode(dcCam, mode, &colorCoding);
    384 
    385             uint32_t width, height;
    386             dc1394_get_image_size_from_video_mode(dcCam, mode, &width, &height);
    387             if ((int)width == frameWidth || (int)height == frameHeight)
    388             {
    389                 if (colorCoding == DC1394_COLOR_CODING_RGB8 ||
    390                         colorCoding == DC1394_COLOR_CODING_RAW8)
    391                 {
    392                     bestMode = mode;
    393                     break;
    394                 }
    395 
    396                 if (colorCoding == DC1394_COLOR_CODING_YUV411 ||
    397                         colorCoding == DC1394_COLOR_CODING_YUV422 ||
    398                         (colorCoding == DC1394_COLOR_CODING_YUV444 &&
    399                         pref < 1))
    400                 {
    401                     bestMode = mode;
    402                     pref = 1;
    403                     break;
    404                 }
    405 
    406                 if (colorCoding == DC1394_COLOR_CODING_MONO8)
    407                 {
    408                     bestMode = mode;
    409                     pref = 0;
    410                 }
    411             }
    412         }
    413         if ((int)bestMode >= 0)
    414             code = dc1394_video_set_mode(dcCam, bestMode);
    415     }
    416 
    417     if (fps > 0)
    418     {
    419         dc1394video_mode_t mode;
    420         dc1394framerates_t framerates;
    421         double minDiff = DBL_MAX;
    422         dc1394framerate_t bestFps = (dc1394framerate_t) - 1;
    423 
    424         dc1394_video_get_mode(dcCam, &mode);
    425         dc1394_video_get_supported_framerates(dcCam, mode, &framerates);
    426 
    427         for (i = 0; i < (int)framerates.num; i++)
    428         {
    429             dc1394framerate_t ifps = framerates.framerates[i];
    430             double fps1 = (1 << (ifps - DC1394_FRAMERATE_1_875)) * 1.875;
    431             double diff = fabs(fps1 - fps);
    432             if (diff < minDiff)
    433             {
    434                 minDiff = diff;
    435                 bestFps = ifps;
    436             }
    437         }
    438         if ((int)bestFps >= 0)
    439             code = dc1394_video_set_framerate(dcCam, bestFps);
    440     }
    441 
    442     if (cameraId == VIDERE)
    443     {
    444         bayerFilter = DC1394_COLOR_FILTER_GBRG;
    445         nimages = 2;
    446         uint32_t value = 0;
    447         dc1394_get_control_register(dcCam, 0x50c, &value);
    448         colorStereo = (value & 0x80000000) != 0;
    449     }
    450 
    451     code = dc1394_capture_setup(dcCam, nDMABufs, DC1394_CAPTURE_FLAGS_DEFAULT);
    452     if (code >= 0)
    453     {
    454         FD_SET(dc1394_capture_get_fileno(dcCam), &dc1394.camFds);
    455         dc1394_video_set_transmission(dcCam, DC1394_ON);
    456         if (cameraId == VIDERE)
    457         {
    458             enum { PROC_MODE_OFF, PROC_MODE_NONE, PROC_MODE_TEST, PROC_MODE_RECTIFIED, PROC_MODE_DISPARITY, PROC_MODE_DISPARITY_RAW };
    459             int procMode = PROC_MODE_RECTIFIED;
    460             usleep(100000);
    461             uint32_t qval1 = 0x08000000 | (0x90 << 16) | ((procMode & 0x7) << 16);
    462             uint32_t qval2 = 0x08000000 | (0x9C << 16);
    463             dc1394_set_control_register(dcCam, 0xFF000, qval1);
    464             dc1394_set_control_register(dcCam, 0xFF000, qval2);
    465         }
    466         started = true;
    467     }
    468 
    469     return code >= 0;
    470 }
    471 
    472 bool CvCaptureCAM_DC1394_v2_CPP::open(int index)
    473 {
    474     bool result = false;
    475     dc1394camera_list_t* cameraList = 0;
    476     dc1394error_t err;
    477 
    478     close();
    479 
    480     if (!dc1394.dc)
    481         goto _exit_;
    482 
    483     err = dc1394_camera_enumerate(dc1394.dc, &cameraList);
    484     if (err < 0 || !cameraList || (unsigned)index >= (unsigned)cameraList->num)
    485         goto _exit_;
    486 
    487     guid = cameraList->ids[index].guid;
    488     dcCam = dc1394_camera_new(dc1394.dc, guid);
    489     if (!dcCam)
    490         goto _exit_;
    491 
    492     cameraId = dcCam->vendor_id;
    493     //get all features
    494     if (dc1394_feature_get_all(dcCam,&feature_set) == DC1394_SUCCESS)
    495         result = true;
    496     else
    497         result = false;
    498 
    499 _exit_:
    500     if (cameraList)
    501         dc1394_camera_free_list(cameraList);
    502 
    503     return result;
    504 }
    505 
    506 void CvCaptureCAM_DC1394_v2_CPP::close()
    507 {
    508     if (dcCam)
    509     {
    510         // check for fileno valid before using
    511         int fileno=dc1394_capture_get_fileno(dcCam);
    512 
    513         if (fileno>=0 && FD_ISSET(fileno, &dc1394.camFds))
    514             FD_CLR(fileno, &dc1394.camFds);
    515         dc1394_video_set_transmission(dcCam, DC1394_OFF);
    516         dc1394_capture_stop(dcCam);
    517         dc1394_camera_free(dcCam);
    518         dcCam = 0;
    519         started = false;
    520     }
    521 
    522     for (int i = 0; i < NIMG; i++)
    523     {
    524         cvReleaseImage(&img[i]);
    525         cvReleaseImage(&maps[i][0]);
    526         cvReleaseImage(&maps[i][1]);
    527     }
    528     if (frameC)
    529     {
    530         if (frameC->image)
    531             free(frameC->image);
    532         free(frameC);
    533         frameC = 0;
    534     }
    535 }
    536 
    537 
    538 bool CvCaptureCAM_DC1394_v2_CPP::grabFrame()
    539 {
    540     dc1394capture_policy_t policy = DC1394_CAPTURE_POLICY_WAIT;
    541     bool code = false, isColor;
    542     dc1394video_frame_t *dcFrame = 0, *fs = 0;
    543     int i, nch;
    544 
    545     if (!dcCam || (!started && !startCapture()))
    546         return false;
    547 
    548     dc1394_capture_dequeue(dcCam, policy, &dcFrame);
    549 
    550     if (!dcFrame)
    551         return false;
    552 
    553     if (/*dcFrame->frames_behind > 1 ||*/ dc1394_capture_is_frame_corrupt(dcCam, dcFrame) == DC1394_TRUE)
    554     {
    555         goto _exit_;
    556     }
    557 
    558     isColor = dcFrame->color_coding != DC1394_COLOR_CODING_MONO8 &&
    559               dcFrame->color_coding != DC1394_COLOR_CODING_MONO16 &&
    560               dcFrame->color_coding != DC1394_COLOR_CODING_MONO16S;
    561 
    562     if (nimages == 2)
    563     {
    564         fs = (dc1394video_frame_t*)calloc(1, sizeof(*fs));
    565 
    566         //dc1394_deinterlace_stereo_frames(dcFrame, fs, DC1394_STEREO_METHOD_INTERLACED);
    567         dc1394_deinterlace_stereo_frames_fixed(dcFrame, fs, DC1394_STEREO_METHOD_INTERLACED);
    568 
    569         dc1394_capture_enqueue(dcCam, dcFrame); // release the captured frame as soon as possible
    570         dcFrame = 0;
    571         if (!fs->image)
    572             goto _exit_;
    573         isColor = colorStereo;
    574     }
    575     nch = isColor ? 3 : 1;
    576 
    577     for (i = 0; i < nimages; i++)
    578     {
    579         IplImage fhdr;
    580         dc1394video_frame_t f = fs ? *fs : *dcFrame, *fc = &f;
    581         f.size[1] /= nimages;
    582         f.image += f.size[0] * f.size[1] * i; // TODO: make it more universal
    583         if (isColor)
    584         {
    585             if (!frameC)
    586                 frameC = (dc1394video_frame_t*)calloc(1, sizeof(*frameC));
    587             frameC->color_coding = nch == 3 ? DC1394_COLOR_CODING_RGB8 : DC1394_COLOR_CODING_MONO8;
    588             if (nimages == 1)
    589             {
    590                 dc1394_convert_frames(&f, frameC);
    591                 dc1394_capture_enqueue(dcCam, dcFrame);
    592                 dcFrame = 0;
    593             }
    594             else
    595             {
    596                 f.color_filter = bayerFilter;
    597                 dc1394_debayer_frames(&f, frameC, bayer);
    598             }
    599             fc = frameC;
    600         }
    601         if (!img[i])
    602             img[i] = cvCreateImage(cvSize(fc->size[0], fc->size[1]), 8, nch);
    603         cvInitImageHeader(&fhdr, cvSize(fc->size[0], fc->size[1]), 8, nch);
    604         cvSetData(&fhdr, fc->image, fc->size[0]*nch);
    605 
    606     // Swap R&B channels:
    607     if (nch==3)
    608         cvConvertImage(&fhdr,&fhdr,CV_CVTIMG_SWAP_RB);
    609 
    610         if( rectify && cameraId == VIDERE && nimages == 2 )
    611         {
    612             if( !maps[0][0] || maps[0][0]->width != img[i]->width || maps[0][0]->height != img[i]->height )
    613             {
    614                 CvSize size = cvGetSize(img[i]);
    615                 cvReleaseImage(&maps[0][0]);
    616                 cvReleaseImage(&maps[0][1]);
    617                 cvReleaseImage(&maps[1][0]);
    618                 cvReleaseImage(&maps[1][1]);
    619                 maps[0][0] = cvCreateImage(size, IPL_DEPTH_16S, 2);
    620                 maps[0][1] = cvCreateImage(size, IPL_DEPTH_16S, 1);
    621                 maps[1][0] = cvCreateImage(size, IPL_DEPTH_16S, 2);
    622                 maps[1][1] = cvCreateImage(size, IPL_DEPTH_16S, 1);
    623                 char buf[4*4096];
    624                 if( getVidereCalibrationInfo( buf, (int)sizeof(buf) ) &&
    625                     initVidereRectifyMaps( buf, maps[0], maps[1] ))
    626                     ;
    627                 else
    628                     rectify = false;
    629             }
    630             cvRemap(&fhdr, img[i], maps[i][0], maps[i][1]);
    631         }
    632         else
    633             cvCopy(&fhdr, img[i]);
    634     }
    635 
    636     code = true;
    637 
    638 _exit_:
    639     if (dcFrame)
    640         dc1394_capture_enqueue(dcCam, dcFrame);
    641     if (fs)
    642     {
    643         if (fs->image)
    644             free(fs->image);
    645         free(fs);
    646     }
    647 
    648     return code;
    649 }
    650 
    651 IplImage* CvCaptureCAM_DC1394_v2_CPP::retrieveFrame(int idx)
    652 {
    653     return 0 <= idx && idx < nimages ? img[idx] : 0;
    654 }
    655 
    656 double CvCaptureCAM_DC1394_v2_CPP::getProperty(int propId) const
    657 {
    658     // Simulate mutable (C++11-like) member variable
    659     dc1394featureset_t& fs = const_cast<dc1394featureset_t&>(feature_set);
    660 
    661     switch (propId)
    662     {
    663     case CV_CAP_PROP_FRAME_WIDTH:
    664         return frameWidth ? frameWidth : frameHeight*4 / 3;
    665     case CV_CAP_PROP_FRAME_HEIGHT:
    666         return frameHeight ? frameHeight : frameWidth*3 / 4;
    667     case CV_CAP_PROP_FPS:
    668         return fps;
    669     case CV_CAP_PROP_RECTIFICATION:
    670         return rectify ? 1 : 0;
    671     case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
    672         if (dc1394_feature_whitebalance_get_value(dcCam,
    673                                                   &fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value,
    674                                                   &fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value) == DC1394_SUCCESS)
    675         return feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value;
    676         break;
    677     case CV_CAP_PROP_WHITE_BALANCE_RED_V:
    678         if (dc1394_feature_whitebalance_get_value(dcCam,
    679                                                   &fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value,
    680                                                   &fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value) == DC1394_SUCCESS)
    681         return feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value;
    682         break;
    683     case CV_CAP_PROP_GUID:
    684         //the least 32 bits are enough to identify the camera
    685         return (double) (guid & 0x00000000FFFFFFFF);
    686         break;
    687     case CV_CAP_PROP_MODE:
    688         return (double) userMode;
    689         break;
    690     case CV_CAP_PROP_ISO_SPEED:
    691         return (double) isoSpeed;
    692     case CV_CAP_PROP_BUFFERSIZE:
    693         return (double) nDMABufs;
    694     default:
    695         if (propId<CV_CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1
    696             && dcCam)
    697             //&& feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].on_off_capable)
    698             if (dc1394_feature_get_value(dcCam,(dc1394feature_t)dc1394properties[propId],
    699                 &fs.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].value) == DC1394_SUCCESS)
    700               return feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].value;
    701     }
    702     return -1; // the value of the feature can be 0, so returning 0 as an error is wrong
    703 }
    704 
    705 bool CvCaptureCAM_DC1394_v2_CPP::setProperty(int propId, double value)
    706 {
    707     switch (propId)
    708     {
    709     case CV_CAP_PROP_FRAME_WIDTH:
    710         if(started)
    711             return false;
    712         frameWidth = cvRound(value);
    713         frameHeight = 0;
    714         break;
    715     case CV_CAP_PROP_FRAME_HEIGHT:
    716         if(started)
    717             return false;
    718         frameWidth = 0;
    719         frameHeight = cvRound(value);
    720         break;
    721     case CV_CAP_PROP_FPS:
    722         if(started)
    723             return false;
    724         fps = value;
    725         break;
    726     case CV_CAP_PROP_RECTIFICATION:
    727         if( cameraId != VIDERE )
    728             return false;
    729         rectify = fabs(value) > FLT_EPSILON;
    730         break;
    731     case CV_CAP_PROP_MODE:
    732         if(started)
    733           return false;
    734         userMode = cvRound(value);
    735         break;
    736     case CV_CAP_PROP_ISO_SPEED:
    737         if(started)
    738           return false;
    739         isoSpeed = cvRound(value);
    740         break;
    741     case CV_CAP_PROP_BUFFERSIZE:
    742         if(started)
    743             return false;
    744         nDMABufs = value;
    745         break;
    746         //The code below is based on coriander, callbacks.c:795, refer to case RANGE_MENU_MAN :
    747          default:
    748              if (propId<CV_CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1
    749                  && dcCam)
    750              {
    751                  //get the corresponding feature from property-id
    752                  dc1394feature_info_t *act_feature = &feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN];
    753 
    754                  if (cvRound(value) == CV_CAP_PROP_DC1394_OFF)
    755                  {
    756                      if (  (act_feature->on_off_capable)
    757                            && (dc1394_feature_set_power(dcCam, act_feature->id, DC1394_OFF) == DC1394_SUCCESS))
    758                      {
    759                          act_feature->is_on=DC1394_OFF;
    760                          return true;
    761                      }
    762                      return false;
    763                  }
    764                  //try to turn the feature ON, feature can be ON and at the same time it can be not capable to change state to OFF
    765                  if ( (act_feature->is_on == DC1394_OFF) && (act_feature->on_off_capable == DC1394_TRUE))
    766                  {
    767                      if (dc1394_feature_set_power(dcCam, act_feature->id, DC1394_ON) == DC1394_SUCCESS)
    768                        feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].is_on=DC1394_ON;
    769                  }
    770                  //turn off absolute mode - the actual value will be stored in the value field,
    771                  //otherwise it would be stored into CSR (control and status register) absolute value
    772                  if (act_feature->absolute_capable
    773                      && dc1394_feature_set_absolute_control(dcCam, act_feature->id, DC1394_OFF) !=DC1394_SUCCESS)
    774                      return false;
    775                  else
    776                      act_feature->abs_control=DC1394_OFF;
    777                  //set AUTO
    778                  if (cvRound(value) == CV_CAP_PROP_DC1394_MODE_AUTO)
    779                  {
    780                      if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_AUTO)!=DC1394_SUCCESS)
    781                          return false;
    782                      act_feature->current_mode=DC1394_FEATURE_MODE_AUTO;
    783                      return true;
    784                  }
    785                  //set ONE PUSH
    786                  if (cvRound(value) == CV_CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO)
    787                  {
    788                      //have to set to manual first, otherwise one push will be ignored (AVT  manual 4.3.0 p. 115)
    789                      if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_ONE_PUSH_AUTO)!=DC1394_SUCCESS)
    790                          return false;
    791                      //will change to
    792                      act_feature->current_mode=DC1394_FEATURE_MODE_ONE_PUSH_AUTO;
    793                      return true;
    794                  }
    795                  //set the feature to MANUAL mode,
    796                  if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_MANUAL)!=DC1394_SUCCESS)
    797                      return false;
    798                  else
    799                      act_feature->current_mode=DC1394_FEATURE_MODE_MANUAL;
    800                  // if property is one of the white balance features treat it in different way
    801                  if (propId == CV_CAP_PROP_WHITE_BALANCE_BLUE_U)
    802                  {
    803                      if (dc1394_feature_whitebalance_set_value(dcCam,cvRound(value), act_feature->RV_value)!=DC1394_SUCCESS)
    804                          return false;
    805                      else
    806                      {
    807                          act_feature->BU_value = cvRound(value);
    808                          return true;
    809                      }
    810                  }
    811                  if (propId == CV_CAP_PROP_WHITE_BALANCE_RED_V)
    812                  {
    813                      if (dc1394_feature_whitebalance_set_value(dcCam, act_feature->BU_value, cvRound(value))!=DC1394_SUCCESS)
    814                          return false;
    815                      else
    816                      {
    817                          act_feature->RV_value = cvRound(value);
    818                          return true;
    819                      }
    820                  }
    821 
    822                  //first: check boundaries
    823                  if (value < act_feature->min)
    824                  {
    825                      value = act_feature->min;
    826                  }
    827                  else if (value > act_feature->max)
    828                  {
    829                      value = act_feature->max;
    830                  }
    831 
    832                  if (dc1394_feature_set_value(dcCam, act_feature->id, cvRound(value)) == DC1394_SUCCESS)
    833                  {
    834                      act_feature->value = value;
    835                      return true;
    836                  }
    837              }
    838              return false;
    839     }
    840     return true;
    841 }
    842 
    843 
    844 bool CvCaptureCAM_DC1394_v2_CPP::getVidereCalibrationInfo( char* buf, int bufSize )
    845 {
    846     int pos;
    847 
    848     for( pos = 0; pos < bufSize - 4; pos += 4 )
    849     {
    850         uint32_t quad = getControlRegister(dcCam, 0xF0800 + pos);
    851         if( quad == 0 || quad == 0xffffffff )
    852             break;
    853         buf[pos] = (uchar)(quad >> 24);
    854         buf[pos+1] = (uchar)(quad >> 16);
    855         buf[pos+2] = (uchar)(quad >> 8);
    856         buf[pos+3] = (uchar)(quad);
    857     }
    858 
    859     if( pos == 0 )
    860         return false;
    861 
    862     buf[pos] = '\0';
    863     return true;
    864 }
    865 
    866 
    867 bool CvCaptureCAM_DC1394_v2_CPP::initVidereRectifyMaps( const char* info,
    868     IplImage* ml[2], IplImage* mr[2] )
    869 {
    870     float identity_data[] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
    871     CvMat l_rect = cvMat(3, 3, CV_32F, identity_data), r_rect = l_rect;
    872     float l_intrinsic_data[] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
    873     float r_intrinsic_data[] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
    874     CvMat l_intrinsic = cvMat(3, 3, CV_32F, l_intrinsic_data);
    875     CvMat r_intrinsic = cvMat(3, 3, CV_32F, r_intrinsic_data);
    876     float l_distortion_data[] = {0,0,0,0,0}, r_distortion_data[] = {0,0,0,0,0};
    877     CvMat l_distortion = cvMat(1, 5, CV_32F, l_distortion_data);
    878     CvMat r_distortion = cvMat(1, 5, CV_32F, r_distortion_data);
    879     IplImage* mx = cvCreateImage(cvGetSize(ml[0]), IPL_DEPTH_32F, 1);
    880     IplImage* my = cvCreateImage(cvGetSize(ml[0]), IPL_DEPTH_32F, 1);
    881     int k, j;
    882 
    883     for( k = 0; k < 2; k++ )
    884     {
    885         const char* section_name = k == 0 ? "[left_camera]" : "[right_camera]";
    886         static const char* param_names[] = { "f ", "fy", "Cx", "Cy" "kappa1", "kappa2", "tau1", "tau2", "kappa3", 0 };
    887         const char* section_start = strstr( info, section_name );
    888         CvMat* intrinsic = k == 0 ? &l_intrinsic : &r_intrinsic;
    889         CvMat* distortion = k == 0 ? &l_distortion : &r_distortion;
    890         CvMat* rectification = k == 0 ? &l_rect : &r_rect;
    891         IplImage** dst = k == 0 ? ml : mr;
    892         if( !section_start )
    893             break;
    894         section_start += strlen(section_name);
    895         for( j = 0; param_names[j] != 0; j++ )
    896         {
    897             const char* param_value_start = strstr(section_start, param_names[j]);
    898             float val=0;
    899             if(!param_value_start)
    900                 break;
    901             sscanf(param_value_start + strlen(param_names[j]), "%f", &val);
    902             if( j < 4 )
    903                 intrinsic->data.fl[j == 0 ? 0 : j == 1 ? 4 : j == 2 ? 2 : 5] = val;
    904             else
    905                 distortion->data.fl[j - 4] = val;
    906         }
    907         if( param_names[j] != 0 )
    908             break;
    909 
    910         // some sanity check for the principal point
    911         if( fabs(mx->width*0.5 - intrinsic->data.fl[2]) > mx->width*0.1 ||
    912             fabs(my->height*0.5 - intrinsic->data.fl[5]) > my->height*0.1 )
    913         {
    914             cvScale( &intrinsic, &intrinsic, 0.5 ); // try the corrected intrinsic matrix for 2x lower resolution
    915             if( fabs(mx->width*0.5 - intrinsic->data.fl[2]) > mx->width*0.05 ||
    916                 fabs(my->height*0.5 - intrinsic->data.fl[5]) > my->height*0.05 )
    917                 cvScale( &intrinsic, &intrinsic, 2 ); // revert it back if the new variant is not much better
    918             intrinsic->data.fl[8] = 1;
    919         }
    920 
    921         cvInitUndistortRectifyMap( intrinsic, distortion,
    922                     rectification, intrinsic, mx, my );
    923         cvConvertMaps( mx, my, dst[0], dst[1] );
    924     }
    925 
    926     cvReleaseImage( &mx );
    927     cvReleaseImage( &my );
    928     return k >= 2;
    929 }
    930 
    931 
    932 CvCapture* cvCreateCameraCapture_DC1394_2(int index)
    933 {
    934     CvCaptureCAM_DC1394_v2_CPP* capture = new CvCaptureCAM_DC1394_v2_CPP;
    935 
    936     if (capture->open(index))
    937         return capture;
    938 
    939     delete capture;
    940     return 0;
    941 }
    942 
    943 #endif
    944