Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

Keyframes.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_VideoSet_Keyframes_h
00002 #define Impala_Core_VideoSet_Keyframes_h
00003 
00004 #include "Persistency/ImageSetRepository.h"
00005 #include "Basis/Quid.h"
00006 #include "Core/Table/MakeGroupIndex.h"
00007 #include "Core/VideoSet/VideoSet.h"
00008 #include "Core/ImageSet/ImageSet.h"
00009 #include "Core/Table/TableTem.h"
00010 #include "Core/Table/Read.h"
00011 #include "Core/Table/Write.h"
00012 #include "Core/Table/RemoveRow.h"
00013 #include "Core/Table/QuidTable.h"
00014 #include "Core/Column/Find.h"
00015 #include "Link/DiskImage/DiskImageFuncs.h"
00016 
00017 namespace Impala
00018 {
00019 namespace Core
00020 {
00021 namespace VideoSet
00022 {
00023 
00024 
00025 typedef Table::TableTem<Column::ColumnTem<Int32>,
00026                         Column::ColumnTem<Int32>,
00027                         Column::ColumnTem<Int32>,
00028                         Column::ColumnTem<String> > KeyframesBaseType;
00029 
00030 
00031 class Keyframes : public KeyframesBaseType
00032 {
00033     typedef Impala::Core::Table::GroupIndex GroupIndex;
00034 
00035 public:
00036 
00037     Keyframes(VideoSet* vidSet, String name) : KeyframesBaseType(0)
00038     {
00039         mVidSet = vidSet;
00040         mName = name;
00041         mVideoGroups = 0;
00042         mShotGroups = 0;
00043         SetColName(1, "videoId");
00044         SetColName(2, "shotId");
00045         SetColName(3, "frameNr");
00046         SetColName(4, "name");
00047 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00048         if (!mName.empty())
00049             Load();
00050 #else // REPOSITORY_USED
00051         if (!mName.empty())
00052             ILOG_ERROR("Load keyframes via repository");
00053 #endif // REPOSITORY_USED
00054     }
00055 
00056     // inquiry part
00057 
00058     int
00059     GetNrKeyframes()
00060     {
00061         return Size();
00062     }
00063 
00064     int
00065     GetVideoId(int keyId)
00066     {
00067         return Get1(keyId);
00068     }
00069 
00070     int
00071     GetShotId(int keyId)
00072     {
00073         return Get2(keyId);
00074     }
00075 
00076     String
00077     GetName(int keyId)
00078     {
00079         return Get4(keyId);
00080     }
00081 
00082     bool
00083     IsRKF(int keyId)
00084     {
00085         return Get4(keyId).find("_RKF") != String::npos;
00086     }
00087 
00088     int
00089     GetFrameNr(int keyId)
00090     {
00091         return Get3(keyId);
00092     }
00093 
00094     Core::Table::QuidTable*
00095     MakeRkfTable()
00096     {
00097         Core::Table::QuidTable* quids = new Core::Table::QuidTable(0);
00098         for(int i=0 ; i<GetNrKeyframes() ; ++i)
00099         {
00100             if(IsRKF(i))
00101                 quids->Add(GetQuidFrame(i));
00102         }
00103         return quids;
00104     }
00105     
00106     Quid
00107     GetQuidFrame(int keyId)
00108     {
00109         return MakeQuidFrame(mVidSet->GetSetId(), GetVideoId(keyId),
00110                              GetFrameNr(keyId));
00111     }
00112 
00113     int
00114     GetFrameId(Quid quid)
00115     {
00116         if (QuidClass(quid) == QUID_CLASS_FRAME)
00117         {
00118             int vidId = QuidObject(quid);
00119             int frame = QuidId(quid);
00120             return GetFrameIdVideo(vidId, frame);
00121         }
00122         ILOG_ERROR("GetFrameId: Unknown quid : " << QuidObj(quid));
00123         return -1;
00124     }
00125 
00126     int
00127     GetFrameId(String name)
00128     {
00129         int rank = Find(GetColumn4(), name, 0, Size());
00130         if (rank == Size())
00131             return -1;
00132         return rank;
00133     }
00134 
00135     // frameNr's are not unique, so "segment" start and end are required
00136     int
00137     GetFrameId(int frameNr, int idxStart, int idxEnd)
00138     {
00139         int rank = Find(GetColumn3(), frameNr, idxStart, idxEnd);
00140         if (rank == idxEnd)
00141             return -1;
00142         return rank;
00143     }
00144 
00145     void
00146     RemoveDuplicates()
00147     {
00148         int i=0;
00149         while (i < Size()-1)
00150         {
00151             int j = i+1;
00152             while ((Get1(i) == Get1(j)) && (Get2(i) == Get2(j))) // same shot?
00153             {
00154                 if (Get3(i) == Get3(j)) // same frame number?
00155                 {
00156                     if (Get4(i).find("_RKF") != String::npos)
00157                     {
00158                         Core::Table::RemoveRow(this, j);
00159                     }
00160                     else
00161                     {
00162                         Core::Table::RemoveRow(this, i);
00163                         j = i+1;
00164                     }
00165                 }
00166                 else
00167                 {
00168                     j++;
00169                 }
00170             }
00171             i++;
00172         }
00173         UpdateGroups();
00174     }
00175 
00176     VideoSet*
00177     GetVideoSet()
00178     {
00179         return mVidSet;
00180     }
00181 
00182     // video and shot groups
00183 
00184     void
00185     UpdateGroups()
00186     {
00187         if (mVideoGroups == 0)
00188         {
00189             mVideoGroups = new GroupIndex(0);
00190             mVideoGroups->SetColName(1, "firstKeyframeId");
00191             mVideoGroups->SetColName(2, "nrKeyframes");
00192         }
00193         MakeGroupIndex(mVideoGroups, GetColumn1(), 0, Size());
00194         if (mShotGroups == 0)
00195         {
00196             mShotGroups = new GroupIndex(0);
00197             mShotGroups->SetColName(1, "firstKeyframeId");
00198             mShotGroups->SetColName(2, "nrKeyframes");
00199         }
00200         // todo?: statement below fails in case a video has only 1 shot
00201         MakeGroupIndex(mShotGroups, GetColumn2(), 0, Size());
00202     }
00203 
00204     int
00205     GetNrVideos()
00206     {
00207         return mVideoGroups->Size();
00208     }
00209 
00210     int
00211     GetFirstKeyframeVideo(int videoId)
00212     {
00213         return mVideoGroups->Get1(videoId);
00214     }
00215 
00216     int
00217     GetNrKeyframesVideo(int videoId)
00218     {
00219         return mVideoGroups->Get2(videoId);
00220     }
00221 
00222     int
00223     GetFrameIdVideo(int videoId, int frameNr)
00224     {
00225         int start = GetFirstKeyframeVideo(videoId);
00226         int nr = GetNrKeyframesVideo(videoId);
00227         return GetFrameId(frameNr, start, start+nr);
00228     }
00229 
00230     int
00231     GetNrShots()
00232     {
00233         return mShotGroups->Size();
00234     }
00235 
00236     int
00237     GetFirstKeyframeShot(int shotId)
00238     {
00239         return mShotGroups->Get1(shotId);
00240     }
00241 
00242     int
00243     GetNrKeyframesShot(int shotId)
00244     {
00245         return mShotGroups->Get2(shotId);
00246     }
00247 
00248     int
00249     GetShotRKF(int shotId)
00250     {
00251         int start = GetFirstKeyframeShot(shotId);
00252         int end = start + GetNrKeyframesShot(shotId);
00253         for (int i=start ; i<end ; i++)
00254             if (IsRKF(i))
00255                 return i;
00256         return start;
00257     }
00258 
00259     // misc
00260 
00261     int
00262     Diff(Keyframes* arg)
00263     {
00264         if (GetNrKeyframes() != arg->GetNrKeyframes())
00265         {
00266             ILOG_ERROR("Diff: nrKeyframes differs: " << GetNrKeyframes() <<
00267                        " vs " << arg->GetNrKeyframes());
00268             return 1;
00269         }
00270         int nDiff = 0;
00271         for (int i=0 ; i<GetNrKeyframes() ; i++)
00272         {
00273             if (GetVideoId(i) != arg->GetVideoId(i))
00274             {
00275                 ILOG_DEBUG("Id " << i << " differs " << GetVideoId(i) <<
00276                            " vs " << arg->GetVideoId(i));
00277                 nDiff++;
00278             }
00279             else if (GetShotId(i) != arg->GetShotId(i))
00280             {
00281                 ILOG_DEBUG("ShotId " << i << " differs " << GetShotId(i) <<
00282                            " vs " << arg->GetShotId(i));
00283                 nDiff++;
00284             }
00285             else if (GetFrameNr(i) != arg->GetFrameNr(i))
00286             {
00287                 ILOG_DEBUG("FrameNr " << i << " differs " << GetFrameNr(i) <<
00288                            " vs " << arg->GetFrameNr(i));
00289                 nDiff++;
00290             }
00291             else if (GetName(i) != arg->GetName(i))
00292             {
00293                 ILOG_DEBUG("Name " << i << " differs " << GetName(i) <<
00294                            " vs " << arg->GetName(i));
00295                 nDiff++;
00296             }
00297         }
00298         if (nDiff > 0)
00299             ILOG_ERROR("Found " << nDiff << " differences");
00300         return nDiff;
00301     }
00302 
00303     // I/O part
00304 
00305 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00306     void
00307     Load()
00308     {
00309         String fName = mVidSet->GetFilePathVideoIndex("", mName + ".tab",
00310                                                       false, false);
00311         Read(this, fName, mVidSet->GetDatabase());
00312         UpdateGroups();
00313     }
00314 
00315     void
00316     Save(String name, bool binary)
00317     {
00318         if (!name.empty())
00319             mName = name;
00320         String fName = mVidSet->GetFilePathVideoIndex("", mName + ".tab",
00321                                                       true, false);
00322         Write(this, fName, mVidSet->GetDatabase(), binary);
00323     }
00324 
00325     void
00326     Update(String name)
00327     {
00328         if (!name.empty())
00329             mName = name;
00330         String fName = mVidSet->GetFilePathVideoIndex("", mName + ".tab",
00331                                                       true, true);
00332         if (fName.empty())  // try force override thru read
00333             fName = mVidSet->GetFilePathVideoIndex("", mName + ".tab",
00334                                                    false, false);
00335         Write(this, fName, mVidSet->GetDatabase(), true);
00336     }
00337 #endif // REPOSITORY_USED
00338 
00339     void
00340     WriteImageSets(bool writeIsUpdate = false)
00341     {
00342         UpdateGroups();
00343 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00344         ImageSet::ImageSet keySet(mVidSet->GetDatabase(), "keyframes.txt", false);
00345         ImageSet::ImageSet thumbSet(mVidSet->GetDatabase(), "thumbnails.txt", false);
00346 #else // REPOSITORY_USED
00347         ImageSet::ImageSet keySet("keyframes.txt");
00348         ImageSet::ImageSet thumbSet("thumbnails.txt");
00349 #endif // REPOSITORY_USED
00350         for (int s=0 ; s<GetNrShots() ; s++)
00351         {
00352             int start = GetFirstKeyframeShot(s);
00353             int end = start + GetNrKeyframesShot(s);
00354 
00355             //int vid = Get1(start);
00356             int vid = Get1(start) - Get1(0); // assume id's are contiguous
00357             String vidName = mVidSet->GetFile(vid);
00358             String vidSec = mVidSet->GetSectionOfFile(vid);
00359             String vidDir = mVidSet->GetDirOfFile(vid);
00360 
00361             String keySec = "keyframes/";
00362             if (Link::DiskImage::DiskImageUsed())
00363             {
00364                 String videoPath = mVidSet->GetAsPath(vid);
00365                 int posSep = videoPath.find_last_of('/');
00366                 keySec += videoPath.substr(0, posSep);
00367             }
00368             else
00369             {
00370                 keySec += vidSec + "/" + vidDir;
00371             }
00372 
00373             String thumbSec = StringReplace(keySec, "keyframes", "thumbnails");
00374             for (int k=start ; k<end ; k++)
00375             {
00376                 keySet.AddFile(Get4(k), keySec, vidName);
00377                 thumbSet.AddFile(Get4(k), thumbSec, vidName);
00378             }
00379         }
00380         if (writeIsUpdate)
00381         {
00382 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00383             keySet.UpdateImageSet();
00384             thumbSet.UpdateImageSet();
00385 #else // REPOSITORY_USED
00386             ILOG_ERROR("WriteImageSets: Update not implemented yet");
00387 #endif // REPOSITORY_USED
00388         }
00389         else
00390         {
00391 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00392             keySet.SaveImageSet();
00393             thumbSet.SaveImageSet();
00394 #else // REPOSITORY_USED
00395             Persistency::ImageSetLocator keyLoc(mVidSet->GetLocator(),
00396                                                 "keyframes.txt");
00397             Persistency::ImageSetRepository().Add(keyLoc, &keySet);
00398             Persistency::ImageSetLocator thumbLoc(mVidSet->GetLocator(),
00399                                                   "thumbnails.txt");
00400             Persistency::ImageSetRepository().Add(thumbLoc, &thumbSet);
00401 #endif // REPOSITORY_USED
00402         }
00403     }
00404 
00405     void
00406     DumpGroups()
00407     {
00408         mVideoGroups->Dump();
00409         mShotGroups->Dump();
00410     }
00411 
00412 private:
00413 
00414     VideoSet*   mVidSet;
00415     String      mName;
00416     GroupIndex* mVideoGroups;
00417     GroupIndex* mShotGroups;
00418 
00419     ILOG_VAR_DEC;
00420 
00421 };
00422 
00423 ILOG_VAR_INIT(Keyframes, Impala.Core.VideoSet);
00424 
00425 } // namespace VideoSet
00426 } // namespace Core
00427 } // namespace Impala
00428 
00429 #endif

Generated on Fri Mar 19 09:31:30 2010 for ImpalaSrc by  doxygen 1.5.1