SequenceFileStream.C
Go to the documentation of this file.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/SequenceFileStream.H"
00039 #include "Component/ModelOptionDef.H"
00040 #include "Raster/DeBayer.H"
00041 #include "Image/Image.H"
00042 #include "Image/Pixels.H"
00043 #include "Raster/GenericFrame.H"
00044 #include "Transport/TransportOpts.H"
00045 #include "Util/log.H"
00046 #include "rutz/trace.h"
00047
00048 #include <stdio.h>
00049 #include <fcntl.h>
00050
00051 const ModelOptionDef OPT_SequenceFileStreamUseMmap =
00052 { MODOPT_ARG(bool), "SequenceFileStreamUseMmap", &MOC_INPUT, OPTEXP_CORE,
00053 "Whether to use mmap() instead of read() to stream data from disk. The"
00054 "default is to use mmap(), which may be significantly faster, but may"
00055 "be somewhat less portable.",
00056 "seqfile-use-mmap", '\0', "<true|false>", "false" };
00057
00058
00059 SequenceFileStream::SequenceFileStream(OptionManager& mgr,
00060 const std::string& descrName, const std::string& tagName) :
00061 FrameIstream(mgr, descrName, tagName),
00062 itsUseMmap(&OPT_SequenceFileStreamUseMmap, this),
00063 itsFrame(), itsFrameSpec(), itsFrameSpecValid(false), itsFileHandle(-1),
00064 itsMmapFile()
00065 { }
00066
00067
00068 SequenceFileStream::~SequenceFileStream()
00069 { }
00070
00071
00072 void SequenceFileStream::setConfigInfo(const std::string& filename)
00073 {
00074 this->setFileName(filename);
00075 }
00076
00077
00078
00079 GenericFrameSpec SequenceFileStream::peekFrameSpec()
00080 {
00081 GVX_TRACE(__PRETTY_FUNCTION__);
00082
00083 if (!itsFrameSpecValid)
00084 {
00085 if (itsFrame.initialized() == false) itsFrame = readFrame();
00086
00087 itsFrameSpec = itsFrame.frameSpec();
00088 itsFrameSpecValid = true;
00089 }
00090
00091 return itsFrameSpec;
00092 }
00093
00094
00095 void SequenceFileStream::setFileName(const std::string& fname)
00096 {
00097 GVX_TRACE(__PRETTY_FUNCTION__);
00098
00099
00100 if (itsFileHandle != -1) close(itsFileHandle);
00101
00102 #ifdef HAVE_O_LARGEFILE
00103 itsFileHandle = open(fname.c_str(), O_LARGEFILE | O_RDONLY);
00104 #else
00105 itsFileHandle = open(fname.c_str(), O_RDONLY);
00106 #endif
00107
00108 if(itsFileHandle == -1) PLFATAL("Could Not Open File %s", fname.c_str());
00109
00110 int32_t header[146];
00111 ssize_t headerSize;
00112
00113
00114 headerSize = read(itsFileHandle, &header, (size_t)(sizeof(int32_t) * 146) );
00115
00116
00117 if (headerSize != size_t(sizeof(int32_t) * 146) )
00118 LFATAL("Could not fully read .seq file header. File: %s", fname.c_str());
00119
00120
00121 if(header[7] != 3)
00122 LFATAL("Wrong version number found in .seq file header (%d != 3).", header[7]);
00123
00124
00125 if(header[0] != 0xfeed)
00126 LFATAL("Missing magic number from .seq file header (%x != 0xfeed).", header[0]);
00127
00128 if(header[139] != 8 || header[140] != 8 || (header[142] != 100 && header[142] != 101))
00129 LFATAL("seq file in a format other than 8-bit bayer\n");
00130
00131 itsDataOffset = header[8];
00132 itsWidth = header[137];
00133 itsHeight = header[138];
00134 itsFrameCount = header[143];
00135 itsFirstFrame = header[144];
00136 itsTrueImageSize = header[145];
00137 itsImageSizeBytes = header[141];
00138
00139 LINFO("Opening Sequence File with %d Frames", itsFrameCount);
00140
00141
00142 if (itsUseMmap.getVal()) {
00143
00144 close(itsFileHandle); itsFileHandle = -1;
00145 itsMmapFile.reset(new rutz::mapped_infile(fname.c_str()));
00146 }
00147 }
00148
00149 bool SequenceFileStream::setFrameNumber(int n)
00150 {
00151 if ((unsigned int)n > itsFrameCount) return false;
00152
00153 itsFrameOffset = n;
00154 return true;
00155 }
00156
00157
00158 GenericFrame SequenceFileStream::readFrame()
00159 {
00160 GVX_TRACE(__PRETTY_FUNCTION__);
00161
00162 if (itsUseMmap.getVal()) { if (itsMmapFile.is_invalid()) LFATAL("File not mmap'd"); }
00163 else { if (itsFileHandle == -1) LFATAL("File not open"); }
00164
00165 GenericFrame ret;
00166
00167
00168 if (itsFrame.initialized()) {
00169 ret = itsFrame;
00170 itsFrame = GenericFrame();
00171 } else {
00172
00173 off_t seekPosition = itsDataOffset + (itsFirstFrame + itsFrameOffset) * itsTrueImageSize;
00174
00175 if (itsUseMmap.getVal()) {
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 Image<byte> img(reinterpret_cast<const byte *>(itsMmapFile->memory()) + seekPosition, itsWidth, itsHeight);
00190
00191
00192
00193
00194 Image<PixRGB<byte> > frame = deBayer(img, BAYER_GRBG);
00195 ret = GenericFrame(frame);
00196
00197
00198 } else {
00199
00200 #ifdef HAVE_O_LARGEFILE
00201 lseek64(itsFileHandle, seekPosition, SEEK_SET);
00202 #else
00203 lseek(itsFileHandle, seekPosition, SEEK_SET);
00204 #endif
00205
00206
00207 Image<byte> tempImage(itsWidth, itsHeight, NO_INIT);
00208
00209 size_t numRead = read(itsFileHandle, tempImage.getArrayPtr(), itsWidth * itsHeight);
00210
00211 if (numRead <= 0) { LERROR("Frame Not Read From Sequence File"); return GenericFrame(); }
00212
00213
00214 Image<PixRGB<byte> > frame = deBayer(tempImage, BAYER_GRBG);
00215 ret = GenericFrame(frame);
00216 }
00217
00218 ++itsFrameOffset;
00219 }
00220
00221 return ret;
00222 }
00223
00224