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