00001 #include <pthread.h>
00002 #include <semaphore.h>
00003 #include <time.h>
00004
00005 #include <FCam/Event.h>
00006 #include <FCam/Action.h>
00007 #include <FCam/Dummy/Sensor.h>
00008
00009 #include "Daemon.h"
00010 #include "Platform.h"
00011 #include "../Debug.h"
00012
00013
00014 namespace FCam { namespace Dummy {
00015
00016 Sensor::Sensor(): FCam::Sensor(), daemon(NULL), shotsPending_(0) {
00017 dprintf(DBG_MINOR, "Initializing dummy simulator sensor.\n");
00018 pthread_mutex_init(&requestMutex, NULL);
00019 }
00020
00021 Sensor::~Sensor() {
00022 dprintf(DBG_MINOR, "Destroying dummy simulator sensor.\n");
00023 stop();
00024 pthread_mutex_destroy(&requestMutex);
00025 }
00026
00027 void Sensor::capture(const FCam::Shot &s) {
00028 Shot dummyShot(s);
00029 dummyShot.id = s.id;
00030 capture(dummyShot);
00031 }
00032
00033 void Sensor::capture(const Shot &shot) {
00034 dprintf(DBG_MINOR, "Queuing capture request.\n");
00035 start();
00036
00037 _Frame *f = new _Frame;
00038 f->_shot = shot;
00039 f->_shot.id = shot.id;
00040
00041 pthread_mutex_lock(&requestMutex);
00042 shotsPending_++;
00043 daemon->requestQueue.push(f);
00044 pthread_mutex_unlock(&requestMutex);
00045
00046 daemon->launchThreads();
00047 }
00048
00049 void Sensor::capture(const std::vector<FCam::Shot> &burst) {
00050 std::vector<Shot> dummyBurst;
00051 dummyBurst.reserve(burst.size());
00052 for (unsigned int i=0; i < burst.size(); i++ ) {
00053 dummyBurst.push_back(Shot(burst[i]));
00054 dummyBurst[i].id = burst[i].id;
00055 }
00056 capture(dummyBurst);
00057 }
00058
00059 void Sensor::capture(const std::vector<Shot> &burst) {
00060 dprintf(DBG_MINOR, "Queuing capture request burst.\n");
00061 start();
00062
00063 std::vector<_Frame *> frames;
00064
00065 for (size_t i=0; i < burst.size(); i++) {
00066 _Frame *f = new _Frame;
00067 f->_shot = burst[i];
00068 f->_shot.id = burst[i].id;
00069
00070 frames.push_back(f);
00071 }
00072
00073 pthread_mutex_lock(&requestMutex);
00074 for (size_t i=0; i < frames.size(); i++) {
00075 shotsPending_++;
00076 daemon->requestQueue.push(frames[i]);
00077 }
00078 pthread_mutex_unlock(&requestMutex);
00079
00080 daemon->launchThreads();
00081 }
00082
00083 void Sensor::stream(const FCam::Shot &s) {
00084 Shot dummyShot(s);
00085 dummyShot.id = s.id;
00086 stream(dummyShot);
00087 }
00088
00089 void Sensor::stream(const Shot &shot) {
00090 dprintf(DBG_MINOR, "Configuring streaming shot.\n");
00091 pthread_mutex_lock(&requestMutex);
00092 streamingShot.clear();
00093 streamingShot.push_back(shot);
00094 streamingShot[0].id = shot.id;
00095 pthread_mutex_unlock(&requestMutex);
00096
00097 start();
00098 if (daemon->requestQueue.size() == 0) capture(streamingShot);
00099 }
00100
00101 void Sensor::stream(const std::vector<FCam::Shot> &burst) {
00102 std::vector<Shot> dummyBurst;
00103 dummyBurst.reserve(burst.size());
00104 for (unsigned int i=0; i < burst.size(); i++ ) {
00105 dummyBurst.push_back(burst[i]);
00106 dummyBurst[i].id = burst[i].id;
00107 }
00108 stream(dummyBurst);
00109 }
00110
00111 void Sensor::stream(const std::vector<Shot> &burst) {
00112 dprintf(DBG_MINOR, "Configuring streaming burst.\n");
00113 pthread_mutex_lock(&requestMutex);
00114 streamingShot = burst;
00115 for (size_t i=0; i < burst.size(); i++) {
00116 streamingShot[i].id = burst[i].id;
00117 }
00118 pthread_mutex_unlock(&requestMutex);
00119
00120 start();
00121 if (daemon->requestQueue.size() == 0) capture(streamingShot);
00122 }
00123
00124 bool Sensor::streaming() {
00125 return streamingShot.size() > 0;
00126 }
00127
00128 void Sensor::stopStreaming() {
00129 dprintf(DBG_MINOR, "Stopping streaming.\n");
00130 pthread_mutex_lock(&requestMutex);
00131 streamingShot.clear();
00132 pthread_mutex_unlock(&requestMutex);
00133 }
00134
00135 void Sensor::start() {
00136 dprintf(4, "Creating and launching daemon.\n");
00137 if (daemon) return;
00138 daemon = new Daemon(this);
00139 if (streamingShot.size()) daemon->launchThreads();
00140 dprintf(4, "Daemon created.\n");
00141 }
00142
00143 void Sensor::stop() {
00144 dprintf(4, "Destroying daemon.\n");
00145 if (!daemon) return;
00146 delete daemon;
00147 daemon = NULL;
00148 }
00149
00150 FCam::Dummy::Frame Sensor::getFrame() {
00151 dprintf(DBG_MINOR, "Getting a frame.\n");
00152 if (!daemon) {
00153 Frame invalid;
00154 error(Event::SensorStoppedError, this, "Can't request frame before calling capture or stream\n");
00155 return invalid;
00156 }
00157
00158 _Frame *_f;
00159 _f = daemon->frameQueue.pull();
00160
00161 Frame frame(_f);
00162
00163 shotsPending_--;
00164
00165 dprintf(DBG_MINOR, "Frame received.\n");
00166 return frame;
00167 }
00168
00169 int Sensor::rollingShutterTime(const FCam::Shot &s) const {
00170 return 0;
00171 }
00172
00173 void Sensor::generateRequest() {
00174 dprintf(4, "GenerateRequest called by daemon.\n");
00175 pthread_mutex_lock(&requestMutex);
00176 if (streamingShot.size() ) {
00177 for (size_t i = 0; i < streamingShot.size(); i++) {
00178 _Frame *f = new _Frame;
00179 f->_shot = streamingShot[i];
00180 f->_shot.id = streamingShot[i].id;
00181 shotsPending_++;
00182 daemon->requestQueue.push(f);
00183 }
00184 }
00185 pthread_mutex_unlock(&requestMutex);
00186 }
00187
00188
00189 void Sensor::enforceDropPolicy() {
00190
00191 }
00192
00193 int Sensor::framesPending() const {
00194 if (!daemon) return 0;
00195 return daemon->frameQueue.size();
00196 }
00197
00198 int Sensor::shotsPending() const {
00199 return shotsPending_;
00200 }
00201
00202 unsigned short Sensor::minRawValue() const {return Platform::minRawValue;}
00203 unsigned short Sensor::maxRawValue() const {return Platform::maxRawValue;}
00204
00205 BayerPattern Sensor::bayerPattern() const {return Platform::bayerPattern;}
00206
00207 const std::string &Sensor::manufacturer() const {return Platform::manufacturer;}
00208
00209 const std::string &Sensor::model() const {return Platform::model;}
00210
00211 void Sensor::rawToRGBColorMatrix(int kelvin, float *matrix) const {
00212
00213 Platform::rawToRGBColorMatrix(kelvin, matrix);
00214 }
00215
00216 }}