src/qvmplayercamera/qvmplayercamera.cpp

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 #include <sys/types.h>
00026 #include <sys/stat.h>
00027 #include <unistd.h>
00028 #include <stdlib.h>
00029 #include <fcntl.h>
00030 #include <stdio.h>
00031 
00032 #include <QApplication>
00033 #include <QDebug>
00034 #include <QObject>
00035 #include <QStringList>
00036 #include <QRegExp>
00037 #include <QMutex>
00038 
00039 #include <qvcore/qvworker.h>
00040 #include <qvmplayercamera/qvmplayercamera.h>
00041 
00042 /******************* Auxiliary QVCheckOKMPlayerCamera Class *******************/
00043 QVCheckOKMplayerCamera::QVCheckOKMplayerCamera(QFile & fifo_file,int max_time_ms_to_wait_for_open) : QThread(), _fifo_file(fifo_file), _max_time_ms_to_wait_for_open(max_time_ms_to_wait_for_open)
00044         {
00045         qDebug() << "QVCheckOKMplayerCamera::QVCheckOKMplayerCamera()";
00046         qDebug() << "QVCheckOKMplayerCamera::QVCheckOKMplayerCamera() <- return";
00047         }
00048 
00049 QVCheckOKMplayerCamera::~QVCheckOKMplayerCamera()
00050         {
00051         qDebug() << "QVCheckOKMplayerCamera::~QVCheckOKMplayerCamera()";
00052         quit();
00053         wait();
00054         qDebug() << "QVCheckOKMplayerCamera::~QVCheckOKMplayerCamera: thread finished";
00055         qDebug() << "QVCheckOKMplayerCamera::~QVCheckOKMplayerCamera() <- return";
00056         }
00057 
00058 void QVCheckOKMplayerCamera::run()
00059         {
00060         qDebug() << "QVCheckOKMplayerCamera::run()";
00061         QTimer::singleShot(_max_time_ms_to_wait_for_open, this, SLOT(writeErrorInFifo()));
00062         qDebug() << "QVCheckOKMplayerCamera::run() <- entering event loop";
00063         exec();
00064         qDebug() << "QVCheckOKMplayerCamera::run() <- back from event loop";
00065         qDebug() << "QVCheckOKMplayerCamera::run() <- return";
00066         }
00067 
00068 
00069 void QVCheckOKMplayerCamera::writeErrorInFifo()
00070         {
00071         qDebug() << "QVCheckOKMplayerCamera::writeErrorInFifo()";
00072         _fifo_file.write("MPLAYER ERROR\n"); 
00073         qDebug() << "QVCheckOKMplayerCamera::writeErrorInFifo() -> return";
00074         };
00075 
00076 /********************* Auxiliary QVCameraThread Class *************************/
00077 //QVCameraThread::QVCameraThread(): QThread(), objectList(), slotList(), timer(NULL)
00078 QVCameraThread::QVCameraThread(QObject *object,char *slot): QThread(), _object(object), _slot(slot)
00079         {
00080         qDebug() << "QVCameraThread::QVCameraThread()";
00081         _object->moveToThread(this);
00082         qDebug() << "QVCameraThread::QVCameraThread(): object moved to thread";
00083         qDebug() << "QVCameraThread::QVCameraThread() <- return";
00084         }
00085 
00086 QVCameraThread::~QVCameraThread()
00087         {
00088         qDebug() << "QVCameraThread::~QVCameraThread()";
00089         disconnect();
00090         quit();
00091         qDebug() << "QVCameraThread::~QVCameraThread(): sent quit to thread";
00092         wait();
00093         qDebug() << "QVCameraThread::~QVCameraThread(): thread finished";
00094         qDebug() << "QVCameraThread::~QVCameraThread() <- return";
00095         }
00096 
00097 void QVCameraThread::run()
00098         {
00099         qDebug() << "QVCameraThread::run()";
00100         QTimer *timer = new QTimer();
00101         timer->start(0);
00102         connect(timer, SIGNAL(timeout()),_object,_slot);
00103         qDebug() << "QVCameraThread::run(): timer created, started and connected";
00104         qDebug() << "QVCameraThread::run(): entering event processing loop";
00105         exec();
00106         qDebug() << "QVCameraThread::run(): back from event processing loop";
00107         delete timer;
00108         qDebug() << "QVCameraThread::run(): timer deleted";
00109         qDebug() << "QVCameraThread::run() <- return";
00110         }
00111 
00112 /********************* Auxiliary QVMPlayerIOProcessor class *******************/
00113 QVMPlayerIOProcessor::QVMPlayerIOProcessor(QProcess * mplayer): QObject(), command_queue(), command_queue_mutex()
00114         {
00115         qDebug() << "QVMPlayerIOProcessor::QVMPlayerIOProcessor()";
00116         rows = cols = 0;
00117         fps = time_length = time_pos = 0;
00118         speed = 1;
00119         this->mplayer = mplayer;
00120         mplayer->waitForReadyRead();
00121         qDebug() << "QVMPlayerIOProcessor::QVMPlayerIOProcessor() <- return";
00122         }
00123 
00124 QVMPlayerIOProcessor::~QVMPlayerIOProcessor()
00125         {
00126         qDebug() << "QVMPlayerIOProcessor::~QVMPlayerIOProcessor()";
00127         qDebug() << "QVMPlayerIOProcessor::~QVMPlayerIOProcessor() <- return";
00128         }
00129 
00130 void QVMPlayerIOProcessor::queueCommandToMPlayer(const QString &com_str, bool ifEmpty)
00131         {
00132         qDebug() << "QVMPlayerIOProcessor::queueCommand("<< com_str <<")";
00133         qDebug() << "QVMPlayerIOProcessor::queueCommand(): command_queue.size() = "
00134                 << command_queue.size();
00135         command_queue_mutex.lock();
00136         if(!ifEmpty || command_queue.size()==0)
00137                 command_queue << com_str + '\n';
00138         command_queue_mutex.unlock();
00139         qDebug() << "QVMPlayerIOProcessor::queueCommand() <- return";
00140         }
00141 
00142 void QVMPlayerIOProcessor::sendCommandToMPlayer()
00143         {
00144         qDebug() << "QVMPlayerIOProcessor::sendCommandToMPlayer()";
00145         command_queue_mutex.lock();
00146         if (command_queue.size() > 0)
00147                 {
00148                 qDebug() << "QVMPlayerIOProcessor::sendCommandToMPlayer(): sending command:" << command_queue.head();
00149                 mplayer->write(qPrintable(command_queue.dequeue()));
00150                 }
00151         command_queue_mutex.unlock();
00152         qDebug() << "QVMPlayerIOProcessor::sendCommandToMPlayer(): wait for bytes written";
00153         // BUG: In Windows this hangs?
00154         #ifdef unix
00155         mplayer->waitForBytesWritten();
00156         #endif
00157         qDebug() << "QVMPlayerIOProcessor::sendCommandToMPlayer() <- return";
00158         }
00159 
00160 int QVMPlayerIOProcessor::interpretMPlayerOutput()
00161         {
00162         qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput()";
00163         int length = -1;
00164         char buf[1024];
00165 
00166         length = mplayer->readLine(buf, sizeof(buf));
00167 
00168         if (length == -1)
00169                 qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): length == -1";
00170         else    {
00171                 QString str(buf);
00172                 QStringList variables = str.simplified().split("=");
00173                 QStringList palabras = str.simplified().split(" ");
00174 
00175                 if(variables[0] == "ANS_speed")
00176                         {
00177                         speed = variables[1].toDouble();
00178                         qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): updating speed =" << speed;
00179                         }
00180                 else if(variables[0] == "ANS_LENGTH")
00181                         {
00182                         time_length = variables[1].toDouble();
00183                         qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): updating time_length =" << time_length;
00184                         }
00185                 else if(variables[0] == "ANS_TIME_POSITION")
00186                         {
00187                         time_pos = variables[1].toDouble();
00188                         qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): updating time_pos =" << time_pos;
00189                         }
00190                 else if (palabras[0] == "VIDEO:")
00191                         {
00192                         // ya tenemos las especificaciones de fps
00193                         for (int i = 0; i < palabras.size(); ++i)
00194                                 if (palabras[i] == "fps")
00195                                         fps = palabras[i-1].toDouble();
00196 
00197                         qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): updating fps" << fps;
00198                         }
00199                 else if (palabras[0] == "VO:")
00200                         {
00201                         // ya tenemos las especificaciones del video y dimensiones
00202                         QStringList dimensiones = palabras[2].split("x");
00203                         cols = dimensiones[0].toInt();
00204                         rows = dimensiones[1].toInt();
00205                         qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): updating cols" << cols;
00206                         qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): updating rows" << rows;
00207                         }
00208                 else
00209                         qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): uninterpreted mplayer output:" << str;
00210                 }
00211         qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput() <- return" << length;
00212         return length;
00213         }
00214 
00215 /******************* Auxiliary QVMPlayerFrameGrabber Class ********************/
00216 QVMPlayerFrameGrabber::QVMPlayerFrameGrabber(QVMPlayerIOProcessor *mplayerIOProcessor, QFile *fifoInput, uInt rows, uInt cols, bool isRGB, bool realTime): QObject()
00217         {
00218         qDebug() << "QVMPlayerFrameGrabber::QVMPlayerFrameGrabber(fifoInput," << mplayerIOProcessor->rows << "," << mplayerIOProcessor->cols << "," << isRGB << "," << realTime <<")";
00219         
00220         this->mplayerIOProcessor = mplayerIOProcessor;
00221         this->fifoInput = fifoInput;
00222         this->realTime = realTime;
00223         this->isYUV = not isRGB;
00224         this->finished = false;
00225         this->frames_read = 0;
00226 
00227         debug_in_memcpy = debug_in_updateSlot = false;
00228 
00229         if(isYUV)
00230                 {
00231                 imgY = QVImage<uChar>(cols, rows, cols);
00232                 img_auxY = QVImage<uChar>(cols, rows, cols);
00233                 img_auxU = QVImage<uChar>(cols/2, rows/2, cols/2);
00234                 img_auxV = QVImage<uChar>(cols/2, rows/2, cols/2);
00235                 // ...a YUV420 rows x cols image:
00236                 buf_size = rows*cols + rows*cols/4 + rows*cols/4;
00237                 }
00238         else    {
00239                 imgRGB = QVImage<uChar,3>(cols, rows, 3*cols);
00240                 img_auxRGB = QVImage<uChar,3>(cols, rows, 3*cols);
00241                 // ...or a RGB rows x cols image:
00242                 buf_size = 3*rows*cols;
00243                 }
00244 
00245         if (realTime)
00246                 {
00247                 qvcamerathread = new QVCameraThread(this,SLOT(updateSlot()));
00248                 qvcamerathread->start(QThread::NormalPriority);
00249                 }
00250 
00251         qDebug() << "QVMPlayerFrameGrabber::QVMPlayerFrameGrabber() <- return";
00252         };
00253 
00254 QVMPlayerFrameGrabber::~QVMPlayerFrameGrabber()
00255         {
00256         qDebug() << "QVMPlayerFrameGrabber::~QVMPlayerFrameGrabber()";
00257         finished = true;
00258         if (realTime) delete qvcamerathread;
00259         qDebug() << "QVMPlayerFrameGrabber::~QVMPlayerFrameGrabber(): thread deleted.";
00260         qDebug() << "QVMPlayerFrameGrabber::~QVMPlayerFrameGrabber() <- return";
00261         }
00262 
00263 void QVMPlayerFrameGrabber::getNewFrame(QVImage<uChar,3> &img)
00264         {
00265         readToBuffer(img.getWriteData(), buf_size);
00266         }
00267 
00268 void QVMPlayerFrameGrabber::getNewFrame(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV)
00269         {
00270         qDebug() << "QVMPlayerFrameGrabber::getNewFrame(): reading YUV header";
00271         char buf[1024];
00272         fifoInput->readLine(buf, sizeof(buf));
00273         readToBuffer(imgY.getWriteData(), 2*buf_size/3);
00274         readToBuffer(imgU.getWriteData(), buf_size/6);
00275         readToBuffer(imgV.getWriteData(), buf_size/6);
00276         qDebug() << "QVMPlayerFrameGrabber::getNewFrame() <- return";
00277         }
00278 
00279 void QVMPlayerFrameGrabber::updateSlot()
00280         {
00281         qDebug() << "QVMPlayerFrameGrabber::updateSlot()";
00282 
00283         qDebug() << "QVMPlayerFrameGrabber::updateSlot(): sent command to mplayer: get_time_pos";
00284         mplayerIOProcessor->queueCommandToMPlayer("pausing_keep get_time_pos\n",true);
00285 
00286         // Avoid QSocketNotifier annoying message, by deferring call:
00287         emit sendCommandSignal(); // NOT mplayerIOProcessor->sendCommandToMPlayer();
00288 
00289         // New frame read:
00290         qDebug() << "QVMPlayerFrameGrabber::updateSlot(): reading frame";
00291         QVImage<uChar, 1> tempY;
00292         QVImage<uChar, 1> tempU;
00293         QVImage<uChar, 1> tempV;
00294         QVImage<uChar, 3> tempRGB;
00295 
00296         // We always read in temporal images, that are later safely copied:
00297         // There is no copy overhead because QVImage uses QSharedData (reference
00298         // counting).
00299         if (isYUV)
00300                 getNewFrame(tempY = img_auxY, tempU = img_auxU, tempV = img_auxV);
00301         else    
00302                 getNewFrame(tempRGB = img_auxRGB);
00303 
00304         // If in real time, we lock, to avoid collision with the thread that is
00305         // grabbing from the camera:
00306         if(realTime)
00307                 {
00308                 mutex.lock();
00309                 debug_in_updateSlot = true;
00310                 if (debug_in_memcpy)
00311                         {
00312                         std::cerr << "(BUG1) entered frameUpdate while memcpying!";
00313                         exit(0);
00314                         }
00315                 }
00316 
00317         if (isYUV)
00318                 {
00319                 img_auxY = tempY;
00320                 img_auxU = tempU;
00321                 img_auxV = tempV;
00322                 }
00323         else
00324                 img_auxRGB = tempRGB;
00325 
00326         // Unlock (if in real time):
00327         if(realTime)
00328                 {
00329                 if (debug_in_memcpy) {
00330                         std::cerr << "(BUG2) entered frameUpdate while memcpying!";
00331                         exit(0);
00332                 }
00333                 debug_in_updateSlot = false;
00334                 condition.wakeAll(); // Wake possible waiting grabs.
00335                 mutex.unlock();
00336                 }
00337 
00338         qDebug() << "QVMPlayerFrameGrabber::updateSlot(): finished" << finished;
00339         frames_read++;
00340         qDebug() << "QVMPlayerFrameGrabber::updateSlot(): frames read" << frames_read;
00341 
00342         mplayerIOProcessor->interpretMPlayerOutput();
00343 
00344         qDebug() << "QVMPlayerFrameGrabber::updateSlot() <- return";
00345 
00346         emit newReadFrameGrabber();
00347         }
00348 
00349 void QVMPlayerFrameGrabber::updateFrameBuffer()
00350         {
00351         qDebug() << "QVMPlayerFrameGrabber::updateFrameBuffer()";
00352 
00353         // Here we come from a grab, so we always lock (if in real time, it is 
00354         // obviously needed, but also if not in real time, to make non-real-cameras
00355         // grabbing also thread-safe (won't be used normally, but who knows...
00356         // maybe the programmer wish to read different frames from different
00357         // threads, without discarding any frame as could happen with real time
00358         // cameras).
00359         mutex.lock();
00360         if (debug_in_updateSlot) 
00361                 {
00362                 std::cerr << "(BUG3) entered memcpy while frameUpdating!";
00363                 exit(0);
00364                 }
00365 
00366         if(realTime)
00367                 condition.wait(&mutex); // If in real time, wait for next fresh frame.
00368         debug_in_memcpy = true;
00369 
00370         // If in real time, updateSlot is asynchronously called by a dedicated
00371         // thread, otherwise we have to call it explicitly.
00372         if(not realTime)
00373                 updateSlot();
00374 
00375         if (isYUV)
00376                 {
00377                 imgY = img_auxY;
00378                 imgU = img_auxU;
00379                 imgV = img_auxV;
00380                 }
00381         else
00382                 imgRGB = img_auxRGB;
00383 
00384         if (debug_in_updateSlot) 
00385                 {
00386                 std::cerr << "(BUG4) entered memcpy while frameUpdating!";
00387                 exit(0);
00388                 }
00389         debug_in_memcpy = false;
00390         mutex.unlock();
00391 
00392         qDebug() << "QVMPlayerFrameGrabber::updateFrameBuffer() <- return";
00393         }
00394 
00395 void QVMPlayerFrameGrabber::getQVImageYUV(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV) const
00396         {
00397         qDebug() << "QVMPlayerFrameGrabber::getQVImageYUV()";
00398         imgY = this->imgY;
00399         imgU = this->imgU;
00400         imgV = this->imgV;
00401         qDebug() << "QVMPlayerFrameGrabber::getQVImageYUV() <- return";
00402         }
00403 
00404 void QVMPlayerFrameGrabber::getQVImageGray(QVImage<uChar> &imgGray) const
00405         {
00406         qDebug() << "QVMPlayerFrameGrabber::getQVImageYUV()";
00407         imgGray = imgY;
00408         qDebug() << "QVMPlayerFrameGrabber::getQVImageYUV() <- return";
00409         }
00410 
00411 void QVMPlayerFrameGrabber::getQVImageRGB(QVImage<uChar,3> &img) const
00412         {
00413         qDebug() << "QVMPlayerFrameGrabber::getQVImageRGB()";
00414         img = imgRGB;
00415         qDebug() << "QVMPlayerFrameGrabber::getQVImageRGB() <- return";
00416         }
00417 
00418 void QVMPlayerFrameGrabber::readToBuffer(uChar *buf_img_aux, uInt buf_size)
00419         {
00420         uInt totbytes = 0;
00421         while (totbytes != buf_size and not finished)
00422                 {
00423                 int nbytes = fifoInput->read((char *)(buf_img_aux+totbytes), buf_size-totbytes);
00424 
00425                 totbytes += nbytes;
00426                 qDebug() << "QVMPlayerFrameGrabber::readNewFrame(): read" << nbytes << "bytes";
00427 
00428                 if(nbytes == 0)
00429                         {
00430                         finished = TRUE;
00431                         qDebug() << "QVMPlayerFrameGrabber::readNewFrame(): read 0 bytes, finishing" << finished;
00432                         break;
00433                         }
00434 
00435                 if(nbytes == -1)
00436                         {
00437                         // BUG: problem in Windows, suddenly pipe can not be read ?!!?
00438                         // errorString() -> "Device did not accept the command."
00439                         finished = TRUE;
00440                         qDebug() << "QVMPlayerFrameGrabber::readNewFrame(): error -" << fifoInput->errorString();
00441                         break;
00442                         }                       
00443                 }
00444         }
00445 
00446 /***************************** QVMPlayerCamera Class **************************/
00447 QVMPlayerCamera::QVMPlayerCamera(QString name):QVCamera(name), open_options(Default)
00448         {
00449         qDebug() << "QVMPlayerCamera::QVMPlayerCamera()";
00450         frames_grabbed = 0;
00451         rgbMode = false;
00452         setStatus(Closed);
00453         live_camera = FALSE;
00454 
00455         // Properties (to allow reading from argc and argv):
00456         addProperty<int>("Rows", inputFlag, 0, "Rows to open the camera");
00457         addProperty<int>("Cols", inputFlag, 0, "Columns to open the camera");
00458         addProperty<bool>("RealTime", inputFlag, FALSE,"If the camera should be opened in real time mode");
00459         addProperty<bool>("Deinterlaced", inputFlag, FALSE,"If the camera should be opened in deinterlaced mode");
00460         addProperty<bool>("NoLoop", inputFlag, FALSE,"If the camera should be opened in no loop mode");
00461         addProperty<bool>("RGBMEncoder", inputFlag, FALSE,"If the camera should be opened in RGB using mencoder");
00462         addProperty<QString>("URL", inputFlag, QString(""),"URL of the video source (see doc.)");
00463         //addProperty<int>("Count",0,"Test param");
00464 
00465         // QVImage's
00466         addProperty< QVImage<uChar,3> >("RGB image", outputFlag, QVImage<uChar,3>(), "Last grabbed RGB image");
00467         addProperty< QVImage<uChar,1> >("Y channel image",outputFlag, QVImage<uChar,1>(), "Last grabbed Y channel image");
00468         addProperty< QVImage<uChar,1> >("U channel image",outputFlag, QVImage<uChar,1>(), "Last grabbed U channel image");
00469         addProperty< QVImage<uChar,1> >("V channel image",outputFlag, QVImage<uChar,1>(), "Last grabbed V channel image");
00470 
00471         qDebug() << "QVMPlayerCamera::QVMPlayerCamera() <- return";
00472         }
00473 
00474 QVMPlayerCamera::~QVMPlayerCamera()
00475         {
00476         qDebug() << "QVMPlayerCamera::~QVMPlayerCamera()";
00477         if (status != Closed) closeCam();
00478         qDebug() << "QVMPlayerCamera::~QVMPlayerCamera() <- deleting image";
00479         setImageBuffer(NULL);
00480         qDebug() << "QVMPlayerCamera::~QVMPlayerCamera() <- return";
00481         }
00482 
00483 /*// This function process url's query values (those listed after the '?' simbol) and
00484 // creates a QString undestandable for the mplayer.
00485 QString urlQueryValuesString(QUrl url)
00486         {
00487         QString s;
00488 
00489         QList<QPair<QString, QString> > queryItems = url.queryItems();
00490         for (int i = 0; i < queryItems.size(); ++i)
00491                 s += ":" + queryItems.at(i).first + "=" + queryItems.at(i).second;
00492 
00493         return s;
00494         }*/
00495 
00496 // Auxiliary function to init mplayer arguments:
00497 QStringList QVMPlayerCamera::initMPlayerArgs(uInt rows, uInt cols)
00498         {
00499         qDebug() << "QVMPlayerCamera::initMPlayerArgs()";
00500 
00501         qDebug() << "QVMPlayerCamera::initMPlayerArgs(): scheme" << url.scheme();
00502         qDebug() << "QVMPlayerCamera::initMPlayerArgs(): path" << url.path();
00503 
00504         QStringList mplayer_args;
00505 
00506         /*if((url.scheme() == "v4l") or (url.scheme() == "v4l2"))
00507                 {
00508                 // Video for Linux cameras:
00509                 live_camera = TRUE;
00510 
00511                 if(url.queryItemValue("height") != QString() and
00512                    url.queryItemValue("width") != QString())
00513                         {
00514                         mplayer_args << "tv://" << "-tv" <<
00515                                 QString("driver=%1:device=%2:width=%3:height=%4")
00516                                 .arg(url.scheme()).arg(url.path())
00517                                 .arg(url.queryItemValue("width")).arg(url.queryItemValue("height"));
00518                         }
00519                 else    {
00520                         mplayer_args << "tv://" << "-tv" <<
00521                                 QString("driver=%1:device=%2")
00522                                 .arg(url.scheme()).arg(url.path());
00523                         }
00524                 }
00525         else if(url.scheme() == "analog")
00526                 {
00527                 // Analog cameras (connected to v4l or v4l2 cards):
00528                 live_camera = TRUE;
00529                 // It works with both v4l and v4l2. We take v4l, for example:
00530 
00531                 if(url.queryItemValue("height") != QString() and
00532                    url.queryItemValue("width") != QString())
00533                         {
00534                         mplayer_args << "tv://" << "-tv" << QString("driver=v4l:input=%1:device=%2:width=%3:height=%4")
00535                                 .arg(url.queryItemValue("input")).arg(url.path())
00536                                 .arg(url.queryItemValue("width")).arg(url.queryItemValue("height"));
00537                 
00538                         }
00539                 else    {
00540                         mplayer_args << "tv://" << "-tv" <<
00541                                 QString("driver=%1:device=%2")
00542                                 .arg(url.scheme()).arg(url.path());
00543                         }
00544                 }*/
00545 
00546         // Different mplayer args for different kind of image sources:
00547         if((url.scheme() == "v4l") or (url.scheme() == "v4l2") or (url.scheme() == "analog"))
00548                 {
00549                 // Video for Linux cameras:
00550                 live_camera = TRUE;
00551                 QString urlQueryValues = QString("driver=%1:device=%2").arg(url.scheme()).arg(url.path());
00552 
00553                 QList<QPair<QString, QString> > queryItems = url.queryItems();
00554                 for (int i = 0; i < queryItems.size(); ++i)
00555                         urlQueryValues += ":" + queryItems.at(i).first + "=" + queryItems.at(i).second;
00556 
00557                 mplayer_args << "tv://" << "-tv" << urlQueryValues;
00558                 }
00559         else if(url.scheme() == "dv")
00560                 {
00561                 // DV cameras (connected through firewire):
00562                 live_camera = TRUE;
00563                 mplayer_args << url.path() << "-demuxer" << "rawdv" << "-cache" << "400";
00564                 }
00565         else if(url.scheme() == "iidc")
00566                 {
00567                 // IIDC cameras (connected through firewire):
00568                 live_camera = TRUE;
00569                 // For example, iidc:///dev/video1394/0?from=/dev/video0:to=/dev/video1
00570                 qFatal("Currently this driver does not work (apparently with\n"
00571                         "vloopback writing and then reading from a fifo with mplayer\ndoes not work).\n");
00572                 }
00573         else if(url.scheme() == "tv")
00574                 {
00575                 // Analog TV input:
00576                 live_camera = TRUE;
00577                 qFatal("tv URL: Still not implemented\n");
00578                 }
00579         else if(url.scheme() == "dvb")
00580                 {
00581                 // Digital TV input:
00582                 live_camera = TRUE;
00583                 qFatal("dvb URL: Still not implemented\n");
00584                 }
00585         else    { 
00586                 // Other: URL could only be now rtsp:// http://, ftp://, dvd://, vcd://,
00587                 //  mf:// or file://, so we pass it directly to mplayer:
00588                 live_camera = FALSE;
00589                 mplayer_args << url.toString();
00590                 }
00591 
00592         // IMPORTANT!! All -vf filters MUST be together, separated by commas, and in
00593         // the right order.
00594         // By now, we only use deinterlacing and scale, and in that order:
00595         QString aux;
00596 
00597         // Deinterlace option:
00598         if(open_options & Deinterlaced) aux = "pp=md";
00599         if(rows != 0 or cols != 0)
00600                 {
00601                 if(aux != QString())
00602                         aux += QString(",scale=%1:%2").arg(cols).arg(rows);
00603         else
00604                         aux = QString("scale=%1:%2").arg(cols).arg(rows);
00605         }
00606 
00607         if (aux != QString()) mplayer_args << "-vf" << aux;
00608 
00609         // Real time option:
00610         if(not (open_options & RealTime))
00611                 {
00612                 if(not live_camera)
00613                         mplayer_args << "-benchmark";
00614                 else
00615                         // The user attempted to open a live camera in continuous mode.
00616                         // We issue a warning:
00617                         qWarning("Warning: opening live cameras in continuous mode "
00618                                          "wastes less CPU time, but it is prone to delays in "
00619                                          "the pipe of images if your process is slower than "
00620                                          "the camera.");
00621                 }
00622 
00623         // Loop option:
00624         if(not (open_options & NoLoop)) mplayer_args << "-loop" << "0";
00625 
00626         // Additional arguments (slave, quiet, nosound & yuv4mpeg output):
00627         mplayer_args << "-slave" << "-quiet" << "-nosound"
00628                 << "-vo" << QString("yuv4mpeg:file=%1").arg(namedPipe->getInputFilePath());
00629 
00630         qDebug() << "QVMPlayerCamera::initMPlayerArgs() <- return";
00631 
00632         return QStringList(mplayer_args);
00633         }
00634 
00635 // (Implicit) default open method for a camera (uses introspection to read 
00636 // parameters, allowing initialization from argc and argv):
00637 bool QVMPlayerCamera::openCam()
00638         {
00639         //QString urlProp = ;
00640         /*int   rowsProp = ,
00641                 colsProp = ;*/
00642         /*bool  realTimeProp,
00643                 deinterlacedProp = ,
00644                 noLoopProp = ;*/
00645         //bool  rgbMEncoderProp = getPropertyValue<bool>("RGBMEncoder");
00646         //if (rgbMEncoderProp) optsProp |= RGBMEncoder;
00647 
00648         OpenOptions optsProp = Default;
00649         if (getPropertyValue<bool>("RealTime"))         optsProp |= RealTime;
00650         if (getPropertyValue<bool>("Deinterlaced"))     optsProp |= Deinterlaced;
00651         if (getPropertyValue<bool>("NoLoop"))           optsProp |= NoLoop;
00652         if (rgbMode)                                    optsProp |= RGBMEncoder;
00653 
00654         return openCam(getPropertyValue<QString>("URL"), getPropertyValue<int>("Rows"), getPropertyValue<int>("Cols"), optsProp);
00655         }
00656 
00657 // Explicit open url (and possible options) method:
00658 bool QVMPlayerCamera::openCam(const QString & urlstring,OpenOptions opts)
00659         { return openCam(urlstring,0,0,opts); }
00660 
00661 // Main method to open a camera:
00662 bool QVMPlayerCamera::openCam(const QString & urlstring, uInt rows, uInt cols, OpenOptions opts)
00663         {
00664         qDebug() << "QVMPlayerCamera::openCam(" << urlstring << "," << rows << "," << cols << "," << opts << ")";
00665 
00666         setStatus(Closed);
00667 
00668         open_options = opts;
00669 
00670         // Pipe initialization
00671         namedPipe = new QNamedPipe(QString("mplayer"));
00672         fifo_file.setFileName(namedPipe->getOutputFilePath());
00673 
00674         if(open_options & QVMPlayerCamera::RGBMEncoder)
00675                 {
00676                 namedPipeAux = new QNamedPipe(QString("mplayer-aux"));
00677                 fifo_file_2.setFileName(namedPipeAux->getOutputFilePath());
00678                 }
00679 
00680         url.setUrl(urlstring);
00681 
00682         QStringList mplayer_args = initMPlayerArgs(rows,cols);
00683         qDebug() << "QVMPlayerCamera::openCam(): MPlayer args ->" << mplayer_args;
00684         mplayer.start("mplayer",mplayer_args);
00685         qDebug() << "QVMPlayerCamera::openCam(): after mplayer.start()";
00686         if(not mplayer.waitForStarted(1000))
00687                 qFatal("Mplayer failed to start: Are you sure it is installed and in the correct PATH?");
00688         qDebug() << "QVMPlayerCamera::openCam(): after mplayer.waitForstarted()";
00689         
00690         // We create a guarding thread that will unblock the subsequent
00691         // fifo_file.readLine in the case that mplayer does not start OK (due,
00692         // for example, to a wrong URL, an incorrect file format, or whatever).
00693         // If mplayer starts OK before two seconds (for local videos) or ten
00694         // seconds (for DVD, VCD and remote videos), this thread silently stops and
00695         // is deleted.
00696         int max_time_ms_to_wait_for_open;
00697         if(urlstring.contains("http://") or urlstring.contains("rtsp://") or
00698            urlstring.contains("ftp://") or urlstring.contains("dvd://") or
00699            urlstring.contains("vcd://"))
00700                 max_time_ms_to_wait_for_open = 10000;
00701         else
00702                 max_time_ms_to_wait_for_open = 2000;
00703         QVCheckOKMplayerCamera *check_thread = new QVCheckOKMplayerCamera(fifo_file,max_time_ms_to_wait_for_open);
00704         check_thread->moveToThread(check_thread);
00705         check_thread->start();
00706         qDebug() << "QVMPlayerCamera::openCam(): after starting QVCheckOKMplayerCamera thread";
00707 
00708         // Important to open in ReadWrite mode, to avoid infinite waiting if
00709         // mplayer did not start OK, and because perhaps the former guarding
00710         // thread will write in the FIFO.
00711         qDebug() << "QVMPlayerCamera::openCam(): opening fifo_file";
00712         if((fifo_file.open(QIODevice::ReadWrite|QIODevice::Unbuffered)) == -1)
00713                 qFatal("Error opening fifo %s\n", qPrintable(namedPipe->getPipeName()));
00714         qDebug() << "QVMPlayerCamera::openCam(): reading fifo_file";
00715         // Now we read YUV header:
00716         char buf[1024];
00717         int len;
00718         if ((len = fifo_file.readLine(buf, sizeof(buf))) == -1) return FALSE;
00719         if (QString(buf) == QString("MPLAYER ERROR\n")) { 
00720                 std::cerr << "QVMPlayerCamera::openCam(): Warning: Mplayer could not open the requested url (" << qPrintable(urlstring) << ")\n" ;
00721                 check_thread->quit();
00722                 check_thread->wait();
00723                 delete check_thread;
00724 
00725                 // Cleaning: mplayer.waitForFinished();
00726                 mplayer.terminate();
00727                 if (not mplayer.waitForFinished(500)) mplayer.kill();   
00728                 fifo_file.close();
00729                 delete namedPipe;
00730                 if(open_options & QVMPlayerCamera::RGBMEncoder)
00731                         delete namedPipeAux;
00732 
00733                 qDebug() << "QVMPlayerCamera::openCam(): QVCheckOKMplayerCamera thread deleted after detecting an error; returning FALSE";
00734                 return FALSE;
00735         }
00736 
00737         // If in RGBMEncoder mode, we also launch mencoder (previously writing
00738         // the read line back to the pipe, because mencoder will need it):
00739         if(open_options & QVMPlayerCamera::RGBMEncoder)
00740                 {
00741                 fifo_file.write(buf,len);
00742                 mencoder.start("mencoder", QStringList() << namedPipe->getOutputFilePath() << "-nosound" << "-o" << namedPipeAux->getInputFilePath()<< "-ovc" << "raw" << "-of" << "rawvideo" << "-vf" << "format=rgb24" );
00743                 qDebug() << "QVMPlayerCamera::openCam(): mencoder started";
00744                 if(not mencoder.waitForStarted(1000))
00745                         qFatal("Mencoder failed to start: Are you sure it is installed and in the correct PATH?");
00746                 qDebug() << "QVMPlayerCamera::openCam(): opening fifo_file_2";
00747                 if((fifo_file_2.open(QIODevice::ReadOnly|QIODevice::Unbuffered))==-1)
00748                         qFatal("Error opening fifo %s\n", qPrintable(namedPipeAux->getPipeName()));
00749                 }
00750 
00751         check_thread->quit();
00752         check_thread->wait();
00753         delete check_thread;
00754         qDebug() << "QVMPlayerCamera::openCam(): QVCheckOKMplayerCamera thread deleted after correct launch of mplayer";
00755 
00756         qDebug() << "QVMPlayerCamera::openCam(): going to create QVMPlayerIOProcessor...";
00757         mplayerIOProcessor = new QVMPlayerIOProcessor(&mplayer);
00758 
00759         qDebug() << "QVMPlayerCamera::openCam(): waiting for initialization.";
00760         while(getRows() == 0 || getCols() == 0)
00761                 mplayerIOProcessor->interpretMPlayerOutput();
00762 
00763         qDebug() << "QVMPlayerCamera::openCam(): video dims (" << getCols() << "," << getRows() << ")";
00764         qDebug() << "QVMPlayerCamera::openCam(): fps " << getFPS();
00765 
00766         mplayerIOProcessor->queueCommandToMPlayer("get_time_length");
00767 
00768         if (open_options & QVMPlayerCamera::RGBMEncoder)
00769                 {
00770                 setImageBuffer(new QVImage<uChar,3>(getRows(), getCols(), 3*getCols()));
00771                 mplayerFrameGrabber = new QVMPlayerFrameGrabber(mplayerIOProcessor, &fifo_file_2, getRows(), getCols(), true, open_options & QVMPlayerCamera::RealTime);
00772                 }
00773         else    {
00774                 setImageBuffer(new QVImage<uChar,1>(getRows(), getCols(), getCols()));
00775                 mplayerFrameGrabber = new QVMPlayerFrameGrabber(mplayerIOProcessor, &fifo_file, getRows(), getCols(), false, open_options & QVMPlayerCamera::RealTime);
00776                 }
00777 
00778         connect(mplayerFrameGrabber,SIGNAL(newReadFrameGrabber()),this,SIGNAL(newRead()));
00779 
00780         // These signals are to defer the call to sendCommandToMplayer, and avoid
00781         // the "QSocketNotifier:: socket notifier cannot be enabled from another
00782         // thread" warning.
00783         connect(mplayerFrameGrabber,SIGNAL(sendCommandSignal()),mplayerIOProcessor,SLOT(sendCommandToMPlayer()));
00784         connect(this,SIGNAL(sendCommandSignal()),mplayerIOProcessor,SLOT(sendCommandToMPlayer()));
00785 
00786 
00787         setStatus(Running);
00788 
00789         qDebug() << "QVMPlayerCamera::openCam() <- return";
00790 
00791         emit camOpened();
00792 
00793         //grab();
00794 
00795         return TRUE;
00796         }
00797 
00798 // Close camera method:
00799 void QVMPlayerCamera::closeCam()
00800         {
00801         qDebug() << "QVMPlayerCamera::closeCam()";
00802 
00803         if (status == Closed)
00804                 {
00805                 qDebug() << "QVMPlayerCamera::closeCam(): camera already closed. Returning";
00806                 qDebug() << "QVMPlayerCamera::closeCam() <- return";
00807                 return;
00808                 }
00809 
00810         setStatus(Closed);
00811 
00812         emit camClosed();
00813 
00814         mplayerIOProcessor->queueCommandToMPlayer("quit");      
00815         // Avoid QSocketNotifier annoying message, by deferring call:
00816         emit sendCommandSignal(); // NOT mplayerIOProcessor->sendCommandToMPlayer();
00817 
00818         delete mplayerFrameGrabber;
00819         qDebug() << "QVMPlayerCamera::closeCam(): mplayerFrameGrabber deleted";
00820 
00821         delete mplayerIOProcessor;
00822         qDebug() << "QVMPlayerCamera::closeCam(): mplayerIOProcessor deleted";
00823 
00824         mplayer.terminate();
00825         while (not mplayer.waitForFinished(500)) mplayer.kill();
00826         qDebug() << "QVMPlayerCamera::closeCam(): mplayer terminated";
00827         
00828         if (open_options & QVMPlayerCamera::RGBMEncoder)
00829                 {
00830                 mencoder.terminate();
00831                 while (not mencoder.waitForFinished(500)) mencoder.kill();
00832                 }
00833 
00834         qDebug() << "QVMPlayerCamera::closeCam(): mencoder terminated";
00835         
00836         fifo_file.close();
00837         qDebug() << "QVMPlayerCamera::closeCam(): closed fifo_file";
00838         
00839         if(open_options & QVMPlayerCamera::RGBMEncoder)
00840                 fifo_file_2.close();
00841         qDebug() << "QVMPlayerCamera::closeCam(): closed fifo_file2";
00842         
00843         delete namedPipe;
00844         qDebug() << "mplayercamera2::closecam(): deleted namedpipe";
00845 
00846         if(open_options & QVMPlayerCamera::RGBMEncoder)
00847                 delete namedPipeAux;
00848         qDebug() << "QVMPlayerCamera::closeCam(): deleted namedPipeAux";
00849 
00850         qDebug() << "QVMPlayerCamera::closeCam() <- return";
00851         }
00852 
00853 bool QVMPlayerCamera::grab()
00854         {
00855         qDebug() << "QVMPlayerCamera::grab()";
00856 
00857         if(!performGrab())
00858                 return false;
00859 
00860         if (open_options & QVMPlayerCamera::RGBMEncoder)
00861                 {
00862                 QVImage<uChar,3> grabbedRGBImage;
00863                 mplayerFrameGrabber->getQVImageRGB(grabbedRGBImage);
00864                 setPropertyValue< QVImage<uChar,3> >("RGB image", grabbedRGBImage);
00865                 }
00866         else    {
00867                 QVImage<uChar> grabbedYImage, grabbedUImage, grabbedVImage;
00868                 mplayerFrameGrabber->getQVImageYUV(grabbedYImage, grabbedUImage, grabbedVImage);
00869 
00870                 setPropertyValue< QVImage<uChar,1> >("Y channel image", grabbedYImage);
00871                 setPropertyValue< QVImage<uChar,1> >("U channel image", grabbedUImage);
00872                 setPropertyValue< QVImage<uChar,1> >("V channel image", grabbedVImage);
00873                 }
00874 
00875         writeOutputProperties();
00876 
00877         qDebug() << "QVMPlayerCamera::grab() <~ return";
00878 
00879         return true;
00880         }
00881 
00882 bool QVMPlayerCamera::grab(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV)
00883         {
00884         qDebug() << "QVMPlayerCamera::grab(imageY, imageU, imageV)";
00885         //QVImage<uChar> grabbedYImage, grabbedUImage, grabbedVImage;
00886         //QVImage<uChar,3> grabbedRGBImage;
00887 
00888         bool newImages = performGrab();
00889 
00890         if (newImages)
00891                 mplayerFrameGrabber->getQVImageYUV(imgY, imgU, imgV);
00892 
00893         setPropertyValue< QVImage<uChar,1> >("Y channel image", imgY);
00894         setPropertyValue< QVImage<uChar,1> >("U channel image", imgU);
00895         setPropertyValue< QVImage<uChar,1> >("V channel image", imgV);
00896 
00897         /*imgY = grabbedYImage;
00898         imgU = grabbedUImage;
00899         imgV = grabbedVImage;*/
00900 
00901         qDebug() << "QVMPlayerCamera::grab() <~ return";
00902 
00903         return newImages;
00904         }
00905 
00906 bool QVMPlayerCamera::grab(QVImage<uChar,3> & imageRGB)
00907         {
00908         qDebug() << "QVMPlayerCamera::grab(imageRGB)";
00909         //QVImage<uChar> grabbedYImage, grabbedUImage, grabbedVImage;
00910         //QVImage<uChar,3> grabbedRGBImage;
00911         bool newImages = performGrab();
00912 
00913         if (newImages)
00914                 mplayerFrameGrabber->getQVImageRGB(imageRGB);
00915 
00916         setPropertyValue< QVImage<uChar,3> >("RGB image", imageRGB);
00917         //imageRGB = grabbedRGBImage;
00918         
00919         qDebug() << "QVMPlayerCamera::grab() <~ return";
00920         return newImages;
00921         }
00922 
00923 bool QVMPlayerCamera::grab(QVImage<uChar,1> & imageGray)
00924         {
00925         qDebug() << "QVMPlayerCamera::grab(imageGray)";
00926         //QVImage<uChar> grabbedYImage, grabbedUImage, grabbedVImage;
00927         //QVImage<uChar,3> grabbedRGBImage;
00928 
00929         bool newImages = performGrab();
00930 
00931         if (newImages)
00932                 mplayerFrameGrabber->getQVImageGray(imageGray);
00933 
00934         //imageGray = grabbedYImage;
00935         setPropertyValue< QVImage<uChar,1> >("Y channel image", imageGray);
00936 
00937         qDebug() << "QVMPlayerCamera::grab() <~ return";
00938         return newImages;
00939         }
00940 
00941 bool QVMPlayerCamera::performGrab()
00942         {
00943         // First, if there are any pending commands, we send them to mplayer:
00944         qDebug() << "QVMPlayerCamera::performGrab()";
00945 
00946         if (isClosed()) return false;
00947 
00948         qDebug() << "QVMPlayerCamera::performGrab(): status != Closed";
00949 
00950 /*      qDebug() << "QVMPlayerCamera::performGrab(): sent command to mplayer: get_time_pos";
00951         mplayerIOProcessor->queueCommandToMPlayer("pausing_keep get_time_pos\n",true);
00952 */
00953         bool newFrameGrabbed = false;
00954         // This is for when the camera is paused; it will return the same frames
00955         // over and over, but not immediately, but at a maximum fps rate (to avoid
00956         // intense CPU usage, that will slow the rest of the application and the
00957         // GUI.
00958         // DEPRECATED: uInt milisecsToWait = (getFPS() == 0)? 100 : (uInt)(1000/getFPS());
00959         //uInt milisecsToWait = 0;
00960 
00961         switch(status)
00962                 {
00963                 case RunningOneStep:
00964                         qDebug() << "QVMPlayerCamera::performGrab(): status == RunningOneStep";
00965                         setStatus(Paused);
00966                 case Running:
00967                         qDebug() << "QVMPlayerCamera::performGrab(): status == Running";
00968                         mplayerFrameGrabber->updateFrameBuffer();
00969                         frames_grabbed++;
00970                         newFrameGrabbed = true;
00971                         qDebug() << "QVMPlayerCamera::performGrab(): frames grabbed" << getFramesGrabbed();
00972                         break;
00973 
00974                 case Paused:
00975                         qDebug() << "QVMPlayerCamera::performGrab(): status == Paused";
00976                         /* DEPRECATED: qDebug() << "QVMPlayerCamera::performGrab(): locking";
00977                         mutexJustToSleepMiliseconds.lock();
00978                         qDebug() << "QVMPlayerCamera::performGrab(): pausing" << milisecsToWait
00979                                 << "milisecs (video is "<< getFPS() <<" FPS's)";
00980                         conditionJustToSleepMiliseconds.wait(&mutexJustToSleepMiliseconds,milisecsToWait);
00981                         qDebug() << "QVMPlayerCamera::performGrab(): unlocking";
00982                         mutexJustToSleepMiliseconds.unlock(); */
00983                         break;
00984 
00985                 default:
00986                         break;
00987                 }
00988         qDebug() << "QVMPlayerCamera::performGrab(): checking finished";
00989 
00990         if (mplayerFrameGrabber->finished)
00991                 closeCam();
00992         else
00993                 emit newGrab();
00994 
00995         qDebug() << "QVMPlayerCamera::performGrab() <- return";
00996 
00997         return newFrameGrabbed;
00998         }
00999 
01000 // Pause, unpause, next frame, set speed, seek and close camer slots:
01001 // In all of them, the corresponding command is sent to the shared command queue
01002 // data structure, so access is accordingly protected .
01003 void QVMPlayerCamera::pauseCam()
01004         {
01005         qDebug() << "QVMPlayerCamera::pauseCam()";
01006         if(status == Closed) return;
01007         setStatus(Paused);
01008         qDebug() << "QVMPlayerCamera::pauseCam() <- return";
01009         }
01010 
01011 void QVMPlayerCamera::unpauseCam()
01012         {
01013         qDebug() << "QVMPlayerCamera::unpauseCam()";
01014         if(status == Closed) return;
01015         setStatus(Running);
01016         qDebug() << "QVMPlayerCamera::unpauseCam() <~ return";
01017         }
01018 
01019 void QVMPlayerCamera::nextFrameCam()
01020         {
01021         qDebug() << "QVMPlayerCamera::nextFrameCam()";
01022         if(status == Closed) return;
01023         setStatus(RunningOneStep);
01024         qDebug() << "QVMPlayerCamera::nextFrameCam() <~ return";
01025         }
01026 
01027 void QVMPlayerCamera::setSpeedCam(double d)
01028         {
01029         qDebug() << "QVMPlayerCamera::setSpeedCam()";
01030         if(status == Closed) return;
01031         mplayerIOProcessor->queueCommandToMPlayer(QString("pausing_keep speed_set ") + QString::number(d));
01032         mplayerIOProcessor->queueCommandToMPlayer("get_property speed");
01033         qDebug() << "QVMPlayerCamera::setSpeedCam() <~ return";
01034         }
01035 
01036 void QVMPlayerCamera::seekCam(TSeekType seek,double d)
01037         {
01038         qDebug() << "QVMPlayerCamera::seekCam()";
01039         if(status == Closed) return;
01040         if(status == Paused)
01041                 setStatus(RunningOneStep);
01042         QString command = QString("pausing_keep seek ") + QString::number(d) + " " + QString::number(seek);
01043         mplayerIOProcessor->queueCommandToMPlayer(command);
01044         qDebug() << "QVMPlayerCamera::seekCam() <~ return";
01045         }
01046 
01047 bool QVMPlayerCamera::link(QVWorker* worker, const QString imageName)
01048         {
01049         connect(worker, SIGNAL(startIteration()), this, SLOT(grab()), Qt::DirectConnection);
01050 
01051         if(worker->isType<QVImage<uChar,1> >(imageName))
01052                 return this->linkProperty("Y channel image",worker,imageName,AsynchronousLink);
01053         else if(worker->isType<QVImage<uChar,3> >(imageName))
01054                 {
01055                 rgbMode = true;
01056                 return this->linkProperty("RGB image",worker,imageName,AsynchronousLink);
01057                 }
01058         else
01059                 {
01060                 disconnect(worker, SIGNAL(startIteration()), this, SLOT(grab()));
01061                 std::cerr << "Warning: QVMPlayerCamera::link(): unsupported property type: property " << qPrintable(imageName)
01062                         << " in holder " << qPrintable(worker->getName()) << "is not a QVImage<uChar,1> or QVImage<uChar,3>" << std::endl;
01063                 return FALSE; //Should never get here;
01064                 }
01065         }
01066 
01067 bool QVMPlayerCamera::link(QVWorker* worker, const QString imageNameY, const QString imageNameU, const QString imageNameV)
01068         {
01069         if(!worker->isType< QVImage<uChar,1> >(imageNameY))
01070                 {
01071                 std::cerr << "Warning: QVMPlayerCamera::link(): image " << qPrintable(imageNameY) << "is not of type QVImage<uChar,1> in holder "
01072                         << qPrintable(worker->getName()) << std::endl;
01073                 return FALSE;
01074                 }
01075 
01076         if(!worker->isType< QVImage<uChar,1> >(imageNameU))
01077                 {
01078                 std::cerr << "Warning: QVMPlayerCamera::link(): image " << qPrintable(imageNameU) << "is not of type QVImage<uChar,1> in holder "
01079                         << qPrintable(worker->getName()) << std::endl;
01080                 return FALSE;
01081                 }
01082 
01083         if(!worker->isType< QVImage<uChar,1> >(imageNameV))
01084                 {
01085                 std::cerr << "Warning: QVMPlayerCamera::link(): image " << qPrintable(imageNameV) << "is not of type QVImage<uChar,1> in holder "
01086                         << qPrintable(worker->getName()) << std::endl;
01087                 return FALSE;
01088                 }
01089 
01090         connect(worker, SIGNAL(startIteration()), this, SLOT(grab()), Qt::DirectConnection);
01091         return  this->linkProperty("Y channel image", worker, imageNameY, AsynchronousLink) &&
01092                 this->linkProperty("U channel image", worker, imageNameU, AsynchronousLink) &&
01093                 this->linkProperty("V channel image", worker, imageNameV, AsynchronousLink);
01094         }
01095 

Generated on Thu Dec 13 13:06:26 2007 for QVision by  doxygen 1.5.3