psycho-movie.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 "Image/Image.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 et->calibrate(d);
00115
00116 if (etc->getModelParamString("EyeTrackerType").compare("EL") == 0){
00117 et->closeSDL();
00118 d->openDisplay();
00119 LINFO("Switching SDL: Eyelink-->iLab");
00120 }else{
00121 d->clearScreen();
00122 }
00123
00124 d->displayText("<SPACE> for random play; other key for ordered");
00125 int c = d->waitForKey(true);
00126
00127
00128 uint nbmovies = manager.numExtraArgs(); int index[nbmovies];
00129 for (uint i = 0; i < nbmovies; i ++) index[i] = i;
00130 if (c == ' ') { LINFO("Randomizing movies..."); randShuffle(index,nbmovies);}
00131
00132
00133 for (uint i = 0; i < nbmovies; i ++)
00134 {
00135
00136 d->clearScreen();
00137 bool streaming = true;
00138 LINFO("Buffering '%s'...", manager.getExtraArg(index[i]).c_str());
00139 mp->setFileName(manager.getExtraArg(index[i]));
00140
00141 std::deque<VideoFrame> cache;
00142 for (uint j = 0; j < CACHELEN; j ++)
00143 {
00144 streaming = cacheFrame(mp, cache);
00145 if (streaming == false) break;
00146 }
00147 LINFO("'%s' ready.", manager.getExtraArg(index[i]).c_str());
00148
00149
00150 sleep(1); if (system("/bin/sync")) LERROR("error in sync()");
00151
00152
00153 d->displayFixation();
00154
00155
00156 d->waitForKey(true); int frame = 0;
00157 d->waitNextRequestedVsync(false, true);
00158 d->pushEvent(std::string("===== Playing movie: ") +
00159 manager.getExtraArg(index[i]) + " =====");
00160
00161
00162 et->track(true);
00163
00164
00165 d->displayFixationBlink();
00166
00167
00168 d->createVideoOverlay(VIDFMT_YUV420P,mp->getWidth(),mp->getHeight());
00169
00170
00171 rutz::time start = rutz::time::wall_clock_now();
00172 while(cache.size())
00173 {
00174
00175 if (streaming) streaming = cacheFrame(mp, cache);
00176
00177
00178 VideoFrame vidframe = cache.back();
00179 d->displayVideoOverlay(vidframe, frame,
00180 SDLdisplay::NEXT_VSYNC);
00181 cache.pop_back();
00182
00183 ++frame;
00184 }
00185 rutz::time stop = rutz::time::wall_clock_now();
00186 const double secs = (stop-start).sec();
00187 LINFO("%d frames in %.04f sec (~%.04f fps)", frame, secs, frame/secs);
00188
00189
00190
00191
00192
00193 d->destroyYUVoverlay();
00194 d->clearScreen();
00195
00196
00197 usleep(50000);
00198 et->track(false);
00199
00200 if (i<nbmovies-1){
00201 if (etc->getModelParamString("EyeTrackerType").compare("EL") == 0){
00202 d->closeDisplay();
00203 et->openSDL();
00204
00205 et->recalibrate(d,13);
00206 et->calibrate(d);
00207
00208 et->closeSDL();
00209 d->openDisplay();
00210 LINFO("Switching SDL for quick calibration");
00211 }else{
00212
00213 et->recalibrate(d,13);
00214 }
00215 }
00216 }
00217
00218 d->clearScreen();
00219 d->displayText("Experiment complete. Thank you!");
00220 d->waitForKey(true);
00221
00222
00223 manager.stop();
00224
00225
00226 return 0;
00227 }
00228
00229
00230 extern "C" int main(const int argc, char** argv)
00231 {
00232
00233
00234
00235
00236 try
00237 {
00238 return submain(argc, argv);
00239 }
00240 catch (...)
00241 {
00242 REPORT_CURRENT_EXCEPTION;
00243 }
00244
00245 return 1;
00246 }
00247
00248
00249
00250
00251
00252