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