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
00017
00018
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 dprintf(3, "Entering Sensor::stop\n");
00038 stopStreaming();
00039
00040 if (!daemon) return;
00041
00042 dprintf(3, "Cancelling outstanding requests\n");
00043
00044
00045 pthread_mutex_lock(&requestMutex);
00046 _Frame *req;
00047 while (daemon->requestQueue.tryPullBack(&req)) {
00048 delete req;
00049 shotsPending_--;
00050 }
00051 pthread_mutex_unlock(&requestMutex);
00052
00053 dprintf(3, "Discarding remaining frames\n");
00054
00055
00056 while (shotsPending_) {
00057 delete daemon->frameQueue.pull();
00058 decShotsPending();
00059 }
00060
00061 dprintf(3, "Deleting daemon\n");
00062
00063
00064 if (!daemon) return;
00065 delete daemon;
00066 daemon = NULL;
00067
00068 dprintf(3, "Sensor stopped\n");
00069 }
00070
00071 void Sensor::capture(const FCam::Shot &shot) {
00072 start();
00073
00074 _Frame *f = new _Frame;
00075
00076
00077 f->_shot = shot;
00078
00079 f->_shot.id = shot.id;
00080
00081
00082 pthread_mutex_lock(&requestMutex);
00083 shotsPending_++;
00084 daemon->requestQueue.push(f);
00085 pthread_mutex_unlock(&requestMutex);
00086
00087 daemon->launchThreads();
00088 }
00089
00090 void Sensor::capture(const std::vector<FCam::Shot> &burst) {
00091 start();
00092
00093 std::vector<_Frame *> frames;
00094
00095 for (size_t i = 0; i < burst.size(); i++) {
00096 _Frame *f = new _Frame;
00097 f->_shot = burst[i];
00098
00099
00100 f->_shot.id = burst[i].id;
00101
00102 frames.push_back(f);
00103 }
00104
00105 pthread_mutex_lock(&requestMutex);
00106 for (size_t i = 0; i < frames.size(); i++) {
00107 shotsPending_++;
00108 daemon->requestQueue.push(frames[i]);
00109 }
00110 pthread_mutex_unlock(&requestMutex);
00111
00112 daemon->launchThreads();
00113 }
00114
00115 void Sensor::stream(const FCam::Shot &shot) {
00116 pthread_mutex_lock(&requestMutex);
00117 streamingShot.clear();
00118
00119 streamingShot.push_back(shot);
00120 streamingShot[0].id = shot.id;
00121 pthread_mutex_unlock(&requestMutex);
00122
00123 start();
00124 if (daemon->requestQueue.size() == 0) capture(streamingShot);
00125 }
00126
00127 void Sensor::stream(const std::vector<FCam::Shot> &burst) {
00128
00129 pthread_mutex_lock(&requestMutex);
00130
00131
00132 streamingShot = burst;
00133
00134
00135 for (size_t i = 0; i < burst.size(); i++) {
00136 streamingShot[i].id = burst[i].id;
00137 }
00138 pthread_mutex_unlock(&requestMutex);
00139
00140 start();
00141 if (daemon->requestQueue.size() == 0) capture(streamingShot);
00142 }
00143
00144 bool Sensor::streaming() {
00145 return streamingShot.size() > 0;
00146 }
00147
00148 void Sensor::stopStreaming() {
00149 pthread_mutex_lock(&requestMutex);
00150 streamingShot.clear();
00151 pthread_mutex_unlock(&requestMutex);
00152 }
00153
00154 Frame Sensor::getFrame() {
00155 if (!daemon) {
00156 Frame invalid;
00157 error(Event::SensorStoppedError, "Can't request a frame before calling capture or stream\n");
00158 return invalid;
00159 }
00160 Frame frame(daemon->frameQueue.pull());
00161 FCam::Sensor::tagFrame(frame);
00162 for (size_t i = 0; i < devices.size(); i++) {
00163 devices[i]->tagFrame(frame);
00164 }
00165 decShotsPending();
00166 return frame;
00167 }
00168
00169 int Sensor::rollingShutterTime(const Shot &s) const {
00170
00171 if (s.image.height() > 960) return 77000;
00172 else return 33000;
00173 }
00174
00175
00176 void Sensor::generateRequest() {
00177 pthread_mutex_lock(&requestMutex);
00178 if (streamingShot.size()) {
00179 for (size_t i = 0; i < streamingShot.size(); i++) {
00180 _Frame *f = new _Frame;
00181 f->_shot = streamingShot[i];
00182 f->_shot.id = streamingShot[i].id;
00183 shotsPending_++;
00184 daemon->requestQueue.push(f);
00185 }
00186 }
00187 pthread_mutex_unlock(&requestMutex);
00188
00189 }
00190
00191 void Sensor::enforceDropPolicy() {
00192 if (!daemon) return;
00193 daemon->setDropPolicy(dropPolicy, frameLimit);
00194 }
00195
00196 int Sensor::framesPending() const {
00197 if (!daemon) return 0;
00198 return daemon->frameQueue.size();
00199 }
00200
00201 int Sensor::shotsPending() const {
00202 return shotsPending_;
00203 }
00204
00205 void Sensor::decShotsPending() {
00206 pthread_mutex_lock(&requestMutex);
00207 shotsPending_--;
00208 pthread_mutex_unlock(&requestMutex);
00209 }
00210
00211 unsigned short Sensor::minRawValue() const {return Platform::minRawValue;}
00212 unsigned short Sensor::maxRawValue() const {return Platform::maxRawValue;}
00213
00214 BayerPattern Sensor::bayerPattern() const {return Platform::bayerPattern;}
00215
00216 const std::string &Sensor::manufacturer() const {return Platform::manufacturer;}
00217
00218 const std::string &Sensor::model() const {return Platform::model;}
00219
00220 void Sensor::rawToRGBColorMatrix(int kelvin, float *matrix) const {
00221
00222 Platform::rawToRGBColorMatrix(kelvin, matrix);
00223 }
00224
00225
00226 }}