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
00039
00040
00041
00042 #include "Beowulf/Beowulf.H"
00043 #include "Component/ModelManager.H"
00044 #include "Devices/FrameGrabberConfigurator.H"
00045 #include "GUI/XWindow.H"
00046 #include "Image/ColorOps.H"
00047 #include "Image/DrawOps.H"
00048 #include "Image/Image.H"
00049 #include "Image/Pixels.H"
00050 #include "Image/ShapeOps.H"
00051 #include "Parallel/pvisionTCP-defs.H"
00052 #include "Transport/FrameIstream.H"
00053 #include "Util/Assert.H"
00054
00055 #include <signal.h>
00056
00057
00058
00059 #define NAVG 20
00060
00061 #define NSTAT 6
00062
00063
00064 #define PRESCALE 2
00065
00066 static bool goforever = true;
00067
00068
00069 void terminate(int s)
00070 { LERROR("*** INTERRUPT ***"); goforever = false; exit(1); }
00071
00072
00073 int main(const int argc, const char **argv)
00074 {
00075 MYLOGVERB = LOG_INFO;
00076
00077
00078 ModelManager manager("Parallel Vision TCP Version 2");
00079
00080
00081 nub::soft_ref<FrameGrabberConfigurator>
00082 gbc(new FrameGrabberConfigurator(manager));
00083 manager.addSubComponent(gbc);
00084
00085 nub::soft_ref<Beowulf>
00086 beo(new Beowulf(manager, "Beowulf Master", "BeowulfMaster", true));
00087 manager.addSubComponent(beo);
00088
00089
00090 if (manager.parseCommandLine(argc, argv, "<nframes> <framepause>", 2, 2)
00091 == false) return(1);
00092
00093
00094 nub::soft_ref<FrameIstream> gb = gbc->getFrameGrabber();
00095 if (gb.isInvalid())
00096 LFATAL("You need to select a frame grabber type via the "
00097 "--fg-type=XX command-line option for this program "
00098 "to be useful");
00099 int w = gb->getWidth(), h = gb->getHeight();
00100
00101 int nframes = manager.getExtraArgAs<int>(0);
00102 if (nframes < 1 || nframes > 2048) LFATAL("Invalid number of frames");
00103 uint64 framepause = manager.getExtraArgAs<uint64>(1);
00104 if (framepause < 1 || framepause > 2048) LFATAL("Invalid framepause");
00105
00106
00107 signal(SIGHUP, terminate); signal(SIGINT, terminate);
00108 signal(SIGQUIT, terminate); signal(SIGTERM, terminate);
00109 signal(SIGALRM, terminate);
00110
00111
00112 XWindow xw(gb->peekDims(), -1, -1, "USC Saliency Cam");
00113 int32 frame = 0;
00114 PixRGB<byte> pix(255, 255, 0);
00115 Point2D<int> win(w/2, h/2);
00116 int foa_size = std::min(w, h) / 12;
00117 TCPmessage rmsg;
00118 TCPmessage smsg;
00119 Timer tim;
00120 int t[NSTAT][NAVG], ff;
00121 int latency = 0, nlat = 0;
00122 int dropped = 0;
00123
00124
00125 Image< PixRGB<byte> > ima[nframes];
00126
00127
00128 manager.start();
00129
00130
00131 gb->startStream();
00132
00133
00134 while(goforever)
00135 {
00136
00137 tim.reset(); ff = frame % NAVG;
00138
00139
00140 int32 index = frame % nframes;
00141 ima[index] = gb->readRGB();
00142 t[0][ff] = tim.get();
00143
00144
00145 if (frame >= nframes)
00146 xw.drawImage(ima[(frame - nframes + 1) % nframes]);
00147 t[1][ff] = tim.get() - t[0][ff];
00148 if (t[1][ff] > 20)
00149 LINFO("*** Display took %dms for frame %d", t[1][ff], frame);
00150
00151
00152 if (dropped == 0)
00153 {
00154
00155 Image< PixRGB<byte> > tmpi = ima[index];
00156 tmpi = rescale(tmpi,
00157 tmpi.getWidth() >> PRESCALE,
00158 tmpi.getHeight() >> PRESCALE);
00159
00160
00161 int32 offset; if (frame & 1) offset = POFFSET; else offset = 0;
00162
00163
00164
00165 Image<byte> lum = luminance(tmpi);
00166 smsg.reset(frame, BEO_LUMINANCE);
00167 smsg.addImage(lum);
00168 beo->send(offset + 0, smsg);
00169
00170
00171 Image<byte> r, g, b, y; getRGBY(tmpi, r, g, b, y, (byte)25);
00172 smsg.reset(frame, BEO_REDGREEN);
00173 smsg.addImage(r); smsg.addImage(g);
00174 beo->send(offset + 1, smsg);
00175 smsg.reset(frame, BEO_BLUEYELLOW);
00176 smsg.addImage(b); smsg.addImage(y);
00177 beo->send(offset + 2, smsg);
00178
00179
00180 }
00181 t[2][ff] = tim.get() - t[1][ff] - t[0][ff];
00182
00183
00184 int32 rframe, raction, rnode = -1, recnb = 0;
00185 while(beo->receive(rnode, rmsg, rframe, raction, 5))
00186 {
00187
00188 latency += frame - rframe; nlat ++;
00189
00190
00191 switch(raction)
00192 {
00193 case BEO_WINNER:
00194 {
00195 const Fixation fix = rmsg.getElementFixation();
00196 win.i = fix.i; win.j = fix.j; rframe = fix.frame;
00197
00198
00199 if (rframe > frame - nframes)
00200 {
00201
00202
00203 win.i <<= PRESCALE;
00204 win.i += int(((1 << (PRESCALE - 1)) *
00205 float(rand()) ) / RAND_MAX);
00206 win.j <<= PRESCALE;
00207 win.j += int(((1 << (PRESCALE - 1)) *
00208 float(rand()) ) / RAND_MAX);
00209
00210
00211 int32 fidx = rframe % nframes;
00212 drawPatch(ima[fidx], win, 3, pix);
00213 drawCircle(ima[fidx], win, foa_size, pix, 3);
00214
00215 if (dropped) dropped --;
00216 }
00217 else
00218 {
00219 dropped += 3;
00220 LINFO(" dropping frame %d (%d) [now %d]; dropped = %d",
00221 rframe, rframe % nframes, frame, dropped);
00222 }
00223 }
00224 break;
00225 default:
00226 LERROR("Bogus action %d -- IGNORING.", raction);
00227 break;
00228 }
00229
00230 recnb ++; if (recnb > 4) break;
00231 }
00232 t[3][ff] = tim.get() - t[2][ff] - t[1][ff] - t[0][ff];
00233
00234
00235 if (ff == 1 && frame > 1)
00236 {
00237 int avg[NSTAT];
00238 for (int j = 0; j < NSTAT; j ++)
00239 {
00240 avg[j] = 0;
00241 for (int i = 0; i < NAVG; i ++) avg[j] += t[j][i];
00242 avg[j] /= NAVG;
00243 }
00244 if (nlat == 0) { latency = -1; nlat = 1; }
00245 LINFO("%.1ffps/%llxms [G=%d D=%d S=%d R=%d A=%d T=%d F=%d]",
00246 1000.0 / ((float)(avg[5])), framepause,
00247 avg[0], avg[1], avg[2], avg[3], avg[4], avg[5],
00248 latency / nlat);
00249 latency = 0; nlat = 0;
00250
00251 if (dropped) dropped --;
00252 }
00253 t[4][ff] = tim.get();
00254
00255
00256 while(tim.get() < framepause)
00257 {
00258 struct timespec ts, ts2;
00259 ts.tv_sec = 0; ts.tv_nsec = 1000000;
00260 nanosleep(&ts, &ts2);
00261 }
00262
00263 t[5][ff] = tim.get();
00264
00265
00266 frame++;
00267 }
00268
00269
00270
00271 manager.stop();
00272 exit(0);
00273 }
00274
00275
00276
00277
00278
00279