PARP Research Group University of Murcia, Spain


src/qvio/qvyuv4mpeg2cameraworker.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007, 2008, 2009. 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 <QVYUV4MPEG2CameraWorker>
00026 #include <qvipp.h>
00027 
00028 #include <qvdefines.h>
00029 
00030 bool QVYUV4MPEG2CameraWorker::openCam(QString fileName, int &cols, int &rows, int &fps)
00031         {
00032         total_frames = 0;
00033         total_time = 0.0;
00034         current_time = 0.0;
00035 
00036         // We initially save requested number or rows and cols:
00037         out_rows = rows;
00038         out_cols = cols;
00039 
00040         // RealTime flag:
00041         realTime = getPropertyValue<bool>("RealTime");
00042 
00043         // Try to open file, and read yuv4mpeg2 header.
00044         videoFile.setFileName(fileName);
00045         if (!videoFile.exists())
00046                 {
00047                 QString msg = QString("QVYUV4MPEG2CameraWorker::openCam: File '") + fileName + "' doesn't seem to exist." ;
00048                 qWarning() << msg;
00049                 setLastError(msg);
00050                 return FALSE;
00051                 }
00052         else if (!videoFile.open(QIODevice::ReadOnly))
00053                 {
00054                 QString msg = QString("QVYUV4MPEG2CameraWorker::openCam: Can't open file '") + fileName + "' in read mode." ;
00055                 qWarning() << msg;
00056                 setLastError(msg);
00057                 return FALSE;
00058                 }
00059         else if (!readYUV4MPEG2Header(videoFile, cols, rows, fps))
00060                 {
00061                 QString msg = QString("QVYUV4MPEG2CameraWorker::openCam: File '") + fileName + "' doesn't seem to be a valid yuv4mpeg2 video file.";
00062                 qWarning() << msg;
00063                 setLastError(msg);
00064                 return FALSE;
00065                 }
00066         else    // Everything correct.
00067                 {
00068                 // Size of the header:
00069                 header_size = videoFile.pos();
00070 
00071                 // cols, rows and fps were passed by variable (so they have now the real, input source video file values.
00072                 inp_cols = cols;
00073                 inp_rows = rows;
00074 
00075                 // Output cols and rows:
00076                 if(out_cols != 0 and out_rows != 0) 
00077                         {
00078                         // Even rounding of out_rows and out_cols:
00079                         out_cols = out_cols + (out_cols%2);
00080                         out_rows = out_rows + (out_rows%2);
00081                         }
00082                 else // cols==0 or rows==0 means default (input) size:
00083                         {
00084                         out_cols = inp_cols;
00085                         out_rows = inp_rows;
00086                         }
00087 
00088                 // If requested number of cols or rows is different from original input video size, we will have to rescale:
00089                 rescale = (inp_cols != out_cols) or (inp_rows != out_rows);
00090 
00091                 // Finally, output cols and rows are "returned" to the caller:
00092                 cols = out_cols; rows = out_rows;
00093 
00094                 // We save FPS (useful for real time cameras):
00095                 out_fps = fps;
00096 
00097                 // We compute the total number of frames of the video (file size divided by size of each frame). Header
00098                 // size is discounted, and then the 6 constant comes from the "Frame\n" string at the beginning of each frame:
00099                 total_frames = (videoFile.size()-header_size) / (inp_cols*inp_rows + inp_cols*inp_rows/2 + 6);
00100 
00101                 // Finally, we compute the time length in seconds:
00102                 total_time = static_cast<double>(total_frames) / out_fps;
00103 
00104                 return TRUE;
00105                 }
00106         }
00107 
00108 void QVYUV4MPEG2CameraWorker::closeCam()
00109         {
00110         videoFile.close();
00111         }
00112 
00113 bool QVYUV4MPEG2CameraWorker::grab(QVImage<uChar,1> &imgY, QVImage<uChar,1> &imgU, QVImage<uChar,1> &imgV)
00114         {
00115         QVImage<uChar,1> inp_imgY(inp_cols,inp_rows), inp_imgU(inp_cols/2,inp_rows/2), inp_imgV(inp_cols/2,inp_rows/2);
00116         bool ret_value = FALSE;
00117 
00118         // Simulated read delay for real time cameras:
00119         static QTime last_time;
00120         if(realTime)
00121                 {
00122                         int msecs_to_wait = (int)(1000/(double)out_fps) - last_time.elapsed();
00123                         if((msecs_to_wait > 0) and (msecs_to_wait < (int)(1000/(double)out_fps)))
00124                                 msleep(msecs_to_wait);
00125                 }
00126 
00127         if (readYUV4MPEG2Frame(videoFile, inp_imgY, inp_imgU, inp_imgV))
00128                 {
00129                 ret_value = TRUE;
00130                 }
00131         else if (videoFile.atEnd())
00132                 {
00133                 if (noLoop)
00134                         return FALSE;
00135                 else
00136                         {
00137                         qDebug() << "QVYUV4MPEG2CameraWorker::grabFrame(): Reseting the video at frame " << getPropertyValue<int>("Frames");
00138                         videoFile.reset();
00139                         readYUV4MPEG2Frame(videoFile, inp_imgY, inp_imgU, inp_imgV);
00140                         ret_value = TRUE;
00141                         }
00142                 }
00143         else    {
00144                 qFatal("QVYUV4MPEG2CameraWorker::grab(): readYUV4MPEG2Frame() returned FALSE, and videoFile is not at end... aborting\n");
00145                 }
00146         
00147         // Possible rescaling:
00148         if(rescale)
00149                 {
00150                 Resize(inp_imgY,imgY);
00151                 Resize(inp_imgU,imgU);
00152                 Resize(inp_imgV,imgV);
00153                 }
00154         else
00155                 {
00156                 imgY = inp_imgY;
00157                 imgU = inp_imgU;
00158                 imgV = inp_imgV;
00159                 }
00160 
00161         if(realTime)
00162                 last_time.start();
00163 
00164         return ret_value;
00165         }
00166 
00167 double QVYUV4MPEG2CameraWorker::lengthOfVideo()
00168         {
00169         return total_time;
00170         }
00171 
00172 double QVYUV4MPEG2CameraWorker::currentPos()
00173         {
00174         return total_time*videoFile.pos()/videoFile.size();
00175         }
00176 
00177 void QVYUV4MPEG2CameraWorker::setCurrentPos(double time_pos)
00178         {
00179         int frame = (int)((time_pos*total_frames)/total_time);
00180         videoFile.seek(header_size+frame*(inp_cols*inp_rows + inp_cols*inp_rows/2 + 6));
00181         }



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