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
00047 _Frame *f = new _Frame;
00048 f->_shot = shot;
00049 f->_shot.id = shot.id;
00050
00051
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]));
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
00076 _Frame *f = new _Frame;
00077 f->_shot = burst[i];
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
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]));
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
00124 streamingShot = burst;
00125
00126
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
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
00186 if (s.image.height() > 960) return 77000;
00187 else return 33000;
00188 }
00189
00190 int Sensor::rollingShutterTime(const FCam::Shot &s) const {
00191
00192 if (s.image.height() > 960) return 77000;
00193 else return 33000;
00194 }
00195
00196
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
00205 _Frame *f = new _Frame;
00206 f->_shot = streamingShot[i];
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
00251 Platform::rawToRGBColorMatrix(kelvin, matrix);
00252 }
00253
00254 }}