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 
00043 // Auxiliary QVCheckOKMPlayerCamera Class.
00044 // This is an internal convenience thread used only to unblock the open function
00045 // when it is waiting for mplayer to read from the fifo, in the case when
00046 // mplayer aborted when starting (due to bad URL, or wrong file format, for
00047 // example).
00048 
00050 class QVCheckOKMplayerCamera: public QThread
00051 {
00052         Q_OBJECT
00053         public:
00054                 QVCheckOKMplayerCamera(QFile & fifo_file,int max_time_ms_to_wait_for_open);
00055                 ~QVCheckOKMplayerCamera();
00056                 void run();
00057         private slots:
00058                 void writeErrorInFifo();
00059         private:
00060                 QFile & _fifo_file;
00061                 int _max_time_ms_to_wait_for_open;
00062 };
00064 
00065 // Auxiliary QVCameraThread Class.
00066 // This is an internal convenience thread used in real time cameras to keep
00067 // updating the frames from mplayer independently of the user grabs.
00068 
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         };
00082 
00083 // Auxiliary QVMPlayerIOProcessor class.
00084 // Auxiliary class to communicate through stdin and stdout with mplayer, and
00085 // read data such as the number of rows and cols of the video, the fps, and also
00086 // to send commands such as pausing, ask for current position, and so on.
00087 
00089 class QVMPlayerIOProcessor: public QObject
00090         {
00091         Q_OBJECT
00092         public:
00093                 QVMPlayerIOProcessor(QProcess *mplayer);
00094                 ~QVMPlayerIOProcessor();
00095                 void queueCommandToMPlayer(const QString &, bool ifEmpty = false);
00096                 double fps, speed, time_length, time_pos;
00097                 uInt cols, rows;
00098         public slots:
00099                 int interpretMPlayerOutput();
00100         private slots:
00101                 void sendCommandToMPlayer();
00102         private:
00103                 QQueue<QString> command_queue;
00104                 QMutex command_queue_mutex;
00105                 QProcess *mplayer;
00106         };
00108 
00109 // Auxiliary QVMPlayerFrameGrabber Class.
00111 class QVMPlayerFrameGrabber: public QObject
00112         {
00113         Q_OBJECT
00114 
00115         public:
00116                 QVMPlayerFrameGrabber(QVMPlayerIOProcessor *, QFile *, uInt rows, uInt cols, bool isRGB, bool realTime);
00117                 ~QVMPlayerFrameGrabber();
00118                 uInt getFrameSize() const { return buf_size; };
00119 
00120                 void getQVImageGray(QVImage<uChar> &imgGray) const;
00121                 void getQVImageRGB(QVImage<uChar,3> &imgRGB) const;
00122                 void getQVImageYUV(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV) const;
00123 
00124                 void updateFrameBuffer();
00125                 uInt frames_read;
00126                 bool finished;
00127                 QMutex mutex;
00128                 QWaitCondition condition;
00129 
00130         public slots:
00131                 void updateSlot();
00132 
00133         signals:
00134                 void newReadFrameGrabber();
00135                 // This signal is to defer the call to sendCommandToMplayer, and avoid
00136                 // the "QSocketNotifier:: socket notifier cannot be enabled from another
00137                 // thread" warning:
00138                 void sendCommandSignal();
00139 
00140         private:
00141                 QVCameraThread *qvcamerathread;
00142                 QFile *fifoInput;       
00143                 QVMPlayerIOProcessor *mplayerIOProcessor;
00144 
00145                 bool debug_in_memcpy, debug_in_updateSlot;
00146                 bool isYUV, realTime;
00147                 uInt buf_size;
00148 
00149                 QVImage<uChar> imgY, img_auxY, imgU, img_auxU,  imgV, img_auxV;
00150                 QVImage<uChar,3> imgRGB, img_auxRGB;
00151                 void readToBuffer(uChar *buf_img_aux, uInt buf_size);
00152                 void getNewFrame(QVImage<uChar,3> &img);
00153                 void getNewFrame(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV);
00154         };
00156 
00157 // This is for doxygen get the detailed description for QVMPlayerCamera correctly.
00158 class QVWorker;
00159 class QVMPlayerIOProcessor;
00160 
00230 class QVMPlayerCamera : public QVCamera
00231         {
00232         Q_OBJECT
00233 
00234         public:
00236                 QVMPlayerCamera(QString name = QString());
00238                 ~QVMPlayerCamera();
00239 
00240                 // Camera opening options as flags. Combine using | operator to create
00241                 // an OpenOptions flags (observe plural) object:
00243                 enum OpenOption {
00244                         Default = 0x0,          
00245                         RealTime = 0x1,         
00246                         Deinterlaced = 0x2,     
00247                         NoLoop = 0x4,           
00248                         RGBMEncoder = 0x8       
00249                 };
00250 
00251                 Q_DECLARE_FLAGS(OpenOptions,OpenOption);
00252 
00257                 bool openCam(const QString & url,OpenOptions opts = Default);
00258 
00267                 bool openCam(const QString & urlstring, unsigned int r, unsigned int c, OpenOptions opts = Default);
00268 
00281                 bool openCam();
00282 
00288                 bool grab(QVImage<uChar,3> &image);
00289 
00295                 bool grab(QVImage<uChar,1> &image);
00296 
00308                 bool grab(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV);
00309 
00312                 const QString getUrlBase() const { return url.path().split("/").last(); }
00313 
00316                 OpenOptions getOptions() const          { return open_options; };
00317 
00320                 int getBufferSize() const               { return mplayerFrameGrabber->getFrameSize(); };
00321 
00324                 unsigned int getFramesUpdated() const   { return mplayerFrameGrabber->frames_read; }
00325 
00328                 unsigned int getRows() const            { return mplayerIOProcessor->rows; };
00329 
00332                 unsigned int getCols() const            { return mplayerIOProcessor->cols; };
00333 
00336                 double getFPS() const                   { return mplayerIOProcessor->fps; };
00337 
00340                 double getTimeLength() const            { return mplayerIOProcessor->time_length; };
00341 
00344                 double getTimePos() const               { return mplayerIOProcessor->time_pos; };
00345 
00348                 double getSpeed() const                 { return mplayerIOProcessor->speed; };
00349 
00352                 unsigned int getFramesGrabbed() const           { return frames_grabbed; };
00353 
00356                 unsigned int getFramesRead() const              { return mplayerFrameGrabber->frames_read; };
00357 
00360                 bool isLiveCamera() const               { return live_camera; };
00361 
00370                 static bool getFrame(const QString uri, QVImage<uChar,3> &img, int frame = 0)
00371                         {
00372                         QVMPlayerCamera camera;
00373                         if(camera.openCam(uri, QVMPlayerCamera::RGBMEncoder) == -1)
00374                                 return false;
00375                         bool result;
00376                         for (int i=-1; i < frame; i++)
00377                                 result = camera.grab(img);
00378                         camera.closeCam();
00379                         return result;
00380                         }
00381 
00390                 static bool getFrame(const QString uri, QVImage<uChar,1> &img, int frame = 0)
00391                         {
00392                         QVMPlayerCamera camera;
00393                         if(camera.openCam(uri, QVMPlayerCamera::Default) == -1)
00394                                 return false;
00395 
00396                         for (int i=-1; i < frame; i++)
00397                                 if (!camera.grab(img))
00398                                         return false;
00399 
00400                         camera.closeCam();
00401 
00402                         return true;
00403                         }
00404 
00415                 static bool getFrame(const QString uri, QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV,
00416                                 int frame = 0)
00417                         {
00418                         QVMPlayerCamera camera;
00419                         if(camera.openCam(uri, QVMPlayerCamera::Default) == -1)
00420                                 return false;
00421                         bool result;
00422                         for (int i=-1; i < frame; i++)
00423                                 result = camera.grab(imgY, imgU, imgV);
00424                         camera.closeCam();
00425                         return result;
00426                         }
00427 
00428         public slots:
00435                 bool grab();
00436 
00438                 void pauseCam();
00440                 void unpauseCam();
00442                 void nextFrameCam();
00445                 void setSpeedCam(double d);
00452                 void seekCam(QVCamera::TSeekType type, double pos);     
00454                 void closeCam();
00455 
00456                 bool link(QVWorker *,QString imageName);
00457                 bool link(QVWorker *, const QString imageY, const QString imageU, const QString imageV);
00458 
00459         signals:
00460                 // This signal is to defer the call to sendCommandToMplayer, and avoid
00461                 // the "QSocketNotifier:: socket notifier cannot be enabled from another
00462                 // thread" warning:
00463                 void sendCommandSignal();
00464 
00465         private:
00466                 // this boolean value becomes true if any RGB image is linked to the camera, from a worker.
00467                 bool rgbMode;
00468 
00469                 QWaitCondition conditionJustToSleepMiliseconds;
00470 
00471                 OpenOptions open_options;
00472                 QVMPlayerFrameGrabber * mplayerFrameGrabber;
00473                 QVMPlayerIOProcessor * mplayerIOProcessor;
00474 
00475                 QNamedPipe *namedPipe, *namedPipeAux;   // The named fifo(s);
00476                 QUrl url;                               // Camera URL;
00477                 QFile fifo_file,fifo_file_2;            // Named fifo;
00478                 QProcess mplayer, mencoder;             // mplayer and mencoder processes;
00479 
00480                 QStringList initMPlayerArgs(unsigned int rows, unsigned int cols);
00481                 bool performGrab();
00482 
00483                 bool live_camera;
00484                 int frames_grabbed;
00485         };
00486 
00487 // Camera opening flags | operator:
00488 Q_DECLARE_OPERATORS_FOR_FLAGS(QVMPlayerCamera::OpenOptions)
00489 
00490 #endif
00491 
00492 
00493 
00494 

Generated on Wed Jan 16 18:41:29 2008 for QVision by  doxygen 1.5.3