ViSP  2.8.0
vpVideoReader.cpp
1 /****************************************************************************
2  *
3  * $Id: vpImagePoint.h 2359 2009-11-24 15:09:25Z nmelchio $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Read videos and image sequences.
36  *
37  * Authors:
38  * Nicolas Melchior
39  * Fabien Spindler
40  *
41  *****************************************************************************/
42 
48 #include <visp/vpDebug.h>
49 #include <visp/vpVideoReader.h>
50 
51 #include <iostream>
52 #include <fstream>
53 
58 {
59  imSequence = NULL;
60  #ifdef VISP_HAVE_FFMPEG
61  ffmpeg = NULL;
62  #endif
63  initFileName = false;
64  isOpen = false;
65  firstFrame = 0;
66  frameCount = 0;
67  lastFrame = 0;
68  firstFrameIndexIsSet = false;
69  lastFrameIndexIsSet = false;
70 }
71 
72 
77 {
78  if (imSequence != NULL)
79  {
80  delete imSequence;
81  }
82  #ifdef VISP_HAVE_FFMPEG
83  if (ffmpeg != NULL)
84  {
85  delete ffmpeg;
86  }
87  #endif
88 }
89 
90 
100 void vpVideoReader::setFileName(const char *filename)
101 {
102  if (filename == '\0')
103  {
104  vpERROR_TRACE("filename empty ") ;
105  throw (vpImageException(vpImageException::noFileNameError,"filename empty ")) ;
106  }
107 
108  strcpy(this->fileName,filename);
109 
110  formatType = getFormat(fileName);
111 
112  initFileName = true;
113 }
114 
124 void vpVideoReader::setFileName(const std::string &filename)
125 {
126  setFileName(filename.c_str());
127 }
128 
137 {
138  if (!initFileName)
139  {
140  vpERROR_TRACE("The generic filename has to be set");
141  throw (vpImageException(vpImageException::noFileNameError,"filename empty"));
142  }
143 
144  if (formatType == FORMAT_PGM ||
145  formatType == FORMAT_PPM ||
146  formatType == FORMAT_JPEG ||
147  formatType == FORMAT_PNG ||
148  formatType == FORMAT_TIFF ||
149  formatType == FORMAT_BMP ||
150  formatType == FORMAT_DIB ||
151  formatType == FORMAT_PBM ||
152  formatType == FORMAT_RASTER ||
153  formatType == FORMAT_JPEG2000)
154  {
155  imSequence = new vpDiskGrabber;
156  imSequence->setGenericName(fileName);
157  if (firstFrameIndexIsSet)
158  imSequence->setImageNumber(firstFrame);
159  }
160  #ifdef VISP_HAVE_FFMPEG
161  else if (formatType == FORMAT_AVI ||
162  formatType == FORMAT_MPEG ||
163  formatType == FORMAT_MOV ||
164  formatType == FORMAT_OGV)
165  {
166  ffmpeg = new vpFFMPEG;
167  if(!ffmpeg->openStream(fileName, vpFFMPEG::COLORED))
168  throw (vpException(vpException::ioError ,"Could not open the video"));
169  ffmpeg->initStream();
170  }
171 
172  #else
173  else if (formatType == FORMAT_AVI ||
174  formatType == FORMAT_MPEG ||
175  formatType == FORMAT_MOV ||
176  formatType == FORMAT_OGV)
177  {
178  vpERROR_TRACE("To read video files the FFmpeg library has to be installed");
179  throw (vpException(vpException::fatalError ,"the FFmpeg library is required"));
180  }
181  #endif
182  else if (formatType == FORMAT_UNKNOWN)
183  {
184  vpERROR_TRACE("The format of the file does not correpsond to a readable format.");
185  throw (vpException(vpException::fatalError ,"The format of the file does not correpsond to a readable format."));
186  }
187 
188  findFirstFrameIndex();
189  frameCount = firstFrame;
190  if(!getFrame(I,firstFrame))
191  {
192  vpERROR_TRACE("Could not read the first frame");
193  throw (vpException(vpException::ioError ,"Could not read the first frame"));
194  }
195  height = I.getHeight();
196  width = I.getWidth();
197 
198  isOpen = true;
199 
200  findLastFrameIndex();
201 }
202 
203 
212 {
213  if (!initFileName)
214  {
215  vpERROR_TRACE("The generic filename has to be set");
216  throw (vpImageException(vpImageException::noFileNameError,"filename empty"));
217  }
218 
219  if (formatType == FORMAT_PGM ||
220  formatType == FORMAT_PPM ||
221  formatType == FORMAT_JPEG ||
222  formatType == FORMAT_PNG ||
223  formatType == FORMAT_TIFF ||
224  formatType == FORMAT_BMP ||
225  formatType == FORMAT_DIB ||
226  formatType == FORMAT_PBM ||
227  formatType == FORMAT_RASTER ||
228  formatType == FORMAT_JPEG2000)
229  {
230  imSequence = new vpDiskGrabber;
231  imSequence->setGenericName(fileName);
232  if (firstFrameIndexIsSet)
233  imSequence->setImageNumber(firstFrame);
234  }
235  #ifdef VISP_HAVE_FFMPEG
236  else if (formatType == FORMAT_AVI ||
237  formatType == FORMAT_MPEG ||
238  formatType == FORMAT_MOV ||
239  formatType == FORMAT_OGV)
240  {
241  ffmpeg = new vpFFMPEG;
242  if (!ffmpeg->openStream(fileName, vpFFMPEG::GRAY_SCALED))
243  throw (vpException(vpException::ioError ,"Could not open the video"));
244  ffmpeg->initStream();
245  }
246  #else
247  else if (formatType == FORMAT_AVI ||
248  formatType == FORMAT_MPEG ||
249  formatType == FORMAT_MOV ||
250  formatType == FORMAT_OGV)
251  {
252  vpERROR_TRACE("To read video files the FFmpeg library has to be installed");
253  throw (vpException(vpException::fatalError ,"the FFmpeg library is required"));
254  }
255  #endif
256  else if (formatType == FORMAT_UNKNOWN)
257  {
258  vpERROR_TRACE("The format of the file does not correpsond to a readable format.");
259  throw (vpException(vpException::fatalError ,"The format of the file does not correpsond to a readable format."));
260  }
261 
262  findFirstFrameIndex();
263  frameCount = firstFrame;
264  if(!getFrame(I,firstFrame))
265  {
266  vpERROR_TRACE("Could not read the first frame");
267  throw (vpException(vpException::ioError ,"Could not read the first frame"));
268  }
269  height = I.getHeight();
270  width = I.getWidth();
271 
272  isOpen = true;
273 
274  findLastFrameIndex();
275 }
276 
277 
288 {
289  if (!isOpen) {
290  open(I);
291  }
292 
293  //getFrame(I,frameCount);
294  if (imSequence != NULL)
295  imSequence->acquire(I);
296  #ifdef VISP_HAVE_FFMPEG
297  else if (ffmpeg !=NULL)
298  ffmpeg->acquire(I);
299  #endif
300 
301  frameCount++;
302 }
303 
304 
313 {
314  if (!isOpen) {
315  open(I);
316  }
317 
318  if (imSequence != NULL)
319  imSequence->acquire(I);
320  #ifdef VISP_HAVE_FFMPEG
321  else if (ffmpeg != NULL)
322  ffmpeg->acquire(I);
323  #endif
324 
325  frameCount++;
326 }
327 
328 
342 {
343  if (imSequence != NULL)
344  {
345  try
346  {
347  imSequence->acquire(I, frame);
348  }
349  catch(...)
350  {
351  vpERROR_TRACE("Couldn't find the %u th frame", frame) ;
352  return false;
353  }
354  }
355  #ifdef VISP_HAVE_FFMPEG
356  else
357  {
358 
359  if(!ffmpeg->getFrame(I, (unsigned int)frame))
360  {
361  vpERROR_TRACE("Couldn't find the %ld th frame", frame) ;
362  return false;
363  }
364  }
365  #endif
366  return true;
367 }
368 
369 
383 {
384  if (imSequence != NULL)
385  {
386  try
387  {
388  imSequence->acquire(I, frame);
389  }
390  catch(...)
391  {
392  vpERROR_TRACE("Couldn't find the %u th frame", frame) ;
393  return false;
394  }
395  }
396  #ifdef VISP_HAVE_FFMPEG
397  else
398  {
399  if(!ffmpeg->getFrame(I, (unsigned int)frame))
400  {
401  vpERROR_TRACE("Couldn't find the %ld th frame", frame) ;
402  return false;
403  }
404  }
405  #endif
406  return true;
407 }
408 
409 
415 vpVideoReader::vpVideoFormatType
416 vpVideoReader::getFormat(const char *filename)
417 {
418  std::string sfilename(filename);
419 
420  std::string ext = vpVideoReader::getExtension(sfilename);
421 
422  if (ext.compare(".PGM") == 0)
423  return FORMAT_PGM;
424  else if (ext.compare(".pgm") == 0)
425  return FORMAT_PGM;
426  else if (ext.compare(".PPM") == 0)
427  return FORMAT_PPM;
428  else if (ext.compare(".ppm") == 0)
429  return FORMAT_PPM;
430  else if (ext.compare(".JPG") == 0)
431  return FORMAT_JPEG;
432  else if (ext.compare(".jpg") == 0)
433  return FORMAT_JPEG;
434  else if (ext.compare(".JPEG") == 0)
435  return FORMAT_JPEG;
436  else if (ext.compare(".jpeg") == 0)
437  return FORMAT_JPEG;
438  else if (ext.compare(".PNG") == 0)
439  return FORMAT_PNG;
440  else if (ext.compare(".png") == 0)
441  return FORMAT_PNG;
442  else if (ext.compare(".AVI") == 0)
443  return FORMAT_AVI;
444  else if (ext.compare(".avi") == 0)
445  return FORMAT_AVI;
446  else if (ext.compare(".MPEG") == 0)
447  return FORMAT_MPEG;
448  else if (ext.compare(".mpeg") == 0)
449  return FORMAT_MPEG;
450  else if (ext.compare(".MPG") == 0)
451  return FORMAT_MPEG;
452  else if (ext.compare(".mpg") == 0)
453  return FORMAT_MPEG;
454  else if (ext.compare(".MOV") == 0)
455  return FORMAT_MOV;
456  else if (ext.compare(".mov") == 0)
457  return FORMAT_MOV;
458  else if (ext.compare(".OGV") == 0)
459  return FORMAT_OGV;
460  else if (ext.compare(".ogv") == 0)
461  return FORMAT_OGV;
462  else
463  return FORMAT_UNKNOWN;
464 }
465 
466 // return the extension of the file including the dot
467 std::string vpVideoReader::getExtension(const std::string &filename)
468 {
469  // extract the extension
470  size_t dot = filename.find_last_of(".");
471  std::string ext = filename.substr(dot, filename.size()-1);
472  return ext;
473 }
474 
475 
479 void
480 vpVideoReader::findLastFrameIndex()
481 {
482  if (!isOpen)
483  {
484  vpERROR_TRACE("Use the open method before");
485  throw (vpException(vpException::notInitialized,"file not yet opened"));
486  }
487 
488  if (imSequence != NULL)
489  {
490  char name[FILENAME_MAX];
491  int image_number = firstFrame;
492  std::fstream file;
493  bool failed;
494  do
495  {
496  sprintf(name,fileName,image_number) ;
497  file.open(name, std::fstream::in);
498  failed = file.fail();
499  if (!failed) file.close();
500  image_number++;
501  }while(!failed);
502 
503  lastFrame = image_number - 2;
504  }
505 
506  #ifdef VISP_HAVE_FFMPEG
507  else if (ffmpeg != NULL)
508  lastFrame = (long)(ffmpeg->getFrameNumber() - 1);
509  #endif
510 }
514 void
515 vpVideoReader::findFirstFrameIndex()
516 {
517  if (imSequence != NULL)
518  {
519  if (! firstFrameIndexIsSet) {
520  char name[FILENAME_MAX];
521  int image_number = 0;
522  std::fstream file;
523  bool failed;
524  do {
525  sprintf(name, fileName, image_number) ;
526  file.open(name, std::fstream::in);
527  failed = file.fail();
528  if (!failed) file.close();
529  image_number++;
530  } while(failed);
531 
532  firstFrame = image_number - 1;
533  imSequence->setImageNumber(firstFrame);
534  }
535  }
536 
537  #ifdef VISP_HAVE_FFMPEG
538  else if (ffmpeg != NULL) {
539  if (! firstFrameIndexIsSet) {
540  firstFrame = (long)(0);
541  }
542  }
543  #endif
544 }
545 
552 {
553  double framerate = -1.;
554 
555 #ifdef VISP_HAVE_FFMPEG
556  if (ffmpeg != NULL)
557  framerate = ffmpeg->getFramerate();
558 #endif
559  return framerate;
560 }
double getFramerate() const
Definition: vpFFMPEG.h:223
unsigned int getWidth() const
Definition: vpImage.h:159
#define vpERROR_TRACE
Definition: vpDebug.h:379
bool getFrame(vpImage< vpRGBa > &I, unsigned int frameNumber)
Definition: vpFFMPEG.cpp:285
error that can be emited by ViSP classes.
Definition: vpException.h:75
Error that can be emited by the vpImage class and its derivates.
unsigned long getFrameNumber() const
Definition: vpFFMPEG.h:216
void open(vpImage< vpRGBa > &I)
bool getFrame(vpImage< vpRGBa > &I, long frame)
unsigned int height
Number of rows in the image.
bool openStream(const char *filename, vpFFMPEGColorType color_type)
Definition: vpFFMPEG.cpp:107
void acquire(vpImage< vpRGBa > &I)
This class interfaces the FFmpeg library to enable video stream reading or writing.
Definition: vpFFMPEG.h:149
void setImageNumber(long number)
void setFileName(const char *filename)
Class to grab (ie. read) images from the disk.
bool acquire(vpImage< vpRGBa > &I)
Definition: vpFFMPEG.cpp:339
unsigned int getHeight() const
Definition: vpImage.h:150
double getFramerate() const
void acquire(vpImage< unsigned char > &I)
bool initStream()
Definition: vpFFMPEG.cpp:226
unsigned int width
Number of columns in the image.
void setGenericName(const char *genericName)