PARP Research Group University of Murcia, Spain


src/qvio/qvmplayerproxy.h

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007, 2008. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00024 
00025 #ifndef QVMPLAYERPROXY_H
00026 #define QVMPLAYERPROXY_H
00027 
00028 #include <QProcess>
00029 #include <QString>
00030 #include <QUrl>
00031 #include <QThread>
00032 #include <QMutex>
00033 #include <QWaitCondition>
00034 #include <QFile>
00035 #include <QTimer>
00036 #include <QQueue>
00037 
00038 #include <QVCamera>
00039 #include <qvutils/qnamedpipe.h>
00040 
00041 #ifndef DOXYGEN_IGNORE_THIS
00042 // Auxiliary QVCheckOKMPlayerCamera Class.
00043 // This is an internal convenience thread used only to unblock the open function
00044 // when it is waiting for mplayer to read from the fifo, in the case when
00045 // mplayer aborted when starting (due to bad URL, or wrong file format, for
00046 // example).
00047 
00048 class QVCheckOKMplayerCamera: public QThread
00049 {
00050         Q_OBJECT
00051         public:
00052                 QVCheckOKMplayerCamera(QFile & fifo_file,int max_time_ms_to_wait_for_open);
00053                 void run();
00054         private slots:
00055                 void writeErrorInFifo();
00056         private:
00057                 QFile & _fifo_file;
00058                 int _max_time_ms_to_wait_for_open;
00059 };
00060 
00061 // Auxiliary QVCameraThread Class.
00062 // This is an internal convenience thread used in real time cameras to keep
00063 // updating the frames from mplayer independently of the user grabs.
00064 
00065 class QVCameraThread: public QThread
00066         {
00067         Q_OBJECT
00068         public:
00069                 QVCameraThread(QObject *object,char *slot);
00070                 ~QVCameraThread();
00071                 void run();
00072         private:
00073                 QObject *_object;
00074                 char *_slot;
00075         };
00076 
00077 // Auxiliary QVMPlayerIOProcessor class.
00078 // Auxiliary class to communicate through stdin and stdout with mplayer, and
00079 // read data such as the number of rows and cols of the video, the fps, and also
00080 // to send commands such as pausing, ask for current position, and so on.
00081 
00082 class QVMPlayerIOProcessor: public QObject
00083         {
00084         Q_OBJECT
00085         public:
00086                 QVMPlayerIOProcessor(QProcess *mplayer);
00087                 ~QVMPlayerIOProcessor();
00088                 void queueCommandToMPlayer(const QString &, bool ifEmpty = false);
00089                 double fps, speed, time_length, time_pos;
00090                 uInt cols, rows;
00091         public slots:
00092                 int interpretMPlayerOutput();
00093         private slots:
00094                 void sendCommandToMPlayer();
00095         private:
00096                 QQueue<QString> command_queue;
00097                 QMutex command_queue_mutex;
00098                 QProcess *mplayer;
00099         };
00100 
00101 // Auxiliary QVMPlayerFrameGrabber Class.
00102 class QVMPlayerFrameGrabber: public QObject
00103         {
00104         Q_OBJECT
00105 
00106         public:
00107                 QVMPlayerFrameGrabber(  QVMPlayerIOProcessor *, QString pipeName, bool realTime, const uInt waitMilisecs);
00108                 ~QVMPlayerFrameGrabber();
00109 
00110                 void getQVImageGray(QVImage<uChar> &imgGray) const;
00111                 void getQVImageYUV(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV) const;
00112 
00113                 void updateFrameBuffer();
00114 
00115                 bool isFinished()       const   { return finished; }
00116                 bool framesRead()       const   { return frames_read; }
00117 
00118         public slots:
00119                 void updateSlot();
00120 
00121         signals:
00122                 void newReadFrameGrabber();
00123                 // This signal is to defer the call to sendCommandToMplayer, and avoid
00124                 // the "QSocketNotifier:: socket notifier cannot be enabled from another
00125                 // thread" warning:
00126                 void sendCommandSignal();
00127 
00128         private:
00129                 QVCameraThread *qvcamerathread;
00130                 QFile fifoInput;        
00131                 QVMPlayerIOProcessor *mplayerIOProcessor;
00132 
00133                 QMutex mutex;
00134                 QWaitCondition condition;
00135                 
00136                 uInt frames_read;
00137                 bool finished, realTime, inited;
00138                 //bool debug_in_memcpy, debug_in_updateSlot;
00139 
00140                 QVImage<uChar> imgY, imgU, imgV, img_auxY, img_auxU,  img_auxV;
00141         };
00142 #endif
00143 
00144 // This is for doxygen get the detailed description for QVMPlayerProxy correctly.
00145 //class QVWorker;
00146 
00234 class QVMPlayerProxy : public QObject
00235         {
00236         Q_OBJECT
00237         public:
00239                 QVMPlayerProxy(QString name = QString());
00241                 ~QVMPlayerProxy();
00242 
00243                 // Camera opening options as flags. Combine using | operator to create
00244                 // an OpenOptions flags (observe plural) object:
00246                 enum OpenOption {
00248                         Default = 0x0,
00250                         RealTime = 0x1,
00252                         Deinterlaced = 0x2,
00254                         NoLoop = 0x4,
00256                         RGBMEncoder = 0x8
00257                 };
00258 
00259                 Q_DECLARE_FLAGS(OpenOptions,OpenOption);
00260 
00269                 bool openCam(const QString & urlstring, OpenOptions opts = Default, unsigned int r = 0, unsigned int c = 0);
00270 
00276                 bool grab(QVImage<uChar,3> &image);
00277 
00283                 bool grab(QVImage<uChar,1> &image);
00284 
00296                 bool grab(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV);
00297 
00301                 const QString getUrlBase() const                { return path.split("/").last(); }
00302 
00305                 OpenOptions getOptions() const                  { return open_options; };
00306 
00309                 unsigned int getFramesUpdated() const           { return mplayerFrameGrabber->framesRead(); }
00310 
00313                 unsigned int getRows() const                    { return mplayerIOProcessor->rows; };
00314 
00317                 unsigned int getCols() const                    { return mplayerIOProcessor->cols; };
00318 
00321                 double getFPS() const                           { return mplayerIOProcessor->fps; };
00322 
00325                 double getTimeLength() const                    { return mplayerIOProcessor->time_length; };
00326 
00329                 double getTimePos() const                       { return mplayerIOProcessor->time_pos; };
00330 
00333                 double getSpeed() const                         { return mplayerIOProcessor->speed; };
00334 
00337                 unsigned int getFramesGrabbed() const           { return frames_grabbed; };
00338 
00341                 unsigned int getFramesRead() const              { return mplayerFrameGrabber->framesRead(); };
00342 
00345                 bool isLiveCamera() const                       { return live_camera; };
00346 
00347                 QVCamera::TCameraStatus getCameraStatus() const { return status; };
00348                 bool isClosed() const { return status == QVCamera::Closed; };
00349                 bool isRunning() const { return status == QVCamera::Running; };
00350                 bool isRunningOneStep() const { return status == QVCamera::RunningOneStep; };
00351                 bool isPaused() const { return status == QVCamera::Paused; };
00352 
00353         public slots:
00354 
00356                 void pauseCam()                                         { pauseCamSlot(); }
00357 
00359                 void unpauseCam()                                       { unpauseCamSlot(); }
00360 
00362                 void nextFrameCam()                                     { nextFrameCamSlot(); }
00363 
00366                 void setSpeedCam(double d)                              { setSpeedCam(d); }
00367 
00374                 void seekCam(QVCamera::TSeekType type, double pos)      { seekCamSlot(type, pos); }
00375 
00377                 void closeCam();
00378 
00379                 void pauseCamSlot();
00380                 void unpauseCamSlot();
00381                 void nextFrameCamSlot();
00382                 void setSpeedCamSlot(double d);
00383                 void seekCamSlot(QVCamera::TSeekType type, double pos);
00384 
00385 
00386         signals:
00387                 // This signal is to defer the call to sendCommandToMplayer, and avoid
00388                 // the "QSocketNotifier:: socket notifier cannot be enabled from another
00389                 // thread" warning:
00390                 void sendCommandSignal();
00391                 void newGrab();
00392                 void newRead();
00393                 void camClosed();
00394                 void camOpened();
00395                 void statusChange(QVCamera::TCameraStatus);
00396 
00397         private:
00398                 // this boolean value becomes true if any RGB image is linked to the camera, from a worker.
00399                 //bool rgbMode;
00400                 QVCamera::TCameraStatus status;
00401 
00402                 OpenOptions open_options;
00403                 QVMPlayerFrameGrabber * mplayerFrameGrabber;
00404                 QVMPlayerIOProcessor * mplayerIOProcessor;
00405 
00406                 QNamedPipe *namedPipe;                  // The named fifo;
00407                 QProcess mplayer;                       // mplayer and mencoder processes;
00408 
00409                 void initMPlayerArgs(QString urlString, unsigned int rows, unsigned int cols);
00410                 bool performGrab();
00411 
00412                 QStringList mplayer_args;               // MPlayer arguments
00413                 QString path, schema;                   // path and schema extracted from the URL
00414                 
00415                 bool live_camera;
00416                 int frames_grabbed;
00417 
00418                 void setStatus(QVCamera::TCameraStatus status) 
00419                         { this->status = status; emit statusChange(status); }
00420         };
00421 
00422 // Camera opening flags | operator:
00423 Q_DECLARE_OPERATORS_FOR_FLAGS(QVMPlayerProxy::OpenOptions)
00424 
00425 #endif
00426 
00427 
00428 
00429 



QVision framework. PARP research group, copyright 2007, 2008.