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

src/N900/Sensor.cpp

00001 #include <pthread.h>
00002 
00003 #include "FCam/Action.h"
00004 #include "FCam/N900/Sensor.h"
00005 
00006 #include "Platform.h"
00007 #include "Daemon.h"
00008 #include "ButtonListener.h"
00009 #include "../Debug.h"
00010 
00011 
00012 
00013 namespace FCam { namespace N900 {
00014 
00015     Sensor::Sensor() : FCam::Sensor(), daemon(NULL), shotsPending_(0) {
00016         // make sure the N900 button listener is running
00017         
00018         // TODO: put this somewhere better?
00019         ButtonListener::instance();
00020         
00021         pthread_mutex_init(&requestMutex, NULL);
00022         
00023     }
00024     
00025     Sensor::~Sensor() {
00026         stop();
00027         pthread_mutex_destroy(&requestMutex);
00028     }
00029     
00030     void Sensor::start() {        
00031         if (daemon) return;
00032         daemon = new Daemon(this);
00033         if (streamingShot.size()) daemon->launchThreads();
00034     }
00035 
00036     void Sensor::stop() {
00037         if (!daemon) return;
00038         delete daemon;
00039         daemon = NULL;
00040     }
00041     
00042     void Sensor::capture(const FCam::Shot &shot) {
00043         start();
00044         
00045         _Frame *f = new _Frame;
00046         
00047         // make a deep copy of the shot to attach to the request
00048         f->_shot = shot;        
00049         // clone the shot ID
00050         f->_shot.id = shot.id;
00051         
00052         // push the frame to the daemon
00053         pthread_mutex_lock(&requestMutex);
00054         shotsPending_++;
00055         daemon->requestQueue.push(f);
00056         pthread_mutex_unlock(&requestMutex);
00057 
00058         daemon->launchThreads();
00059     }
00060     
00061     void Sensor::capture(const std::vector<FCam::Shot> &burst) {
00062         start();              
00063 
00064         std::vector<_Frame *> frames;
00065         
00066         for (size_t i = 0; i < burst.size(); i++) {
00067             _Frame *f = new _Frame;
00068             f->_shot = burst[i];
00069             
00070             // clone the shot ID
00071             f->_shot.id = burst[i].id;
00072             
00073             frames.push_back(f); 
00074         }
00075 
00076         pthread_mutex_lock(&requestMutex);
00077         for (size_t i = 0; i < frames.size(); i++) {
00078             shotsPending_++;
00079             daemon->requestQueue.push(frames[i]);
00080         }
00081         pthread_mutex_unlock(&requestMutex);
00082 
00083         daemon->launchThreads();
00084     }
00085     
00086     void Sensor::stream(const FCam::Shot &shot) {
00087         pthread_mutex_lock(&requestMutex);
00088         streamingShot.clear();
00089         // this makes a deep copy of the shot
00090         streamingShot.push_back(shot);
00091         streamingShot[0].id = shot.id;
00092         pthread_mutex_unlock(&requestMutex);
00093 
00094         start();
00095         if (daemon->requestQueue.size() == 0) capture(streamingShot);
00096     }
00097     
00098     void Sensor::stream(const std::vector<FCam::Shot> &burst) {
00099         
00100         pthread_mutex_lock(&requestMutex);
00101         
00102         // do a deep copy of the burst
00103         streamingShot = burst;
00104         
00105         // clone the ids
00106         for (size_t i = 0; i < burst.size(); i++) {
00107             streamingShot[i].id = burst[i].id;
00108         }
00109         pthread_mutex_unlock(&requestMutex);
00110 
00111         start();
00112         if (daemon->requestQueue.size() == 0) capture(streamingShot);
00113     }
00114     
00115     bool Sensor::streaming() {
00116         return streamingShot.size() > 0;
00117     }
00118     
00119     void Sensor::stopStreaming() {
00120         pthread_mutex_lock(&requestMutex);
00121         streamingShot.clear();
00122         pthread_mutex_unlock(&requestMutex);
00123     }
00124         
00125     Frame Sensor::getFrame() {
00126         // TODO: How should we handle getFrame when the sensor is stopped?
00127         if (!daemon) {
00128             Frame invalid;
00129             error(Event::SensorStoppedError, "Can't request a frame before calling capture or stream\n");
00130             return invalid;
00131         }        
00132         Frame frame(daemon->frameQueue.pull());
00133         FCam::Sensor::tagFrame(frame); // Use the base class tagFrame
00134         for (size_t i = 0; i < devices.size(); i++) {
00135             devices[i]->tagFrame(frame);
00136         }
00137         shotsPending_--;
00138         return frame;
00139     }
00140     
00141     int Sensor::rollingShutterTime(const Shot &s) const {
00142         // TODO: put better numbers here
00143         if (s.image.height() > 960) return 77000;
00144         else return 33000;
00145     }
00146     
00147     // the Daemon calls this when it's time for new frames to be queued up
00148     void Sensor::generateRequest() {
00149         pthread_mutex_lock(&requestMutex);
00150         if (streamingShot.size()) {
00151             for (size_t i = 0; i < streamingShot.size(); i++) {
00152                 _Frame *f = new _Frame;
00153                 f->_shot = streamingShot[i];                
00154                 f->_shot.id = streamingShot[i].id;                
00155                 shotsPending_++;
00156                 daemon->requestQueue.push(f);
00157             }
00158         }
00159         pthread_mutex_unlock(&requestMutex);
00160 
00161     }
00162     
00163     void Sensor::enforceDropPolicy() {
00164         if (!daemon) return;
00165         daemon->setDropPolicy(dropPolicy, frameLimit);
00166     }
00167     
00168     int Sensor::framesPending() const {
00169         if (!daemon) return 0;
00170         return daemon->frameQueue.size();
00171     }
00172     
00173     int Sensor::shotsPending() const {
00174         return shotsPending_;
00175     }
00176         
00177     unsigned short Sensor::minRawValue() const {return Platform::minRawValue;}
00178     unsigned short Sensor::maxRawValue() const {return Platform::maxRawValue;}
00179         
00180     BayerPattern Sensor::bayerPattern() const {return Platform::bayerPattern;}        
00181 
00182     const std::string &Sensor::manufacturer() const {return Platform::manufacturer;}
00183 
00184     const std::string &Sensor::model() const {return Platform::model;}        
00185 
00186     void Sensor::rawToRGBColorMatrix(int kelvin, float *matrix) const {
00187         // call the static platform implementation
00188         Platform::rawToRGBColorMatrix(kelvin, matrix);
00189     }
00190 
00191 
00192 }}

Generated on Thu Jul 15 2010 17:51:28 for FCam by  doxygen 1.7.1