BufferedInputFrameSeries.C

Go to the documentation of this file.
00001 /*!@file Media/BufferedInputFrameSeries.C Buffered input with frames loaded in a worker thread */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Media/BufferedInputFrameSeries.C $
00035 // $Id: BufferedInputFrameSeries.C 9819 2008-06-17 05:48:53Z itti $
00036 //
00037 
00038 #ifndef MEDIA_BUFFEREDINPUTFRAMESERIES_C_DEFINED
00039 #define MEDIA_BUFFEREDINPUTFRAMESERIES_C_DEFINED
00040 
00041 #include "Media/BufferedInputFrameSeries.H"
00042 
00043 #include "Util/log.H"
00044 
00045 struct BufferedInputFrameSeries::Checkpoint
00046 {
00047   Checkpoint(int f, int q, int mq) : framenum(f), qsize(q), minqsize(mq) {}
00048 
00049   int framenum;
00050   int qsize;
00051   int minqsize;
00052 };
00053 
00054 // ######################################################################
00055 BufferedInputFrameSeries::
00056 BufferedInputFrameSeries(OptionManager& mgr, const size_t qsize,
00057                          const bool forcergb)
00058   :
00059   ModelComponent(mgr, "Input Buffer", "BufferedInputFrameSeries"),
00060   itsSrc(new InputFrameSeries(mgr)),
00061   itsFrameSpec(),
00062   itsQ(qsize),
00063   itsInputDone(false),
00064   itsStop(false),
00065   itsNumFilled(),
00066   itsMinNumFilled(int(qsize)),
00067   itsFrameNum(0),
00068   itsCheckpoints(),
00069   itsForceRGB(forcergb)
00070 {
00071   if (0 != pthread_mutex_init(&itsQmut, NULL))
00072     LFATAL("pthread_mutex_init() failed");
00073 
00074   this->addSubComponent(itsSrc);
00075 }
00076 
00077 // ######################################################################
00078 GenericFrameSpec BufferedInputFrameSeries::peekFrameSpec() const
00079 {
00080   if (!this->started())
00081     LFATAL("must be start()-ed before peekFrameSpec()");
00082 
00083   return itsFrameSpec;
00084 }
00085 
00086 // ######################################################################
00087 GenericFrame BufferedInputFrameSeries::get(bool* did_underflow)
00088 {
00089   GenericFrame result;
00090 
00091   const bool pop_ok = itsQ.pop_front(result);
00092 
00093   if (pop_ok)
00094     {
00095       const int n = itsNumFilled.atomic_decr_return();
00096       if (n < itsMinNumFilled)
00097         itsMinNumFilled = n;
00098     }
00099 
00100   if (did_underflow != 0)
00101     // we have premature underflow if the pop fails (!pop_ok) before
00102     // our underlying input source is finished (!itsInputDone):
00103     *did_underflow = (!pop_ok && !itsInputDone);
00104 
00105   if (++itsFrameNum % 100 == 0)
00106     itsCheckpoints.push_back
00107       (Checkpoint(itsFrameNum, itsNumFilled.atomic_get(),
00108                   itsMinNumFilled));
00109 
00110   return result;
00111 }
00112 
00113 // ######################################################################
00114 void BufferedInputFrameSeries::start2()
00115 {
00116   itsFrameSpec = itsSrc->peekFrameSpec();
00117 
00118   if (0 != pthread_create(&itsFillThread, NULL, &c_fill,
00119                           static_cast<void*>(this)))
00120     LFATAL("pthread_create() failed");
00121 
00122   itsMinNumFilled = int(itsQ.size());
00123   itsFrameNum = 0;
00124   itsCheckpoints.clear();
00125 }
00126 
00127 // ######################################################################
00128 void BufferedInputFrameSeries::stop1()
00129 {
00130   itsStop = true;
00131 
00132   if (0 != pthread_join(itsFillThread, NULL))
00133     LERROR("pthread_join() failed");
00134 
00135   for (std::list<Checkpoint>::const_iterator
00136          itr = itsCheckpoints.begin(), stop = itsCheckpoints.end();
00137        itr != stop; ++itr)
00138     {
00139       LINFO("checkpoint frame %06d - queue fill : %d/%d (min %d)",
00140             (*itr).framenum, (*itr).qsize, int(itsQ.size()),
00141             (*itr).minqsize);
00142     }
00143 }
00144 
00145 // ######################################################################
00146 void* BufferedInputFrameSeries::c_fill(void* p)
00147 {
00148   try
00149     {
00150       BufferedInputFrameSeries* const b =
00151         static_cast<BufferedInputFrameSeries*>(p);
00152 
00153       while (true)
00154         {
00155           if (b->itsStop)
00156             break;
00157 
00158           // get the next frame:
00159           const FrameState is = b->itsSrc->updateNext();
00160           if (is == FRAME_COMPLETE)
00161             {
00162               b->itsInputDone = true;
00163               return NULL;
00164             }
00165 
00166           GenericFrame f = b->itsSrc->readFrame();
00167           if (!f.initialized())
00168             {
00169               b->itsInputDone = true;
00170               return NULL;
00171             }
00172 
00173           // do we want to force the frame to have a native type of RGB?
00174           if (b->itsForceRGB)
00175             f = GenericFrame(f.asRgb());
00176 
00177           // now try to push it onto the queue (and just keep
00178           // re-trying if the push fails due to the queue being full):
00179           while (true)
00180             {
00181               if (b->itsStop)
00182                 break;
00183 
00184               if (b->itsQ.push_back(f) == true)
00185                 {
00186                   b->itsNumFilled.atomic_incr();
00187                   break;
00188                 }
00189 
00190               usleep(20000);
00191             }
00192         }
00193     }
00194   catch (...)
00195     {
00196       REPORT_CURRENT_EXCEPTION;
00197       exit(1);
00198     }
00199 
00200   return NULL;
00201 }
00202 
00203 // ######################################################################
00204 /* So things look consistent in everyone's emacs... */
00205 /* Local Variables: */
00206 /* mode: c++ */
00207 /* indent-tabs-mode: nil */
00208 /* End: */
00209 
00210 #endif // MEDIA_BUFFEREDINPUTFRAMESERIES_C_DEFINED
Generated on Sun May 8 08:05:20 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3