00001 /*!@file Media/MpegInputStream.C Read frames from movie files */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Media/MpegInputStream.C $ 00035 // $Id: MpegInputStream.C 13800 2010-08-18 20:58:25Z dberg $ 00036 // 00037 00038 #ifndef MEDIA_MPEGINPUTSTREAM_C_DEFINED 00039 #define MEDIA_MPEGINPUTSTREAM_C_DEFINED 00040 00041 #include "Media/MpegInputStream.H" 00042 00043 #include "Component/ModelOptionDef.H" 00044 #include "Image/Image.H" 00045 #include "Image/Pixels.H" 00046 #include "Media/MediaOpts.H" 00047 #include "Media/MovieDecoder.H" 00048 #include "Raster/GenericFrame.H" 00049 #include "Transport/TransportOpts.H" 00050 #include "Util/Assert.H" 00051 #include "Util/log.H" 00052 #include "Video/VideoFrame.H" 00053 #include "rutz/trace.h" 00054 00055 #if defined(INVT_HAVE_AVFORMAT) 00056 // We need to be sure to #include <ffmpeg/avformat.h> before we try to 00057 // test LIBAVFORMAT_BUILD: 00058 # define attribute_deprecated 00059 extern "C" 00060 { 00061 #ifdef HAVE_LIBAVFORMAT_AVFORMAT_H 00062 #include <libavformat/avformat.h> 00063 #else 00064 #ifdef HAVE_FFMPEG_AVFORMAT_H 00065 #include <ffmpeg/avformat.h> 00066 #endif 00067 #endif 00068 } 00069 # if defined(LIBAVFORMAT_BUILD) && (LIBAVFORMAT_BUILD >= 4610) 00070 # include "Media/FfmpegPacketDecoder.H" 00071 # else 00072 # include "Media/FfmpegDecoder.H" 00073 # endif 00074 #endif 00075 00076 #ifdef HAVE_QUICKTIME_QUICKTIME_H 00077 # include "Media/QuartzQuickTimeDecoder.H" 00078 #endif 00079 00080 #include <cstdio> 00081 #include <string> 00082 00083 // private command-line option defs 00084 00085 // Used by: InputMPEGStream 00086 static const ModelOptionDef OPT_InputMPEGStreamCodec = 00087 { MODOPT_ARG_STRING, "InputMPEGStreamCodec", &MOC_INPUT, OPTEXP_CORE, 00088 "Type of video input codec to use (use value 'List' to see list of " 00089 "available codecs on your system, or 'Auto' to automatically determine " 00090 "which codec to use)", 00091 "input-codec", '\0', "<Auto|List|name>", "Auto" }; 00092 00093 // ###################################################################### 00094 InputMPEGStream::InputMPEGStream(OptionManager& mgr, 00095 const std::string& descrName, 00096 const std::string& tagName) 00097 : 00098 FrameIstream(mgr, descrName, tagName), 00099 itsBuffLen(tagName+"BuffLen", this, 65536), 00100 itsCodecName(&OPT_InputMPEGStreamCodec, this), 00101 itsDoPreload(&OPT_InputMPEGStreamPreload, this), 00102 itsFileName(""), 00103 dec(0) 00104 {} 00105 00106 // ###################################################################### 00107 InputMPEGStream::~InputMPEGStream() 00108 { 00109 delete dec; 00110 } 00111 00112 // ###################################################################### 00113 void InputMPEGStream::stop2() 00114 { 00115 delete dec; 00116 dec = 0; 00117 } 00118 00119 // ###################################################################### 00120 void InputMPEGStream::setConfigInfo(const std::string& filename) 00121 { 00122 // NOTE: if you modify any behavior here, then please update the 00123 // corresponding documentation for the global "--in" option inside 00124 // the OPT_InputFrameSource definition in Media/MediaOpts.C 00125 00126 this->setFileName(filename); 00127 } 00128 00129 // ###################################################################### 00130 bool InputMPEGStream::setFrameNumber(const int n) 00131 { 00132 createDecoder(); 00133 00134 LDEBUG("external/internal frame# %d/%d", n, dec->apparentFrameNumber()); 00135 00136 return dec->setFrameNumber(n); 00137 } 00138 00139 // ###################################################################### 00140 GenericFrameSpec InputMPEGStream::peekFrameSpec() 00141 { 00142 GVX_TRACE(__PRETTY_FUNCTION__); 00143 00144 createDecoder(); 00145 ASSERT(dec != 0); 00146 00147 return dec->peekFrameSpec(); 00148 } 00149 00150 // ###################################################################### 00151 void InputMPEGStream::setFileName(std::string fname) 00152 { 00153 GVX_TRACE(__PRETTY_FUNCTION__); 00154 00155 // if we already had an open decoder, nuke it: 00156 if (dec != 0) { delete dec; dec = 0; } 00157 00158 itsFileName = fname; 00159 } 00160 00161 // ###################################################################### 00162 GenericFrame InputMPEGStream::readFrame() 00163 { 00164 GVX_TRACE(__PRETTY_FUNCTION__); 00165 00166 createDecoder(); 00167 ASSERT(dec != 0); 00168 00169 return GenericFrame(dec->readVideoFrame()); 00170 } 00171 00172 // ###################################################################### 00173 Image<PixRGB<byte> > InputMPEGStream::readRGB() 00174 { 00175 GVX_TRACE(__PRETTY_FUNCTION__); 00176 00177 createDecoder(); 00178 ASSERT(dec != 0); 00179 00180 return dec->readRGB(); 00181 } 00182 00183 // ###################################################################### 00184 bool InputMPEGStream::readAndDiscardFrame() 00185 { 00186 GVX_TRACE(__PRETTY_FUNCTION__); 00187 00188 createDecoder(); 00189 ASSERT(dec != 0); 00190 00191 return dec->readAndDiscardFrame(); 00192 } 00193 00194 // ###################################################################### 00195 VideoFrame InputMPEGStream::readVideoFrame() 00196 { 00197 GVX_TRACE(__PRETTY_FUNCTION__); 00198 00199 createDecoder(); 00200 ASSERT(dec != 0); 00201 00202 return dec->readVideoFrame(); 00203 } 00204 00205 // ###################################################################### 00206 void InputMPEGStream::createDecoder() 00207 { 00208 GVX_TRACE(__PRETTY_FUNCTION__); 00209 00210 if (dec == 0) 00211 { 00212 if (itsFileName.length() == 0) 00213 { 00214 LFATAL("no input mpeg filename specified"); 00215 } 00216 00217 #if defined(INVT_HAVE_AVFORMAT) 00218 #if defined(LIBAVFORMAT_BUILD) && (LIBAVFORMAT_BUILD >= 4610) 00219 dec = new FfmpegPacketDecoder(itsFileName.c_str(), 00220 itsDoPreload.getVal()); 00221 #else 00222 // this is the old stream-based FfmpegDecoder, which doesn't 00223 // handle mpeg-4 streams robustly 00224 dec = new FfmpegDecoder(itsCodecName.getVal().c_str(), 00225 itsBuffLen.getVal(), 00226 itsFileName.c_str(), 00227 itsDoPreload.getVal()); 00228 #endif 00229 #elif defined(HAVE_QUICKTIME_QUICKTIME_H) 00230 dec = new QuartzQuickTimeDecoder(itsFileName.c_str()); 00231 #else 00232 LFATAL("you must have an movie-reading library (such as ffmpeg or QuickTime) " 00233 "installed in order to be able to read movie files"); 00234 #endif 00235 } 00236 } 00237 00238 // ###################################################################### 00239 /* So things look consistent in everyone's emacs... */ 00240 /* Local Variables: */ 00241 /* mode: c++ */ 00242 /* indent-tabs-mode: nil */ 00243 /* End: */ 00244 00245 #endif // MEDIA_MPEGINPUTSTREAM_C_DEFINED