Visual Servoing Platform  version 3.0.0
vpVideoReader.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Read videos and image sequences.
32  *
33  * Authors:
34  * Nicolas Melchior
35  * Fabien Spindler
36  *
37  *****************************************************************************/
38 
44 #include <visp3/core/vpDebug.h>
45 #include <visp3/io/vpVideoReader.h>
46 
47 #include <iostream>
48 #include <fstream>
49 #include <limits> // numeric_limits
50 
55  : vpFrameGrabber(), imSequence(NULL),
56 #ifdef VISP_HAVE_FFMPEG
57  ffmpeg(NULL),
58 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
59  capture(), frame(),
60 #endif
61  formatType(FORMAT_UNKNOWN), initFileName(false), isOpen(false), frameCount(0),
62  firstFrame(0), lastFrame(0), firstFrameIndexIsSet(false), lastFrameIndexIsSet(false)
63 {
64 }
65 
70 {
71  if (imSequence != NULL)
72  {
73  delete imSequence;
74  }
75 #ifdef VISP_HAVE_FFMPEG
76  if (ffmpeg != NULL)
77  {
78  delete ffmpeg;
79  }
80 #endif
81 }
82 
83 
93 void vpVideoReader::setFileName(const char *filename)
94 {
95  if (!filename || *filename == '\0')
96  {
97  vpERROR_TRACE("filename empty ") ;
98  throw (vpImageException(vpImageException::noFileNameError,"filename empty ")) ;
99  }
100 
101  if (strlen( filename ) >= FILENAME_MAX) {
103  "Not enough memory to intialize the file name"));
104  }
105 
106  strcpy(this->fileName,filename);
107 
108  formatType = getFormat(fileName);
109 
110  if (formatType == FORMAT_UNKNOWN) {
111  throw(vpException(vpException::badValue, "Filename extension not supported"));
112  }
113 
114  initFileName = true;
115 }
116 
126 void vpVideoReader::setFileName(const std::string &filename)
127 {
128  setFileName(filename.c_str());
129 }
130 
139 {
140  if (!initFileName)
141  {
142  vpERROR_TRACE("The generic filename has to be set");
143  throw (vpImageException(vpImageException::noFileNameError,"filename empty"));
144  }
145 
146  if (isImageExtensionSupported())
147  {
148  imSequence = new vpDiskGrabber;
149  imSequence->setGenericName(fileName);
150  if (firstFrameIndexIsSet)
151  imSequence->setImageNumber(firstFrame);
152  }
153  else if (isVideoExtensionSupported())
154  {
155 #ifdef VISP_HAVE_FFMPEG
156  ffmpeg = new vpFFMPEG;
157  if(!ffmpeg->openStream(fileName, vpFFMPEG::COLORED))
158  throw (vpException(vpException::ioError ,"Could not open the video with ffmpeg"));
159  ffmpeg->initStream();
160 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
161  capture.open(fileName);
162 
163  if(!capture.isOpened())
164  {
165  throw (vpException(vpException::ioError ,"Could not open the video with opencv"));
166  }
167 #else
168  //vpERROR_TRACE("To read video files ViSP should be build with ffmpeg or opencv 3rd party libraries.");
169  throw (vpException(vpException::fatalError ,"To read video files ViSP should be build with ffmpeg or opencv 3rd >= 2.1.0 party libraries."));
170 #endif
171  }
172  else if (formatType == FORMAT_UNKNOWN)
173  {
174  //vpERROR_TRACE("The format of the file does not correspond to a readable format.");
175  throw (vpException(vpException::fatalError ,"The format of the file does not correspond to a readable format supported by ViSP."));
176  }
177 
178  findFirstFrameIndex();
179  frameCount = firstFrame;
180  if(!getFrame(I, firstFrame))
181  {
182  //vpERROR_TRACE("Could not read the video first frame");
183  throw (vpException(vpException::ioError ,"Could not read the video first frame"));
184  }
185 
186  height = I.getHeight();
187  width = I.getWidth();
188 
189  isOpen = true;
190  findLastFrameIndex();
191  frameCount = firstFrame; // open() should not increase the frame counter
192 }
193 
194 
203 {
204  if (!initFileName)
205  {
206  vpERROR_TRACE("The generic filename has to be set");
207  throw (vpImageException(vpImageException::noFileNameError,"filename empty"));
208  }
209 
210  if (isImageExtensionSupported())
211  {
212  imSequence = new vpDiskGrabber;
213  imSequence->setGenericName(fileName);
214  if (firstFrameIndexIsSet)
215  imSequence->setImageNumber(firstFrame);
216  }
217  else if (isVideoExtensionSupported())
218  {
219 #ifdef VISP_HAVE_FFMPEG
220  ffmpeg = new vpFFMPEG;
221  if (!ffmpeg->openStream(fileName, vpFFMPEG::GRAY_SCALED))
222  throw (vpException(vpException::ioError ,"Could not open the video with ffmpeg"));
223  ffmpeg->initStream();
224 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
225  capture.open(fileName);
226 
227  if(!capture.isOpened())
228  {
229  throw (vpException(vpException::ioError ,"Could not open the video with opencv"));
230  }
231 #else
232  //vpERROR_TRACE("To read video files ViSP should be build with ffmpeg or opencv 3rd party libraries.");
233  throw (vpException(vpException::fatalError ,"To read video files ViSP should be build with ffmpeg or opencv >= 2.1.0 3rd party libraries."));
234 #endif
235  }
236  else if (formatType == FORMAT_UNKNOWN)
237  {
238  //vpERROR_TRACE("The format of the file does not correspond to a readable format.");
239  throw (vpException(vpException::fatalError ,"The format of the file does not correspond to a readable format supported by ViSP."));
240  }
241 
242  findFirstFrameIndex();
243  frameCount = firstFrame;
244  if(!getFrame(I,firstFrame))
245  {
246  //vpERROR_TRACE("Could not read the video first frame");
247  throw (vpException(vpException::ioError ,"Could not read the video first frame"));
248  }
249 
250  height = I.getHeight();
251  width = I.getWidth();
252 
253  isOpen = true;
254  findLastFrameIndex();
255  frameCount = firstFrame; // open() should not increase the frame counter
256 }
257 
258 
269 {
270  if (!isOpen) {
271  open(I);
272  }
273 
274  //getFrame(I,frameCount);
275  if (imSequence != NULL)
276  {
277  imSequence->acquire(I);
278  frameCount++; // next index
279  }
280 #ifdef VISP_HAVE_FFMPEG
281  else if (ffmpeg !=NULL)
282  {
283  ffmpeg->acquire(I);
284  frameCount++; // next index
285  }
286 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
287  else
288  {
289  capture >> frame;
290 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
291  frameCount = (long) capture.get(cv::CAP_PROP_POS_FRAMES); // next index
292 #else
293  frameCount = (long) capture.get(CV_CAP_PROP_POS_FRAMES); // next index
294 #endif
295 
296  if(frame.empty())
297  setLastFrameIndex(frameCount-1);
298  else
299  vpImageConvert::convert(frame, I);
300  }
301 #endif
302 }
303 
304 
313 {
314  if (!isOpen) {
315  open(I);
316  }
317 
318  if (imSequence != NULL)
319  {
320  imSequence->acquire(I);
321  frameCount++; // next index
322  }
323 #ifdef VISP_HAVE_FFMPEG
324  else if (ffmpeg != NULL)
325  {
326  ffmpeg->acquire(I);
327  frameCount++; // next index
328  }
329 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
330  else
331  {
332  capture >> frame;
333 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
334  frameCount = (long) capture.get(cv::CAP_PROP_POS_FRAMES); // next index
335 #else
336  frameCount = (long) capture.get(CV_CAP_PROP_POS_FRAMES); // next index
337 #endif
338 
339  if(frame.empty())
340  setLastFrameIndex(frameCount-1);
341  else
342  vpImageConvert::convert(frame, I);
343  }
344 #endif
345 }
346 
347 
360 bool vpVideoReader::getFrame(vpImage<vpRGBa> &I, long frame_index)
361 {
362  if (imSequence != NULL)
363  {
364  try
365  {
366  imSequence->acquire(I, frame_index);
367  frameCount = frame_index + 1; // next index
368  }
369  catch(...)
370  {
371  vpERROR_TRACE("Couldn't find the %u th frame", frame_index) ;
372  return false;
373  }
374  }
375  else
376  {
377 #ifdef VISP_HAVE_FFMPEG
378  if(!ffmpeg->getFrame(I, (unsigned int)frame_index))
379  {
380  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index) ;
381  return false;
382  }
383  frameCount = frame_index + 1; // next index
384 #elif defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x030000)
385  if(!capture.set(cv::CAP_PROP_POS_FRAMES, frame_index))
386  {
387  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index) ;
388  return false;
389  }
390 
391  capture >> frame;
392  frameCount = (long) capture.get(cv::CAP_PROP_POS_FRAMES); // next index
393  if(frame.empty()) {
394  // New trial that makes things working with opencv 3.0.0
395  capture >> frame;
396  if(frame.empty()) {
397  setLastFrameIndex(frameCount-1);
398  return false;
399  }
400  else {
401  vpImageConvert::convert(frame, I);
402  }
403  }
404  else
405  vpImageConvert::convert(frame, I);
406 #elif defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020100)
407  if(!capture.set(CV_CAP_PROP_POS_FRAMES, frame_index))
408  {
409  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index) ;
410  return false;
411  }
412 
413  capture >> frame;
414  frameCount = (long) capture.get(CV_CAP_PROP_POS_FRAMES); // next index
415  if(frame.empty())
416  setLastFrameIndex(frameCount-1);
417  else
418  vpImageConvert::convert(frame, I);
419 #endif
420  }
421 
422  return true;
423 }
424 
425 
439 {
440  if (imSequence != NULL)
441  {
442  try
443  {
444  imSequence->acquire(I, frame_index);
445  frameCount = frame_index + 1;
446  }
447  catch(...)
448  {
449  vpERROR_TRACE("Couldn't find the %u th frame", frame_index) ;
450  return false;
451  }
452  }
453  else
454  {
455 #ifdef VISP_HAVE_FFMPEG
456  if(!ffmpeg->getFrame(I, (unsigned int)frame_index))
457  {
458  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index) ;
459  return false;
460  }
461  frameCount = frame_index + 1; // next index
462 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
463  if(!capture.set(cv::CAP_PROP_POS_FRAMES, frame_index))
464  {
465  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index) ;
466  return false;
467  }
468  capture >> frame;
469  frameCount = (long) capture.get(cv::CAP_PROP_POS_FRAMES); // next index
470  if(frame.empty()) {
471  // New trial that makes things working with opencv 3.0.0
472  capture >> frame;
473  if(frame.empty()) {
474  setLastFrameIndex(frameCount-1);
475  return false;
476  }
477  else {
478  vpImageConvert::convert(frame, I);
479  }
480  }
481  else
482  vpImageConvert::convert(frame, I);
483 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
484  if(!capture.set(CV_CAP_PROP_POS_FRAMES, frame_index))
485  {
486  vpERROR_TRACE("Couldn't find the %ld th frame", frame_index); // next index
487  return false;
488  }
489  capture >> frame;
490  frameCount = (long) capture.get(CV_CAP_PROP_POS_FRAMES);
491  if(frame.empty())
492  setLastFrameIndex(frameCount-1);
493  else
494  vpImageConvert::convert(frame, I);
495 #endif
496  }
497 
498  return true;
499 }
500 
501 
507 vpVideoReader::vpVideoFormatType
508  vpVideoReader::getFormat(const char *filename)
509 {
510  std::string sfilename(filename);
511 
512  std::string ext = vpVideoReader::getExtension(sfilename);
513 
514  if (ext.compare(".PGM") == 0)
515  return FORMAT_PGM;
516  else if (ext.compare(".pgm") == 0)
517  return FORMAT_PGM;
518  else if (ext.compare(".PPM") == 0)
519  return FORMAT_PPM;
520  else if (ext.compare(".ppm") == 0)
521  return FORMAT_PPM;
522  else if (ext.compare(".JPG") == 0)
523  return FORMAT_JPEG;
524  else if (ext.compare(".jpg") == 0)
525  return FORMAT_JPEG;
526  else if (ext.compare(".JPEG") == 0)
527  return FORMAT_JPEG;
528  else if (ext.compare(".jpeg") == 0)
529  return FORMAT_JPEG;
530  else if (ext.compare(".PNG") == 0)
531  return FORMAT_PNG;
532  else if (ext.compare(".png") == 0)
533  return FORMAT_PNG;
534  else if (ext.compare(".TIFF") == 0)
535  return FORMAT_TIFF;
536  else if (ext.compare(".tiff") == 0)
537  return FORMAT_TIFF;
538  else if (ext.compare(".BMP") == 0)
539  return FORMAT_BMP;
540  else if (ext.compare(".bmp") == 0)
541  return FORMAT_BMP;
542  else if (ext.compare(".DIB") == 0)
543  return FORMAT_DIB;
544  else if (ext.compare(".dib") == 0)
545  return FORMAT_DIB;
546  else if (ext.compare(".PBM") == 0)
547  return FORMAT_PBM;
548  else if (ext.compare(".PBM") == 0)
549  return FORMAT_PBM;
550  else if (ext.compare(".SR") == 0)
551  return FORMAT_PBM;
552  else if (ext.compare(".sr") == 0)
553  return FORMAT_PBM;
554  else if (ext.compare(".RAS") == 0)
555  return FORMAT_RASTER;
556  else if (ext.compare(".ras") == 0)
557  return FORMAT_RASTER;
558  else if (ext.compare(".JP2") == 0)
559  return FORMAT_JPEG2000;
560  else if (ext.compare(".jp2") == 0)
561  return FORMAT_JPEG2000;
562  else if (ext.compare(".AVI") == 0)
563  return FORMAT_AVI;
564  else if (ext.compare(".avi") == 0)
565  return FORMAT_AVI;
566  else if (ext.compare(".MPEG") == 0)
567  return FORMAT_MPEG;
568  else if (ext.compare(".mpeg") == 0)
569  return FORMAT_MPEG;
570  else if (ext.compare(".MPG") == 0)
571  return FORMAT_MPEG;
572  else if (ext.compare(".mpg") == 0)
573  return FORMAT_MPEG;
574  else if (ext.compare(".MPEG4") == 0)
575  return FORMAT_MPEG4;
576  else if (ext.compare(".mpeg4") == 0)
577  return FORMAT_MPEG4;
578  else if (ext.compare(".MP4") == 0)
579  return FORMAT_MPEG4;
580  else if (ext.compare(".mp4") == 0)
581  return FORMAT_MPEG4;
582  else if (ext.compare(".MOV") == 0)
583  return FORMAT_MOV;
584  else if (ext.compare(".mov") == 0)
585  return FORMAT_MOV;
586  else if (ext.compare(".OGV") == 0)
587  return FORMAT_OGV;
588  else if (ext.compare(".ogv") == 0)
589  return FORMAT_OGV;
590  else if (ext.compare(".WMV") == 0)
591  return FORMAT_WMV;
592  else if (ext.compare(".wmv") == 0)
593  return FORMAT_WMV;
594  else if (ext.compare(".FLV") == 0)
595  return FORMAT_FLV;
596  else if (ext.compare(".flv") == 0)
597  return FORMAT_FLV;
598  else if (ext.compare(".MKV") == 0)
599  return FORMAT_MKV;
600  else if (ext.compare(".mkv") == 0)
601  return FORMAT_MKV;
602  else
603  return FORMAT_UNKNOWN;
604 }
605 
606 // return the extension of the file including the dot
607 std::string vpVideoReader::getExtension(const std::string &filename)
608 {
609  // extract the extension
610  size_t dot = filename.find_last_of(".");
611  std::string ext = filename.substr(dot, filename.size()-1);
612  return ext;
613 }
614 
615 
619 void vpVideoReader::findLastFrameIndex()
620 {
621  if (!isOpen) {
622  vpERROR_TRACE("Use the open method before");
623  throw (vpException(vpException::notInitialized,"file not yet opened"));
624  }
625 
626  if (imSequence != NULL) {
627  if (! lastFrameIndexIsSet) {
628  char name[FILENAME_MAX];
629  int image_number = firstFrame;
630  bool failed;
631  do {
632  std::fstream file;
633  sprintf(name,fileName,image_number) ;
634  file.open(name, std::ios::in);
635  failed = file.fail();
636  if (!failed) {
637  file.close();
638  image_number++;
639  }
640  } while(!failed);
641 
642  lastFrame = image_number -1;
643  }
644  }
645 
646 #ifdef VISP_HAVE_FFMPEG
647  else if (ffmpeg != NULL) {
648  if (! lastFrameIndexIsSet) {
649  lastFrame = (long)(ffmpeg->getFrameNumber());
650  }
651  }
652 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
653  else if (! lastFrameIndexIsSet)
654  {
655  lastFrame = (long) capture.get(cv::CAP_PROP_FRAME_COUNT);
656  if(lastFrame <= 2) // with tutorial/matching/video-postcard.mpeg it return 2 with OpenCV 3.0.0
657  {
658  //std::cout << "Warning: Problem with cv::CAP_PROP_FRAME_COUNT. We set video last frame to an arbitrary value (1000)." << std::endl;
659  lastFrame = 100000; // Set lastFrame to an arbitrary value
660  }
661  lastFrame--; //Last frame index = total frame count - 1
662  }
663 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
664  else if (! lastFrameIndexIsSet)
665  {
666  lastFrame = (long) capture.get(CV_CAP_PROP_FRAME_COUNT);
667  if(lastFrame <= 2) // with tutorial/matching/video-postcard.mpeg it return 2 with OpenCV 2.4.10
668  {
669  //std::cout << "Warning: Problem with CV_CAP_PROP_FRAME_COUNT. We set video last frame to an arbitrary value (1000)." << std::endl;
670  lastFrame = 100000; // Set lastFrame to an arbitrary value
671  }
672  lastFrame--; //Last frame index = total frame count - 1
673  }
674 #endif
675 }
679 void
680  vpVideoReader::findFirstFrameIndex()
681 {
682  if (imSequence != NULL)
683  {
684  if (! firstFrameIndexIsSet) {
685  char name[FILENAME_MAX];
686  int image_number = 0;
687  bool failed;
688  do {
689  std::fstream file;
690  sprintf(name, fileName, image_number) ;
691  file.open(name, std::ios::in);
692  failed = file.fail();
693  if (!failed) file.close();
694  image_number++;
695  } while(failed);
696 
697  firstFrame = image_number - 1;
698  imSequence->setImageNumber(firstFrame);
699  }
700  }
701 #ifdef VISP_HAVE_FFMPEG
702  else if (ffmpeg != NULL) {
703  if (! firstFrameIndexIsSet) {
704  firstFrame = (long)(0);
705  }
706  }
707 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
708  else if (! firstFrameIndexIsSet)
709  {
710  firstFrame = (long) (0);
711  }
712 #endif
713 }
714 
721 {
722  double framerate = -1.;
723 
724 #ifdef VISP_HAVE_FFMPEG
725  if (ffmpeg != NULL)
726  {
727  framerate = ffmpeg->getFramerate();
728  }
729 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
730  framerate = capture.get(cv::CAP_PROP_FPS);
731  // if(framerate == 0)
732  if(std::fabs(framerate) <= std::numeric_limits<double>::epsilon())
733  {
734  vpERROR_TRACE("Problem with cv::CAP_PROP_FPS") ;
735  }
736 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
737  framerate = capture.get(CV_CAP_PROP_FPS);
738  // if(framerate == 0)
739  if(std::fabs(framerate) <= std::numeric_limits<double>::epsilon())
740  {
741  vpERROR_TRACE("Problem with CV_CAP_PROP_FPS") ;
742  }
743 #endif
744  return framerate;
745 }
746 
750 bool vpVideoReader::isImageExtensionSupported()
751 {
752  return (formatType == FORMAT_PGM ||
753  formatType == FORMAT_PPM ||
754  formatType == FORMAT_JPEG ||
755  formatType == FORMAT_PNG ||
756  formatType == FORMAT_TIFF ||
757  formatType == FORMAT_BMP ||
758  formatType == FORMAT_DIB ||
759  formatType == FORMAT_PBM ||
760  formatType == FORMAT_RASTER ||
761  formatType == FORMAT_JPEG2000);
762 }
763 
767 bool vpVideoReader::isVideoExtensionSupported()
768 {
769  return (formatType == FORMAT_AVI ||
770  formatType == FORMAT_MPEG ||
771  formatType == FORMAT_MPEG4 ||
772  formatType == FORMAT_MOV ||
773  formatType == FORMAT_OGV ||
774  formatType == FORMAT_WMV ||
775  formatType == FORMAT_FLV ||
776  formatType == FORMAT_MKV);
777 }
double getFramerate() const
Definition: vpFFMPEG.h:219
unsigned int getWidth() const
Definition: vpImage.h:161
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
#define vpERROR_TRACE
Definition: vpDebug.h:391
bool getFrame(vpImage< vpRGBa > &I, unsigned int frameNumber)
Definition: vpFFMPEG.cpp:290
error that can be emited by ViSP classes.
Definition: vpException.h:73
Error that can be emited by the vpImage class and its derivates.
unsigned long getFrameNumber() const
Definition: vpFFMPEG.h:212
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:95
void acquire(vpImage< vpRGBa > &I)
This class interfaces the FFmpeg library to enable video stream reading or writing.
Definition: vpFFMPEG.h:145
void setImageNumber(long number)
void setFileName(const char *filename)
Class to grab (ie. read) images from the disk.
Base class for all video devices. It is designed to provide a front end to video sources.
void setLastFrameIndex(const long last_frame)
bool acquire(vpImage< vpRGBa > &I)
Definition: vpFFMPEG.cpp:344
double getFramerate()
unsigned int getHeight() const
Definition: vpImage.h:152
void acquire(vpImage< unsigned char > &I)
bool initStream()
Definition: vpFFMPEG.cpp:231
unsigned int width
Number of columns in the image.
void setGenericName(const char *genericName)