src/qvmplayercamera/qvmplayercamera.h

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007. 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 MPLAYERCAMERA_H
00026 #define MPLAYERCAMERA_H
00027 
00028 #include <QObject>
00029 #include <QProcess>
00030 #include <QString>
00031 #include <QList>
00032 #include <QUrl>
00033 #include <QThread>
00034 #include <QMutex>
00035 #include <QWaitCondition>
00036 #include <QFile>
00037 #include <QTimer>
00038 #include <QQueue>
00039 
00040 #include <qvcore/qvcamera.h>
00041 #include <qvutils/qnamedpipe.h>
00042 
00044 
00045 class QVWorker;
00046 
00047 /******************* Auxiliary QVCheckOKMPlayerCamera Class *******************/
00048 // This is an internal convenience thread used only to unblock the open function
00049 // when it is waiting for mplayer to read from the fifo, in the case when
00050 // mplayer aborted when starting (due to bad URL, or wrong file format, for
00051 // example).
00052 class QVCheckOKMplayerCamera: public QThread
00053 {
00054         Q_OBJECT
00055         public:
00056                 QVCheckOKMplayerCamera(QFile & fifo_file,int max_time_ms_to_wait_for_open);
00057                 ~QVCheckOKMplayerCamera();
00058                 void run();
00059         private slots:
00060                 void writeErrorInFifo();
00061         private:
00062                 QFile & _fifo_file;
00063                 int _max_time_ms_to_wait_for_open;
00064 };
00065 
00066 
00067 /********************* Auxiliary QVCameraThread Class *************************/
00068 // This is an internal convenience thread used in real time cameras to keep
00069 // updating the frames from mplayer independently of the user grabs.
00070 class QVCameraThread: public QThread
00071         {
00072         Q_OBJECT
00073         public:
00074                 QVCameraThread(QObject *object,char *slot);
00075                 ~QVCameraThread();
00076                 void run();
00077         private:
00078                 QObject *_object;
00079                 char *_slot;
00080         };
00081 
00082 /********************* Auxiliary QVMPlayerIOProcessor class *******************/
00083 // Auxiliary class to communicate through stdin and stdout with mplayer, and
00084 // read data such as the number of rows and cols of the video, the fps, and also
00085 // to send commands such as pausing, ask for current position, and so on.
00086 class QVMPlayerIOProcessor: public QObject
00087         {
00088         Q_OBJECT
00089         public:
00090                 QVMPlayerIOProcessor(QProcess *mplayer);
00091                 ~QVMPlayerIOProcessor();
00092                 void queueCommandToMPlayer(const QString &, bool ifEmpty = false);
00093                 double fps, speed, time_length, time_pos;
00094                 uInt cols, rows;
00095         public slots:
00096                 int interpretMPlayerOutput();
00097         private slots:
00098                 void sendCommandToMPlayer();
00099         private:
00100                 QQueue<QString> command_queue;
00101                 QMutex command_queue_mutex;
00102                 QProcess *mplayer;
00103         };
00104 
00105 /******************* Auxiliary QVMPlayerFrameGrabber Class ********************/
00106 class QVMPlayerFrameGrabber : public QObject
00107         {
00108         Q_OBJECT
00109 
00110         public:
00111                 QVMPlayerFrameGrabber(QVMPlayerIOProcessor *, QFile *, uInt rows, uInt cols, bool isRGB, bool realTime);
00112                 ~QVMPlayerFrameGrabber();
00113                 uInt getFrameSize() const { return buf_size; };
00114 
00115                 void getQVImageGray(QVImage<uChar> &imgGray) const;
00116                 void getQVImageRGB(QVImage<uChar,3> &imgRGB) const;
00117                 void getQVImageYUV(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV) const;
00118 
00119                 void updateFrameBuffer();
00120                 uInt frames_read;
00121                 bool finished;
00122                 QMutex mutex;
00123                 QWaitCondition condition;
00124 
00125         public slots:
00126                 void updateSlot();
00127 
00128         signals:
00129                 void newReadFrameGrabber();
00130                 // This signal is to defer the call to sendCommandToMplayer, and avoid
00131                 // the "QSocketNotifier:: socket notifier cannot be enabled from another
00132                 // thread" warning:
00133                 void sendCommandSignal();
00134 
00135         private:
00136                 QVCameraThread *qvcamerathread;
00137                 QFile *fifoInput;       
00138                 QVMPlayerIOProcessor *mplayerIOProcessor;
00139 
00140                 bool debug_in_memcpy, debug_in_updateSlot;
00141                 bool isYUV, realTime;
00142                 uInt buf_size;
00143 
00144                 QVImage<uChar> imgY, img_auxY, imgU, img_auxU,  imgV, img_auxV;
00145                 QVImage<uChar,3> imgRGB, img_auxRGB;
00146                 void readToBuffer(uChar *buf_img_aux, uInt buf_size);
00147                 void getNewFrame(QVImage<uChar,3> &img);
00148                 void getNewFrame(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV);
00149         };
00151 
00159 class QVMPlayerCamera : public QVCamera
00160         {
00161         Q_OBJECT
00162 
00163         public:
00165                 QVMPlayerCamera(QString name = QString());
00167                 ~QVMPlayerCamera();
00168 
00169                 // Camera opening options as flags. Combine using | operator to create
00170                 // an OpenOptions flags (observe plural) object:
00172                 enum OpenOption {
00173                         Default = 0x0,          
00174                         RealTime = 0x1,         
00175                         Deinterlaced = 0x2, 
00176                         NoLoop = 0x4,           
00177                         RGBMEncoder = 0x8 
00178                 };
00179 
00180                 Q_DECLARE_FLAGS(OpenOptions,OpenOption);
00181 
00222                 bool openCam(const QString & url,OpenOptions opts = Default);
00223 
00232                 bool openCam(const QString & urlstring, unsigned int r, unsigned int c, OpenOptions opts = Default);
00233 
00246                 bool openCam();
00247 
00253                 bool grab(QVImage<uChar,3> &image);
00254 
00260                 bool grab(QVImage<uChar,1> &image);
00261 
00273                 bool grab(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV);
00274 
00277                 const QString getUrlBase() const { return url.path().split("/").last(); }
00278 
00281                 OpenOptions getOptions() const          { return open_options; };
00282 
00285                 int getBufferSize() const               { return mplayerFrameGrabber->getFrameSize(); };
00286 
00289                 unsigned int getFramesUpdated() const   { return mplayerFrameGrabber->frames_read; }
00290 
00293                 unsigned int getRows() const            { return mplayerIOProcessor->rows; };
00294 
00297                 unsigned int getCols() const            { return mplayerIOProcessor->cols; };
00298 
00301                 double getFPS() const                   { return mplayerIOProcessor->fps; };
00302 
00305                 double getTimeLength() const            { return mplayerIOProcessor->time_length; };
00306 
00309                 double getTimePos() const               { return mplayerIOProcessor->time_pos; };
00310 
00313                 double getSpeed() const                 { return mplayerIOProcessor->speed; };
00314 
00317                 unsigned int getFramesGrabbed() const           { return frames_grabbed; };
00318 
00321                 unsigned int getFramesRead() const              { return mplayerFrameGrabber->frames_read; };
00322 
00325                 bool isLiveCamera() const               { return live_camera; };
00326 
00335                 static bool getFrame(const QString uri, QVImage<uChar,3> &img, int frame = 0)
00336                         {
00337                         QVMPlayerCamera camera;
00338                         if(camera.openCam(uri, QVMPlayerCamera::RGBMEncoder) == -1)
00339                                 return false;
00340                         bool result;
00341                         for (int i=-1; i < frame; i++)
00342                                 result = camera.grab(img);
00343                         camera.closeCam();
00344                         return result;
00345                         }
00346 
00355                 static bool getFrame(const QString uri, QVImage<uChar,1> &img, int frame = 0)
00356                         {
00357                         QVMPlayerCamera camera;
00358                         if(camera.openCam(uri, QVMPlayerCamera::Default) == -1)
00359                                 return false;
00360 
00361                         for (int i=-1; i < frame; i++)
00362                                 if (!camera.grab(img))
00363                                         return false;
00364 
00365                         camera.closeCam();
00366 
00367                         return true;
00368                         }
00369 
00380                 static bool getFrame(const QString uri, QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV,
00381                                 int frame = 0)
00382                         {
00383                         QVMPlayerCamera camera;
00384                         if(camera.openCam(uri, QVMPlayerCamera::Default) == -1)
00385                                 return false;
00386                         bool result;
00387                         for (int i=-1; i < frame; i++)
00388                                 result = camera.grab(imgY, imgU, imgV);
00389                         camera.closeCam();
00390                         return result;
00391                         }
00392 
00393         public slots:
00400                 bool grab();
00401 
00403                 void pauseCam();
00405                 void unpauseCam();
00407                 void nextFrameCam();
00410                 void setSpeedCam(double d);
00417                 void seekCam(QVCamera::TSeekType type, double pos);     
00419                 void closeCam();
00420 
00421                 bool link(QVWorker *,QString imageName);
00422                 bool link(QVWorker *, const QString imageY, const QString imageU, const QString imageV);
00423 
00424         signals:
00425                 // This signal is to defer the call to sendCommandToMplayer, and avoid
00426                 // the "QSocketNotifier:: socket notifier cannot be enabled from another
00427                 // thread" warning:
00428                 void sendCommandSignal();
00429 
00430         private:
00431                 // this boolean value becomes true if any RGB image is linked to the camera, from a worker.
00432                 bool rgbMode;
00433 
00434                 // Previous images needed to be saved to support cameras in pause mode:
00435                 //QVImage<uChar> grabbedYImage, grabbedUImage, grabbedVImage;
00436                 //QVImage<uChar,3> grabbedRGBImage;
00437 
00438                 // DEPRECATED: QMutex mutexJustToSleepMiliseconds;
00439                 QWaitCondition conditionJustToSleepMiliseconds;
00440 
00441                 OpenOptions open_options;
00442                 QVMPlayerFrameGrabber * mplayerFrameGrabber;
00443                 QVMPlayerIOProcessor * mplayerIOProcessor;
00444 
00445                 QNamedPipe *namedPipe, *namedPipeAux;   // The named fifo(s);
00446                 QUrl url;                               // Camera URL;
00447                 QFile fifo_file,fifo_file_2;            // Named fifo;
00448                 QProcess mplayer, mencoder;             // mplayer and mencoder processes;
00449 
00450                 QStringList initMPlayerArgs(unsigned int rows, unsigned int cols);
00451                 bool performGrab();
00452 
00453                 bool live_camera;
00454                 int frames_grabbed;
00455         };
00456 
00457 // Camera opening flags | operator:
00458 Q_DECLARE_OPERATORS_FOR_FLAGS(QVMPlayerCamera::OpenOptions)
00459 #endif
00460 
00461 
00462 
00463 

Generated on Fri Dec 7 12:20:59 2007 for QVision by  doxygen 1.5.3