Linux1394Capture2.cpp
Go to the documentation of this file.
00001 // ****************************************************************************
00002 // This file is part of the Integrating Vision Toolkit (IVT).
00003 //
00004 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT)
00005 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de).
00006 //
00007 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT).
00008 // All rights reserved.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are met:
00012 //
00013 // 1. Redistributions of source code must retain the above copyright
00014 //    notice, this list of conditions and the following disclaimer.
00015 //
00016 // 2. Redistributions in binary form must reproduce the above copyright
00017 //    notice, this list of conditions and the following disclaimer in the
00018 //    documentation and/or other materials provided with the distribution.
00019 //
00020 // 3. Neither the name of the KIT nor the names of its contributors may be
00021 //    used to endorse or promote products derived from this software
00022 //    without specific prior written permission.
00023 //
00024 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY
00025 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY
00028 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00033 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 // ****************************************************************************
00035 // ****************************************************************************
00036 // Filename:  Linux1394Capture2.cpp
00037 // Author:    Kai Welke, Pedram Azad
00038 // Date:      2007
00039 // ****************************************************************************
00040 // Requires:  * libdc1394v2
00041 //            * libraw1394 >= 1.2.0
00042 // ****************************************************************************
00043 // Changes:   20.12.2007, Kai Welke
00044 //            * Built CLinux1394Capture2 on base of CLinux1394Capture
00045 //            * switched from libdc1394v1 to libdc1394v2 (solved problem 
00046 //              with QT and allowed to use full firewire bandwidth)
00047 //            * added check for maximum bandwidth
00048 //            * generic camera feature access
00049 //            * Format7_0 implemented with ROI and framerate settings
00050 //              format7 support is camera dependant (dragonfly only
00051 //              supports two discrete framerates, dragonfly2 can be
00052 //              adjusted from 0.x ... 60.0 frames.
00053 //            05.05.2011, Kai Welke
00054 //            * Corrected bus reset. Bus for all cameras reset on 
00055 //              creation of first instance. The previous bus reset broke
00056 //              the support of multiple instances. 
00057 // ****************************************************************************
00058 
00059 
00060 // ****************************************************************************
00061 // Includes
00062 // ****************************************************************************
00063 
00064 #include "VideoCapture/Linux1394Capture2.h"
00065 #include "Image/ByteImage.h"
00066 #include "Image/ImageProcessor.h"
00067 #include "Threading/Threading.h"
00068 
00069 #include <stdio.h>
00070 #include <unistd.h>
00071 #include <stdlib.h>
00072 #include <stdarg.h>
00073 #include <algorithm>
00074 
00075 
00076 // ****************************************************************************
00077 // Defines
00078 // ****************************************************************************
00079 
00080 #define DROP_FRAMES 1
00081 #define NUM_BUFFERS 2
00082 
00083 
00084 // *****************************************************************
00085 // Static members
00086 // *****************************************************************
00087 
00088 int                     CLinux1394Capture2::m_nOverallCameras = 0;
00089 CLinux1394Capture2*     CLinux1394Capture2::m_pCameraOpener[MAX_CAMERAS];
00090 int                     CLinux1394Capture2::m_nInstances = 0;
00091 dc1394camera_t*         CLinux1394Capture2::m_cameras[MAX_CAMERAS];
00092 dc1394_t*               CLinux1394Capture2::m_pDC1394;
00093 int                     CLinux1394Capture2::m_nRemainingBandwidth = MAX_S400_BANDWIDTH;
00094 int                     CLinux1394Capture2::m_nCameraBandwidth[MAX_CAMERAS];
00095 
00096 
00097 
00098 // *****************************************************************
00099 // Constructors
00100 // *****************************************************************
00101 
00102 CLinux1394Capture2::CLinux1394Capture2(int nCameras, VideoMode mode, ColorMode colorMode, ImageProcessor::BayerPatternType bayerPatternType, FrameRate frameRate) : m_mode(mode), m_colorMode(colorMode), m_bayerPatternType(bayerPatternType), m_frameRate(frameRate)
00103 {
00104         // number of cameras
00105         m_nCameras = nCameras;
00106         
00107         // init images
00108         m_pTempImageHeader = new CByteImage();
00109 
00110         // init size
00111         width = -1;
00112         height = -1;
00113 
00114         // init features
00115         m_bUseUIDs = false;
00116         m_bFormat7Mode = false;
00117 
00118         // if we are the first instance
00119         if(m_nInstances == 0)
00120                 InitFirstInstance();
00121 
00122         m_nInstances++;
00123 }
00124 
00125 CLinux1394Capture2::CLinux1394Capture2(VideoMode mode, ColorMode colorMode, ImageProcessor::BayerPatternType bayerPatternType, FrameRate frameRate, int nNumberUIDs, ...) : m_mode(mode), m_colorMode(colorMode), m_bayerPatternType(bayerPatternType), m_frameRate(frameRate)
00126 {
00127         // number cameras
00128         m_nCameras = nNumberUIDs;
00129         
00130         // fill camera UIDS
00131         for(int i = 0 ; i < MAX_CAMERAS ; i++)
00132                 m_sCameraUID[i] = "";
00133 
00134         // read variable arguments
00135         va_list ap;
00136         va_start(ap, nNumberUIDs); 
00137 
00138         for(int u = 0 ; u < nNumberUIDs ; u++)
00139         {
00140                 const char* pch = va_arg(ap, const char*);
00141                 m_sCameraUID[u] += pch;
00142                 transform(m_sCameraUID[u].begin(), m_sCameraUID[u].end(), m_sCameraUID[u].begin(), (int(*)(int)) toupper);
00143         } 
00144 
00145         va_end(ap);
00146 
00147         // init images
00148         m_pTempImageHeader = new CByteImage();
00149 
00150         // init size
00151         width = -1;
00152         height = -1;
00153 
00154         // set features
00155         m_bUseUIDs = true;
00156         m_bFormat7Mode = false;
00157 
00158         // if we are the first instance
00159         if(m_nInstances == 0)
00160                 InitFirstInstance();
00161 
00162         m_nInstances++;
00163 }
00164 
00165 
00166 // ****************************************************************************
00167 // Constructors for Format7 Modes
00168 // ****************************************************************************
00169 
00170 CLinux1394Capture2::CLinux1394Capture2(int nCameras, VideoMode mode, float fFormat7FrameRate, int nFormat7MinX, int nFormat7MinY, int nFormat7Width, int nFormat7Height,        ColorMode colorMode, ImageProcessor::BayerPatternType bayerPatternType) :
00171         m_mode(mode), m_colorMode(colorMode), m_bayerPatternType(bayerPatternType)
00172 {
00173         // number cameras
00174         m_nCameras = nCameras;
00175         
00176         // init images
00177         m_pTempImageHeader = new CByteImage();
00178 
00179         // init size
00180         width = -1;
00181         height = -1;
00182         
00183         // set features
00184         m_bFormat7Mode = true;
00185         m_fFormat7FrameRate = fFormat7FrameRate;
00186         m_nFormat7MinX = nFormat7MinX;
00187         m_nFormat7MinY = nFormat7MinY;
00188         
00189         if (nFormat7Width == -1 || nFormat7Height == -1)
00190         {
00191                 switch (mode)
00192                 {
00193                         case e640x480: m_nFormat7Width = 640; m_nFormat7Height = 480; break;
00194                         case e800x600: m_nFormat7Width = 800; m_nFormat7Height = 600; break;
00195                         case e1024x768: m_nFormat7Width = 1024; m_nFormat7Height = 768; break;
00196                         case e1280x960: m_nFormat7Width = 1280; m_nFormat7Height = 960; break;
00197                         case e1600x1200: m_nFormat7Width = 1600; m_nFormat7Height = 1200; break;
00198                         default: m_nFormat7Width = 0; m_nFormat7Height = 0; break;
00199                 }
00200         }
00201         else
00202         {
00203                 m_nFormat7Width = nFormat7Width;
00204                 m_nFormat7Height = nFormat7Height;
00205         }
00206         
00207         m_bUseUIDs = false;
00208 
00209         // if we are first instance
00210         if (m_nInstances == 0)
00211                 InitFirstInstance();
00212 
00213         m_nInstances++;
00214 }
00215 
00216 CLinux1394Capture2::CLinux1394Capture2(VideoMode mode, float fFormat7FrameRate, int nFormat7MinX, int nFormat7MinY, int nFormat7Width, int nFormat7Height,
00217         ColorMode colorMode, ImageProcessor::BayerPatternType bayerPatternType, int nNumberUIDs, ...) :
00218         m_mode(mode), m_colorMode(colorMode), m_bayerPatternType(bayerPatternType)
00219 {
00220         // number cameras
00221         m_nCameras = nNumberUIDs;
00222         
00223         // fill camera UIDS
00224         for(int i = 0 ; i < MAX_CAMERAS ; i++)
00225                 m_sCameraUID[i] = "";
00226 
00227         // read variable arguments
00228         va_list ap;
00229         va_start(ap, nNumberUIDs); 
00230 
00231         for(int u = 0 ; u < nNumberUIDs ; u++)
00232         {
00233                 const char* pch = va_arg(ap, const char*);
00234                 m_sCameraUID[u] += pch;
00235                 transform(m_sCameraUID[u].begin(), m_sCameraUID[u].end(), m_sCameraUID[u].begin(), (int(*)(int)) toupper);
00236         } 
00237 
00238         va_end(ap);
00239 
00240         // init images
00241         m_pTempImageHeader = new CByteImage();
00242 
00243         // init size
00244         width = -1;
00245         height = -1;
00246         
00247         // init features
00248         m_bFormat7Mode = true;
00249         m_fFormat7FrameRate = fFormat7FrameRate;
00250         m_nFormat7MinX = nFormat7MinX;
00251         m_nFormat7MinY = nFormat7MinY;
00252         
00253         if (nFormat7Width == -1 || nFormat7Height == -1)
00254         {
00255                 switch (mode)
00256                 {
00257                         case e640x480: m_nFormat7Width = 640; m_nFormat7Height = 480; break;
00258                         case e800x600: m_nFormat7Width = 800; m_nFormat7Height = 600; break;
00259                         case e1024x768: m_nFormat7Width = 1024; m_nFormat7Height = 768; break;
00260                         case e1280x960: m_nFormat7Width = 1280; m_nFormat7Height = 960; break;
00261                         case e1600x1200: m_nFormat7Width = 1600; m_nFormat7Height = 1200; break;
00262                         default: m_nFormat7Width = 0; m_nFormat7Height = 0; break;
00263                 }
00264         }
00265         else
00266         {
00267                 m_nFormat7Width = nFormat7Width;
00268                 m_nFormat7Height = nFormat7Height;
00269         }
00270 
00271         m_bUseUIDs = true;
00272         m_bFormat7Mode = true;
00273 
00274         // if we are first instance
00275         if (m_nInstances == 0)
00276                 InitFirstInstance();
00277                 
00278         m_nInstances++;
00279 }
00280 
00281 
00282 // *****************************************************************
00283 // Destructor
00284 // *****************************************************************
00285 
00286 CLinux1394Capture2::~CLinux1394Capture2()
00287 {
00288         // close all related cameras
00289         CloseCamera();
00290         
00291         // delete images
00292         delete m_pTempImageHeader;
00293 
00294         // remove this instance
00295         m_nInstances--;
00296 
00297         // if we are last instance      
00298         if(m_nInstances == 0)
00299                 ExitLastInstance();
00300 }
00301 
00302 
00303 // ****************************************************************************
00304 // Methods
00305 // ****************************************************************************
00306 
00307 void CLinux1394Capture2::InitFirstInstance()
00308 {
00309         // set required fields to initial values
00310         for (int i = 0 ; i < MAX_CAMERAS ; i++)
00311         {
00312                 m_pCameraOpener[i] = NULL;
00313                 m_cameras[i] = NULL;
00314         }
00315         
00316         m_nOverallCameras = 0;
00317         
00318         // create new dc handle
00319         m_pDC1394 = dc1394_new();
00320         
00321         // reset all busses (disabled, since some firewire cards take obver 5 seconds to perform the reset)
00322         //ResetAllCameras();
00323 }
00324 
00325 void CLinux1394Capture2::ExitLastInstance()
00326 {
00327         // check if there were listed cameras with no opener and close them
00328         for(int c = 0 ; c < m_nOverallCameras ; c++)
00329         {
00330                 if(m_cameras[c] != NULL)
00331                 {
00332                         dc1394_camera_free(m_cameras[c]);
00333                 }
00334                         
00335                 m_cameras[c] = NULL;
00336         }
00337 
00338         // free dc handle       
00339         dc1394_free(m_pDC1394);
00340 }
00341 
00342 bool CLinux1394Capture2::OpenCamera()
00343 {
00344         CloseCamera();
00345         
00346         // create temporary images and init modes
00347         if(!InitCameraMode())
00348         {
00349                 printf("error: selected camera mode not supported\n");
00350                 return false;
00351         }
00352 
00353         // retrieve info for all cameras
00354         if(!ListCameras())
00355         {
00356                 CloseCamera();
00357                 return false;
00358         }
00359                 
00360         // open cameras
00361         if(m_bUseUIDs)
00362         {
00363                 for(int c = 0 ; c < m_nCameras ; c++)
00364                 {
00365                         bool bOpened = false;
00366                         for(int a = 0 ; a < m_nOverallCameras ; a++)
00367                         {
00368                                 if(m_sCameraUID[c] == CamUIDToString(m_cameras[a]->guid))
00369                                 {
00370                                         if(m_pCameraOpener[a])
00371                                         {
00372                                                 printf("error: camera with UID 0x%s already opened\n", m_sCameraUID[c].c_str());
00373                                                 return false;
00374                                         }
00375                                         if(!OpenCamera(a))
00376                                                 return false;
00377 
00378                                         m_pCameraOpener[a] = this;
00379                                         m_nOpenedCameras[c] = a;
00380                                         bOpened = true;
00381                                 }
00382                         }
00383 
00384                         if(!bOpened)
00385                         {
00386                                 printf("error: could not find camera with UID 0x%s\n",m_sCameraUID[c].c_str());
00387                                 CloseCamera();
00388                                 return false;
00389                         }
00390                 }
00391         } else {
00392                 int nNumberCameras = 0;
00393                 for(int c = 0 ; c < m_nOverallCameras ; c++)
00394                 {
00395                         if(m_pCameraOpener[c] == NULL)
00396                         {
00397                                 if(!OpenCamera(c))
00398                                         return false;
00399         
00400                                 m_pCameraOpener[c] = this;
00401                                 m_nOpenedCameras[nNumberCameras] = c;
00402                                 nNumberCameras++;
00403                         }
00404 
00405                         if( (m_nCameras != -1) && (nNumberCameras == m_nCameras))
00406                                 break;
00407                 }
00408 
00409                 if(m_nCameras == -1) 
00410                 {
00411                         if(nNumberCameras == 0)
00412                         {
00413                                 printf("error: no camera found\n");
00414                                 CloseCamera();
00415                                 return false;
00416                         }
00417                         m_nCameras = nNumberCameras;
00418                 }
00419                 
00420                 if(nNumberCameras < m_nCameras)
00421                 {
00422                         printf("error: could not open requested number of cameras\n");
00423                         CloseCamera();
00424                         return false;
00425                 }
00426         }
00427 
00428         return true;
00429 }
00430 
00431 bool CLinux1394Capture2::OpenCamera(int nCamera)
00432 {
00433         printf("Opening camera %d: Vendor %s, Model %s, UID 0x%s, Format7 = %i\n",nCamera, m_cameras[nCamera]->vendor, m_cameras[nCamera]->model,  CamUIDToString(m_cameras[nCamera]->guid).c_str(), m_bFormat7Mode);
00434         
00435         if (dc1394_video_set_iso_speed(m_cameras[nCamera], DC1394_ISO_SPEED_400) != DC1394_SUCCESS)
00436         {
00437                 printf("error: unable to set ISO speed to 400\n");
00438                 CloseCamera();
00439                 return false;
00440         };
00441         
00442         if (dc1394_video_set_mode(m_cameras[nCamera],m_video_mode) != DC1394_SUCCESS)
00443         {
00444                 printf("error: unable to set video mode\n");
00445                 CloseCamera();
00446                 return false;   
00447         }
00448         
00449         if (m_bFormat7Mode)
00450         {
00451                 if (dc1394_format7_set_image_size(m_cameras[nCamera],m_video_mode, m_nFormat7Width, m_nFormat7Height) != DC1394_SUCCESS)
00452                 {
00453                         printf("error: unable to set format7 image size (%d, %d)\n", m_nFormat7Width, m_nFormat7Height);
00454                         CloseCamera();
00455                         return false;
00456                 }
00457                 
00458                 if (dc1394_format7_set_image_position(m_cameras[nCamera],m_video_mode, m_nFormat7MinX, m_nFormat7MinY) != DC1394_SUCCESS)
00459                 {
00460                         printf("error: unable to set format7 image position (%d, %d)\n", m_nFormat7MinX, m_nFormat7MinY);
00461                         CloseCamera();
00462                         return false;
00463                 }
00464                 
00465                 // calculate packet size from, framerate
00466                 unsigned int nPacketSize = 0;
00467                 if (m_fFormat7FrameRate < 0)
00468                 {
00469                         dc1394_format7_get_recommended_packet_size(m_cameras[nCamera], m_video_mode, &nPacketSize);
00470                 }
00471                 else
00472                 {
00473                         uint64_t frame_size;
00474                         unsigned int nMinBytes, nMaxBytes;
00475                         dc1394_format7_get_total_bytes(m_cameras[nCamera], m_video_mode, &frame_size);
00476                         dc1394_format7_get_packet_parameters(m_cameras[nCamera], m_video_mode, &nMinBytes, &nMaxBytes);
00477                         
00478                         int num_packets = (int) (1.0f / (0.0125f * m_fFormat7FrameRate) + 0.5f);        // number of packets per frame period
00479                         int denominator = num_packets * 8; 
00480                         nPacketSize = (unsigned int) ( ( frame_size + denominator - 1) / float(denominator) / 10.0);
00481                         nPacketSize = nMinBytes * ( nPacketSize / nMinBytes);
00482                         
00483                         if (nPacketSize < nMinBytes)
00484                                 nPacketSize = nMinBytes;
00485                                 
00486                         if (nPacketSize > nMaxBytes)
00487                                 nPacketSize = nMaxBytes;
00488                 }
00489 
00490                 if (dc1394_format7_set_packet_size(m_cameras[nCamera],m_video_mode, nPacketSize) != DC1394_SUCCESS)
00491                 {
00492                         printf("error: unable to set format7 packet size %d (framerate %f)\n", nPacketSize, m_fFormat7FrameRate);
00493                         CloseCamera();
00494                         return false;
00495                 }
00496         }
00497         else
00498         {
00499                 if (dc1394_video_set_framerate(m_cameras[nCamera], GetDCFrameRateMode(m_frameRate)) != DC1394_SUCCESS)
00500                 {
00501                         printf("error: could not set framerate\n");
00502                         CloseCamera();
00503                         return false;
00504                 }
00505         }
00506         
00507         // calculate bandwidth usage
00508         unsigned int nBandwidth;
00509         if(dc1394_video_get_bandwidth_usage(m_cameras[nCamera],&nBandwidth) != DC1394_SUCCESS)
00510         {
00511                 printf("error: unable to calculate bandwidth usage\n");
00512                 CloseCamera();
00513                 return false;
00514         }
00515         
00516         m_nCameraBandwidth[nCamera] = nBandwidth;
00517         m_nRemainingBandwidth -= nBandwidth;
00518         printf("Camera %d bandwidth usage: %d quadlets/cycle (%d quadlets/cycle left)\n",nCamera, nBandwidth, m_nRemainingBandwidth);
00519 
00520         if(m_nRemainingBandwidth < 0)
00521         {
00522                 printf("warning: Opening camera %d would exceed maximum firewire bandwidth (%d quadlets/cycle).\n", nCamera, MAX_S400_BANDWIDTH);
00523                 m_nRemainingBandwidth += nBandwidth;
00524         
00525         // deprecated: using two firewire ports the calculation is wrong. Further several cameras do not provide proper bandwidth information
00526                 //CloseCamera();
00527                 //return false;
00528         }
00529 
00530         // hack: port seems to be busy for some time. so give time and try multiple calls to setup      
00531         bool bSuccess = false;
00532         int nTries = 5;
00533 
00534         while(!bSuccess && (nTries > 0))
00535         {
00536                 if( dc1394_capture_setup(m_cameras[nCamera], NUM_BUFFERS, DC1394_CAPTURE_FLAGS_DEFAULT) == DC1394_SUCCESS)
00537                         bSuccess = true;
00538 
00539                 Threading::SleepThread(10);
00540                 nTries--;
00541         }
00542 
00543         if(!bSuccess)
00544         {
00545                 printf("error: unable to setup camera (mode supported by camera?)\n");
00546                 CloseCamera();
00547                 return false;
00548         }
00549         
00550         
00551         if(dc1394_video_set_transmission(m_cameras[nCamera], DC1394_ON) != DC1394_SUCCESS) 
00552         {
00553                 printf("error: unable to start camera iso transmission\n");
00554                 CloseCamera();
00555                 return false;
00556         }
00557 
00558         return true;
00559 }
00560 
00561 void CLinux1394Capture2::CloseCamera()
00562 {
00563         for (int i = 0; i < m_nOverallCameras; i++)
00564         {
00565                 if(m_pCameraOpener[i] == this)
00566                 {
00567                         // stop video transmission
00568                         if(dc1394_video_set_transmission(m_cameras[i], DC1394_OFF) != DC1394_SUCCESS)
00569                                 printf("Error: could not stop iso transmission\n");
00570                         
00571                         // stop capturer
00572                         if(dc1394_capture_stop(m_cameras[i]) != DC1394_SUCCESS)
00573                                 printf("Error: could not stop capturing\n");
00574                         
00575                         // no opener for this camera
00576                         m_pCameraOpener[i] = NULL;
00577                         
00578                         // adjust remaining bandwidth
00579                         m_nRemainingBandwidth += m_nCameraBandwidth[i];
00580                 }
00581         }
00582         
00583         width = -1;
00584         height = -1;
00585 }
00586 
00587 bool CLinux1394Capture2::InitCameraMode()
00588 {
00589         width = -1;
00590         height = -1;
00591         int video_mode = 0;
00592 
00593         // for format 7 modes (only use mode 0)
00594         if (m_bFormat7Mode)
00595         {
00596                 // set video mode to format 7
00597                 m_video_mode = DC1394_VIDEO_MODE_FORMAT7_0;
00598                 
00599                 // set image size
00600                 width = m_nFormat7Width;
00601                 height = m_nFormat7Height;
00602                 
00603                 // set capture image header correctly
00604                 m_pTempImageHeader->width = width;
00605                 m_pTempImageHeader->height = height;
00606                 m_pTempImageHeader->bytesPerPixel = 1;
00607                 m_pTempImageHeader->type = CByteImage::eGrayScale;
00608                 
00609                 return true;
00610         }
00611         
00612         // standard modes
00613         if (m_mode == e640x480)
00614         {
00615                 width = 640;
00616                 height = 480;
00617                 
00618                 switch (m_colorMode)
00619                 {
00620                         case eGrayScale:
00621                         case eBayerPatternToRGB24:
00622                                 m_video_mode = DC1394_VIDEO_MODE_640x480_MONO8;
00623                         break;
00624                         
00625                         case eRGB24:
00626                                 m_video_mode = DC1394_VIDEO_MODE_640x480_RGB8;
00627                         break;
00628 
00629                         case eYUV411ToRGB24:
00630                                 m_video_mode = DC1394_VIDEO_MODE_640x480_YUV411;
00631                         break;
00632                 }
00633         }
00634         else if (m_mode == e800x600)
00635         {
00636                 width = 800;
00637                 height = 600;
00638                 
00639                 switch (m_colorMode)
00640                 {
00641                         case eGrayScale:
00642                         case eBayerPatternToRGB24:
00643                                 m_video_mode = DC1394_VIDEO_MODE_800x600_MONO8;
00644                         break;
00645                         
00646                         case eRGB24:
00647                                 m_video_mode = DC1394_VIDEO_MODE_800x600_RGB8;
00648                         break;
00649 
00650                         case eYUV411ToRGB24: return false;
00651                 }
00652         }
00653         else if (m_mode == e1024x768)
00654         {
00655                 width = 1024;
00656                 height = 768;
00657                 
00658                 switch (m_colorMode)
00659                 {
00660                         case eGrayScale:
00661                         case eBayerPatternToRGB24:
00662                                 m_video_mode = DC1394_VIDEO_MODE_1024x768_MONO8;
00663                         break;
00664                         
00665                         case eRGB24:
00666                                 m_video_mode = DC1394_VIDEO_MODE_1024x768_RGB8;
00667                         break;
00668 
00669                         case eYUV411ToRGB24: return false;
00670                 }
00671         }
00672         else if (m_mode == e1280x960)
00673         {
00674                 width = 1280;
00675                 height = 960;
00676                 
00677                 switch (m_colorMode)
00678                 {
00679                         case eGrayScale:
00680                         case eBayerPatternToRGB24:
00681                                 m_video_mode = DC1394_VIDEO_MODE_1280x960_MONO8;
00682                         break;
00683                         
00684                         case eRGB24:
00685                                 m_video_mode = DC1394_VIDEO_MODE_1280x960_RGB8;
00686                         break;
00687 
00688                         case eYUV411ToRGB24: return false;
00689                 }
00690         }
00691         else if (m_mode == e1600x1200)
00692         {
00693                 width = 1600;
00694                 height = 1200;
00695                 
00696                 switch (m_colorMode)
00697                 {
00698                         case eGrayScale:
00699                         case eBayerPatternToRGB24:
00700                                 m_video_mode = DC1394_VIDEO_MODE_1600x1200_MONO8;
00701                         break;
00702                         
00703                         case eRGB24:
00704                                 m_video_mode = DC1394_VIDEO_MODE_1600x1200_RGB8;
00705                         break;
00706 
00707                         case eYUV411ToRGB24: return false;
00708                 }
00709         }
00710         else
00711         {
00712                 // mode not supported
00713                 return false;
00714         }
00715         
00716         m_pTempImageHeader->width = width;
00717         m_pTempImageHeader->height = height;
00718         
00719         if (m_colorMode == eBayerPatternToRGB24 || m_colorMode == eGrayScale)
00720         {
00721                 m_pTempImageHeader->bytesPerPixel = 1;
00722                 m_pTempImageHeader->type = CByteImage::eGrayScale;
00723         }
00724         else if (m_colorMode == eRGB24 || m_colorMode == eYUV411ToRGB24)
00725         {
00726                 m_pTempImageHeader->bytesPerPixel = 3;
00727                 m_pTempImageHeader->type = CByteImage::eRGB24;
00728         }
00729 
00730         return true;
00731 }
00732 
00733 
00734 void CLinux1394Capture2::ConvertYUV411(CByteImage* pInput, CByteImage* pOutput)
00735 {
00736         int width = pInput->width;
00737         int height = pInput->height;
00738 
00739         int y1,y2,y3,y4,u,v;
00740         int r,g,b;
00741         
00742         unsigned char* output = pOutput->pixels;
00743         unsigned char* input = pInput->pixels;
00744         // read chunks
00745         for(int i = 0 ; i < height ; i++)
00746         {
00747                 for(int j = 0 ; j < width / 4 ; j++)
00748                 {
00749                         u  = input[0];
00750                         y1 = input[1];
00751                         y2 = input[2];
00752 
00753                         v  = input[3];
00754                         y3 = input[4];
00755                         y4 = input[5];
00756                         
00757                         YUVToRGB(y1,u,v,output);
00758                         YUVToRGB(y2,u,v,output + 3);
00759                         YUVToRGB(y3,u,v,output + 6);
00760                         YUVToRGB(y4,u,v,output + 9);
00761                         
00762                         input += 6;
00763                         output += 12;
00764                 }
00765         }
00766 }
00767 
00768 void CLinux1394Capture2::YUVToRGB(int y, int u, int v, unsigned char* output)
00769 {
00770         int r,g,b;
00771         
00772         // u and v are +-0.5
00773         u -= 128;
00774         v -= 128;
00775         
00776         // conversion
00777         r = int(y + 1.370705 * v);
00778         g = int(y - 0.698001 * v - 0.337633 * u);
00779         b = int(y + 1.732446 * u);
00780         
00781         // clamp to 0..1
00782         if (r < 0) r = 0;
00783         if (g < 0) g = 0;
00784         if (b < 0) b = 0;
00785         if (r > 255) r = 255;
00786         if (g > 255) g = 255;
00787         if (b > 255) b = 255;
00788         
00789         output[0] = (unsigned char) r;
00790         output[1] = (unsigned char) g;
00791         output[2] = (unsigned char) b;
00792 }
00793 
00794 
00795 // *****************************************************************
00796 // CaptureImage
00797 // *****************************************************************
00798 
00799 bool CLinux1394Capture2::CaptureImage(CByteImage **ppImages)
00800 {
00801         if ( (width == -1) || (height == -1) )
00802                 return false;
00803 
00804         int i;
00805 
00806         for (i = 0; i < m_nCameras; i++)
00807         {
00808                 int nCurrentIndex = m_nOpenedCameras[i];
00809                 dc1394video_frame_t* pCurrentFrame = NULL;
00810 
00811                 while(pCurrentFrame == NULL)
00812                 {
00813                         if(dc1394_capture_dequeue(m_cameras[nCurrentIndex], DC1394_CAPTURE_POLICY_POLL, &pCurrentFrame) != DC1394_SUCCESS)
00814                         {
00815                                 printf("Error: could not capture current frame on camera %d\n",nCurrentIndex);
00816                                 return false;
00817                         }
00818                 }
00819 
00820                 m_pTempImageHeader->pixels = (unsigned char *) pCurrentFrame->image;
00821 
00822                 switch (m_colorMode)
00823                 {
00824                         case eBayerPatternToRGB24:
00825                                 ImageProcessor::ConvertBayerPattern(m_pTempImageHeader, ppImages[i], m_bayerPatternType);
00826                         break;
00827 
00828                         case eGrayScale:
00829                         case eRGB24:
00830                                 ImageProcessor::CopyImage(m_pTempImageHeader, ppImages[i]);
00831                         break;
00832 
00833                         case eYUV411ToRGB24:
00834                                 ConvertYUV411(m_pTempImageHeader, ppImages[i]);
00835                         break;
00836                 }
00837 
00838                 if(dc1394_capture_enqueue(m_cameras[nCurrentIndex], pCurrentFrame) != DC1394_SUCCESS)
00839                 {
00840                         printf("Error: could not release current frame of camera %d\n", nCurrentIndex);
00841                         return false;
00842                 }
00843         }
00844         
00845         return true;
00846 }
00847 
00848 bool CLinux1394Capture2::CaptureBayerPatternImage(CByteImage **ppImages)
00849 {
00850         if ( (width == -1) || (height == -1) )
00851                 return false;
00852 
00853         int i;
00854 
00855         // free last frame
00856         for (i = 0; i < m_nCameras; i++)
00857         {
00858                 int nCurrentIndex = m_nOpenedCameras[i];
00859 
00860                 dc1394video_frame_t* pCurrentFrame = NULL;
00861                 // retrieve frame (used poll also WAIT is possible)
00862                 while(pCurrentFrame == NULL)
00863                 {
00864                         if(dc1394_capture_dequeue(m_cameras[nCurrentIndex], DC1394_CAPTURE_POLICY_POLL, &pCurrentFrame) != DC1394_SUCCESS)
00865                         {
00866                                 printf("Error: could not capture current frame on camera %d\n",nCurrentIndex);
00867                                 return false;
00868                         }
00869                 }
00870 
00871                 m_pTempImageHeader->pixels = (unsigned char *) pCurrentFrame->image;
00872                 
00873                 if(m_bFormat7Mode)
00874                 {
00875                         ImageProcessor::CopyImage(m_pTempImageHeader, ppImages[i]);
00876                 }
00877                         
00878                 if (m_mode == e640x480)
00879                 {
00880                         ImageProcessor::CopyImage(m_pTempImageHeader, ppImages[i]);
00881                 }
00882                 else if (m_mode == e320x240)
00883                 {
00884                         ImageProcessor::Resize(m_pTempImageHeader, ppImages[i]);
00885                 }
00886 
00887                 if(dc1394_capture_enqueue(m_cameras[nCurrentIndex], pCurrentFrame) != DC1394_SUCCESS)
00888                 {
00889                         printf("Error: could not release current frame of camera %d\n",nCurrentIndex);
00890                         return false;
00891                 }
00892         }
00893         
00894         return true;
00895 }
00896 
00897 CByteImage::ImageType CLinux1394Capture2::GetType()
00898 {
00899         switch (m_colorMode)
00900         {
00901                 case eYUV411ToRGB24:
00902                 case eBayerPatternToRGB24:
00903                 case eRGB24:
00904                         return CByteImage::eRGB24;
00905                 break;
00906                 
00907                 case eGrayScale:
00908                         return CByteImage::eGrayScale;
00909                 break;
00910         }
00911         
00912         return (CByteImage::ImageType) -1;
00913 }
00914 
00915 void CLinux1394Capture2::SetCameraUids(std::vector<std::string> uids)
00916 {
00917         m_nCameras = uids.size();
00918         
00919         for(int u = 0 ; u < m_nCameras ; u++)
00920         {
00921                 m_sCameraUID[u] += uids[u];
00922                 transform(m_sCameraUID[u].begin(), m_sCameraUID[u].end(), m_sCameraUID[u].begin(), (int(*)(int)) toupper);
00923         } 
00924 }
00925 
00926 void CLinux1394Capture2::SetGain(int nValue)
00927 {
00928         SetFeature(DC1394_FEATURE_GAIN, "gain", nValue);
00929 }
00930 
00931 void CLinux1394Capture2::SetExposure(int nValue)
00932 {
00933         SetFeature(DC1394_FEATURE_EXPOSURE, "exposure", nValue);
00934 }
00935 
00936 void CLinux1394Capture2::SetShutter(int nValue)
00937 {
00938         SetFeature(DC1394_FEATURE_SHUTTER, "shutter", nValue);
00939 }
00940 
00941 void CLinux1394Capture2::SetWhiteBalance(int nU, int nV, int nCamera)
00942 {
00943         if(nCamera == -1)
00944         {
00945                 for (int i = 0; i < m_nCameras; i++)
00946                 {
00947                         int nCurrentCamera = m_nOpenedCameras[i];
00948                         dc1394_feature_whitebalance_set_value(m_cameras[nCurrentCamera], nU, nV);
00949                 }
00950         } else {
00951                 int nCurrentCamera = m_nOpenedCameras[nCamera];
00952                 dc1394_feature_whitebalance_set_value(m_cameras[nCurrentCamera], nU, nV);
00953         }
00954 }
00955 
00956 void CLinux1394Capture2::SetTemperature(int nTemperature)
00957 {
00958         for (int i = 0; i < m_nCameras; i++)
00959         {
00960                 int nCurrentCamera = m_nOpenedCameras[i];
00961                 dc1394_feature_temperature_set_value(m_cameras[nCurrentCamera], nTemperature);
00962         }
00963 }
00964 
00965 void CLinux1394Capture2::ListFeatures()
00966 {
00967         for (int i = 0; i < m_nCameras; i++)
00968         {
00969                 printf("== Camera %d =========================================================================\n", i);
00970                 int nCurrentCamera = m_nOpenedCameras[i];
00971                 dc1394featureset_t      feature_set;
00972 
00973                 dc1394_feature_get_all(m_cameras[nCurrentCamera], &feature_set);
00974                 dc1394_feature_print_all(&feature_set,stdout);
00975         }       
00976 }
00977 
00978 void CLinux1394Capture2::SetFeature(dc1394feature_t feature, std::string sName, int nValue)
00979 {
00980         dc1394bool_t bPresent;
00981         
00982         for (int i = 0; i < m_nCameras; i++)
00983         {
00984                 int nCurrentCamera = m_nOpenedCameras[i];
00985                 dc1394_feature_is_present(m_cameras[nCurrentCamera],feature, &bPresent);
00986                 
00987                 if(!bPresent)
00988                 {
00989                         printf("warning: camera %d does not support %s feature\n", nCurrentCamera, sName.c_str());
00990                         return;
00991                 }  
00992                 
00993                 // check boundaries
00994                 uint32_t nMin, nMax;
00995                 dc1394_feature_get_boundaries(m_cameras[nCurrentCamera],feature, &nMin, &nMax);
00996                 
00997                 if( (nValue != -1) && ((nValue < nMin) || (nValue > nMax)) )
00998                 {
00999                         printf("warning: requested %s %d for camera %d is not in the valid range [%d;%d]\n", sName.c_str(), nValue, nCurrentCamera, nMin, nMax);
01000                         return;
01001                 }
01002                 
01003                 dc1394feature_modes_t availableModes;
01004                 dc1394_feature_get_modes(m_cameras[nCurrentCamera],feature, &availableModes);
01005                 
01006                 bool bHasAuto = false;
01007                 bool bHasManual = false;
01008                 
01009                 for(int i = 0 ; i < availableModes.num ; i++)
01010                 {
01011                         if(availableModes.modes[i] == DC1394_FEATURE_MODE_AUTO)
01012                                 bHasAuto = true;
01013                         if(availableModes.modes[i] == DC1394_FEATURE_MODE_MANUAL)
01014                                 bHasManual = true;
01015                 }
01016                 
01017                 if (nValue == -1)
01018                 {
01019                         if(!bHasAuto)
01020                         {
01021                                 printf("warning: camera %d has no auto %s feature\n", nCurrentCamera, sName.c_str());
01022                                 return;
01023                         }
01024                         dc1394_feature_set_mode(m_cameras[nCurrentCamera], feature, DC1394_FEATURE_MODE_AUTO);
01025                 }
01026                 else
01027                 {
01028                         if(!bHasManual)
01029                         {
01030                                 printf("warning: camera %d has no manual %s feature\n", nCurrentCamera, sName.c_str());
01031                                 return;
01032                         }
01033                         dc1394_feature_set_mode(m_cameras[nCurrentCamera], feature, DC1394_FEATURE_MODE_MANUAL);
01034                         dc1394_feature_set_value(m_cameras[nCurrentCamera], feature, nValue);
01035                 }
01036         }
01037 }
01038 
01039 dc1394framerate_t CLinux1394Capture2::GetDCFrameRateMode(FrameRate frameRate)
01040 {
01041         switch(frameRate)
01042         {
01043                 case e60fps: return DC1394_FRAMERATE_60;
01044                 case e30fps: return DC1394_FRAMERATE_30;
01045                 case e15fps: return DC1394_FRAMERATE_15;
01046                 case e7_5fps: return DC1394_FRAMERATE_7_5;
01047                 case e3_75fps: return DC1394_FRAMERATE_3_75;
01048                 case e1_875fps: return DC1394_FRAMERATE_1_875;
01049 
01050                 default: return DC1394_FRAMERATE_30;
01051         };
01052 }
01053 
01054 void CLinux1394Capture2::ResetAllCameras()
01055 {
01056         dc1394camera_list_t * list;
01057         dc1394camera_t *camera;
01058         dc1394error_t err;
01059 
01060     bool bFinished = false;
01061     int nIndex = 0;
01062     
01063     while(!bFinished)
01064     {
01065                 err=dc1394_camera_enumerate (m_pDC1394, &list);
01066                 
01067                 // check if last camera
01068                 if (nIndex >= list->num) 
01069                 {
01070                         break;                  
01071                 }
01072 
01073                 camera = dc1394_camera_new (m_pDC1394, list->ids[nIndex].guid);
01074                 
01075                 if (!camera) 
01076                 {
01077                         break;
01078                 }
01079 
01080                 dc1394_camera_free_list (list);
01081 
01082                 dc1394_reset_bus (camera);
01083                 
01084                 dc1394_camera_free (camera);
01085                 nIndex++;
01086 
01087                 // give time to bus for recovery after bus reset. Needed for some firewire cards.               
01088                 usleep(50000);
01089         }
01090 }
01091 
01092 bool CLinux1394Capture2::ListCameras()
01093 {
01094         // already listed
01095         if(m_nOverallCameras != 0)
01096                 return true;
01097 
01098         // enumarate cameras
01099         dc1394camera_list_t* camera_list;
01100         
01101         if(dc1394_camera_enumerate(m_pDC1394, &camera_list) != DC1394_SUCCESS)
01102         {
01103                 printf("error: cannot enumerate cameras\n");
01104                 return false;
01105         }
01106    
01107         int nNumberCams = camera_list->num;
01108         
01109         for(int i = 0 ; i < nNumberCams ; i++)
01110         {
01111                 printf("= camera %d ========================================= :\n",i);
01112                 
01113                 m_cameras[i] = dc1394_camera_new(m_pDC1394, camera_list->ids[i].guid);
01114                 m_pCameraOpener[i] = NULL;
01115                 
01116                 if(dc1394_camera_print_info(m_cameras[i], stdout) != DC1394_SUCCESS)
01117                 {
01118                         printf("error: could not retrieve info for camera %d\n",i);
01119                         
01120                         // free camera list
01121                         dc1394_camera_free_list(camera_list);
01122         
01123                         return false;
01124                 }
01125         }
01126         
01127         // free camera list
01128         dc1394_camera_free_list(camera_list);
01129         
01130         m_nOverallCameras = nNumberCams;
01131 
01132         // check some stuff     
01133         if(m_nOverallCameras > MAX_CAMERAS)
01134         {
01135                 printf("error: found more cameras than MAX_CAMERAS\n");
01136                 CloseCamera();
01137                 return false;
01138         }       
01139         
01140         // output info and create camera structures
01141         printf("= Found %d cameras ==================================\n",nNumberCams);
01142         return true;
01143 }
01144 
01145 std::string CLinux1394Capture2::CamUIDToString(uint64_t uid)
01146 {
01147         std::string UID = "";
01148         int nLow = (int) uid;
01149         int nHigh = (int) (uid >> 32);
01150         char szUID[17];
01151     sprintf(szUID,"%08X%08X%c",nHigh,nLow, '\0');
01152         UID += szUID;
01153         
01154         return UID;
01155 }


asr_ivt
Author(s): Allgeyer Tobias, Hutmacher Robin, Kleinert Daniel, Meißner Pascal, Scholz Jonas, Stöckle Patrick
autogenerated on Thu Jun 6 2019 21:46:57