psycho-movie-fixicon.C
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 #include "Component/ModelManager.H"
00038 #include "Image/Image.H"
00039 #include "Raster/Raster.H"
00040 #include "Media/MPEGStream.H"
00041 #include "Media/MediaOpts.H"
00042 #include "Psycho/PsychoDisplay.H"
00043 #include "Psycho/EyeTrackerConfigurator.H"
00044 #include "Psycho/EyeTracker.H"
00045 #include "Psycho/PsychoOpts.H"
00046 #include "Component/EventLog.H"
00047 #include "Component/ComponentOpts.H"
00048 #include "Util/MathFunctions.H"
00049 #include "Util/Types.H"
00050 #include "Video/VideoFrame.H"
00051 #include "rutz/time.h"
00052
00053 #include <deque>
00054
00055 #define CACHELEN 150
00056
00057
00058 static bool cacheFrame(nub::soft_ref<InputMPEGStream>& mp,
00059 std::deque<VideoFrame>& cache)
00060 {
00061 const VideoFrame frame = mp->readVideoFrame();
00062 if (!frame.initialized()) return false;
00063
00064 cache.push_front(frame);
00065 return true;
00066 }
00067
00068
00069 static int submain(const int argc, char** argv)
00070 {
00071 MYLOGVERB = LOG_INFO;
00072
00073
00074 ModelManager manager("Psycho Movie");
00075
00076
00077 nub::soft_ref<InputMPEGStream> mp
00078 (new InputMPEGStream(manager, "Input MPEG Stream", "InputMPEGStream"));
00079 manager.addSubComponent(mp);
00080
00081 nub::soft_ref<EventLog> el(new EventLog(manager));
00082 manager.addSubComponent(el);
00083
00084 nub::soft_ref<EyeTrackerConfigurator>
00085 etc(new EyeTrackerConfigurator(manager));
00086 manager.addSubComponent(etc);
00087
00088 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00089 manager.addSubComponent(d);
00090
00091 manager.setOptionValString(&OPT_InputMPEGStreamPreload, "true");
00092 manager.setOptionValString(&OPT_EventLogFileName, "psychodata.psy");
00093 manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00094
00095
00096 if (manager.parseCommandLine(argc, argv,
00097 "<movie1.mpg> ... <movieN.mpg>", 1, -1)==false)
00098 return(1);
00099
00100
00101 nub::soft_ref<EyeTracker> et = etc->getET();
00102 d->setEyeTracker(et);
00103 d->setEventLog(el);
00104 et->setEventLog(el);
00105
00106
00107 if (etc->getModelParamString("EyeTrackerType").compare("EL") == 0)
00108 d->setModelParamVal("SDLslaveMode", true);
00109
00110
00111 manager.start();
00112
00113
00114 int key;
00115 do {
00116 d->displayRandomText(7, 6);
00117 key = d->waitForKey(true);
00118 } while(key == 114 || key == 101 || key == 116 || key == 102);
00119
00120
00121 d->pushEventBegin("Calibration");
00122 et->calibrate(d);
00123 d->pushEventEnd("Calibration");
00124
00125
00126 Image< PixRGB<byte> > fixicon =
00127 Raster::ReadRGB(d->getModelParamString("PsychoDisplayFixationIcon"));
00128
00129
00130 if (etc->getModelParamString("EyeTrackerType").compare("EL") == 0){
00131 et->closeSDL();
00132 d->openDisplay();
00133 LINFO("Switching SDL: Eyelink-->iLab");
00134 }else{
00135 d->clearScreen();
00136 }
00137
00138 d->displayText("Press any key to start......");
00139 d->waitForKey(true);
00140
00141
00142 uint nbmovies = manager.numExtraArgs(); int index[nbmovies];
00143 for (uint i = 0; i < nbmovies; i ++) index[i] = i;
00144 LINFO("Randomizing movies...");
00145 randShuffle(index,nbmovies);
00146
00147
00148 int x, y, w, h;
00149 for (uint i = 0; i < nbmovies; i ++)
00150 {
00151
00152 d->clearScreen();
00153 bool streaming = true;
00154 LINFO("Buffering '%s'...", manager.getExtraArg(index[i]).c_str());
00155 mp->setFileName(manager.getExtraArg(index[i]));
00156
00157
00158 w = mp->getWidth();
00159 h = mp->getHeight();
00160 x = (d->getWidth()-w)/2;
00161 y = (d->getHeight()-h)/2;
00162
00163 std::deque<VideoFrame> cache;
00164 for (uint j = 0; j < CACHELEN; j ++)
00165 {
00166 streaming = cacheFrame(mp, cache);
00167 if (streaming == false) break;
00168 }
00169 LINFO("'%s' ready.", manager.getExtraArg(index[i]).c_str());
00170
00171
00172 sleep(1); if (system("/bin/sync")) LERROR("error in sync");
00173
00174
00175 d->displayFixationIcon(fixicon);
00176
00177
00178 d->waitForKey(true); int frame = 0;
00179 d->waitNextRequestedVsync(false, true);
00180 d->pushEvent(std::string("===== Playing movie: ") +
00181 manager.getExtraArg(index[i]) + " =====");
00182
00183
00184 et->track(true);
00185
00186
00187 d->displayFixationIconBlink(fixicon);
00188
00189
00190 d->createVideoOverlay(VIDFMT_YUV420P,mp->getWidth(),mp->getHeight());
00191
00192
00193 rutz::time start = rutz::time::wall_clock_now();
00194 while(cache.size())
00195 {
00196
00197 if (streaming) streaming = cacheFrame(mp, cache);
00198
00199
00200 VideoFrame vidframe = cache.back();
00201 d->displayVideoOverlay_pos(vidframe, frame,
00202 SDLdisplay::NEXT_VSYNC,
00203 x, y, w, h);
00204 cache.pop_back();
00205
00206 ++frame;
00207 }
00208 rutz::time stop = rutz::time::wall_clock_now();
00209 const double secs = (stop-start).sec();
00210 LINFO("%d frames in %.04f sec (~%.04f fps)", frame, secs, frame/secs);
00211
00212
00213
00214
00215
00216 d->destroyYUVoverlay();
00217 d->clearScreen();
00218
00219
00220 usleep(50000);
00221 et->track(false);
00222
00223
00224 if (i<nbmovies-1){
00225 if (etc->getModelParamString("EyeTrackerType").compare("EL") == 0){
00226 d->closeDisplay();
00227 et->openSDL();
00228 if ((i+1)%10 == 0){
00229
00230 d->clearScreen();
00231 d->displayText("Please Take a Break");
00232 d->waitForKey(true);
00233 d->displayText("Calibration");
00234 d->pushEventBegin("Calibration");
00235 et->calibrate(d);
00236 d->pushEventEnd("Calibration");
00237 }else{
00238 et->recalibrate(d,13);
00239 }
00240
00241
00242
00243 LINFO("Switching SDL for quick calibration");
00244 }else{
00245
00246 et->recalibrate(d,13);
00247 }
00248 }
00249 }
00250
00251 d->clearScreen();
00252 d->displayText("Experiment complete. Thank you!");
00253 d->waitForKey(true);
00254
00255
00256 manager.stop();
00257
00258
00259 return 0;
00260 }
00261
00262
00263 extern "C" int main(const int argc, char** argv)
00264 {
00265
00266
00267
00268
00269 try
00270 {
00271 return submain(argc, argv);
00272 }
00273 catch (...)
00274 {
00275 REPORT_CURRENT_EXCEPTION;
00276 }
00277
00278 return 1;
00279 }
00280
00281
00282
00283
00284
00285