psycho-monkey.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Component/ModelManager.H"
00039 #include "Component/ModelOptionDef.H"
00040 #include "Transport/TransportOpts.H"
00041 #include "Image/Image.H"
00042 #include "Image/Range.H"
00043 #include "Media/MPEGStream.H"
00044 #include "Media/MediaOpts.H"
00045 #include "Psycho/PsychoDisplay.H"
00046 #include "Psycho/EyeTrackerConfigurator.H"
00047 #include "Psycho/EyeTracker.H"
00048 #include "Psycho/PsychoOpts.H"
00049 #include "Component/EventLog.H"
00050 #include "Component/ComponentOpts.H"
00051 #include "GUI/SDLdisplay.H"
00052 #include "Util/MathFunctions.H"
00053 #include "Util/Types.H"
00054 #include "Util/SimTime.H"
00055 #include "Video/VideoFrame.H"
00056 #include "rutz/rand.h"
00057
00058 #include <deque>
00059 #include <sys/time.h>
00060 #include <unistd.h>
00061
00062 #define CACHELEN 500
00063
00064
00065
00066 static bool cacheFrame(nub::soft_ref<InputMPEGStream>& mp,
00067 std::deque<VideoFrame>& cache,
00068 const bool flip)
00069 {
00070 const VideoFrame frame = mp->readVideoFrame();
00071 if (!frame.initialized()) return false;
00072
00073 if (flip) cache.push_front(frame.getFlippedHoriz());
00074 else cache.push_front(frame);
00075
00076 return true;
00077 }
00078
00079
00080 extern "C" int main(const int argc, char** argv)
00081 {
00082 MYLOGVERB = LOG_INFO;
00083
00084
00085 ModelManager manager("Psycho Monkey");
00086 OModelParam<bool> hflip(&OPT_Hflip, &manager);
00087 OModelParam<bool> keepfix(&OPT_KeepFix, &manager);
00088 OModelParam<float> fixsize(&OPT_FixSize, &manager);
00089 OModelParam<float> ppd(&OPT_Ppd, &manager);
00090 OModelParam<Range<int> > itsWait(&OPT_TrialWait, &manager);
00091 OModelParam<bool> testrun(&OPT_Testrun, &manager);
00092 OModelParam<int> itsPercent(&OPT_GrayFramePrcnt, &manager);
00093 OModelParam<Range<int> > itsRange(&OPT_GrayFrameRange, &manager);
00094
00095
00096 nub::soft_ref<InputMPEGStream> mp
00097 (new InputMPEGStream(manager, "Input MPEG Stream", "InputMPEGStream"));
00098 manager.addSubComponent(mp);
00099
00100 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00101 manager.addSubComponent(d);
00102
00103 nub::soft_ref<EyeTrackerConfigurator>
00104 etc(new EyeTrackerConfigurator(manager));
00105 manager.addSubComponent(etc);
00106
00107 nub::soft_ref<EventLog> el(new EventLog(manager));
00108 manager.addSubComponent(el);
00109
00110 manager.setOptionValString(&OPT_InputMPEGStreamPreload, "true");
00111 manager.setOptionValString(&OPT_EventLogFileName, "psychodata.psy");
00112 manager.setOptionValString(&OPT_EyeTrackerType, "DML");
00113
00114
00115 if (manager.parseCommandLine(argc, argv,
00116 "<movie1.mpg> ... <movieN.mpg>", 1, -1)==false)
00117 return(1);
00118
00119
00120 nub::soft_ref<EyeTracker> et = etc->getET();
00121 d->setEyeTracker(et);
00122 d->setEventLog(el);
00123 et->setEventLog(el);
00124
00125
00126 int fixrad = int(ppd.getVal() * fixsize.getVal());
00127 if ((fixrad % 2) != 0)
00128 --fixrad;
00129 d->setFixationSize(fixrad*2);
00130
00131 const int cx = d->getWidth() /2 - 1 - (fixrad/2 -1);
00132 const int cy = d->getHeight()/2 - 1 - (fixrad/2 -1);
00133
00134
00135 Image<PixRGB<byte> > patch(fixrad,fixrad,ZEROS);
00136 patch += PixRGB<byte>(255,0,0);
00137
00138 std::deque<VideoFrame> cache;
00139 initRandomNumbers();
00140
00141
00142 manager.start();
00143 d->clearScreen();
00144
00145
00146 const uint nbmovies = manager.numExtraArgs();
00147 const float percentage = (float)itsPercent.getVal() * 0.01F;
00148 const float factor = percentage/(1 - percentage);
00149 const uint graycount = uint(factor * (float)nbmovies);
00150 const uint nbtotal = nbmovies + graycount;
00151
00152 LINFO("Randomizing movies...");
00153 int index[nbtotal];
00154 std::string fnames[nbtotal];
00155 for (uint i = 0; i < nbmovies; ++i) index[i] = i;
00156 for (uint i = nbmovies; i < nbtotal; ++i) index[i] = -1;
00157 randShuffle(index, nbtotal);
00158 for (uint i = 0; i < nbtotal; ++i)
00159 fnames[i] = (index[i] < 0) ? "Gray image" : manager.getExtraArg(index[i]);
00160
00161 try {
00162
00163 for (uint i = 0; i < nbtotal; i ++)
00164 {
00165
00166 d->clearScreen();
00167 if (cache.size()) LFATAL("ooops, cache not empty?");
00168 bool streaming = true;
00169 LINFO("Buffering '%s'...", fnames[i].c_str());
00170
00171
00172
00173 if (index[i] > -1)
00174 {
00175 mp->setFileName(fnames[i]);
00176 for (uint j = 0; j < CACHELEN; j ++)
00177 {
00178 streaming = cacheFrame(mp, cache, hflip.getVal());
00179 if (streaming == false) break;
00180 }
00181 }
00182
00183 LINFO("'%s' ready.", fnames[i].c_str());
00184
00185
00186 usleep(rutz::rand_range<int>(itsWait.getVal().min(),
00187 itsWait.getVal().max()) * 1000);
00188
00189
00190
00191 sleep(1); if (system("/bin/sync")) LERROR("Cannot sync()");
00192 LINFO("/bin/sync complete");
00193
00194
00195
00196 while(et->isFixating()) ;
00197 while(d->checkForKey() != -1) ;
00198
00199
00200 d->displayRedDotFixation();
00201
00202
00203 d->checkForKey();
00204
00205
00206 if (!testrun.getVal())
00207 while(true)
00208 {
00209 if (et->isFixating()) break;
00210 if (d->checkForKey() != -1) break;
00211 }
00212
00213 int frame = 0;
00214 if (index[i] > -1) d->waitNextRequestedVsync(false, true);
00215 d->pushEvent(std::string("===== Playing movie: ") +
00216 fnames[i] + " =====");
00217
00218
00219 et->track(true);
00220
00221 if (index[i] > -1)
00222 {
00223
00224 d->createVideoOverlay(VIDFMT_YUV420P);
00225
00226
00227 while(cache.size())
00228 {
00229
00230 if (streaming) streaming = cacheFrame(mp, cache, hflip.getVal());
00231
00232
00233 VideoFrame vidframe = cache.back();
00234 if (keepfix.getVal())
00235 d->displayVideoOverlay_patch(vidframe, frame,
00236 SDLdisplay::NEXT_VSYNC, cx, cy,
00237 patch);
00238 else
00239 d->displayVideoOverlay(vidframe, frame,
00240 SDLdisplay::NEXT_VSYNC);
00241
00242 cache.pop_back();
00243 ++frame;
00244 }
00245
00246
00247
00248
00249
00250 d->destroyYUVoverlay();
00251 d->clearScreen();
00252 }
00253 else
00254 {
00255 d->clearScreen();
00256 usleep(rutz::rand_range<int>(itsRange.getVal().min(),
00257 itsRange.getVal().max()) * 1000);
00258 }
00259
00260
00261
00262 usleep(50000);
00263 et->track(false);
00264 }
00265
00266 d->clearScreen();
00267 LINFO("Experiment complete");
00268 }
00269 catch (...)
00270 {
00271 REPORT_CURRENT_EXCEPTION;
00272 };
00273
00274
00275 manager.stop();
00276
00277
00278 return 0;
00279 }
00280
00281
00282
00283
00284
00285