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

src/N900/Flash.cpp

00001 #include <sys/ioctl.h>
00002 #include <linux/videodev2.h>
00003 
00004 #include "FCam/N900/Flash.h"
00005 #include "FCam/Frame.h"
00006 
00007 #include "../Debug.h"
00008 #include "V4L2Sensor.h"
00009 
00010 namespace FCam { namespace N900 {
00011     
00012     Flash::Flash() :  flashHistory(512) {
00013     }
00014 
00015     Flash::~Flash() {}
00016     
00017     void Flash::setBrightness(float b) {
00018         if (b < minBrightness()) b = minBrightness();
00019         if (b > maxBrightness()) b = maxBrightness();
00020         struct v4l2_control ctrl;
00021         ctrl.id = V4L2_CID_FLASH_INTENSITY;
00022         ctrl.value = b;
00023         int fd = V4L2Sensor::instance("/dev/video0")->getFD();
00024         if (fd < 0) {
00025             V4L2Sensor::instance("/dev/video0")->open();
00026             fd = V4L2Sensor::instance("/dev/video0")->getFD();
00027         }
00028         if (ioctl(fd, VIDIOC_S_CTRL, &ctrl) < 0) {
00029             error(Event::DriverError, this, "VIDIOC_S_CTRL: %d = %d, %d", ctrl.id, ctrl.value, errno);
00030             return;
00031         }
00032     }
00033 
00034     
00035     void Flash::setDuration(int d) {
00036         if (d < minDuration()) d = minDuration();
00037         if (d > maxDuration()) d = maxDuration();
00038         struct v4l2_control ctrl;
00039         ctrl.id = V4L2_CID_FLASH_TIMEOUT;
00040         ctrl.value = d;
00041         int fd = V4L2Sensor::instance("/dev/video0")->getFD();
00042         if (fd < 0) {
00043             V4L2Sensor::instance("/dev/video0")->open();
00044             fd = V4L2Sensor::instance("/dev/video0")->getFD();
00045         }
00046         if (ioctl(fd, VIDIOC_S_CTRL, &ctrl) < 0) {
00047             error(Event::DriverError, this, "VIDIOC_S_CTRL: %d = %d, %d", ctrl.id, ctrl.value, errno);
00048             return;
00049         }
00050     }
00051 
00052     void Flash::fire(float brightness, int duration) {
00053         Time fireTime = Time::now() + fireLatency();
00054         setBrightness(brightness);
00055         setDuration(duration);
00056 
00057         struct v4l2_control ctrl;
00058         ctrl.id = V4L2_CID_FLASH_STROBE;
00059         ctrl.value = 0;
00060         int fd = V4L2Sensor::instance("/dev/video0")->getFD();
00061         if (fd < 0) {
00062             V4L2Sensor::instance("/dev/video0")->open();
00063             fd = V4L2Sensor::instance("/dev/video0")->getFD();
00064         }
00065         if (ioctl(fd, VIDIOC_S_CTRL, &ctrl) < 0) {
00066             error(Event::DriverError, this, "VIDIOC_S_CTRL: %d = %d, %d", ctrl.id, ctrl.value, errno);
00067         } else {
00068             FlashState f;
00069             f.time = fireTime;
00070             f.brightness = brightness;
00071             flashHistory.push(f);
00072             f.time = fireTime + duration;
00073             f.brightness = 0;
00074             flashHistory.push(f);
00075         }        
00076     }
00077         
00078     void Flash::tagFrame(FCam::Frame f) {
00079         Time t1 = f.exposureStartTime();
00080         Time t2 = f.exposureEndTime();
00081 
00082         // what was the state of the flash initially and finally
00083         float b1 = 0; 
00084         float b2 = 0; 
00085 
00086         for (size_t i = 0; i < flashHistory.size(); i++) {
00087             if (t1 > flashHistory[i].time) {
00088                 b1 = flashHistory[i].brightness;
00089                 break;
00090             }
00091         }
00092 
00093         for (size_t i = 0; i < flashHistory.size(); i++) {
00094             if (t2 > flashHistory[i].time) {
00095                 b2 = flashHistory[i].brightness;
00096                 break;
00097             }
00098         }
00099 
00100         // What was the last flash-turning-off event within this
00101         // exposure, and the first flash-turning-on event.
00102         int offTime = -1, onTime = -1;
00103         float brightness;
00104         for (size_t i = 0; i < flashHistory.size(); i++) {
00105             if (flashHistory[i].time < t1) break;
00106             if (flashHistory[i].time > t2) continue;
00107             if (flashHistory[i].brightness == 0 && offTime == -1) {
00108                 offTime = flashHistory[i].time - t1;
00109             }                    
00110             if (flashHistory[i].brightness > 0) {
00111                 brightness = flashHistory[i].brightness;
00112                 onTime = flashHistory[i].time - t1;
00113             }
00114         }
00115 
00116         // If these guys are not set, and the initial brightness is zero, the flash didn't fire
00117         if ((offTime < 0 || onTime < 0) && (b1 == 0)) return;
00118         
00119         if (b1 > 0) {
00120             if (b2 == 0) {
00121                 // it was on initially, turned off and stayed off
00122                 f["flash.brightness"] = b1;
00123                 f["flash.duration"] = offTime;
00124                 f["flash.start"] = 0;
00125                 f["flash.peak"] = offTime/2;
00126             } else {
00127                 // was on at the start and the end of the frame
00128                 f["flash.brightness"] = (b1+b2)/2;
00129                 f["flash.duration"] = t2-t1;
00130                 f["flash.start"] = 0;
00131                 f["flash.peak"] = (t2-t1)/2;
00132             }
00133         } else {
00134             if (b2 > 0) {
00135                 // off initially, turned on, stayed on
00136                 int duration = (t2-t1) - onTime;
00137                 f["flash.brightness"] = b2;
00138                 f["flash.duration"] = duration;
00139                 f["flash.start"] = onTime;
00140                 f["flash.peak"] = onTime + duration/2;
00141             } else {
00142                 // either didn't fire or pulsed somewhere in the middle
00143                 if (onTime >= 0) {
00144                     // pulsed in the middle
00145                     f["flash.brightness"] = brightness;
00146                     f["flash.duration"] = offTime - onTime;
00147                     f["flash.start"] = onTime;
00148                     f["flash.peak"] = onTime + (offTime - onTime)/2;
00149                 } else {
00150                     // didn't fire. No tags.
00151                 }
00152             }
00153         }
00154 
00155         
00156 
00157     }
00158 
00159     float Flash::getBrightness(Time t) {
00160         for (size_t i = 0; i < flashHistory.size(); i++) {
00161             if (t > flashHistory[i].time) {
00162                 return flashHistory[i].brightness;
00163             }
00164         }
00165 
00166         // uh oh, we ran out of history!
00167         error(Event::FlashHistoryError, "Flash brightness at time %d %d is unknown", t.s(), t.us());
00168         return std::numeric_limits<float>::quiet_NaN(); // unknown        
00169     }
00170        
00171 }
00172 }

Generated on Fri Sep 24 2010 15:53:00 for FCam by  doxygen 1.7.1