ViSP  2.9.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 - 2014 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  : imSequence(NULL),
59 #ifdef VISP_HAVE_FFMPEG
60  ffmpeg(NULL),
61 #endif
62  formatType(FORMAT_UNKNOWN), initFileName(false), isOpen(false), frameCount(0),
63  firstFrame(0), lastFrame(0), firstFrameIndexIsSet(false), lastFrameIndexIsSet(false)
64 {
65 }
66 
71 {
72  if (imSequence != NULL)
73  {
74  delete imSequence;
75  }
76  #ifdef VISP_HAVE_FFMPEG
77  if (ffmpeg != NULL)
78  {
79  delete ffmpeg;
80  }
81  #endif
82 }
83 
84 
94 void vpVideoReader::setFileName(const char *filename)
95 {
96  if (filename == '\0')
97  {
98  vpERROR_TRACE("filename empty ") ;
99  throw (vpImageException(vpImageException::noFileNameError,"filename empty ")) ;
100  }
101 
102  if (strlen( filename ) >= FILENAME_MAX) {
104  "Not enough memory to intialize the file name"));
105  }
106 
107  strcpy(this->fileName,filename);
108 
109  formatType = getFormat(fileName);
110 
111  initFileName = true;
112 }
113 
123 void vpVideoReader::setFileName(const std::string &filename)
124 {
125  setFileName(filename.c_str());
126 }
127 
136 {
137  if (!initFileName)
138  {
139  vpERROR_TRACE("The generic filename has to be set");
140  throw (vpImageException(vpImageException::noFileNameError,"filename empty"));
141  }
142 
143  if (formatType == FORMAT_PGM ||
144  formatType == FORMAT_PPM ||
145  formatType == FORMAT_JPEG ||
146  formatType == FORMAT_PNG ||
147  formatType == FORMAT_TIFF ||
148  formatType == FORMAT_BMP ||
149  formatType == FORMAT_DIB ||
150  formatType == FORMAT_PBM ||
151  formatType == FORMAT_RASTER ||
152  formatType == FORMAT_JPEG2000)
153  {
154  imSequence = new vpDiskGrabber;
155  imSequence->setGenericName(fileName);
156  if (firstFrameIndexIsSet)
157  imSequence->setImageNumber(firstFrame);
158  }
159  #ifdef VISP_HAVE_FFMPEG
160  else if (formatType == FORMAT_AVI ||
161  formatType == FORMAT_MPEG ||
162  formatType == FORMAT_MOV ||
163  formatType == FORMAT_OGV)
164  {
165  ffmpeg = new vpFFMPEG;
166  if(!ffmpeg->openStream(fileName, vpFFMPEG::COLORED))
167  throw (vpException(vpException::ioError ,"Could not open the video"));
168  ffmpeg->initStream();
169  }
170 
171  #else
172  else if (formatType == FORMAT_AVI ||
173  formatType == FORMAT_MPEG ||
174  formatType == FORMAT_MOV ||
175  formatType == FORMAT_OGV)
176  {
177  vpERROR_TRACE("To read video files the FFmpeg library has to be installed");
178  throw (vpException(vpException::fatalError ,"the FFmpeg library is required"));
179  }
180  #endif
181  else if (formatType == FORMAT_UNKNOWN)
182  {
183  vpERROR_TRACE("The format of the file does not correpsond to a readable format.");
184  throw (vpException(vpException::fatalError ,"The format of the file does not correpsond to a readable format."));
185  }
186 
187  findFirstFrameIndex();
188  frameCount = firstFrame;
189  if(!getFrame(I,firstFrame))
190  {
191  vpERROR_TRACE("Could not read the first frame");
192  throw (vpException(vpException::ioError ,"Could not read the first frame"));
193  }
194  height = I.getHeight();
195  width = I.getWidth();
196 
197  isOpen = true;
198 
199  findLastFrameIndex();
200 }
201 
202 
211 {
212  if (!initFileName)
213  {
214  vpERROR_TRACE("The generic filename has to be set");
215  throw (vpImageException(vpImageException::noFileNameError,"filename empty"));
216  }
217 
218  if (formatType == FORMAT_PGM ||
219  formatType == FORMAT_PPM ||
220  formatType == FORMAT_JPEG ||
221  formatType == FORMAT_PNG ||
222  formatType == FORMAT_TIFF ||
223  formatType == FORMAT_BMP ||
224  formatType == FORMAT_DIB ||
225  formatType == FORMAT_PBM ||
226  formatType == FORMAT_RASTER ||
227  formatType == FORMAT_JPEG2000)
228  {
229  imSequence = new vpDiskGrabber;
230  imSequence->setGenericName(fileName);
231  if (firstFrameIndexIsSet)
232  imSequence->setImageNumber(firstFrame);
233  }
234  #ifdef VISP_HAVE_FFMPEG
235  else if (formatType == FORMAT_AVI ||
236  formatType == FORMAT_MPEG ||
237  formatType == FORMAT_MOV ||
238  formatType == FORMAT_OGV)
239  {
240  ffmpeg = new vpFFMPEG;
241  if (!ffmpeg->openStream(fileName, vpFFMPEG::GRAY_SCALED))
242  throw (vpException(vpException::ioError ,"Could not open the video"));
243  ffmpeg->initStream();
244  }
245  #else
246  else if (formatType == FORMAT_AVI ||
247  formatType == FORMAT_MPEG ||
248  formatType == FORMAT_MOV ||
249  formatType == FORMAT_OGV)
250  {
251  vpERROR_TRACE("To read video files the FFmpeg library has to be installed");
252  throw (vpException(vpException::fatalError ,"the FFmpeg library is required"));
253  }
254  #endif
255  else if (formatType == FORMAT_UNKNOWN)
256  {
257  vpERROR_TRACE("The format of the file does not correpsond to a readable format.");
258  throw (vpException(vpException::fatalError ,"The format of the file does not correpsond to a readable format."));
259  }
260 
261  findFirstFrameIndex();
262  frameCount = firstFrame;
263  if(!getFrame(I,firstFrame))
264  {
265  vpERROR_TRACE("Could not read the first frame");
266  throw (vpException(vpException::ioError ,"Could not read the first frame"));
267  }
268  height = I.getHeight();
269  width = I.getWidth();
270 
271  isOpen = true;
272 
273  findLastFrameIndex();
274 }
275 
276 
287 {
288  if (!isOpen) {
289  open(I);
290  }
291 
292  //getFrame(I,frameCount);
293  if (imSequence != NULL)
294  imSequence->acquire(I);
295  #ifdef VISP_HAVE_FFMPEG
296  else if (ffmpeg !=NULL)
297  ffmpeg->acquire(I);
298  #endif
299 
300  frameCount++;
301 }
302 
303 
312 {
313  if (!isOpen) {
314  open(I);
315  }
316 
317  if (imSequence != NULL)
318  imSequence->acquire(I);
319  #ifdef VISP_HAVE_FFMPEG
320  else if (ffmpeg != NULL)
321  ffmpeg->acquire(I);
322  #endif
323 
324  frameCount++;
325 }
326 
327 
341 {
342  if (imSequence != NULL)
343  {
344  try
345  {
346  imSequence->acquire(I, frame);
347  }
348  catch(...)
349  {
350  vpERROR_TRACE("Couldn't find the %u th frame", frame) ;
351  return false;
352  }
353  }
354  #ifdef VISP_HAVE_FFMPEG
355  else
356  {
357 
358  if(!ffmpeg->getFrame(I, (unsigned int)frame))
359  {
360  vpERROR_TRACE("Couldn't find the %ld th frame", frame) ;
361  return false;
362  }
363  }
364  #endif
365  return true;
366 }
367 
368 
382 {
383  if (imSequence != NULL)
384  {
385  try
386  {
387  imSequence->acquire(I, frame);
388  }
389  catch(...)
390  {
391  vpERROR_TRACE("Couldn't find the %u th frame", frame) ;
392  return false;
393  }
394  }
395  #ifdef VISP_HAVE_FFMPEG
396  else
397  {
398  if(!ffmpeg->getFrame(I, (unsigned int)frame))
399  {
400  vpERROR_TRACE("Couldn't find the %ld th frame", frame) ;
401  return false;
402  }
403  }
404  #endif
405  return true;
406 }
407 
408 
414 vpVideoReader::vpVideoFormatType
415 vpVideoReader::getFormat(const char *filename)
416 {
417  std::string sfilename(filename);
418 
419  std::string ext = vpVideoReader::getExtension(sfilename);
420 
421  if (ext.compare(".PGM") == 0)
422  return FORMAT_PGM;
423  else if (ext.compare(".pgm") == 0)
424  return FORMAT_PGM;
425  else if (ext.compare(".PPM") == 0)
426  return FORMAT_PPM;
427  else if (ext.compare(".ppm") == 0)
428  return FORMAT_PPM;
429  else if (ext.compare(".JPG") == 0)
430  return FORMAT_JPEG;
431  else if (ext.compare(".jpg") == 0)
432  return FORMAT_JPEG;
433  else if (ext.compare(".JPEG") == 0)
434  return FORMAT_JPEG;
435  else if (ext.compare(".jpeg") == 0)
436  return FORMAT_JPEG;
437  else if (ext.compare(".PNG") == 0)
438  return FORMAT_PNG;
439  else if (ext.compare(".png") == 0)
440  return FORMAT_PNG;
441  else if (ext.compare(".AVI") == 0)
442  return FORMAT_AVI;
443  else if (ext.compare(".avi") == 0)
444  return FORMAT_AVI;
445  else if (ext.compare(".MPEG") == 0)
446  return FORMAT_MPEG;
447  else if (ext.compare(".mpeg") == 0)
448  return FORMAT_MPEG;
449  else if (ext.compare(".MPG") == 0)
450  return FORMAT_MPEG;
451  else if (ext.compare(".mpg") == 0)
452  return FORMAT_MPEG;
453  else if (ext.compare(".MOV") == 0)
454  return FORMAT_MOV;
455  else if (ext.compare(".mov") == 0)
456  return FORMAT_MOV;
457  else if (ext.compare(".OGV") == 0)
458  return FORMAT_OGV;
459  else if (ext.compare(".ogv") == 0)
460  return FORMAT_OGV;
461  else
462  return FORMAT_UNKNOWN;
463 }
464 
465 // return the extension of the file including the dot
466 std::string vpVideoReader::getExtension(const std::string &filename)
467 {
468  // extract the extension
469  size_t dot = filename.find_last_of(".");
470  std::string ext = filename.substr(dot, filename.size()-1);
471  return ext;
472 }
473 
474 
478 void
479 vpVideoReader::findLastFrameIndex()
480 {
481  if (!isOpen)
482  {
483  vpERROR_TRACE("Use the open method before");
484  throw (vpException(vpException::notInitialized,"file not yet opened"));
485  }
486 
487  if (imSequence != NULL)
488  {
489  if (! lastFrameIndexIsSet) {
490  char name[FILENAME_MAX];
491  int image_number = firstFrame;
492  bool failed;
493  do
494  {
495  std::fstream file;
496  sprintf(name,fileName,image_number) ;
497  file.open(name, std::ios::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 
507 #ifdef VISP_HAVE_FFMPEG
508  else if (ffmpeg != NULL) {
509  if (! lastFrameIndexIsSet) {
510  lastFrame = (long)(ffmpeg->getFrameNumber() - 1);
511  }
512  }
513  #endif
514 }
518 void
519 vpVideoReader::findFirstFrameIndex()
520 {
521  if (imSequence != NULL)
522  {
523  if (! firstFrameIndexIsSet) {
524  char name[FILENAME_MAX];
525  int image_number = 0;
526  bool failed;
527  do {
528  std::fstream file;
529  sprintf(name, fileName, image_number) ;
530  file.open(name, std::ios::in);
531  failed = file.fail();
532  if (!failed) file.close();
533  image_number++;
534  } while(failed);
535 
536  firstFrame = image_number - 1;
537  imSequence->setImageNumber(firstFrame);
538  }
539  }
540 
541  #ifdef VISP_HAVE_FFMPEG
542  else if (ffmpeg != NULL) {
543  if (! firstFrameIndexIsSet) {
544  firstFrame = (long)(0);
545  }
546  }
547  #endif
548 }
549 
556 {
557  double framerate = -1.;
558 
559 #ifdef VISP_HAVE_FFMPEG
560  if (ffmpeg != NULL)
561  framerate = ffmpeg->getFramerate();
562 #endif
563  return framerate;
564 }
double getFramerate() const
Definition: vpFFMPEG.h:223
unsigned int getWidth() const
Definition: vpImage.h:159
#define vpERROR_TRACE
Definition: vpDebug.h:395
bool getFrame(vpImage< vpRGBa > &I, unsigned int frameNumber)
Definition: vpFFMPEG.cpp:277
error that can be emited by ViSP classes.
Definition: vpException.h:76
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:99
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:331
unsigned int getHeight() const
Definition: vpImage.h:150
double getFramerate() const
void acquire(vpImage< unsigned char > &I)
bool initStream()
Definition: vpFFMPEG.cpp:218
unsigned int width
Number of columns in the image.
void setGenericName(const char *genericName)