• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/Dummy/Daemon.cpp

00001 #include <FCam/Event.h>
00002 #include <FCam/processing/DNG.h>
00003 
00004 #include "Daemon.h"
00005 #include "../Debug.h"
00006 
00007 namespace FCam { namespace Dummy {
00008 
00009     Daemon::Daemon(Sensor *sensor): sensor(sensor), stop(false), running(false) {
00010     }
00011 
00012     Daemon::~Daemon() {
00013     stop = true;
00014 
00015     if (running) 
00016         pthread_join(simThread, NULL);
00017 
00018     }
00019 
00020     void Daemon::launchThreads() {
00021     int err = pthread_create(&simThread, NULL, daemon_launch_thread_, this);
00022     if (err) {
00023         error(Event::InternalError, sensor, "Dummy::Sensor::Daemon: Can't launch simulation thread\n");
00024         return;
00025     }
00026     }
00027 
00028     void Daemon::run() {
00029     while (!stop) {
00030         if (!requestQueue.size()) {
00031         sensor->generateRequest();
00032         }
00033         
00034         if (!requestQueue.size()) {
00035         timespec sleepDuration;
00036         sleepDuration.tv_sec = 0;
00037         sleepDuration.tv_nsec = 100e6; // 100 ms
00038         dprintf(5, "Dummy::Sensor::Daemon: Empty queue, sleeping for a bit\n");
00039         nanosleep(&sleepDuration, NULL);
00040         continue;
00041         }
00042         dprintf(4, "Dummy::Sensor::Daemon: Processing new request\n");
00043         _Frame *f = requestQueue.pull();
00044 
00045         f->exposureStartTime = Time::now();
00046         f->exposureEndTime = f->exposureStartTime + f->shot().exposure;
00047         f->exposure = f->shot().exposure;
00048         f->gain = f->shot().gain;
00049         f->whiteBalance = f->shot().whiteBalance;
00050         f->testPattern = f->shot().testPattern;
00051         f->srcFile = f->shot().srcFile;
00052 
00053         timespec frameDuration;
00054         int duration = (f->shot().exposure > f->shot().frameTime ?
00055                 f->shot().exposure : f->shot().frameTime);
00056         frameDuration.tv_sec = duration / 1000000;
00057         frameDuration.tv_nsec = 1000 * (duration % 1000000);
00058 
00059         dprintf(4, "Dummy::Sensor::Daemon: Sleeping for frame duration %d us (%d s %d nsec) at %s\n", duration, frameDuration.tv_sec, frameDuration.tv_nsec,f->exposureStartTime.toString().c_str() );
00060         nanosleep(&frameDuration, NULL);
00061         dprintf(4, "Dummy::Sensor::Daemon: Done sleeping at %s\n", Time::now().toString().c_str() );
00062         f->frameTime = Time::now() - f->exposureStartTime;
00063 
00064         f->image = f->shot().image;
00065         if (f->image.autoAllocate()) {
00066         f->image = Image(f->image.size(), f->image.type());
00067         }
00068         
00069         switch(f->testPattern) {
00070         case BARS:
00071         case CHECKERBOARD:
00072         dprintf(4, "Dummy::Sensor::Daemon: Drawing test pattern\n");
00073         if (!f->image.discard()) {
00074             for(unsigned int y=0; y < f->image.height(); y++) {
00075             for (unsigned int x=0; x < f->image.width(); x++) {
00076                 int fX = 10000*x / (f->image.width()-1);
00077                 int fY = 10000*y / (f->image.height()-1);
00078 
00079                 unsigned short lum;
00080                 unsigned short rawR=0, rawG=0, rawB=0;
00081 
00082                 switch (f->testPattern) {
00083                 case BARS:
00084                 if (fY < 5000) {
00085                     // Vertical bars
00086                     if (fX < 2500) {
00087                     lum = (fX / 100) * 900 / 25 + 100;
00088                     rawR = ((fX / 100) % 2) * lum;
00089                     rawG = ((fX / 100) % 2) * lum;
00090                     rawB = ((fX / 100) % 2) * lum;
00091                     } else if (fX < 5000) {
00092                     lum = ((fX - 2500)/ 100) * 900/ 25 + 100;
00093                     rawR = ((fX / 100) % 2) * lum;
00094                     rawG = ((fX / 100) % 2) * lum / 100;
00095                     rawB = ((fX / 100) % 2) * lum / 100;
00096                     } else if (fX < 7500) {
00097                     lum = ((fX - 5000)/ 100) * 900/ 25 + 100;
00098                     rawR = ((fX / 100) % 2) * lum / 100;
00099                     rawG = ((fX / 100) % 2) * lum;
00100                     rawB = ((fX / 100) % 2) * lum / 100;
00101                     } else {
00102                     lum = ((fX - 7500)/ 100) * 900/ 25 + 100;
00103                     rawR = ((fX / 100) % 2) * lum / 100;
00104                     rawG = ((fX / 100) % 2) * lum / 100;
00105                     rawB = ((fX / 100) % 2) * lum;
00106                     }
00107                 } else {
00108                     // Horizontal bars
00109                     if (fX < 2500) {
00110                     rawR = ((fY / 100) % 2) * 1000;
00111                     rawG = ((fY / 100) % 2) * 1000;
00112                     rawB = ((fY / 100) % 2) * 1000;
00113                     } else if (fX < 5000) {
00114                     rawR = ((fY / 100) % 2) * 1000;
00115                     rawG = 10;
00116                     rawB = 10;
00117                     } else if (fX < 7500) {
00118                     rawR = 10;
00119                     rawG = ((fY / 100) % 2) * 1000;
00120                     rawB = 10;
00121                     } else {
00122                     rawR = 10;
00123                     rawG = 10;
00124                     rawB = ((fY / 100) % 2) * 1000;
00125                     }
00126                 }
00127                 break;
00128                 case CHECKERBOARD:
00129                 if (fX < 5000) {
00130                     if (fY < 5000) {
00131                     lum = fX * 900 / 5000 + 100;
00132                     rawR =
00133                         (((fX / 250) % 2) ^ 
00134                          ((fY / 250) % 2)) *
00135                         lum;
00136                     rawG = rawR;
00137                     rawB = rawR;
00138                     } else {
00139                     lum = fX * 900 / 5000 + 100;
00140                     rawR = 
00141                         (((fX / 250) % 2) ^ 
00142                          ((fY / 250) % 2)) *
00143                         lum;
00144                     rawG = rawR/100;
00145                     rawB = rawR/100;
00146                     }
00147                 } else {
00148                     if (fY < 5000) {
00149                     lum = (fX-5000) * 900 / 5000 + 100;
00150                     rawG = 
00151                         (((fX / 250) % 2) ^ 
00152                          ((fY / 250) % 2)) *
00153                         lum;
00154                     rawR = rawG/100;
00155                     rawB = rawG/100;
00156                     } else {
00157                     lum = (fX-5000) * 900 / 5000 + 100;
00158                     rawB = 
00159                         (((fX / 250) % 2) ^
00160                          ((fY / 250) % 2)) *
00161                         lum;
00162                     rawR = rawB/100;
00163                     rawG = rawB/100;
00164                     }
00165                 }
00166                 break;
00167                 default:
00168                 break;
00169                 }
00170 
00171                 rawR *= f->gain*f->exposure/10000;
00172                 rawG *= f->gain*f->exposure/10000;
00173                 rawB *= f->gain*f->exposure/10000;
00174 
00175                 switch (f->image.type()) {
00176                 case RGB24: {
00177                 unsigned char *px = f->image(x,y);
00178                 px[0] = rawR > 1000 ? 250 : rawR / 4;
00179                 px[1] = rawG > 1000 ? 250 : rawG / 4;
00180                 px[2] = rawB > 1000 ? 250 : rawB / 4;
00181                 break;
00182                 }
00183                 case RGB16: {
00184                 unsigned short *px = (unsigned short *)f->image(x,y);
00185                 unsigned char r =rawR > 1000 ? 250 : rawR / 4;
00186                 unsigned char g = rawG > 1000 ? 250 : rawG / 4;
00187                 unsigned char b = rawB > 1000 ? 250 : rawB / 4;
00188                 *px = ( (r / 8) | 
00189                     ( (g / 4) << 5) |  
00190                     ( (b / 8) << 11) );
00191                 break;
00192                 }
00193                 case UYVY: {
00194                 unsigned char *px = (unsigned char *)f->image(x,y);
00195                 unsigned char r =rawR > 1000 ? 250 : rawR / 4;
00196                 unsigned char g = rawG > 1000 ? 250 : rawG / 4;
00197                 unsigned char b = rawB > 1000 ? 250 : rawB / 4;
00198                 unsigned char y = 0.299 * r + 0.587 * g + 0.114 * b;
00199                 unsigned char u = 128 - 0.168736 *r - 0.331264 * g + 0.5 * b;
00200                 unsigned char v = 128 + 0.5*r - 0.418688*g - 0.081312*b;
00201                 px[0] = (x % 2) ? u : v;
00202                 px[1] = y;
00203                 break;
00204                 }
00205                 case YUV24: {
00206                 unsigned char *px = (unsigned char *)f->image(x,y);
00207                 unsigned char r =rawR > 1000 ? 250 : rawR / 4;
00208                 unsigned char g = rawG > 1000 ? 250 : rawG / 4;
00209                 unsigned char b = rawB > 1000 ? 250 : rawB / 4;
00210                 px[0] = 0.299 * r + 0.587 * g + 0.114 * b;
00211                 px[1] = 128 - 0.168736 *r - 0.331264 * g + 0.5 * b;
00212                 px[2] = 128 + 0.5*r - 0.418688*g - 0.081312*b;
00213                 break;
00214                 }
00215                 case RAW: {
00216                 unsigned short rawVal;
00217                 if ((x % 2 == 0 && y % 2 == 0) ||
00218                     (x % 2 == 1 && y % 2 == 1) ) {
00219                     rawVal = rawG;
00220                 } else if (x % 2 == 1 && y % 2 == 0) {
00221                     rawVal = rawR;
00222                 } else {
00223                     rawVal = rawB;
00224                 }
00225                     
00226                 *(unsigned short *)f->image(x,y) = rawVal;
00227                 break; 
00228                 }
00229                 default:
00230                 break;
00231                 }               
00232             }  
00233             }
00234         }
00235         f->_bayerPattern = sensor->bayerPattern();
00236         f->_minRawValue = sensor->minRawValue();
00237         f->_maxRawValue = sensor->maxRawValue();
00238         f->_manufacturer = sensor->manufacturer();
00239         f->_model = sensor->model();
00240         sensor->rawToRGBColorMatrix(3200, f->rawToRGB3200K);
00241         sensor->rawToRGBColorMatrix(7000, f->rawToRGB7000K);
00242         f->processingDoneTime = Time::now();
00243         break;
00244         case FILE:
00245         if (f->image.type() != RAW) {
00246             error(Event::InternalError, sensor, "Dummy::Sensor: Non-RAW image requested from a source DNG file. Not supported.");
00247             f->image = Image();         
00248         } else {
00249             dprintf(4, "Dummy::Sensor::Daemon: Loading %s\n", f->srcFile.c_str());
00250             FCam::Frame dng = loadDNG(f->srcFile);
00251             if (!dng.valid()) {
00252             error(Event::InternalError, sensor, "Dummy::Sensor: Unable to load file %s as a source Frame.", f->srcFile.c_str());
00253             } else {
00254             if (!f->image.discard()) {
00255                 f->image = dng.image();
00256             } else {
00257                 f->image = Image(dng.image().size(), dng.image().type(), Image::Discard);
00258             }
00259             f->exposureStartTime = dng.exposureStartTime();
00260             f->exposureEndTime = dng.exposureEndTime();
00261             f->processingDoneTime = dng.processingDoneTime();
00262             f->exposure = dng.exposure();
00263             f->frameTime = dng.frameTime();
00264             f->gain = dng.gain();
00265             f->whiteBalance = dng.whiteBalance();
00266             f->histogram = dng.histogram();
00267             f->sharpness = dng.sharpness();
00268             f->tags = dng.tags();
00269             f->_bayerPattern = dng.bayerPattern();
00270             f->_minRawValue = dng.minRawValue();
00271             f->_maxRawValue = dng.maxRawValue();
00272             f->_manufacturer = dng.manufacturer();
00273             f->_model = dng.model();
00274             dng.rawToRGBColorMatrix(3200, f->rawToRGB3200K);
00275             dng.rawToRGBColorMatrix(7000, f->rawToRGB7000K);
00276             }
00277         }       
00278         }
00279         frameQueue.push(f);
00280     }
00281     }
00282 
00283     void *daemon_launch_thread_(void *arg) {
00284     Daemon *d = (Daemon *)arg;
00285     dprintf(DBG_MINOR, "Dummy::Sensor: Launching dummy simulator thread\n");
00286     d->running = true;
00287     d->run();
00288     d->running = false;
00289     pthread_exit(NULL);
00290     return NULL;
00291     }
00292 
00293 }}

Generated on Thu Jul 15 2010 17:51:28 for FCam by  doxygen 1.7.1