00001 #ifndef Impala_Core_Trec_Collection_h
00002 #define Impala_Core_Trec_Collection_h
00003
00004 #include "Persistency/Mpeg7DocRepository.h"
00005 #include "Core/VideoSet/Keyframes.h"
00006 #include "Core/VideoSet/Segmentation.h"
00007 #include "Core/VideoSet/Mpeg7Doc.h"
00008 #include "Core/ImageSet/ImageSet.h"
00009
00010 namespace Impala
00011 {
00012 namespace Core
00013 {
00014 namespace Trec
00015 {
00016
00017
00018 class Collection : public Util::XmlDoc
00019 {
00020 public:
00021
00022 typedef VideoSet::Segmentation Segmentation;
00023 typedef VideoSet::Keyframes Keyframes;
00024 typedef VideoSet::Mpeg7Doc Mpeg7Doc;
00025
00026 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00027 Collection(String fileName, Util::Database* db)
00028 {
00029 ReadData(fileName, db);
00030 }
00031 #else // REPOSITORY_USED
00032 Collection(const Persistency::FileLocator& loc)
00033 {
00034 ReadData(loc);
00035 }
00036 #endif // REPOSITORY_USED
00037
00038
00039
00040 int
00041 NrVideoFiles()
00042 {
00043 return mId.size();
00044 }
00045
00046 void
00047 WriteVideoSet(String setName, String use, String clipsKeys)
00048 {
00049 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00050 VideoSet::VideoSet* vidSet = new VideoSet::VideoSet(mDb, setName, false);
00051 #else // REPOSITORY_USED
00052 VideoSet::VideoSet* vidSet = new VideoSet::VideoSet(setName);
00053 #endif // REPOSITORY_USED
00054 Segmentation segm(vidSet, "");
00055 Keyframes keyframes(vidSet, "");
00056 int videoId = 0;
00057 int offset = 0;
00058 for (int v=0 ; v<NrVideoFiles() ; v++)
00059 {
00060 if ((!use.empty()) && (mUse[v] != use))
00061 {
00062 if (use == "test")
00063 offset = v + 1;
00064 continue;
00065 }
00066
00067 vidSet->AddFile(mFileName[v], ".", ".");
00068
00069 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00070 Mpeg7Doc mp7doc(mSrcDir + MakeString(mId[v]) + ".mp7.xml", mDb);
00071 Mpeg7Doc* mp7 = &mp7doc;
00072 #else // REPOSITORY_USED
00073 String fileName = mSrcDir + MakeString(mId[v]) + ".mp7.xml";
00074 Persistency::Mpeg7DocLocator loc(fileName);
00075 std::cout << "loc = " << loc << std::endl;
00076 Mpeg7Doc* mp7 = Persistency::Mpeg7DocRepository().Get(loc);
00077 #endif // REPOSITORY_USED
00078 ILOG_INFO("video " << mFileName[v] << " shots " << mp7->NrShots());
00079 int lastFrame = 0;
00080 for (int s=0 ; s<mp7->NrShots() ; s++)
00081 {
00082 if (mp7->StartFrame(s) != lastFrame)
00083 {
00084 ILOG_ERROR("shot " << s << " has gap (previous shot end "
00085 << lastFrame << ", this shot start " <<
00086 mp7->StartFrame(s) << "), adjusting start");
00087 segm.Add(videoId, lastFrame, mp7->EndFrame(s),
00088 mp7->ShotName(s));
00089 }
00090 else
00091 {
00092 segm.Add(videoId, mp7->StartFrame(s), mp7->EndFrame(s),
00093 mp7->ShotName(s));
00094 }
00095 lastFrame = mp7->EndFrame(s) + 1;
00096 if (clipsKeys.empty())
00097 {
00098 int shotId = segm.Size() - 1;
00099 for (int k=0 ; k<mp7->NrKeyframes(s) ; k++)
00100 {
00101 String name = mp7->KeyframeName(s, k) + ".jpg";
00102 keyframes.Add(videoId, shotId, mp7->KeyframeFrame(s, k),
00103 name);
00104 }
00105 }
00106 }
00107 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00108 #else // REPOSITORY_USED
00109 delete mp7;
00110 #endif // REPOSITORY_USED
00111 videoId++;
00112 }
00113 if (!clipsKeys.empty())
00114 ReadKeyframesClips(&segm, &keyframes, clipsKeys, offset);
00115 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00116 vidSet->SaveVideoSet();
00117 bool binary = true;
00118 segm.Save("segmentation", binary);
00119 #else // REPOSITORY_USED
00120 Persistency::Locator baseLoc = vidSet->GetLocator();
00121 bool binary = true;
00122 Persistency::VideoSetRepository().Add(baseLoc, vidSet);
00123 Persistency::SegmentationLocator sLoc(baseLoc, "segmentation");
00124 Persistency::SegmentationRepository().Add(sLoc, &segm);
00125 #endif // REPOSITORY_USED
00126
00127 keyframes.RemoveDuplicates();
00128 for (int i=0 ; i<keyframes.Size() ; i++)
00129 {
00130 int frame = keyframes.GetFrameNr(i);
00131 int shotId = keyframes.GetShotId(i);
00132 int start = segm.GetStart(shotId);
00133 int end = segm.GetEnd(shotId);
00134 if ((frame < start) || (frame > end))
00135 {
00136 ILOG_ERROR("keyframe " << i << ": frame " << frame <<
00137 " outside shot " << start << " - " << end);
00138 }
00139 }
00140 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00141 keyframes.Save("keyframes", binary);
00142 #else // REPOSITORY_USED
00143 Persistency::KeyframesLocator kLoc(baseLoc, "keyframes");
00144 Persistency::KeyframesRepository().Add(kLoc, &keyframes);
00145 #endif // REPOSITORY_USED
00146 keyframes.WriteImageSets();
00147 }
00148
00149 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00150 void
00151 WriteTo(std::ostream& os)
00152 {
00153 for (int i=0 ; i<NrVideoFiles() ; i++)
00154 {
00155 os << mId[i] << " = " << mFileName[i] << ", use " << mUse[i]
00156 << ", source " << mSource[i] << std::endl;
00157 Mpeg7Doc mp7(mSrcDir + MakeString(mId[i]) + ".mp7.xml", mDb);
00158 mp7.WriteTo(os);
00159 }
00160 }
00161 #endif // REPOSITORY_USED
00162
00163 private:
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 void
00179 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00180 ReadData(String fileName, Util::Database* db)
00181 {
00182 mDb = db;
00183 mSrcDir = FileNamePath(fileName);
00184 Util::IOBuffer* ioBuf = db->GetIOBuffer(fileName, true, true, "");
00185 Persistency::XmlFileReader reader;
00186 DOMDocument* doc = reader.Read(fileName, ioBuf);
00187 #else // REPOSITORY_USED
00188 ReadData(const Persistency::FileLocator& loc)
00189 {
00190 mSrcDir = FileNamePath(loc.GetName());
00191 typedef Persistency::RepositoryInFileSystem FS;
00192 Persistency::File file = FS::GetInstance().GetFile(loc, false, false);
00193 Util::IOBuffer* ioBuf = file.GetReadBuffer(true, "");
00194 Persistency::XmlFileReader reader;
00195 DOMDocument* doc = reader.Read(loc.GetName(), ioBuf);
00196 #endif // REPOSITORY_USED
00197 delete ioBuf;
00198 DOMNodeList* vList = reader.FindElementsByName(doc, "VideoFile");
00199 for (XMLSize_t i=0 ; i<vList->getLength() ; i++)
00200 {
00201 DOMNode* video = vList->item(i);
00202 DOMNodeList* children = video->getChildNodes();
00203 for (XMLSize_t j=0 ; j<children->getLength() ; j++)
00204 {
00205 DOMNode* child = children->item(j);
00206 DOMNode* grandChild = child->getFirstChild();
00207 if (!grandChild)
00208 continue;
00209 String name = XMLCh2String(child->getNodeName());
00210 String val = XMLCh2String(grandChild->getNodeValue());
00211 ILOG_DEBUG("read " << name << " = " << val);
00212 if (name == "id")
00213 mId.push_back(atol(val));
00214 else if (name == "filename")
00215 mFileName.push_back(val);
00216 else if (name == "use")
00217 mUse.push_back(val);
00218 else if (name == "source")
00219 mSource.push_back(val);
00220 }
00221 }
00222 }
00223
00237 void
00238 ReadKeyframesClips(Segmentation* segm, Keyframes* keyframes,
00239 String clipsKeys, int offset)
00240 {
00241 std::vector<String> lines;
00242 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00243 Util::DatabaseReadString(std::back_inserter(lines), clipsKeys, mDb, true);
00244 #else // REPOSITORY_USED
00245 Persistency::FileLocator loc(clipsKeys);
00246 typedef Persistency::RepositoryInFileSystem FS;
00247 Persistency::File file = FS::GetInstance().GetFile(loc, false, false);
00248 file.ReadStrings(std::back_inserter(lines), true);
00249 #endif // REPOSITORY_USED
00250 ILOG_DEBUG("clipsKeys nr lines = " << lines.size());
00251 int curShot = -1;
00252 int lastShot = -1;
00253 for (int i=0 ; i<lines.size() ; i++)
00254 {
00255 Util::StringParser p(lines[i]);
00256 int frameNr = atol(FileNameBase(p.GetString(' ')));
00257 int vidId = atol(p.GetString('_'));
00258 if (vidId - 1 < offset)
00259 {
00260 ILOG_DEBUG("skipping " << vidId - 1);
00261 continue;
00262 }
00263 int shotId = atol(p.GetString('_'));
00264 int shotSub = atol(p.GetString(' '));
00265 String imName = FileNameTail(p.GetString(' '));
00266 ILOG_DEBUG("frameNr = " << frameNr << ", vid = " << vidId <<
00267 ", shot = " << shotId << ", imName = " << imName);
00268 if (shotId != lastShot)
00269 {
00270 curShot++;
00271 lastShot = shotId;
00272 if (curShot > segm->GetNrShots())
00273 {
00274 ILOG_ERROR("Too many keyframes");
00275 return;
00276 }
00277 }
00278 if ((vidId - 1 - offset) != segm->GetVideoId(curShot))
00279 ILOG_ERROR("ReadKeyframesClips: wrong vidId on line" << i);
00280 if ((frameNr < segm->GetStart(curShot)) ||
00281 (frameNr > segm->GetEnd(curShot)))
00282 {
00283 ILOG_ERROR("ReadKeyframesClips: frame " << frameNr <<
00284 " outside shot [" << segm->GetStart(curShot)
00285 << "," << segm->GetEnd(curShot) << "], line nr = "
00286 << i << ", curshot = " << curShot);
00287 }
00288 keyframes->Add(vidId - 1 - offset, curShot, frameNr, imName);
00289 }
00290 }
00291
00292 public:
00293
00294
00295
00296 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00297 Util::Database* mDb;
00298 #endif // REPOSITORY_USED
00299 String mSrcDir;
00300 std::vector<int> mId;
00301 std::vector<String> mFileName;
00302 std::vector<String> mUse;
00303 std::vector<String> mSource;
00304
00305 ILOG_VAR_DEC;
00306
00307 };
00308
00309 ILOG_VAR_INIT(Collection, Impala.Core.Trec);
00310
00311 }
00312 }
00313 }
00314
00315 #endif