• 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->platform().bayerPattern();
00236                 f->_minRawValue = sensor->platform().minRawValue();
00237                 f->_maxRawValue = sensor->platform().maxRawValue();
00238                 f->_manufacturer = sensor->platform().manufacturer();
00239                 f->_model = sensor->platform().model();
00240                 sensor->platform().rawToRGBColorMatrix(3200, f->rawToRGB3200K);
00241                 sensor->platform().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.platform().bayerPattern();
00270                         f->_minRawValue = dng.platform().minRawValue();
00271                         f->_maxRawValue = dng.platform().maxRawValue();
00272                         f->_manufacturer = dng.platform().manufacturer();
00273                         f->_model = dng.platform().model();
00274                         dng.platform().rawToRGBColorMatrix(3200, f->rawToRGB3200K);
00275                         dng.platform().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 Mon Aug 16 2010 14:25:45 for FCam by  doxygen 1.7.1