00001 #include <pthread.h>
00002
00003 #include "FCam/Action.h"
00004 #include "FCam/N900/Sensor.h"
00005
00006 #include "FCam/N900/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 pthread_mutex_lock(&requestMutex);
00129
00130
00131 streamingShot = burst;
00132
00133
00134 for (size_t i = 0; i < burst.size(); i++) {
00135 streamingShot[i].id = burst[i].id;
00136 }
00137 pthread_mutex_unlock(&requestMutex);
00138
00139 start();
00140 if (daemon->requestQueue.size() == 0) capture(streamingShot);
00141 }
00142
00143 bool Sensor::streaming() {
00144 return streamingShot.size() > 0;
00145 }
00146
00147 void Sensor::stopStreaming() {
00148 pthread_mutex_lock(&requestMutex);
00149 streamingShot.clear();
00150 pthread_mutex_unlock(&requestMutex);
00151 }
00152
00153 Frame Sensor::getFrame() {
00154 if (!daemon) {
00155 Frame invalid;
00156 error(Event::SensorStoppedError, "Can't request a frame before calling capture or stream\n");
00157 return invalid;
00158 }
00159 Frame frame(daemon->frameQueue.pull());
00160 FCam::Sensor::tagFrame(frame);
00161 for (size_t i = 0; i < devices.size(); i++) {
00162 devices[i]->tagFrame(frame);
00163 }
00164 decShotsPending();
00165 return frame;
00166 }
00167
00168 int Sensor::rollingShutterTime(const Shot &s) const {
00169
00170 if (s.image.height() > 960) return 77000;
00171 else return 33000;
00172 }
00173
00174
00175 void Sensor::generateRequest() {
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 if (!daemon) return;
00192 daemon->setDropPolicy(dropPolicy, frameLimit);
00193 }
00194
00195 int Sensor::framesPending() const {
00196 if (!daemon) return 0;
00197 return daemon->frameQueue.size();
00198 }
00199
00200 int Sensor::shotsPending() const {
00201 return shotsPending_;
00202 }
00203
00204 void Sensor::decShotsPending() {
00205 pthread_mutex_lock(&requestMutex);
00206 shotsPending_--;
00207 pthread_mutex_unlock(&requestMutex);
00208 }
00209
00210 }}