00001 /*!@file AppMedia/app-iplayer.C An awesome ilab media player, 00002 basically a ifstream and ofstream with some added key commands for 00003 forward, backward, pause, and to mark frame numbers. */ 00004 00005 // //////////////////////////////////////////////////////////////////// // 00006 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00007 // by the University of Southern California (USC) and the iLab at USC. // 00008 // See http://iLab.usc.edu for information about this project. // 00009 // //////////////////////////////////////////////////////////////////// // 00010 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00011 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00012 // in Visual Environments, and Applications'' by Christof Koch and // 00013 // Laurent Itti, California Institute of Technology, 2001 (patent // 00014 // pending; application number 09/912,225 filed July 23, 2001; see // 00015 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00016 // //////////////////////////////////////////////////////////////////// // 00017 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00018 // // 00019 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00020 // redistribute it and/or modify it under the terms of the GNU General // 00021 // Public License as published by the Free Software Foundation; either // 00022 // version 2 of the License, or (at your option) any later version. // 00023 // // 00024 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00025 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00026 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00027 // PURPOSE. See the GNU General Public License for more details. // 00028 // // 00029 // You should have received a copy of the GNU General Public License // 00030 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00031 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00032 // Boston, MA 02111-1307 USA. // 00033 // //////////////////////////////////////////////////////////////////// // 00034 // 00035 // Primary maintainer for this file: David J. Berg <dberg@usc.edu> 00036 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppMedia/app-iplayer.C $ 00037 00038 #ifndef APPMEDIA_APP_STREAM_C_DEFINED 00039 #define APPMEDIA_APP_STREAM_C_DEFINED 00040 00041 #define INIT_BUFF_LENGTH 100 00042 00043 #include "Component/ModelManager.H" 00044 #include "Media/Streamer.H" 00045 #include "Util/StringConversions.H" 00046 #include "Devices/KeyBoard.H" 00047 #include "Raster/Raster.H" 00048 00049 #include <iostream> 00050 #include <fstream> 00051 #include <deque> 00052 #include <vector> 00053 00054 class iPlayer : public Streamer 00055 { 00056 public: 00057 iPlayer() 00058 : 00059 Streamer("iPlayer"), 00060 itsOutPrefix("iplayer-output"), 00061 itsKeyBoard(), 00062 itsBuffer(), 00063 itsFrameCount(-1), 00064 itsStart(), 00065 itsEnd(), 00066 itsEdits(), 00067 itsOutFile(), 00068 itsBuffLength(INIT_BUFF_LENGTH) 00069 { }; 00070 00071 ~iPlayer() 00072 { 00073 if ( (itsStart.size() > 0) && (itsEnd.size() > 0) ) 00074 { 00075 if (itsStart.size() < itsEnd.size()) 00076 itsEnd.pop_back(); 00077 else if (itsStart.size() > itsEnd.size()) 00078 itsStart.pop_back(); 00079 00080 for (uint ii = 0; ii < itsStart.size(); ++ii) 00081 itsOutStream << itsStart[ii] << " " << itsEnd[ii] << std::endl; 00082 00083 itsOutStream.close(); 00084 } 00085 } 00086 private: 00087 //handle any extra args 00088 virtual void handleExtraArgs(const ModelManager& mgr) 00089 { 00090 itsOutFile = mgr.getExtraArg(0); 00091 itsOutStream.open(itsOutFile.c_str(), std::ios::out | std::ios::app); 00092 00093 if (mgr.numExtraArgs() > 1) 00094 itsBuffLength = fromStr<uint>(mgr.getExtraArg(1)); 00095 00096 if (!itsOutStream.is_open()) 00097 LFATAL("Could not open '%s' for output.", itsOutFile.c_str()); 00098 00099 LINFO("Key bindings: "); 00100 LINFO("<space>: pause"); 00101 LINFO("<,>: backward"); 00102 LINFO("<.>: forward"); 00103 LINFO("<z>: mark start of sequence"); 00104 LINFO("<x>: mark end of sequence"); 00105 LINFO("<u>: undo add sequence start/end"); 00106 LINFO(" "); 00107 LINFO(" "); 00108 }; 00109 00110 //process on every frame 00111 virtual void onFrame(const GenericFrame& input, 00112 FrameOstream& ofs, 00113 const int frameNum) 00114 { 00115 itsBuffer.push_back(input); 00116 if (itsBuffer.size() > itsBuffLength) 00117 itsBuffer.pop_front(); 00118 00119 00120 ofs.writeFrame(itsBuffer.back(), itsOutPrefix, 00121 FrameInfo("copy of input frame", SRC_POS)); 00122 00123 ++itsFrameCount; 00124 LINFO("showing frame: %d ", itsFrameCount); 00125 00126 int key = itsKeyBoard.getKeyAsChar(false); 00127 switch (key) 00128 { 00129 case 32: //space 00130 { 00131 LINFO("entering edit mode"); 00132 key = -1; 00133 uint itsEditPos = itsFrameCount; 00134 uint itsBufPos = itsBuffer.size() - 1; 00135 00136 while (key != 32)//keep in edit mode until space is again pressed 00137 { 00138 key = itsKeyBoard.getKeyAsChar(true); 00139 switch (key) 00140 { 00141 case 27://escape key 00142 LFATAL("Playback aborted by user, exiting."); 00143 break; 00144 00145 case 44: //, 00146 { 00147 LINFO("back one frame"); 00148 if (itsBufPos <= 0) 00149 LINFO("cannot seek backward any further."); 00150 else 00151 { 00152 --itsBufPos; 00153 --itsEditPos; 00154 } 00155 } 00156 break; 00157 00158 case 46: //. 00159 { 00160 LINFO("forward one frame"); 00161 if ( itsBufPos >= (itsBuffer.size() - 1) ) 00162 LINFO("cannot seek forward any further."); 00163 else 00164 { 00165 ++itsBufPos; 00166 ++itsEditPos; 00167 } 00168 } 00169 break; 00170 00171 case 122://z 00172 { 00173 int diff = itsStart.size() - itsEnd.size(); 00174 if (diff > 0) 00175 LINFO("You have attempted to add two clip onset markers " 00176 "in a row, ignoring command"); 00177 else 00178 { 00179 LINFO("marked clip onset"); 00180 itsStart.push_back(itsEditPos); 00181 itsEdits.push_back(ADD_START); 00182 } 00183 } 00184 break; 00185 00186 case 120://x 00187 { 00188 int diff = itsStart.size() - itsEnd.size(); 00189 if (diff < 0) 00190 LINFO("You have attempted to add two clip offset markers " 00191 "in a row, ignoring command"); 00192 else 00193 { 00194 LINFO("marked clip offset"); 00195 itsEnd.push_back(itsEditPos); 00196 itsEdits.push_back(ADD_END); 00197 } 00198 } 00199 break; 00200 00201 case 117://u 00202 { 00203 if (itsEdits.size() > 0) 00204 { 00205 COMMAND last = itsEdits.back(); 00206 LINFO("undoing last edit: '%s' ", 00207 last ? "mark end" : "mark start"); 00208 itsEdits.pop_back(); 00209 00210 if (last) 00211 itsEnd.pop_back(); 00212 else 00213 itsStart.pop_back(); 00214 } 00215 else 00216 LINFO("No more edits to undo"); 00217 } 00218 break; 00219 } 00220 00221 //now show a frame since we have recieved a command 00222 ofs.writeFrame(itsBuffer[itsBufPos], itsOutPrefix, 00223 FrameInfo("copy of input frame", SRC_POS)); 00224 LINFO("showing frame: %d ", itsEditPos); 00225 } 00226 LINFO("exiting edit mode"); 00227 } 00228 break; 00229 00230 case 27://escape key 00231 LFATAL("Playback aborted by user, exiting."); 00232 break; 00233 } 00234 }; 00235 00236 enum COMMAND {ADD_START = 0, ADD_END = 1};//to hold our edit states 00237 00238 std::string itsOutPrefix; //our output prefix 00239 KeyBoard itsKeyBoard; //a hook to our keyboard 00240 std::deque<GenericFrame> itsBuffer; //hold our generic frames 00241 int itsFrameCount; //keep track of which frame we are on 00242 std::vector<uint> itsStart, itsEnd; 00243 std::vector<COMMAND> itsEdits; 00244 std::string itsOutFile; 00245 std::ofstream itsOutStream; 00246 uint itsBuffLength; 00247 }; 00248 00249 int main(const int argc, const char **argv) 00250 { 00251 iPlayer s; 00252 return s.run(argc, argv, "<output file name>", 1, 2); 00253 } 00254 00255 // ###################################################################### 00256 /* So things look consistent in everyone's emacs... */ 00257 /* Local Variables: */ 00258 /* indent-tabs-mode: nil */ 00259 /* End: */ 00260 00261 #endif // APPMEDIA_APP_STREAM_C_DEFINED