00001 #ifndef Impala_Core_VideoSet_SelectFrames_h
00002 #define Impala_Core_VideoSet_SelectFrames_h
00003
00004 #include "Persistency/KeyframesRepository.h"
00005 #include "Persistency/SegmentationRepository.h"
00006 #include "Persistency/QuidTableRepository.h"
00007 #include "Core/VideoSet/Reporter.h"
00008 #include "Core/VideoSet/Keyframes.h"
00009 #include "Core/VideoSet/Segmentation.h"
00010 #include "Core/Table/QuidTable.h"
00011 #include "Core/Table/Write.h"
00012
00013 namespace Impala
00014 {
00015 namespace Core
00016 {
00017 namespace VideoSet
00018 {
00019
00020
00021 class SelectFrames : public Listener
00022 {
00023 public:
00024
00025 SelectFrames(Reporter* reporter, CmdOptions& options)
00026 {
00027 mReporter = reporter;
00028 if (options.GetNrArg() < 4)
00029 {
00030 ILOG_ERROR("Missing argument");
00031 return;
00032 }
00033 mQuidName = options.GetArg(2);
00034 mNrExtra = atol(options.GetArg(3));
00035 mQuids = new Table::QuidTable(100);
00036 }
00037
00038 virtual void
00039 HandleNewWalk(VideoSet* vs)
00040 {
00041 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00042 mKeyframes = new Keyframes(vs, "keyframes");
00043 mSegmentation = new Segmentation(vs, "segmentation");
00044 #else // REPOSITORY_USED
00045 Persistency::KeyframesLocator kLoc(vs->GetLocator(), "keyframes");
00046 mKeyframes = Persistency::KeyframesRepository().Get(kLoc, vs);
00047 Persistency::SegmentationLocator sLoc(vs->GetLocator(), "segmentation");
00048 mSegmentation = Persistency::SegmentationRepository().Get(sLoc, vs);
00049 #endif // REPOSITORY_USED
00050
00051 }
00052
00053 virtual void
00054 HandleNewShot(VideoSet* vs, int fileId, Stream::RgbDataSrc* src, int shotId)
00055 {
00056 mFrameNrs.clear();
00057 if(shotId == -1)
00058 {
00059 ILOG_WARN("shotId=-1 encountered in HandleNewShot... iFrame outside shot segmentation?");
00060 }
00061 }
00062
00063 virtual void
00064 HandleNewFrame(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00065 {
00066 if (src->CurIsIFrame())
00067 mFrameNrs.push_back(src->FrameNr());
00068 }
00069
00070 virtual void
00071 HandleDoneShot(VideoSet* vs, int fileId, Stream::RgbDataSrc* src, int shotId)
00072 {
00073 int firstKey = mKeyframes->GetFirstKeyframeShot(shotId);
00074 int nrKey = mKeyframes->GetNrKeyframesShot(shotId);
00075 ILOG_DEBUG("firstkey=" << firstKey << " nrKey=" << nrKey <<
00076 " shotId="<< shotId);
00077 std::vector<int> keyframes;
00078 for (int i=0 ; i<nrKey ; i++)
00079 {
00080 int frameNr = mKeyframes->GetFrameNr(firstKey + i);
00081 keyframes.push_back(frameNr);
00082 }
00083
00084 AddBeginMiddleEnd(keyframes);
00085 std::sort(keyframes.begin(), keyframes.end());
00086 for (int i=0 ; i<keyframes.size() ; i++)
00087 {
00088 Quid q = vs->GetQuidFrame(fileId, keyframes[i]);
00089 mQuids->Add(q);
00090 }
00091 }
00092
00093 virtual void
00094 HandleDoneWalk(VideoSet* vs)
00095 {
00096 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00097 String fName = vs->GetFilePathVideoIndex("", mQuidName, true, false);
00098 if (!fName.empty())
00099 Core::Table::Write(mQuids, fName, vs->GetDatabase(), true);
00100 #else // REPOSITORY_USED
00101 Persistency::QuidTableLocator loc(vs->GetLocator(), "VideoIndex",
00102 mQuidName);
00103 Persistency::QuidTableRepository().Add(loc, mQuids);
00104 #endif // REPOSITORY_USED
00105 delete mQuids;
00106 }
00107
00108 private:
00109
00110 void
00111 AddBegin(std::vector<int>& keyframes)
00112 {
00113 int nrAdded = 0;
00114 int i = 0;
00115 while ((nrAdded < mNrExtra) && (i < mFrameNrs.size()))
00116 {
00117 if (std::find(keyframes.begin(), keyframes.end(), mFrameNrs[i]) ==
00118 keyframes.end())
00119 {
00120 keyframes.push_back(mFrameNrs[i]);
00121 nrAdded++;
00122 }
00123 i++;
00124 }
00125 }
00126
00127 void
00128 AddBeginMiddleEnd(std::vector<int>& keyframes)
00129 {
00130 int totalNr = mFrameNrs.size();
00131 int part = totalNr / 3;
00132 if (totalNr % 3 != 0)
00133 part++;
00134 std::vector<int> idxVec;
00135 for (int p=0 ; p<part ; p++)
00136 {
00137 for (int i=0 ; i<3 ; i++)
00138 {
00139 int idx = i*part + p;
00140 if (idx < totalNr)
00141 idxVec.push_back(idx);
00142 }
00143 }
00144
00145 int nrAdded = 0;
00146 int i = 0;
00147 while ((nrAdded < mNrExtra) && (i < idxVec.size()))
00148 {
00149 int frame = mFrameNrs[idxVec[i]];
00150 if (std::find(keyframes.begin(), keyframes.end(), frame) ==
00151 keyframes.end())
00152 {
00153 keyframes.push_back(frame);
00154 nrAdded++;
00155 }
00156 i++;
00157 }
00158 }
00159
00160 Reporter* mReporter;
00161 Keyframes* mKeyframes;
00162 Segmentation* mSegmentation;
00163 String mQuidName;
00164 int mNrExtra;
00165 std::vector<int> mFrameNrs;
00166 Core::Table::QuidTable* mQuids;
00167
00168 ILOG_VAR_DEC;
00169
00170 };
00171
00172 ILOG_VAR_INIT(SelectFrames, Impala.Core.VideoSet);
00173
00174 }
00175 }
00176 }
00177
00178 #endif