00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 <qvipp.h>
00040
00041 #include <QVWorker>
00042 #include <QVMPlayerCamera>
00043
00044
00045 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)
00046 {
00047 qDebug() << "QVCheckOKMplayerCamera::QVCheckOKMplayerCamera()";
00048 qDebug() << "QVCheckOKMplayerCamera::QVCheckOKMplayerCamera() <- return";
00049 }
00050
00051 QVCheckOKMplayerCamera::~QVCheckOKMplayerCamera()
00052 {
00053 qDebug() << "QVCheckOKMplayerCamera::~QVCheckOKMplayerCamera()";
00054 quit();
00055 wait();
00056 qDebug() << "QVCheckOKMplayerCamera::~QVCheckOKMplayerCamera: thread finished";
00057 qDebug() << "QVCheckOKMplayerCamera::~QVCheckOKMplayerCamera() <- return";
00058 }
00059
00060 void QVCheckOKMplayerCamera::run()
00061 {
00062 qDebug() << "QVCheckOKMplayerCamera::run()";
00063 QTimer::singleShot(_max_time_ms_to_wait_for_open, this, SLOT(writeErrorInFifo()));
00064 qDebug() << "QVCheckOKMplayerCamera::run() <- entering event loop";
00065 exec();
00066 qDebug() << "QVCheckOKMplayerCamera::run() <- back from event loop";
00067 qDebug() << "QVCheckOKMplayerCamera::run() <- return";
00068 }
00069
00070
00071 void QVCheckOKMplayerCamera::writeErrorInFifo()
00072 {
00073 qDebug() << "QVCheckOKMplayerCamera::writeErrorInFifo()";
00074 _fifo_file.write("MPLAYER ERROR\n");
00075 qDebug() << "QVCheckOKMplayerCamera::writeErrorInFifo() -> return";
00076 };
00077
00078
00079 QVCameraThread::QVCameraThread(QObject *object,char *slot): QThread(), _object(object), _slot(slot)
00080 {
00081 qDebug() << "QVCameraThread::QVCameraThread()";
00082 _object->moveToThread(this);
00083 qDebug() << "QVCameraThread::QVCameraThread(): object moved to thread";
00084 qDebug() << "QVCameraThread::QVCameraThread() <- return";
00085 }
00086
00087 QVCameraThread::~QVCameraThread()
00088 {
00089 qDebug() << "QVCameraThread::~QVCameraThread()";
00090 disconnect();
00091 quit();
00092 qDebug() << "QVCameraThread::~QVCameraThread(): sent quit to thread";
00093 wait();
00094 qDebug() << "QVCameraThread::~QVCameraThread(): thread finished";
00095 qDebug() << "QVCameraThread::~QVCameraThread() <- return";
00096 }
00097
00098 void QVCameraThread::run()
00099 {
00100 qDebug() << "QVCameraThread::run()";
00101 QTimer *timer = new QTimer();
00102 timer->start(0);
00103 connect(timer, SIGNAL(timeout()),_object,_slot);
00104 qDebug() << "QVCameraThread::run(): timer created, started and connected";
00105 qDebug() << "QVCameraThread::run(): entering event processing loop";
00106 exec();
00107 qDebug() << "QVCameraThread::run(): back from event processing loop";
00108 delete timer;
00109 qDebug() << "QVCameraThread::run(): timer deleted";
00110 qDebug() << "QVCameraThread::run() <- return";
00111 }
00112
00113
00114 QVMPlayerIOProcessor::QVMPlayerIOProcessor(QProcess * mplayer): QObject(), command_queue(), command_queue_mutex()
00115 {
00116 qDebug() << "QVMPlayerIOProcessor::QVMPlayerIOProcessor()";
00117 rows = cols = 0;
00118 fps = time_length = time_pos = 0;
00119 speed = 1;
00120 this->mplayer = mplayer;
00121 mplayer->waitForReadyRead();
00122 qDebug() << "QVMPlayerIOProcessor::QVMPlayerIOProcessor() <- return";
00123 }
00124
00125 QVMPlayerIOProcessor::~QVMPlayerIOProcessor()
00126 {
00127 qDebug() << "QVMPlayerIOProcessor::~QVMPlayerIOProcessor()";
00128 qDebug() << "QVMPlayerIOProcessor::~QVMPlayerIOProcessor() <- return";
00129 }
00130
00131 void QVMPlayerIOProcessor::queueCommandToMPlayer(const QString &com_str, bool ifEmpty)
00132 {
00133 qDebug() << "QVMPlayerIOProcessor::queueCommand("<< com_str <<")";
00134 qDebug() << "QVMPlayerIOProcessor::queueCommand(): command_queue.size() = "
00135 << command_queue.size();
00136 command_queue_mutex.lock();
00137 if(!ifEmpty || command_queue.size()==0)
00138 command_queue << com_str + '\n';
00139 command_queue_mutex.unlock();
00140 qDebug() << "QVMPlayerIOProcessor::queueCommand() <- return";
00141 }
00142
00143 void QVMPlayerIOProcessor::sendCommandToMPlayer()
00144 {
00145 qDebug() << "QVMPlayerIOProcessor::sendCommandToMPlayer()";
00146 command_queue_mutex.lock();
00147 if (command_queue.size() > 0)
00148 {
00149 qDebug() << "QVMPlayerIOProcessor::sendCommandToMPlayer(): sending command:" << command_queue.head();
00150 mplayer->write(qPrintable(command_queue.dequeue()));
00151 }
00152 command_queue_mutex.unlock();
00153 qDebug() << "QVMPlayerIOProcessor::sendCommandToMPlayer(): wait for bytes written";
00154
00155 #ifdef unix
00156 mplayer->waitForBytesWritten();
00157 #endif
00158 qDebug() << "QVMPlayerIOProcessor::sendCommandToMPlayer() <- return";
00159 }
00160
00161 int QVMPlayerIOProcessor::interpretMPlayerOutput()
00162 {
00163 qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput()";
00164 int length = -1;
00165 char buf[1024];
00166
00167 length = mplayer->readLine(buf, sizeof(buf));
00168
00169 if (length == -1)
00170 qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): length == -1";
00171 else {
00172 QString str(buf);
00173 QStringList variables = str.simplified().split("=");
00174 QStringList palabras = str.simplified().split(" ");
00175
00176 if(variables[0] == "ANS_speed")
00177 {
00178 speed = variables[1].toDouble();
00179 qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): updating speed =" << speed;
00180 }
00181 else if(variables[0] == "ANS_LENGTH")
00182 {
00183 time_length = variables[1].toDouble();
00184 qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): updating time_length =" << time_length;
00185 }
00186 else if(variables[0] == "ANS_TIME_POSITION")
00187 {
00188 time_pos = variables[1].toDouble();
00189 qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): updating time_pos =" << time_pos;
00190 }
00191 else if (palabras[0] == "VIDEO:")
00192 {
00193
00194 for (int i = 0; i < palabras.size(); ++i)
00195 if (palabras[i] == "fps")
00196 fps = palabras[i-1].toDouble();
00197
00198 qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): updating fps" << fps;
00199 }
00200 else if (palabras[0] == "VO:")
00201 {
00202
00203 QStringList dimensiones = palabras[2].split("x");
00204 cols = dimensiones[0].toInt();
00205 rows = dimensiones[1].toInt();
00206 qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): updating cols" << cols;
00207 qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): updating rows" << rows;
00208 }
00209 else
00210 qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput(): uninterpreted mplayer output:" << str;
00211 }
00212 qDebug() << "QVMPlayerIOProcessor::interpretMPlayerOutput() <- return" << length;
00213 return length;
00214 }
00215
00216
00217 QVMPlayerFrameGrabber::QVMPlayerFrameGrabber(QVMPlayerIOProcessor *mplayerIOProcessor, QFile *fifoInput, uInt rows, uInt cols, bool realTime): QObject()
00218 {
00219 qDebug() << "QVMPlayerFrameGrabber::QVMPlayerFrameGrabber(fifoInput," << mplayerIOProcessor->rows << "," << mplayerIOProcessor->cols
00220 << "," << realTime <<")";
00221
00222 this->mplayerIOProcessor = mplayerIOProcessor;
00223 this->fifoInput = fifoInput;
00224 this->realTime = realTime;
00225 this->finished = false;
00226 this->frames_read = 0;
00227
00228 debug_in_memcpy = debug_in_updateSlot = false;
00229
00231 imgY = QVImage<uChar>(cols, rows, cols);
00232
00233 img_auxY = QVImage<uChar>(cols, rows, cols);
00234 img_auxU = QVImage<uChar>(cols/2, rows/2, cols/2);
00235 img_auxV = QVImage<uChar>(cols/2, rows/2, cols/2);
00236
00237
00238
00239
00240 buf_size = rows*cols + rows*cols/4 + rows*cols/4;
00241
00242 if (realTime)
00243 {
00244 qvcamerathread = new QVCameraThread(this,SLOT(updateSlot()));
00245 qvcamerathread->start(QThread::NormalPriority);
00246 }
00247
00248 qDebug() << "QVMPlayerFrameGrabber::QVMPlayerFrameGrabber() <- return";
00249 };
00250
00251 QVMPlayerFrameGrabber::~QVMPlayerFrameGrabber()
00252 {
00253 qDebug() << "QVMPlayerFrameGrabber::~QVMPlayerFrameGrabber()";
00254 finished = true;
00255 if (realTime) delete qvcamerathread;
00256 qDebug() << "QVMPlayerFrameGrabber::~QVMPlayerFrameGrabber(): thread deleted.";
00257 qDebug() << "QVMPlayerFrameGrabber::~QVMPlayerFrameGrabber() <- return";
00258 }
00259
00260 void QVMPlayerFrameGrabber::getNewFrame(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV)
00261 {
00262 qDebug() << "QVMPlayerFrameGrabber::getNewFrame(): reading YUV header";
00263 char buf[1024];
00264 fifoInput->readLine(buf, sizeof(buf));
00265 readToBuffer(imgY.getWriteData(), 2*buf_size/3);
00266 readToBuffer(imgU.getWriteData(), buf_size/6);
00267 readToBuffer(imgV.getWriteData(), buf_size/6);
00268 qDebug() << "QVMPlayerFrameGrabber::getNewFrame() <- return";
00269 }
00270
00271 void QVMPlayerFrameGrabber::updateSlot()
00272 {
00273 qDebug() << "QVMPlayerFrameGrabber::updateSlot()";
00274
00275 qDebug() << "QVMPlayerFrameGrabber::updateSlot(): sent command to mplayer: get_time_pos";
00276 mplayerIOProcessor->queueCommandToMPlayer("pausing_keep get_time_pos\n",true);
00277
00278
00279 emit sendCommandSignal();
00280
00281
00282 qDebug() << "QVMPlayerFrameGrabber::updateSlot(): reading frame";
00283 QVImage<uChar, 1> tempY;
00284 QVImage<uChar, 1> tempU;
00285 QVImage<uChar, 1> tempV;
00286
00287
00288
00289
00290 getNewFrame(tempY = img_auxY, tempU = img_auxU, tempV = img_auxV);
00291
00292
00293
00294 if(realTime)
00295 {
00296 mutex.lock();
00297 debug_in_updateSlot = true;
00298 if (debug_in_memcpy)
00299 {
00300 std::cerr << "(BUG1) entered frameUpdate while memcpying!";
00301 exit(0);
00302 }
00303 }
00304
00305 img_auxY = tempY;
00306 img_auxU = tempU;
00307 img_auxV = tempV;
00308
00309
00310 if(realTime)
00311 {
00312 if (debug_in_memcpy) {
00313 std::cerr << "(BUG2) entered frameUpdate while memcpying!";
00314 exit(0);
00315 }
00316 debug_in_updateSlot = false;
00317 condition.wakeAll();
00318 mutex.unlock();
00319 }
00320
00321 qDebug() << "QVMPlayerFrameGrabber::updateSlot(): finished" << finished;
00322 frames_read++;
00323 qDebug() << "QVMPlayerFrameGrabber::updateSlot(): frames read" << frames_read;
00324
00325 mplayerIOProcessor->interpretMPlayerOutput();
00326
00327 qDebug() << "QVMPlayerFrameGrabber::updateSlot() <- return";
00328
00329 emit newReadFrameGrabber();
00330 }
00331
00332 void QVMPlayerFrameGrabber::updateFrameBuffer()
00333 {
00334 qDebug() << "QVMPlayerFrameGrabber::updateFrameBuffer()";
00335
00336
00337
00338
00339
00340
00341
00342 mutex.lock();
00343 if (debug_in_updateSlot)
00344 {
00345 std::cerr << "(BUG3) entered memcpy while frameUpdating!";
00346 exit(0);
00347 }
00348
00349 if(realTime)
00350 condition.wait(&mutex);
00351 debug_in_memcpy = true;
00352
00353
00354
00355 if(not realTime)
00356 updateSlot();
00357
00358 imgY = img_auxY;
00359 imgU = img_auxU;
00360 imgV = img_auxV;
00361
00362
00363 if (debug_in_updateSlot)
00364 {
00365 std::cerr << "(BUG4) entered memcpy while frameUpdating!";
00366 exit(0);
00367 }
00368 debug_in_memcpy = false;
00369 mutex.unlock();
00370
00371 qDebug() << "QVMPlayerFrameGrabber::updateFrameBuffer() <- return";
00372 }
00373
00374 void QVMPlayerFrameGrabber::getQVImageYUV(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV) const
00375 {
00376 qDebug() << "QVMPlayerFrameGrabber::getQVImageYUV()";
00377 imgY = this->imgY;
00378 imgU = this->imgU;
00379 imgV = this->imgV;
00380 qDebug() << "QVMPlayerFrameGrabber::getQVImageYUV() <- return";
00381 }
00382
00383 void QVMPlayerFrameGrabber::getQVImageGray(QVImage<uChar> &imgGray) const
00384 {
00385 qDebug() << "QVMPlayerFrameGrabber::getQVImageGray()";
00386 imgGray = imgY;
00387 qDebug() << "QVMPlayerFrameGrabber::getQVImageGray() <- return";
00388 }
00389
00390 void QVMPlayerFrameGrabber::readToBuffer(uChar *buf_img_aux, uInt buf_size)
00391 {
00392 uInt totbytes = 0;
00393 while (totbytes != buf_size and not finished)
00394 {
00395 int nbytes = fifoInput->read((char *)(buf_img_aux+totbytes), buf_size-totbytes);
00396
00397 totbytes += nbytes;
00398 qDebug() << "QVMPlayerFrameGrabber::readNewFrame(): read" << nbytes << "bytes";
00399
00400 if(nbytes == 0)
00401 {
00402 finished = TRUE;
00403 qDebug() << "QVMPlayerFrameGrabber::readNewFrame(): read 0 bytes, finishing" << finished;
00404 break;
00405 }
00406
00407 if(nbytes == -1)
00408 {
00409
00410
00411 finished = TRUE;
00412 qDebug() << "QVMPlayerFrameGrabber::readNewFrame(): error -" << fifoInput->errorString();
00413 break;
00414 }
00415 }
00416 }
00417
00418
00419 QVMPlayerCamera::QVMPlayerCamera(QString name):QVCamera(name), open_options(Default)
00420 {
00421 qDebug() << "QVMPlayerCamera::QVMPlayerCamera()";
00422 if (qvApp == NULL)
00423 {
00424 QString str = "QVWorker::QVWorker(): the QVWorker cannot be created before the QVApplication instance. Aborting now.";
00425 std::cerr << qPrintable(str) << std::endl;
00426 exit(1);
00427 }
00428
00429 frames_grabbed = 0;
00430 rgbMode = false;
00431 setStatus(Closed);
00432 live_camera = FALSE;
00433
00434
00435 addProperty<int>("Rows", inputFlag, 0, "Rows to open the camera");
00436 addProperty<int>("Cols", inputFlag, 0, "Columns to open the camera");
00437 addProperty<bool>("RealTime", inputFlag, FALSE,"If the camera should be opened in real time mode");
00438 addProperty<bool>("Deinterlaced", inputFlag, FALSE,"If the camera should be opened in deinterlaced mode");
00439 addProperty<bool>("NoLoop", inputFlag, FALSE,"If the camera should be opened in no loop mode");
00440
00441 addProperty<QString>("URL", inputFlag, QString(""),"URL of the video source");
00442
00443
00444
00445 addProperty< QVImage<uChar,3> >("RGB image", outputFlag, QVImage<uChar,3>(), "Last grabbed RGB image");
00446 addProperty< QVImage<uChar,1> >("Y channel image",outputFlag, QVImage<uChar,1>(), "Last grabbed Y channel image");
00447 addProperty< QVImage<uChar,1> >("U channel image",outputFlag, QVImage<uChar,1>(), "Last grabbed U channel image");
00448 addProperty< QVImage<uChar,1> >("V channel image",outputFlag, QVImage<uChar,1>(), "Last grabbed V channel image");
00449
00450 qDebug() << "QVMPlayerCamera::QVMPlayerCamera() <- return";
00451 }
00452
00453 QVMPlayerCamera::~QVMPlayerCamera()
00454 {
00455 qDebug() << "QVMPlayerCamera::~QVMPlayerCamera()";
00456 if (status != Closed) closeCam();
00457 qDebug() << "QVMPlayerCamera::~QVMPlayerCamera() <- deleting image";
00458 setImageBuffer(NULL);
00459 qDebug() << "QVMPlayerCamera::~QVMPlayerCamera() <- return";
00460 }
00461
00462 void QVMPlayerCamera::initMPlayerArgs(QString urlString, uInt rows, uInt cols)
00463 {
00464 qDebug() << "QVMPlayerCamera::initMPlayerArgs()";
00465 qDebug() << "QVMPlayerCamera::initMPlayerArgs(): url string =" << urlString;
00466
00467
00468 if(not (open_options & NoLoop)) mplayer_args << "-loop" << "0";
00469
00470 mplayer_args << "-fixed-vo";
00471
00472 QUrl url(urlString);
00473
00474 if (url.host() != "")
00475 path = url.host() + "/";
00476
00477 path += url.path();
00478
00479 qDebug() << "QVMPlayerCamera::initMPlayerArgs(): path" << path;
00480
00481
00482
00483
00484 if (url.scheme() != "")
00485 schema = url.scheme();
00486 else if (urlString.startsWith("/dev/video"))
00487 schema = "v4l";
00488 else if (urlString.startsWith("/dev/dv"))
00489 schema = "dv";
00490 else if (urlString.contains("*"))
00491 schema = "mf";
00492 else if (urlString.startsWith("www."))
00493 schema = "http";
00494 else if (urlString.startsWith("ftp."))
00495 schema = "ftp";
00496
00497 qDebug() << "QVMPlayerCamera::initMPlayerArgs(): scheme" << schema;
00498
00499 live_camera = TRUE;
00500
00501
00502 if ((schema == "v4l") or (schema == "v4l2") or (schema == "analog"))
00503 {
00504
00505 QString urlQueryValues = QString("driver=%1:device=%2").arg(schema).arg(path);
00506
00507 QList<QPair<QString, QString> > queryItems = url.queryItems();
00508 for (int i = 0; i < queryItems.size(); ++i)
00509 urlQueryValues += ":" + queryItems.at(i).first + "=" + queryItems.at(i).second;
00510
00511 mplayer_args << "tv://" << "-tv" << urlQueryValues;
00512 }
00513 else if (schema == "dv")
00514
00515 mplayer_args << path << "-demuxer" << "rawdv" << "-cache" << "400";
00516 else if (schema == "iidc")
00517
00518
00519 qFatal("Currently this driver does not work (apparently with\n"
00520 "vloopback writing and then reading from a fifo with mplayer\ndoes not work).\n");
00521 else if (schema == "tv")
00522
00523 qFatal("tv URL: Still not implemented\n");
00524 else if (schema == "dvb")
00525
00526 qFatal("dvb URL: Still not implemented\n");
00527 else
00528 {
00529
00530 live_camera = FALSE;
00531 if (schema != "")
00532 mplayer_args << QString(schema + "://" + path);
00533 else
00534 mplayer_args << path;
00535 }
00536
00537
00538
00539 QString aux;
00540
00541
00542 if(open_options & Deinterlaced) aux = "pp=md";
00543
00544 if(rows != 0 or cols != 0)
00545 {
00546 if(aux != QString())
00547 aux += QString(",scale=%1:%2").arg(cols).arg(rows);
00548 else
00549 aux = QString("scale=%1:%2").arg(cols).arg(rows);
00550 }
00551
00552 if (aux != QString()) mplayer_args << "-vf" << aux;
00553
00554
00555 if(not (open_options & RealTime))
00556 {
00557 if(not live_camera)
00558 mplayer_args << "-benchmark";
00559 else
00560
00561
00562 qWarning("Warning: opening live cameras in continuous mode "
00563 "wastes less CPU time, but it is prone to delays in "
00564 "the pipe of images if your process is slower than "
00565 "the camera.");
00566 }
00567
00568
00569 mplayer_args << "-slave" << "-quiet" << "-nosound" << "-vo" << QString("yuv4mpeg:file=%1").arg(namedPipe->getInputFilePath());
00570
00571 qDebug() << "QVMPlayerCamera::initMPlayerArgs() <- return";
00572 }
00573
00574
00575
00576 bool QVMPlayerCamera::openCam()
00577 {
00578 OpenOptions optsProp = Default;
00579
00580 readInputProperties();
00581
00582 if (getPropertyValue<bool>("RealTime")) optsProp |= RealTime;
00583 if (getPropertyValue<bool>("Deinterlaced")) optsProp |= Deinterlaced;
00584 if (getPropertyValue<bool>("NoLoop")) optsProp |= NoLoop;
00585 if (rgbMode) optsProp |= RGBMEncoder;
00586
00587 return openCam(getPropertyValue<QString>("URL"), getPropertyValue<int>("Rows"), getPropertyValue<int>("Cols"), optsProp);
00588 }
00589
00590
00591 bool QVMPlayerCamera::openCam(const QString & urlstring,OpenOptions opts)
00592 { return openCam(urlstring,0,0,opts); }
00593
00594
00595 bool QVMPlayerCamera::openCam(const QString & urlstring, uInt rows, uInt cols, OpenOptions opts)
00596 {
00597 qDebug() << "QVMPlayerCamera::openCam(" << urlstring << "," << rows << "," << cols << "," << opts << ")";
00598
00599 setStatus(Closed);
00600
00601 open_options = opts;
00602
00603
00604 namedPipe = new QNamedPipe(QString("mplayer"));
00605 fifo_file.setFileName(namedPipe->getOutputFilePath());
00606
00607 initMPlayerArgs(urlstring, rows, cols);
00608
00609 qDebug() << "QVMPlayerCamera::openCam(): MPlayer args ->" << mplayer_args;
00610 mplayer.start(MPLAYER_BINARY_PATH,mplayer_args);
00611 qDebug() << "QVMPlayerCamera::openCam(): after mplayer.start()";
00612 if(not mplayer.waitForStarted(1000))
00613 qFatal("Mplayer failed to start: Are you sure it is installed and in the correct PATH?");
00614 qDebug() << "QVMPlayerCamera::openCam(): after mplayer.waitForstarted()";
00615
00616
00617
00618
00619
00620
00621
00622 QVCheckOKMplayerCamera *check_thread;
00623 if (schema == "http" or schema == "ftp" or schema == "rtsp" or schema == "dvd" or schema == "vcd")
00624 check_thread = new QVCheckOKMplayerCamera(fifo_file, 10000);
00625 else
00626 check_thread = new QVCheckOKMplayerCamera(fifo_file, 2000);
00627
00628 check_thread->moveToThread(check_thread);
00629 check_thread->start();
00630 qDebug() << "QVMPlayerCamera::openCam(): after starting QVCheckOKMplayerCamera thread";
00631
00632
00633
00634
00635 qDebug() << "QVMPlayerCamera::openCam(): opening fifo_file";
00636 if((fifo_file.open(QIODevice::ReadWrite|QIODevice::Unbuffered)) == -1)
00637 qFatal("Error opening fifo %s\n", qPrintable(namedPipe->getPipeName()));
00638 qDebug() << "QVMPlayerCamera::openCam(): reading fifo_file";
00639
00640
00641 char buf[1024];
00642 int len;
00643 if ((len = fifo_file.readLine(buf, sizeof(buf))) == -1) return FALSE;
00644 if (QString(buf) == QString("MPLAYER ERROR\n")) {
00645 std::cerr << "QVMPlayerCamera::openCam(): Warning: Mplayer could not open the requested video source (" << qPrintable(urlstring) << ") of type " << qPrintable(schema) <<std::endl;
00646 check_thread->quit();
00647 check_thread->wait();
00648 delete check_thread;
00649
00650
00651 mplayer.terminate();
00652 if (not mplayer.waitForFinished(500)) mplayer.kill();
00653 fifo_file.close();
00654 delete namedPipe;
00655
00656 qDebug() << "QVMPlayerCamera::openCam(): QVCheckOKMplayerCamera thread deleted after detecting an error; returning FALSE";
00657 return FALSE;
00658 }
00659
00660 check_thread->quit();
00661 check_thread->wait();
00662
00663 delete check_thread;
00664 qDebug() << "QVMPlayerCamera::openCam(): QVCheckOKMplayerCamera thread deleted after correct launch of mplayer";
00665
00666 qDebug() << "QVMPlayerCamera::openCam(): going to create QVMPlayerIOProcessor...";
00667 mplayerIOProcessor = new QVMPlayerIOProcessor(&mplayer);
00668
00669 qDebug() << "QVMPlayerCamera::openCam(): waiting for initialization.";
00670 while(getRows() == 0 || getCols() == 0)
00671 mplayerIOProcessor->interpretMPlayerOutput();
00672
00673 qDebug() << "QVMPlayerCamera::openCam(): video dims (" << getCols() << "," << getRows() << ")";
00674 qDebug() << "QVMPlayerCamera::openCam(): fps " << getFPS();
00675
00676 mplayerIOProcessor->queueCommandToMPlayer("get_time_length");
00677
00678 setImageBuffer(new QVImage<uChar,1>(getRows(), getCols(), getCols()));
00679 mplayerFrameGrabber = new QVMPlayerFrameGrabber(mplayerIOProcessor, &fifo_file, getRows(), getCols(), open_options & QVMPlayerCamera::RealTime);
00680
00681 connect(mplayerFrameGrabber,SIGNAL(newReadFrameGrabber()),this,SIGNAL(newRead()));
00682
00683
00684
00685
00686 connect(mplayerFrameGrabber,SIGNAL(sendCommandSignal()),mplayerIOProcessor,SLOT(sendCommandToMPlayer()));
00687 connect(this,SIGNAL(sendCommandSignal()),mplayerIOProcessor,SLOT(sendCommandToMPlayer()));
00688
00689 setStatus(Running);
00690
00691 qDebug() << "QVMPlayerCamera::openCam() <- return";
00692
00693 emit camOpened();
00694
00695
00696
00697 return TRUE;
00698 }
00699
00700
00701 void QVMPlayerCamera::closeCam()
00702 {
00703 qDebug() << "QVMPlayerCamera::closeCam()";
00704
00705 if (status == Closed)
00706 {
00707 qDebug() << "QVMPlayerCamera::closeCam(): camera already closed. Returning";
00708 qDebug() << "QVMPlayerCamera::closeCam() <- return";
00709 return;
00710 }
00711
00712 setStatus(Closed);
00713
00714 emit camClosed();
00715
00716 mplayerIOProcessor->queueCommandToMPlayer("quit");
00717
00718 emit sendCommandSignal();
00719
00720 delete mplayerFrameGrabber;
00721 qDebug() << "QVMPlayerCamera::closeCam(): mplayerFrameGrabber deleted";
00722
00723 delete mplayerIOProcessor;
00724 qDebug() << "QVMPlayerCamera::closeCam(): mplayerIOProcessor deleted";
00725
00726 mplayer.terminate();
00727 while (not mplayer.waitForFinished(500)) mplayer.kill();
00728 qDebug() << "QVMPlayerCamera::closeCam(): mplayer terminated";
00729
00730 fifo_file.close();
00731 qDebug() << "QVMPlayerCamera::closeCam(): closed fifo_file";
00732
00733 delete namedPipe;
00734 qDebug() << "QVMPlayerCamera::closecam(): deleted namedpipe";
00735
00736 qDebug() << "QVMPlayerCamera::closeCam() <- return";
00737 }
00738
00739 bool QVMPlayerCamera::grab()
00740 {
00741 qDebug() << "QVMPlayerCamera::grab()";
00742
00743 if(!performGrab())
00744 return false;
00745
00746 QVImage<uChar> grabbedYImage, grabbedUImage, grabbedVImage;
00747 mplayerFrameGrabber->getQVImageYUV(grabbedYImage, grabbedUImage, grabbedVImage);
00748
00749 setPropertyValue< QVImage<uChar,1> >("Y channel image", grabbedYImage);
00750 setPropertyValue< QVImage<uChar,1> >("U channel image", grabbedUImage);
00751 setPropertyValue< QVImage<uChar,1> >("V channel image", grabbedVImage);
00752
00753 if (open_options & QVMPlayerCamera::RGBMEncoder)
00754 {
00755 QVImage<uChar,3> grabbedRGBImage(grabbedYImage.getCols(),grabbedYImage.getRows());
00756 YUV420ToRGB(grabbedYImage, grabbedUImage, grabbedVImage, grabbedRGBImage);
00757 setPropertyValue< QVImage<uChar,3> >("RGB image", grabbedRGBImage);
00758 }
00759
00760
00761
00762
00763
00764
00765
00766
00767 writeOutputProperties();
00768
00769 qDebug() << "QVMPlayerCamera::grab() <~ return";
00770
00771 return true;
00772 }
00773
00774 bool QVMPlayerCamera::grab(QVImage<uChar> &imgY, QVImage<uChar> &imgU, QVImage<uChar> &imgV)
00775 {
00776 qDebug() << "QVMPlayerCamera::grab(imageY, imageU, imageV)";
00777
00778 bool newImages = performGrab();
00779
00780 if (newImages)
00781 mplayerFrameGrabber->getQVImageYUV(imgY, imgU, imgV);
00782
00783 setPropertyValue< QVImage<uChar,1> >("Y channel image", imgY);
00784 setPropertyValue< QVImage<uChar,1> >("U channel image", imgU);
00785 setPropertyValue< QVImage<uChar,1> >("V channel image", imgV);
00786
00787 qDebug() << "QVMPlayerCamera::grab() <~ return";
00788
00789 return newImages;
00790 }
00791
00792 bool QVMPlayerCamera::grab(QVImage<uChar,3> & imageRGB)
00793 {
00794 qDebug() << "QVMPlayerCamera::grab(imageRGB)";
00795 bool newImages = performGrab();
00796
00797 QVImage<uChar> grabbedYImage, grabbedUImage, grabbedVImage;
00798
00799 if (newImages)
00800 {
00801 mplayerFrameGrabber->getQVImageYUV(grabbedYImage, grabbedUImage, grabbedVImage);
00802
00803 imageRGB = QVImage<uChar,3>(grabbedYImage.getCols(),grabbedYImage.getRows());
00804 YUV420ToRGB(grabbedYImage, grabbedUImage, grabbedVImage, imageRGB);
00805 }
00806
00807 setPropertyValue< QVImage<uChar,3> >("RGB image", imageRGB);
00808
00809 qDebug() << "QVMPlayerCamera::grab() <~ return";
00810 return newImages;
00811 }
00812
00813 bool QVMPlayerCamera::grab(QVImage<uChar,1> & imageGray)
00814 {
00815 qDebug() << "QVMPlayerCamera::grab(imageGray)";
00816
00817 bool newImages = performGrab();
00818
00819 if (newImages)
00820 mplayerFrameGrabber->getQVImageGray(imageGray);
00821
00822 setPropertyValue< QVImage<uChar,1> >("Y channel image", imageGray);
00823
00824 qDebug() << "QVMPlayerCamera::grab() <~ return";
00825 return newImages;
00826 }
00827
00828 bool QVMPlayerCamera::performGrab()
00829 {
00830
00831 qDebug() << "QVMPlayerCamera::performGrab()";
00832
00833 if (isClosed()) return false;
00834
00835 qDebug() << "QVMPlayerCamera::performGrab(): status != Closed";
00836
00837 bool newFrameGrabbed = false;
00838
00839
00840
00841
00842
00843 switch(status)
00844 {
00845 case RunningOneStep:
00846 qDebug() << "QVMPlayerCamera::performGrab(): status == RunningOneStep";
00847 setStatus(Paused);
00848 case Running:
00849 qDebug() << "QVMPlayerCamera::performGrab(): status == Running";
00850 mplayerFrameGrabber->updateFrameBuffer();
00851 frames_grabbed++;
00852 newFrameGrabbed = true;
00853 qDebug() << "QVMPlayerCamera::performGrab(): frames grabbed" << getFramesGrabbed();
00854 break;
00855
00856 case Paused:
00857 qDebug() << "QVMPlayerCamera::performGrab(): status == Paused";
00858
00859
00860
00861
00862
00863
00864
00865 break;
00866
00867 default:
00868 break;
00869 }
00870 qDebug() << "QVMPlayerCamera::performGrab(): checking finished";
00871
00872 if (mplayerFrameGrabber->finished)
00873 closeCam();
00874 else
00875 emit newGrab();
00876
00877 qDebug() << "QVMPlayerCamera::performGrab() <- return";
00878
00879 return newFrameGrabbed;
00880 }
00881
00882
00883
00884
00885 void QVMPlayerCamera::pauseCam()
00886 {
00887 qDebug() << "QVMPlayerCamera::pauseCam()";
00888 if(status == Closed) return;
00889 setStatus(Paused);
00890 qDebug() << "QVMPlayerCamera::pauseCam() <- return";
00891 }
00892
00893 void QVMPlayerCamera::unpauseCam()
00894 {
00895 qDebug() << "QVMPlayerCamera::unpauseCam()";
00896 if(status == Closed) return;
00897 setStatus(Running);
00898 qDebug() << "QVMPlayerCamera::unpauseCam() <~ return";
00899 }
00900
00901 void QVMPlayerCamera::nextFrameCam()
00902 {
00903 qDebug() << "QVMPlayerCamera::nextFrameCam()";
00904 if(status == Closed) return;
00905 setStatus(RunningOneStep);
00906 qDebug() << "QVMPlayerCamera::nextFrameCam() <~ return";
00907 }
00908
00909 void QVMPlayerCamera::setSpeedCam(double d)
00910 {
00911 qDebug() << "QVMPlayerCamera::setSpeedCam()";
00912 if(status == Closed) return;
00913 mplayerIOProcessor->queueCommandToMPlayer(QString("pausing_keep speed_set ") + QString::number(d));
00914 mplayerIOProcessor->queueCommandToMPlayer("get_property speed");
00915 qDebug() << "QVMPlayerCamera::setSpeedCam() <~ return";
00916 }
00917
00918 void QVMPlayerCamera::seekCam(TSeekType seek,double d)
00919 {
00920 qDebug() << "QVMPlayerCamera::seekCam()";
00921 if(status == Closed) return;
00922 if(status == Paused)
00923 setStatus(RunningOneStep);
00924 QString command = QString("pausing_keep seek ") + QString::number(d) + " " + QString::number(seek);
00925 mplayerIOProcessor->queueCommandToMPlayer(command);
00926 qDebug() << "QVMPlayerCamera::seekCam() <~ return";
00927 }
00928
00929 bool QVMPlayerCamera::link(QVWorker* worker, const QString imageName)
00930 {
00931 if(worker->isType<QVImage<uChar,1> >(imageName))
00932 {
00933 connect(worker, SIGNAL(startIteration()), this, SLOT(grab()), Qt::DirectConnection);
00934 return this->linkProperty("Y channel image", worker, imageName, AsynchronousLink);
00935 }
00936 else if(worker->isType<QVImage<uChar,3> >(imageName))
00937 {
00938 rgbMode = true;
00939 connect(worker, SIGNAL(startIteration()), this, SLOT(grab()), Qt::DirectConnection);
00940 return this->linkProperty("RGB image", worker, imageName, AsynchronousLink);
00941 }
00942 else
00943 {
00944 std::cerr << "Warning: QVMPlayerCamera::link(): unsupported property type: property " << qPrintable(imageName)
00945 << " in holder " << qPrintable(worker->getName()) << "is not a QVImage<uChar,1> or QVImage<uChar,3>" << std::endl;
00946 return FALSE;
00947 }
00948 }
00949
00950 bool QVMPlayerCamera::link(QVWorker* worker, const QString imageNameY, const QString imageNameU, const QString imageNameV)
00951 {
00952 if(!worker->isType< QVImage<uChar,1> >(imageNameY))
00953 {
00954 std::cerr << "Warning: QVMPlayerCamera::link(): image " << qPrintable(imageNameY) << "is not of type QVImage<uChar,1> in holder "
00955 << qPrintable(worker->getName()) << std::endl;
00956 return FALSE;
00957 }
00958
00959 if(!worker->isType< QVImage<uChar,1> >(imageNameU))
00960 {
00961 std::cerr << "Warning: QVMPlayerCamera::link(): image " << qPrintable(imageNameU) << "is not of type QVImage<uChar,1> in holder "
00962 << qPrintable(worker->getName()) << std::endl;
00963 return FALSE;
00964 }
00965
00966 if(!worker->isType< QVImage<uChar,1> >(imageNameV))
00967 {
00968 std::cerr << "Warning: QVMPlayerCamera::link(): image " << qPrintable(imageNameV) << "is not of type QVImage<uChar,1> in holder "
00969 << qPrintable(worker->getName()) << std::endl;
00970 return FALSE;
00971 }
00972
00973 connect(worker, SIGNAL(startIteration()), this, SLOT(grab()), Qt::DirectConnection);
00974 return this->linkProperty("Y channel image", worker, imageNameY, AsynchronousLink) &&
00975 this->linkProperty("U channel image", worker, imageNameU, AsynchronousLink) &&
00976 this->linkProperty("V channel image", worker, imageNameV, AsynchronousLink);
00977 }
00978
00979 bool QVMPlayerCamera::unlink(QVWorker* worker, const QString imageName)
00980 {
00981 disconnect(worker, SIGNAL(startIteration()), this, SLOT(grab()));
00982
00983 if (rgbMode) {
00984 return unlinkProperty("RGB image", worker, imageName);
00985 }
00986 else {
00987 return unlinkProperty("Y channel image", worker, imageName);
00988 }
00989 }
00990