• 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 Thu Jul 15 2010 17:51:28 for FCam by  doxygen 1.7.1