QtDisplayStream.C

Go to the documentation of this file.
00001 /*!@file GUI/QtDisplayStream.C FrameOstream subclass that displays images in a QWidgetStack */
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/GUI/QtDisplayStream.C $
00035 // $Id: QtDisplayStream.C 12269 2009-12-17 01:23:34Z itti $
00036 //
00037 
00038 #ifndef GUI_QTDISPLAYSTREAM_C_DEFINED
00039 #define GUI_QTDISPLAYSTREAM_C_DEFINED
00040 
00041 #ifdef INVT_HAVE_QT3
00042 
00043 #include "GUI/QtDisplayStream.H"
00044 
00045 #include "Component/GlobalOpts.H"
00046 #include "Component/ModelOptionDef.H"
00047 #include "GUI/QtImageStack.H"
00048 #include "Image/Image.H"
00049 #include "Image/Pixels.H"
00050 #include "QtUtil/ImageConvert.H"
00051 #include "QtUtil/Util.H" // for argv2qt()
00052 #include "Transport/FrameOstreamFactory.H"
00053 #include "Transport/TransportOpts.H"
00054 #include "Util/sformat.H"
00055 
00056 #include <qapplication.h>
00057 #include <qpixmap.h>
00058 
00059 // Used by: QtDisplayStream
00060 const ModelOptionDef OPT_QdisplayEcho =
00061   { MODOPT_ARG_STRING, "QdisplayEcho", &MOC_OUTPUT, OPTEXP_CORE,
00062     "Optional output destination for screen-grabs of the Qt display frames.",
00063     "qdisplay-echo", '\0', "<raster|display|mpeg|none>", "none" };
00064 
00065 // Used by: QtDisplayStream
00066 const ModelOptionDef OPT_QdisplayPrefDims =
00067   { MODOPT_ARG(Dims), "QdisplayPrefDims", &MOC_OUTPUT, OPTEXP_CORE,
00068     "Preferred scaled dimensions for Qt display frames, "
00069     "or 0x0 for no preference",
00070     "qdisplay-pref-dims", '\0', "<WxH>", "640x480" };
00071 
00072 // Used by: QtDisplayStream
00073 const ModelOptionDef OPT_QdisplayPrefMaxDims =
00074   { MODOPT_ARG(Dims), "QdisplayPrefMaxDims", &MOC_OUTPUT, OPTEXP_CORE,
00075     "If an image larger than these dimensions is sent to a Qt display "
00076     "frame, initially scale it down to smaller than these dimensions "
00077     "(you can always scale it up later by using the buttons on the "
00078     "Qt display widget",
00079     "qdisplay-pref-max-dims", '\0', "<WxH>", "1600x1200" };
00080 
00081 namespace
00082 {
00083   QApplication* qapp = 0;
00084 
00085   pthread_once_t qapp_init_once = PTHREAD_ONCE_INIT;
00086   pthread_t qapp_thread;
00087 
00088   void* qapp_thread_run(void* app)
00089   {
00090     QApplication* a = static_cast<QApplication*>(app);
00091 
00092     //a->connect(a, SIGNAL(lastWindowClosed()),
00093     //           a, SLOT(quit()));
00094 
00095     const int result = a->exec();
00096     LDEBUG("QApplication exit status %d", result);
00097     return reinterpret_cast<void*>(result);
00098   }
00099 
00100   void qapp_thread_init()
00101   {
00102     ASSERT(qapp == 0);
00103 
00104     const char* dpy = getenv("DISPLAY");
00105     const bool havedpy = (dpy != 0 && dpy[0] != '\0');
00106     if (!havedpy)
00107       {
00108         if (setenv("DISPLAY", ":0.0", 1) == 0)
00109           LINFO("the DISPLAY environment variable is not set; "
00110                 "assuming DISPLAY=\":0.0\"");
00111         else
00112           LFATAL("the DISPLAY environment variable is not set; "
00113                  "can't use Qt without a DISPLAY");
00114       }
00115 
00116     // NOTE, there is a QApplication constructor that takes a 'bool
00117     // usegui' parameter that specifies whether or not a DISPLAY is
00118     // available; however we can't just pass usegui=false here,
00119     // because we'd still need a way to avoid constructing any QWidget
00120     // objects
00121 
00122     int argc = 1;
00123     const char* argv[2] = { "QtDisplayStream", 0 };
00124     qapp = new QApplication(argc, argv2qt(argc, argv));
00125 
00126     if (0 != pthread_create(&qapp_thread, NULL, &qapp_thread_run, qapp))
00127       LFATAL("couldn't create thread for QApplication");
00128   }
00129 }
00130 
00131 // ######################################################################
00132 class QAppLockClass
00133 {
00134 public:
00135   QAppLockClass(QApplication* qapp) : itsApp(qapp)
00136   {
00137     itsApp->lock();
00138   }
00139 
00140   ~QAppLockClass()
00141   {
00142     itsApp->unlock();
00143   }
00144 
00145 private:
00146   QAppLockClass(const QAppLockClass&);
00147   QAppLockClass& operator=(const QAppLockClass&);
00148 
00149   QApplication* itsApp;
00150 };
00151 
00152 // ######################################################################
00153 #define QAPP_LOCK(qapp) QAppLockClass anonymous_qapp_lock_(qapp)
00154 
00155 // ######################################################################
00156 QtDisplayStream::QtDisplayStream(OptionManager& mgr,
00157                                  const std::string& descrName,
00158                                  const std::string& tagName)
00159   :
00160   FrameOstream(mgr, descrName, tagName),
00161   itsQtEcho(&OPT_QdisplayEcho, this),
00162   itsPreferredDims(&OPT_QdisplayPrefDims, this),
00163   itsPreferredMaxDims(&OPT_QdisplayPrefMaxDims, this),
00164   itsTestMode(&OPT_TestMode, this),
00165   itsWidget(0),
00166   itsShown(false),
00167   itsFrameNumber(-1),
00168   itsEcho()
00169 {
00170   pthread_once(&qapp_init_once, &qapp_thread_init);
00171 
00172   ASSERT(qapp != 0);
00173 
00174   QAPP_LOCK(qapp);
00175   itsWidget = new QtImageStack;
00176 }
00177 
00178 // ######################################################################
00179 QtDisplayStream::~QtDisplayStream()
00180 {
00181   itsWidget->deleteLater();
00182 }
00183 
00184 // ######################################################################
00185 void QtDisplayStream::paramChanged(ModelParamBase* const param,
00186                                    const bool valueChanged,
00187                                    ParamClient::ChangeStatus* status)
00188 {
00189   FrameOstream::paramChanged(param, valueChanged, status);
00190 
00191   if (param == &itsQtEcho && itsQtEcho.getVal().length() > 0)
00192     {
00193       if (itsQtEcho.getVal().compare("none") == 0)
00194         {
00195           if (itsEcho.is_valid())
00196             this->removeSubComponent(*itsEcho);
00197 
00198           itsEcho = nub::soft_ref<FrameOstream>();
00199         }
00200       else
00201         {
00202           itsEcho = makeFrameOstream(itsQtEcho.getVal(),
00203                                      this->getManager());
00204           this->addSubComponent(itsEcho);
00205           itsEcho->exportOptions(MC_RECURSE);
00206         }
00207     }
00208   else if (param == &itsPreferredDims)
00209     {
00210       itsWidget->setPreferredDims(itsPreferredDims.getVal());
00211     }
00212   else if (param == &itsPreferredMaxDims)
00213     {
00214       itsWidget->setPreferredMaxDims(itsPreferredMaxDims.getVal());
00215     }
00216 }
00217 
00218 // ######################################################################
00219 bool QtDisplayStream::setFrameNumber(int n)
00220 {
00221   if (itsFrameNumber != n)
00222     {
00223       if (itsEcho.is_valid())
00224         {
00225           QAPP_LOCK(qapp);
00226           QPixmap pixmap = QPixmap::grabWidget(itsWidget);
00227           Image<PixRGB<byte> > img = convertToImage(pixmap);
00228           itsEcho->setFrameNumber(n);
00229           itsEcho->writeRGB(img, "qtecho");
00230         }
00231 
00232       itsFrameNumber = n;
00233     }
00234 
00235   return itsWidget->setFrameNumber(n);
00236 }
00237 
00238 // ######################################################################
00239 void QtDisplayStream::writeFrame(const GenericFrame& frame,
00240                                  const std::string& shortname,
00241                                  const FrameInfo& auxinfo)
00242 {
00243   QAPP_LOCK(qapp);
00244   itsWidget->addFrame(frame, shortname, auxinfo);
00245   if (!itsShown && !itsTestMode.getVal())
00246     { itsShown = true; itsWidget->show(); }
00247 }
00248 
00249 // ######################################################################
00250 bool QtDisplayStream::isVoid() const
00251 {
00252   return itsWidget->isClosed();
00253 }
00254 
00255 // ######################################################################
00256 void QtDisplayStream::closeStream(const std::string& shortname)
00257 {
00258   QAPP_LOCK(qapp);
00259   itsWidget->removeFrame(shortname);
00260 }
00261 
00262 // ######################################################################
00263 bool QtDisplayStream::isClosed() const
00264 {
00265   return itsWidget->isClosed();
00266 }
00267 
00268 #endif // INVT_HAVE_QT3
00269 
00270 // ######################################################################
00271 /* So things look consistent in everyone's emacs... */
00272 /* Local Variables: */
00273 /* mode: c++ */
00274 /* indent-tabs-mode: nil */
00275 /* End: */
00276 
00277 #endif // GUI_QTDISPLAYSTREAM_C_DEFINED
Generated on Sun May 8 08:04:48 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3