• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/F2/Sensor.cpp

00001 #include <pthread.h>
00002 
00003 #include "FCam/Action.h"
00004 #include "FCam/F2/Sensor.h"
00005 
00006 #include "Platform.h"
00007 #include "Daemon.h"
00008 #include "linux/mt9p031.h"
00009 #include "../Debug.h"
00010 
00011 
00012 
00013 namespace FCam { namespace F2 {
00014 
00015 
00016     Sensor::Sensor() : FCam::Sensor(), daemon(NULL), shotsPending_(0) {
00017         pthread_mutex_init(&requestMutex, NULL);
00018     }
00019 
00020     Sensor::~Sensor() {
00021         stop();
00022         pthread_mutex_destroy(&requestMutex);
00023     }
00024 
00025     void Sensor::start() {
00026         if (daemon) return;
00027         daemon = new Daemon(this);
00028         daemon->launchThreads();
00029     }
00030 
00031     void Sensor::stop() {
00032         if (!daemon) return;
00033         delete daemon;
00034         daemon = NULL;
00035     }
00036 
00037     void Sensor::capture(const FCam::Shot &s) {
00038         Shot F2s(s);
00039         F2s.id = s.id;
00040         capture(F2s);
00041     }
00042 
00043     void Sensor::capture(const Shot &shot) {
00044         start();
00045 
00046         // Construct initial fields of \ref F2::_Frame 
00047         _Frame *f = new _Frame;
00048         f->_shot = shot;        // make a deep copy here as well
00049         f->_shot.id = shot.id;
00050 
00051         // push the frame to the daemon
00052         pthread_mutex_lock(&requestMutex);
00053         shotsPending_++;
00054         daemon->requestQueue.push(f);
00055         pthread_mutex_unlock(&requestMutex);
00056     }
00057 
00058     void Sensor::capture(const std::vector<FCam::Shot> &burst) {
00059         std::vector<Shot> F2Burst;
00060         F2Burst.reserve(burst.size());
00061         for (unsigned int i=0; i < burst.size(); i++ ) {
00062             F2Burst.push_back(Shot(burst[i])); // Does this make an unneccessary copy?
00063             F2Burst[i].id = burst[i].id;
00064         }
00065         capture(F2Burst);
00066     }
00067         
00068     void Sensor::capture(const std::vector<Shot> &burst) {
00069         start();
00070 
00071         std::vector<_Frame *> frames;
00072 
00073         for (size_t i = 0; i < burst.size(); i++) {
00074            
00075             // Construct initial fields of \ref F2::_Frame 
00076             _Frame *f = new _Frame;
00077             f->_shot = burst[i];        // make a deep copy here as well
00078             f->_shot.id = burst[i].id;
00079 
00080             frames.push_back(f);
00081         }
00082 
00083         pthread_mutex_lock(&requestMutex);
00084         for (size_t i = 0; i < frames.size(); i++) {
00085             shotsPending_++;
00086             daemon->requestQueue.push(frames[i]);
00087         }
00088         pthread_mutex_unlock(&requestMutex);
00089     }
00090 
00091     void Sensor::stream(const FCam::Shot &s) {
00092         Shot F2s(s);
00093         F2s.id = s.id;
00094         stream(F2s);
00095     }
00096 
00097     void Sensor::stream(const Shot &shot) {
00098 
00099 
00100         pthread_mutex_lock(&requestMutex);
00101         streamingShot.clear();
00102         // this makes a deep copy of the shot
00103         streamingShot.push_back(shot);
00104         streamingShot[0].id = shot.id;
00105         pthread_mutex_unlock(&requestMutex);
00106 
00107         start();
00108         if (daemon->requestQueue.size() == 0) capture(streamingShot);
00109     }
00110 
00111     void Sensor::stream(const std::vector<FCam::Shot> &burst) {
00112         std::vector<Shot> F2Burst;
00113         F2Burst.reserve(burst.size());
00114         for (unsigned int i=0; i < burst.size(); i++ ) {
00115             F2Burst.push_back(Shot(burst[i])); // Does this make an unneccessary copy?
00116             F2Burst[i].id = burst[i].id;
00117         }
00118         stream(F2Burst);
00119     }
00120 
00121     void Sensor::stream(const std::vector<Shot> &burst) {
00122         pthread_mutex_lock(&requestMutex);
00123         // do a deep copy of the burst
00124         streamingShot = burst;
00125 
00126         // Now to copy the IDs
00127         for (unsigned int i=0; i<burst.size(); i++) {
00128             streamingShot[i].id = burst[i].id;
00129         }
00130         pthread_mutex_unlock(&requestMutex);
00131 
00132         start();
00133         if (daemon->requestQueue.size() == 0) capture(streamingShot);
00134     }
00135 
00136     bool Sensor::streaming() {
00137         return streamingShot.size() > 0;
00138     }
00139 
00140     void Sensor::stopStreaming() {
00141         pthread_mutex_lock(&requestMutex);
00142         streamingShot.clear();
00143         pthread_mutex_unlock(&requestMutex);
00144     }
00145 
00146     FCam::F2::Frame Sensor::getFrame() {
00147         // TODO: How should we handle getFrame when the sensor is stopped?
00148         start();
00149 
00150         _Frame *_f;
00151         _f = daemon->frameQueue.pull();
00152 
00153         Frame frame(_f);
00154         FCam::Sensor::tagFrame(frame);
00155         for (size_t i=0; i< devices.size(); i++) {
00156             devices[i]->tagFrame(frame);
00157         }
00158         shotsPending_--;
00159         return frame;
00160     }
00161         
00162     
00163     Size Sensor::minImageSize() const {
00164         return Size(640, 480);
00165     } 
00166     Size Sensor::maxImageSize() const {
00167         return Size(MT9P031_ACTIVE_WIDTH, MT9P031_ACTIVE_HEIGHT);
00168     }
00169     Size Sensor::pixelArraySize() {
00170         return Size(MT9P031_ARRAY_WIDTH, MT9P031_ARRAY_HEIGHT);
00171     }
00172         
00173     Rect Sensor::activeArrayRect() {
00174         return Rect(0,0, 
00175                     MT9P031_ACTIVE_WIDTH, MT9P031_ACTIVE_HEIGHT);
00176     }         
00177     Rect Sensor::pixelArrayRect() {
00178         return Rect(MT9P031_MIN_COL, 
00179                     MT9P031_MIN_ROW, 
00180                     MT9P031_ARRAY_WIDTH, 
00181                     MT9P031_ARRAY_HEIGHT);
00182     } 
00183         
00184     int Sensor::rollingShutterTime(const Shot &s) const {
00185         // TODO: put better numbers here
00186         if (s.image.height() > 960) return 77000;
00187         else return 33000;
00188     }
00189 
00190     int Sensor::rollingShutterTime(const FCam::Shot &s) const {
00191         // TODO: put better numbers here
00192         if (s.image.height() > 960) return 77000;
00193         else return 33000;
00194     }
00195 
00196     // the Daemon calls this when it's time for new frames to be queued up
00197     void Sensor::generateRequest() {
00198         pthread_mutex_lock(&requestMutex);
00199         if (streamingShot.size() ) {
00200             std::vector<_Frame *> frames;
00201             
00202             for (size_t i = 0; i < streamingShot.size(); i++) {
00203                
00204                 // Construct initial sections of F2::_Frame 
00205                 _Frame *f = new _Frame;
00206                 f->_shot = streamingShot[i];        // make a deep copy here as well
00207                 f->_shot.id = streamingShot[i].id;
00208                 
00209                 frames.push_back(f);
00210             }
00211             
00212             for (size_t i = 0; i < frames.size(); i++) {
00213                 shotsPending_++;
00214                 daemon->requestQueue.push(frames[i]);
00215             }
00216         }
00217         pthread_mutex_unlock(&requestMutex);
00218     }
00219 
00220     void Sensor::enforceDropPolicy() {
00221         if (!daemon) return;
00222         daemon->setDropPolicy(dropPolicy, frameLimit);
00223     }
00224 
00225     int Sensor::framesPending() const {
00226         if (!daemon) return 0;
00227         return daemon->frameQueue.size();
00228     }
00229 
00230     int Sensor::shotsPending() const {
00231         if (!daemon) return 0;
00232         return shotsPending_;
00233     }
00234 
00235     void Sensor::debugTiming(bool enable) {
00236         start();
00237         daemon->debugTiming(enable);
00238     }
00239   
00240     unsigned short Sensor::minRawValue() const {return Platform::minRawValue;}
00241     unsigned short Sensor::maxRawValue() const {return Platform::maxRawValue;}
00242         
00243     BayerPattern Sensor::bayerPattern() const {return Platform::bayerPattern;}        
00244 
00245     const std::string &Sensor::manufacturer() const {return Platform::manufacturer;}
00246 
00247     const std::string &Sensor::model() const {return Platform::model;}        
00248 
00249     void Sensor::rawToRGBColorMatrix(int kelvin, float *matrix) const {
00250         // call the static platform implementation
00251         Platform::rawToRGBColorMatrix(kelvin, matrix);
00252     }
00253 
00254 }}

Generated on Fri Sep 24 2010 15:53:00 for FCam by  doxygen 1.7.1