libeblearntools
/home/rex/ebltrunk/tools/libeblearntools/include/camera_mcams.hpp
00001 /***************************************************************************
00002  *   Copyright (C) 2011 by Soumith Chintala   *
00003  *   soumith@gmail.com   *
00004  *   All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Redistribution under a license not approved by the Open Source 
00014  *       Initiative (http://www.opensource.org) must display the 
00015  *       following acknowledgement in all advertising material:
00016  *        This product includes software developed at the Courant
00017  *        Institute of Mathematical Sciences (http://cims.nyu.edu).
00018  *     * The names of the authors may not be used to endorse or promote products
00019  *       derived from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
00022  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00023  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00024  * DISCLAIMED. IN NO EVENT SHALL ThE AUTHORS BE LIABLE FOR ANY
00025  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  ***************************************************************************/
00032 
00033 #ifndef CAMERA_MCAMS_HPP_
00034 #define CAMERA_MCAMS_HPP_
00035 
00036 #ifdef __LINUX__
00037 
00038 #include <fcntl.h>              /* low-level i/o */
00039 #include <unistd.h>
00040 #include <errno.h>
00041 #include <malloc.h>
00042 #include <sys/stat.h>
00043 #include <sys/types.h>
00044 #include <sys/time.h>
00045 #include <sys/mman.h>
00046 #include <sys/ioctl.h>
00047 #include <asm/types.h>          /* for videodev2.h */
00048 #include <linux/videodev2.h>
00049 
00050 
00051 #endif
00052 
00053 namespace ebl {
00054 
00056   // constructors & initializations
00057 
00058   template <typename Tdata>
00059   camera_mcams<Tdata>::camera_mcams(configuration &conf,
00060                                     vector<string> &devs, int height_,
00061                                     int width_, bool grayscale_,
00062                                     bool mode_rgb)
00063     : camera<Tdata>(height_ * ((devs.size() % 2) ? ((devs.size() / 2) + 1) : 
00064                                (devs.size() / 2)), width_ * 2 ), 
00065       started(false), nbuffers(grayscale_ ? 1 : 3) {
00066     // reading mcam_type to initialize the appropriate constructors
00067     string cam_type = conf.get_string("mcam_type");
00068     // get devices paths
00069     vector<string> devices;
00070     for (uint i = 0; i < devs.size(); ++i)
00071       devices.push_back(conf.get_string(devs[i]));
00072     cout << "Initializing " << cam_type << " cameras with devices: " << devices
00073          << endl;
00074     
00075     uint ncams = devs.size();
00076     // this multiplier to split the display into 2x(n/2) matrix of cameras
00077     int height_multiplier = ncams % 2 ? ncams / 2 + 1 : ncams / 2;
00078     // if (ncams < 2) eblerror("mcams needs at least 2 cameras as arguments");
00079     // allocate buffers
00080     frame = idx<Tdata>(height_ * height_multiplier , width_ * 2, nbuffers);
00081     for (uint i = 0; i < devices.size(); ++i) {
00082       cam_frames.push_back(frame.narrow(0, height_ , height_ * (i/2)));
00083       cam_frames[i] = cam_frames[i].narrow(1, width_, width_ * (i%2));
00084     }
00085     // instantiate cameras
00086     for (uint i = 0; i < devices.size(); ++i) {
00087       if(cam_type.compare("v4l2") == 0)
00088         cams.push_back(new ebl::camera_v4l2<Tdata>
00089                        (devices[i].c_str(), height_, width_, 
00090                         grayscale_, mode_rgb));
00091       else if(cam_type.compare("opencv") == 0)
00092         cams.push_back(new ebl::camera_opencv<Tdata>(i, height_, width_));
00093       else eblerror("Camera type not supported in camera_mcams");
00094     }
00095   }
00096   
00097   template <typename Tdata>
00098   camera_mcams<Tdata>::~camera_mcams() {
00099     for (uint i = 0; i < cams.size(); ++i)
00100       delete cams[i];
00101   }
00102 
00103 #ifdef __LINUX__
00104   
00106   // frame grabbing
00107 
00108   template <typename Tdata>
00109   void camera_mcams<Tdata>::start() {
00110     cout<<" Starting camera_mcams "<<endl;
00111     started = true;
00112   }
00113   
00114 #endif
00115   
00116   template <typename Tdata>
00117   idx<Tdata> camera_mcams<Tdata>::grab() {
00118 #ifdef __LINUX__
00119     if (!started)
00120       this->start();
00121     // for each camera, grab the new frame
00122     for( uint i=0; i < cams.size(); ++i) {
00123       idx_copy(cams[i]->grab(),cam_frames[i]);
00124     }
00125     cout<<"fps_grab:"<<this->fps_grab<<endl;
00126 #endif
00127     frame_id_++;
00128     return this->postprocess();
00129     //return frame_;
00130   }
00131 
00132 } // end namespace ebl
00133 
00134 #endif /* CAMERA_MCAMS_HPP_ */