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 Collection(const Persistency::FileLocator& loc)
00027 {
00028 ReadData(loc);
00029 }
00030
00031
00032
00033 int
00034 NrVideoFiles()
00035 {
00036 return mId.size();
00037 }
00038
00039 void
00040 WriteVideoSet(const Persistency::Locator& loc, String use, String clipsKeys,
00041 bool vidSetOnly)
00042 {
00043 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00044 VideoSet::VideoSet* vidSet =
00045 new VideoSet::VideoSet(&Util::Database::GetInstance(),
00046 loc.GetDataSet(), false);
00047 #else // REPOSITORY_USED
00048 VideoSet::VideoSet* vidSet = new VideoSet::VideoSet(loc.GetDataSet());
00049 vidSet->SetProtocolAndHost(loc.GetProtocolAndHost());
00050 #endif // REPOSITORY_USED
00051 Segmentation segm(vidSet, "");
00052 Keyframes keyframes(vidSet, "");
00053 int videoId = 0;
00054 int offset = 0;
00055 for (int v=0 ; v<NrVideoFiles() ; v++)
00056
00057 {
00058 if ((!use.empty()) && (mUse[v] != use))
00059 {
00060 if (use == "test")
00061 offset = v + 1;
00062 continue;
00063 }
00064
00065 vidSet->AddFile(mFileName[v], ".");
00066 if (vidSetOnly)
00067 continue;
00068
00069 Stream::RgbDataSrc* rgbSrc = vidSet->GetVideo(videoId);
00070 if (!rgbSrc)
00071 {
00072 ILOG_ERROR("WriteVideoSet: no src for v=" << v << " (" <<
00073 mFileName[v] << ")");
00074 return;
00075 }
00076 if ((rgbSrc->FrameRateNum() < 0) || (rgbSrc->FrameRateDen() < 0))
00077 {
00078 ILOG_ERROR("WriteVideoSet: no framerate for v=" << v << " (" <<
00079 mFileName[v] << ")");
00080 return;
00081 }
00082
00083 String fileName = mSrcDir + MakeString(mId[v]) + ".mp7.xml";
00084 Persistency::Mpeg7DocLocator loc(fileName);
00085 loc.SetFrameRateNum(rgbSrc->FrameRateNum());
00086 loc.SetFrameRateDen(rgbSrc->FrameRateDen());
00087 Mpeg7Doc* mp7 = Persistency::Mpeg7DocRepository().Get(loc);
00088 ILOG_INFO("video " << mFileName[v] << " shots " << mp7->NrShots());
00089 int lastFrame = 0;
00090 for (int s=0 ; s<mp7->NrShots() ; s++)
00091 {
00092 if (mp7->StartFrame(s) != lastFrame)
00093 {
00094 ILOG_ERROR("shot " << s << " has gap (previous shot end "
00095 << lastFrame << ", this shot start " <<
00096 mp7->StartFrame(s) << "), adjusting start");
00097 segm.Add(videoId, lastFrame, mp7->EndFrame(s),
00098 mp7->ShotName(s));
00099 }
00100 else
00101 {
00102 segm.Add(videoId, mp7->StartFrame(s), mp7->EndFrame(s),
00103 mp7->ShotName(s));
00104 }
00105 lastFrame = mp7->EndFrame(s) + 1;
00106 if (clipsKeys.empty())
00107 {
00108 int shotId = segm.Size() - 1;
00109 for (int k=0 ; k<mp7->NrKeyframes(s) ; k++)
00110 {
00111 String name = mp7->KeyframeName(s, k) + ".jpg";
00112 keyframes.Add(videoId, shotId, mp7->KeyframeFrame(s, k),
00113 name);
00114 }
00115 }
00116 }
00117 delete mp7;
00118 delete rgbSrc;
00119 videoId++;
00120 }
00121 if (!clipsKeys.empty())
00122 ReadKeyframesClips(&segm, &keyframes, clipsKeys, offset);
00123 Persistency::Locator baseLoc = vidSet->GetLocator();
00124 bool binary = true;
00125 if (vidSetOnly)
00126 {
00127 Persistency::VideoSetRepository().Add(baseLoc, vidSet);
00128 return;
00129 }
00130 Persistency::SegmentationLocator sLoc(baseLoc, "segmentation");
00131 Persistency::SegmentationRepository().Add(sLoc, &segm);
00132
00133 keyframes.RemoveDuplicates();
00134 for (int i=0 ; i<keyframes.Size() ; i++)
00135 {
00136 int frame = keyframes.GetFrameNr(i);
00137 int shotId = keyframes.GetShotId(i);
00138 int start = segm.GetStart(shotId);
00139 int end = segm.GetEnd(shotId);
00140 if ((frame < start) || (frame > end))
00141 {
00142 ILOG_ERROR("keyframe " << i << ": frame " << frame <<
00143 " outside shot " << start << " - " << end);
00144 }
00145 }
00146 Persistency::KeyframesLocator kLoc(baseLoc, "keyframes");
00147 Persistency::KeyframesRepository().Add(kLoc, &keyframes);
00148 keyframes.WriteImageSets();
00149 }
00150
00151 private:
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 void
00167 ReadData(const Persistency::FileLocator& loc)
00168 {
00169 mSrcDir = FileNamePath(loc.GetName());
00170 typedef Persistency::RepositoryInFileSystem FS;
00171 Persistency::File file = FS::GetInstance().GetFile(loc, false, false);
00172 Util::IOBuffer* ioBuf = file.GetReadBuffer(true, "");
00173 Persistency::XmlFileReader reader;
00174 DOMDocument* doc = reader.Read(loc.GetName(), ioBuf);
00175 delete ioBuf;
00176 DOMNodeList* vList = reader.FindElementsByName(doc, "VideoFile");
00177 for (XMLSize_t i=0 ; i<vList->getLength() ; i++)
00178 {
00179 DOMNode* video = vList->item(i);
00180 DOMNodeList* children = video->getChildNodes();
00181 for (XMLSize_t j=0 ; j<children->getLength() ; j++)
00182 {
00183 DOMNode* child = children->item(j);
00184 DOMNode* grandChild = child->getFirstChild();
00185 if (!grandChild)
00186 continue;
00187 String name = XMLCh2String(child->getNodeName());
00188 String val = XMLCh2String(grandChild->getNodeValue());
00189 ILOG_DEBUG("read " << name << " = " << val);
00190 if (name == "id")
00191 mId.push_back(atol(val));
00192 else if (name == "filename")
00193 mFileName.push_back(val);
00194 else if (name == "use")
00195 mUse.push_back(val);
00196 else if (name == "source")
00197 mSource.push_back(val);
00198 }
00199 }
00200 }
00201
00215 void
00216 ReadKeyframesClips(Segmentation* segm, Keyframes* keyframes,
00217 String clipsKeys, int offset)
00218 {
00219 std::vector<String> lines;
00220 Persistency::FileLocator loc(clipsKeys);
00221 typedef Persistency::RepositoryInFileSystem FS;
00222 Persistency::File file = FS::GetInstance().GetFile(loc, false, false);
00223 file.ReadStrings(std::back_inserter(lines), true);
00224 ILOG_DEBUG("clipsKeys nr lines = " << lines.size());
00225 int curShot = -1;
00226 int lastShot = -1;
00227 for (int i=0 ; i<lines.size() ; i++)
00228 {
00229 Util::StringParser p(lines[i]);
00230 int frameNr = atol(FileNameBase(p.GetString(' ')));
00231 int vidId = atol(p.GetString('_'));
00232 if (vidId - 1 < offset)
00233 {
00234 ILOG_DEBUG("skipping " << vidId - 1);
00235 continue;
00236 }
00237 int shotId = atol(p.GetString('_'));
00238 int shotSub = atol(p.GetString(' '));
00239 String imName = FileNameTail(p.GetString(' '));
00240 ILOG_DEBUG("frameNr = " << frameNr << ", vid = " << vidId <<
00241 ", shot = " << shotId << ", imName = " << imName);
00242 if (shotId != lastShot)
00243 {
00244 curShot++;
00245 lastShot = shotId;
00246 if (curShot > segm->GetNrShots())
00247 {
00248 ILOG_ERROR("Too many keyframes");
00249 return;
00250 }
00251 }
00252 if ((vidId - 1 - offset) != segm->GetVideoId(curShot))
00253 ILOG_ERROR("ReadKeyframesClips: wrong vidId on line" << i);
00254 if ((frameNr < segm->GetStart(curShot)) ||
00255 (frameNr > segm->GetEnd(curShot)))
00256 {
00257 ILOG_ERROR("ReadKeyframesClips: frame " << frameNr <<
00258 " outside shot [" << segm->GetStart(curShot)
00259 << "," << segm->GetEnd(curShot) << "], line nr = "
00260 << i << ", curshot = " << curShot);
00261 }
00262 keyframes->Add(vidId - 1 - offset, curShot, frameNr, imName);
00263 }
00264 }
00265
00266 public:
00267
00268
00269
00270 String mSrcDir;
00271 std::vector<int> mId;
00272 std::vector<String> mFileName;
00273 std::vector<String> mUse;
00274 std::vector<String> mSource;
00275
00276 ILOG_VAR_DEC;
00277
00278 };
00279
00280 ILOG_VAR_INIT(Collection, Impala.Core.Trec);
00281
00282 }
00283 }
00284 }
00285
00286 #endif