00001 /*!@file AppPsycho/psycho-EyeDetect.C pulse a white square on a black 00002 background, useful for testing timing of display. Duration will be 00003 50% of period. We use a YUVOverlay to match our video experiments 00004 00005 These are valid command options: 00006 bin/psycho-test-timing 100 100 25 0 [01] [01] --sdl-dims=640x480 (no vblank wait) 00007 bin/psycho-test-timing 100 100 25 1 [01] [01] --sdl-dims=640x480 --sdl-vblank-kludge=1 00008 */ 00009 00010 // //////////////////////////////////////////////////////////////////// // 00011 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00012 // University of Southern California (USC) and the iLab at USC. // 00013 // See http://iLab.usc.edu for information about this project. // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00016 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00017 // in Visual Environments, and Applications'' by Christof Koch and // 00018 // Laurent Itti, California Institute of Technology, 2001 (patent // 00019 // pending; application number 09/912,225 filed July 23, 2001; see // 00020 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00021 // //////////////////////////////////////////////////////////////////// // 00022 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00023 // // 00024 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00025 // redistribute it and/or modify it under the terms of the GNU General // 00026 // Public License as published by the Free Software Foundation; either // 00027 // version 2 of the License, or (at your option) any later version. // 00028 // // 00029 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00030 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00031 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00032 // PURPOSE. See the GNU General Public License for more details. // 00033 // // 00034 // You should have received a copy of the GNU General Public License // 00035 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00036 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00037 // Boston, MA 02111-1307 USA. // 00038 // //////////////////////////////////////////////////////////////////// // 00039 // 00040 // Primary maintainer for this file: David Berg <dberg@usc.edu> 00041 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppPsycho/psycho-test-timing.C $ 00042 00043 #include "Component/ModelManager.H" 00044 #include "Image/Image.H" 00045 #include "Image/DrawOps.H" 00046 #include "Devices/ParPort.H" 00047 #include "Psycho/PsychoDisplay.H" 00048 #include "Psycho/PsychoOpts.H" 00049 #include "Component/EventLog.H" 00050 #include "Component/ComponentOpts.H" 00051 #include "Video/RgbConversion.H" 00052 #include "Video/VideoFrame.H" 00053 #include "Util/MathFunctions.H" 00054 00055 // ###################################################################### 00056 static int submain(const int argc, char** argv) 00057 { 00058 MYLOGVERB = LOG_INFO; // suppress debug messages 00059 00060 // Instantiate a ModelManager: 00061 ModelManager manager("Psycho test timing"); 00062 00063 OModelParam<std::string> itsPort(&OPT_EyeTrackerParDev, &manager); 00064 00065 nub::soft_ref<EventLog> el(new EventLog(manager)); 00066 manager.addSubComponent(el); 00067 00068 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager)); 00069 manager.addSubComponent(d); 00070 00071 nub::soft_ref<ParPort> itsParPort(new ParPort(manager, "Parallel Port", "ParPort")); 00072 00073 itsParPort->setModelParamVal("ParPortDevName", itsPort.getVal()); 00074 00075 manager.addSubComponent(itsParPort); 00076 00077 manager.setOptionValString(&OPT_EventLogFileName, "psychodata.psy"); 00078 00079 // Parse command-line: 00080 if (manager.parseCommandLine(argc, argv,"<xpos> <ypos> <use par> <period in frames> <1=vsync> <1=hard sleep> <1=blink>",7,7)==false) 00081 return(1); 00082 00083 // hook our various babies up and do post-command-line configs: 00084 d->setEventLog(el); 00085 d->setModelParamVal("PsychoDisplayBackgroundColor", PixRGB<byte>(0,0,0)); 00086 00087 // let's get all our ModelComponent instances started: 00088 manager.start(); 00089 00090 //stimulus position and size 00091 const int w = d->getDims().w(), h = d->getDims().h(); 00092 const int fixrad = w / 100; 00093 const int siz2 = (fixrad - 1) / 2; // half cross size 00094 const int i = fromStr<int>(manager.getExtraArg(0)); 00095 const int j = fromStr<int>(manager.getExtraArg(1)); 00096 00097 //make an image of our blank and target stimulus, convert our images 00098 //to yuv format and make a VideoFrame 00099 Rectangle rect = Rectangle::tlbrO(j - siz2, i - siz2, j + fixrad, i + fixrad); 00100 Image<PixRGB<byte> > itsStim(w, h, ZEROS); 00101 byte data[w*h + w*h/2]; 00102 byte *y = &data[0], *u = &data[w*h], *v = &data[w*h + w*h/4]; 00103 toVideoYUV422(itsStim, y, u, v); 00104 VideoFrame blank = VideoFrame::deepCopyOf(VideoFrame(data, 00105 size_t(w*h + w*h/2), 00106 Dims(w,h), 00107 VIDFMT_YUV420P, 00108 false, true)); 00109 00110 drawFilledRect(itsStim, rect, PixRGB<byte>(255,255,255)); 00111 toVideoYUV422(itsStim, y, u, v); 00112 VideoFrame vid(data, size_t(w*h + w*h/2), Dims(w,h), 00113 VIDFMT_YUV420P, false, true); 00114 00115 //create YUV overlay 00116 d->createVideoOverlay(VIDFMT_YUV420P, w, h); 00117 00118 //grab some command line data 00119 const bool usepar = fromStr<bool>(manager.getExtraArg(2)); 00120 const int time = fromStr<int>(manager.getExtraArg(3)); 00121 const bool vsync = fromStr<bool>(manager.getExtraArg(4)); 00122 const bool hardwait = fromStr<bool>(manager.getExtraArg(5)); 00123 const bool blink = fromStr<bool>(manager.getExtraArg(6)); 00124 int frame = 0; 00125 int ltime = time; 00126 if (blink) 00127 ltime = time/2; 00128 00129 //loop until key is hit 00130 if (usepar) 00131 itsParPort->WriteData(255, 0); // strobe off 00132 00133 while ((int)d->checkForKey() != 32) 00134 { 00135 //clear screen and sleep 00136 for (int ii = 0; ii < time; ++ii) 00137 { 00138 if (vsync) 00139 d->displayVideoOverlay(blank, frame, SDLdisplay::NEXT_VSYNC); 00140 else 00141 d->displayVideoOverlay(blank, frame, SDLdisplay::NO_WAIT); 00142 ++frame; 00143 } 00144 00145 //hard wait here if if requested 00146 if (hardwait) 00147 d->waitForKey(); 00148 00149 //write log and pulse the parallel port 00150 if (usepar) 00151 { 00152 d->pushEventBegin("Parallel Port pulse"); 00153 itsParPort->WriteData(255, 255); // strobe on 00154 itsParPort->WriteData(255, 0); // strobe off 00155 d->pushEventEnd("Parallel Port pulse"); 00156 } 00157 00158 //display stimulus and leave on for 1/2 period 00159 for (int ii = 0; ii < ltime; ++ii) 00160 { 00161 if (vsync) 00162 d->displayVideoOverlay(vid, frame, SDLdisplay::NEXT_VSYNC); 00163 else 00164 d->displayVideoOverlay(vid, frame, SDLdisplay::NO_WAIT); 00165 ++frame; 00166 00167 if (blink) 00168 { 00169 if (vsync) 00170 d->displayVideoOverlay(blank, frame, SDLdisplay::NEXT_VSYNC); 00171 else 00172 d->displayVideoOverlay(blank, frame, SDLdisplay::NO_WAIT); 00173 ++frame; 00174 } 00175 } 00176 } 00177 d->destroyYUVoverlay(); 00178 // stop all our ModelComponents 00179 manager.stop(); 00180 00181 // all done! 00182 return 0; 00183 } 00184 00185 // ###################################################################### 00186 extern "C" int main(const int argc, char** argv) 00187 { 00188 // simple wrapper around submain() to catch exceptions (because we 00189 // want to allow PsychoDisplay to shut down cleanly; otherwise if we 00190 // abort while SDL is in fullscreen mode, the X server won't return 00191 // to its original resolution) 00192 try 00193 { 00194 return submain(argc, argv); 00195 } 00196 catch (...) 00197 { 00198 REPORT_CURRENT_EXCEPTION; 00199 } 00200 00201 return 1; 00202 } 00203 00204 // ###################################################################### 00205 /* So things look consistent in everyone's emacs... */ 00206 /* Local Variables: */ 00207 /* indent-tabs-mode: nil */ 00208 /* End: */