00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Media/FrameRange.H"
00039
00040 #include "Util/Assert.H"
00041 #include "Util/StringConversions.H"
00042 #include "Util/StringUtil.H"
00043 #include "Util/log.H"
00044 #include "Util/sformat.H"
00045
00046 #include <iterator>
00047 #include <limits>
00048 #include <vector>
00049 #include <cstdio>
00050
00051
00052 FrameRange::FrameRange() :
00053 itsFirst(0),
00054 itsStep(1),
00055 itsLast(0),
00056 itsDelayTimes(),
00057 itsEventTriggered(false)
00058 {
00059
00060 itsDelayTimes.push_back(SimTime::ZERO());
00061 }
00062
00063 FrameRange::FrameRange(int first, int step, int last, std::vector<SimTime> delays, bool eventTriggered) :
00064 itsFirst(first),
00065 itsStep(step),
00066 itsLast(last),
00067 itsDelayTimes(delays),
00068 itsEventTriggered(eventTriggered)
00069 {
00070
00071 if(itsDelayTimes.size() == 0)
00072 {
00073 itsDelayTimes.push_back(SimTime::ZERO());
00074 }
00075 }
00076
00077
00078 std::string FrameRange::toString() const
00079 {
00080 const std::string range =
00081 itsStep == 1
00082 ? sformat("%d-%d", itsFirst, itsLast)
00083 : sformat("%d-%d-%d", itsFirst, itsStep, itsLast);
00084
00085 if (itsEventTriggered)
00086 {
00087 return sformat("%s@EVENT", range.c_str());
00088 }
00089 else
00090 {
00091 ASSERT(itsDelayTimes.size() > 0);
00092 if (itsDelayTimes.size() == 1)
00093 {
00094 return sformat("%s@%.2fms",
00095 range.c_str(), itsDelayTimes[0].msecs());
00096 }
00097 else
00098 {
00099 SimTime totstime = itsDelayTimes[0];
00100
00101 for (size_t i = 1; i < itsDelayTimes.size(); ++i)
00102 totstime += itsDelayTimes[i] - itsDelayTimes[i-1];
00103
00104
00105 const double aifd =
00106 totstime.msecs() / double(itsDelayTimes.size());
00107 return sformat("%s@variable delay "
00108 "(average inter-frame delay %.2fms)",
00109 range.c_str(), aifd);
00110 }
00111 }
00112 }
00113
00114
00115 FrameRange FrameRange::fromString(const std::string& str)
00116 {
00117 const std::string::size_type at = str.find('@');
00118 if (at == str.npos)
00119 conversion_error::raise<FrameRange>
00120 (str, "missing '@'; expected [first-[last]]@delay");
00121
00122 const std::string range = str.substr(0, at);
00123 const std::string sdelay = str.substr(at+1, str.npos);
00124
00125 int xfirst = -2, xstep = -2, xlast = -2;
00126
00127 if (range.length() == 0)
00128 {
00129 xfirst = 0;
00130 xstep = 1;
00131 xlast = std::numeric_limits<int>::max();
00132 }
00133 else
00134 {
00135 #define EXPECTED_FORMAT "expected [[first[-step]]-[last]]@delay"
00136
00137 std::vector<std::string> tokens;
00138 split(range, "-", std::back_inserter(tokens));
00139
00140 if (tokens.size() != 2 && tokens.size() != 3)
00141 conversion_error::raise<FrameRange>
00142 (str, "missing '-'; " EXPECTED_FORMAT);
00143
00144 const std::string sfirst = tokens.front();
00145 const std::string slast = tokens.back();
00146
00147 if (sfirst.length() == 0)
00148 xfirst = 0;
00149 else if (sscanf(sfirst.c_str(), "%d", &xfirst) != 1)
00150 conversion_error::raise<FrameRange>
00151 (str, "bogus 'first'; " EXPECTED_FORMAT);
00152
00153 if (slast.length() == 0
00154 || slast.compare("MAX") == 0
00155 || slast.compare("max") == 0)
00156 {
00157 xlast = std::numeric_limits<int>::max();
00158 }
00159 else if (sscanf(slast.c_str(), "%d", &xlast) != 1)
00160 {
00161 conversion_error::raise<FrameRange>
00162 (str, "bogus 'last'; " EXPECTED_FORMAT);
00163 }
00164
00165 if (tokens.size() == 3)
00166 {
00167 if (sscanf(tokens[1].c_str(), "%d", &xstep) != 1)
00168 conversion_error::raise<FrameRange>
00169 (str, "bogus 'step'; " EXPECTED_FORMAT);
00170
00171 if (xstep <= 0)
00172 conversion_error::raise<FrameRange>
00173 (str, "bogus 'step'; must be strictly greater than zero");
00174 }
00175 else
00176 xstep = 1;
00177 }
00178
00179 FrameRange result;
00180
00181 result.itsFirst = xfirst;
00182 result.itsStep = xstep;
00183 result.itsLast = xlast;
00184 result.itsEventTriggered = false;
00185 result.itsDelayTimes.resize(0);
00186
00187 LDEBUG("sdelay: %s", sdelay.c_str());
00188
00189
00190 if (sdelay.compare("EVENT") == 0) {
00191 result.itsEventTriggered = true;
00192
00193 result.itsDelayTimes.push_back(SimTime::ZERO());
00194 } else {
00195
00196
00197 const std::string::size_type suffix_pos = sdelay.find(".fl");
00198 if (suffix_pos == str.npos) {
00199
00200
00201 LDEBUG("didn't find fl suffix");
00202 result.itsDelayTimes.push_back(SimTime::fromString(sdelay, "ms"));
00203 } else {
00204
00205
00206 LDEBUG("found fl suffix");
00207 std::string fl_filename=sdelay;
00208 FILE *fl = fopen(fl_filename.c_str(), "r");
00209 if (fl == NULL) LFATAL("Cannot open %s", fl_filename.c_str());
00210
00211 double nextstime;
00212 int i=1;
00213 if (fscanf(fl, "%*s %lf\n", &nextstime) != 1)
00214 {
00215 fclose(fl);
00216 LFATAL("Error reading from %s[%i]",
00217 fl_filename.c_str(), i);
00218 }
00219 if (nextstime!=0)
00220 {
00221 fclose(fl);
00222 LFATAL("Simulation start time must be 0, "
00223 "but is %.2f in file: %s[%d]",
00224 nextstime, fl_filename.c_str(), i);
00225 }
00226 while (!feof(fl)) {
00227 i++;
00228
00229 if (fscanf(fl, "%*s %lf\n", &nextstime) != 1)
00230 {
00231 fclose(fl);
00232 LFATAL("Error reading from %s[%d]",
00233 fl_filename.c_str(), i);
00234 }
00235 result.itsDelayTimes.push_back(SimTime::MSECS(nextstime));
00236 }
00237 }
00238 LDEBUG("added %"ZU" delays to itsDelayTimes", result.itsDelayTimes.size());
00239 }
00240
00241 LDEBUG("parsed FrameRange string '%s' as '%s'",
00242 str.c_str(), result.toString().c_str());
00243
00244 return result;
00245 }
00246
00247
00248 bool FrameRange::operator==(const FrameRange& that) const
00249 {
00250 return (this->itsFirst == that.itsFirst
00251 && this->itsStep == that.itsStep
00252 && this->itsLast == that.itsLast
00253 && this->itsDelayTimes == that.itsDelayTimes
00254 && this->itsEventTriggered == that.itsEventTriggered);
00255 }
00256
00257
00258
00259
00260
00261
00262