00001 #ifndef Impala_Core_VideoSet_VideoIndexValidator_h
00002 #define Impala_Core_VideoSet_VideoIndexValidator_h
00003
00004 #include "Basis/ILog.h"
00005 #include "Basis/StringList.h"
00006 #include "Util/Database.h"
00007 #ifdef AVC_USED
00008 #include "Core/Stream/RgbDataSrcLavc.h"
00009 #include "Core/Stream/RgbDataSrcLavc_old.h"
00010 #endif
00011
00012 namespace Impala
00013 {
00014 namespace Core
00015 {
00016 namespace VideoSet
00017 {
00018
00019
00020
00021 class VideoIndexValidator : public Listener
00022 {
00023
00024 public:
00025
00026 VideoIndexValidator(Reporter* reporter, CmdOptions& options)
00027 {
00028 mSrcType = options.GetString("src");
00029 mEnabled = false;
00030 };
00031
00032 ~VideoIndexValidator()
00033 {
00034 }
00035
00036 void
00037 HandleNewWalk(VideoSet* vs)
00038 {
00039 if (mSrcType != "lavcadhocidx")
00040 {
00041 ILOG_ERROR("Invalid source type: " << mSrcType);
00042 return;
00043 }
00044 mEnabled = true;
00045 }
00046
00047 void
00048 HandleNewFile(VideoSet* vs, int fileId, Stream::RgbDataSrc* src = 0)
00049 {
00050 if (!mEnabled)
00051 return;
00052
00053 ILOG_INFO("Starting index validation for file nr. " << fileId);
00054
00055 bool usingExistingSrc = (src != 0);
00056 if (!usingExistingSrc)
00057 {
00058 src = vs->GetVideo(fileId);
00059 if (src == 0)
00060 {
00061 ILOG_ERROR("Failed to instantiate RGB new data" <<
00062 " source implementation for video nr. " << fileId);
00063 return;
00064 }
00065 }
00066
00067 const String srcName = src->GetName();
00068
00069 ILOG_INFO("Video and index instantiated using " <<
00070 "new implementation for file nr. " << fileId);
00071
00072 Stream::RgbDataSrcInfo* srcNewImpl = (Stream::RgbDataSrcInfo*) src;
00073 const int leadingBadFramesNew = src->LeadingBadFrames();
00074
00075
00076 int hashBufferSize = (srcNewImpl->LastFrame() + 1) * (32 + 1) * 1.10;
00077 char* hashBufferNew = new char[hashBufferSize];
00078 const int bytesWrittenNew =
00079 srcNewImpl->DumpIndexHashes(hashBufferNew, hashBufferSize);
00080 if (!usingExistingSrc)
00081 delete src;
00082 src = 0;
00083
00084 if (bytesWrittenNew >= hashBufferSize)
00085 {
00086 ILOG_ERROR("Hash (new) buffer overflow for video nr. " << fileId);
00087 delete [] hashBufferNew;
00088 return;
00089 }
00090 hashBufferNew[bytesWrittenNew] = '\0';
00091
00092
00093 #ifdef AVC_USED
00094
00095 Util::Database* db = vs->GetDatabase();
00096 Stream::RgbDataSrcInfo* srcOldImpl =
00097 new Stream::RgbDataSrcLavc_old(
00098 Stream::RgbDataSrcFactory::SRC_LAVC_ADHOCIDX, srcName, db, ADHOCIDX);
00099 if (!srcOldImpl)
00100 {
00101 ILOG_ERROR("Failed to instantiate RGB old data" <<
00102 " source implementation for video nr. " << fileId);
00103 delete [] hashBufferNew;
00104 return;
00105 }
00106
00107 ILOG_INFO("Video and index instantiated using " <<
00108 "old implementation for file nr. " << fileId);
00109
00110
00111 const int leadingBadFramesOld = srcOldImpl->LeadingBadFrames();
00112
00113 hashBufferSize = (srcOldImpl->LastFrame() + 1) * (32 + 1) * 1.10;
00114 char* hashBufferOld = new char[hashBufferSize];
00115 const int bytesWrittenOld =
00116 srcOldImpl->DumpIndexHashes(hashBufferOld, hashBufferSize);
00117 delete srcOldImpl;
00118 srcOldImpl = 0;
00119
00120 if (bytesWrittenOld < 0)
00121 {
00122 ILOG_ERROR("Hash (old) buffer overflow for video nr. " << fileId);
00123 delete [] hashBufferNew;
00124 delete [] hashBufferOld;
00125 return;
00126 }
00127 hashBufferOld[bytesWrittenOld] = '\0';
00128
00129 ILOG_INFO("Comparing results for old and new implementation");
00130
00131
00132 if (bytesWrittenNew != bytesWrittenOld)
00133 {
00134 ILOG_WARN("Hash buffer length mismatch for video nr. " <<
00135 fileId << "; existing=" <<
00136 bytesWrittenOld << ", new=" <<
00137 bytesWrittenNew);
00138 }
00139
00140
00141
00142 if (leadingBadFramesOld == leadingBadFramesNew)
00143 {
00144 ILOG_INFO("Identical number of reported leading bad frames" <<
00145 " (\"blank frames\") : " << leadingBadFramesOld);
00146 }
00147 else
00148 ILOG_ERROR("Different number of reported leading bad frames" <<
00149 " (\"blank frames\"); old : " << leadingBadFramesOld <<
00150 ", new : " << leadingBadFramesNew);
00151
00152
00153
00154
00155 StringList oldHashList(hashBufferOld, '\t', true);
00156 StringList newHashList(hashBufferNew, '\t', true);
00157 StringListI oldHashIter = oldHashList.begin();
00158 StringListI newHashIter = newHashList.begin();
00159 int oldHashCount = 0;
00160 int newHashCount = 0;
00161 static const int TEN = 10;
00162 int hashID = 0;
00163 int compared = 0;
00164 int nrOfMismatches = 0;
00165 bool triedFastForward = false;
00166 while (true)
00167 {
00168 if (oldHashIter != oldHashList.end())
00169 {
00170 if (newHashIter != newHashList.end())
00171 {
00172 if (*oldHashIter == *newHashIter)
00173 {
00174 ILOG_DEBUG(hashID << ": [" << *oldHashIter <<
00175 "] -> [" << *newHashIter << "]");
00176 }
00177 else
00178 {
00179 ILOG_ERROR(hashID << ": [" << *oldHashIter <<
00180 "] -> [" << *newHashIter << "] : Hash mismatch!");
00181 nrOfMismatches++;
00182 }
00183 if (*newHashIter != Stream::RgbDataSrcInfo::MISSING_FRAME_HASH)
00184 newHashCount++;
00185 newHashIter++;
00186 }
00187 else
00188 {
00189 ILOG_ERROR(hashID << ": [" << *oldHashIter << "] -> " <<
00190 " (no hash value) : Hash mismatch!");
00191 nrOfMismatches++;
00192 }
00193 if (*oldHashIter != Stream::RgbDataSrcInfo::MISSING_FRAME_HASH)
00194 oldHashCount++;
00195 oldHashIter++;
00196 }
00197 else if (newHashIter != newHashList.end())
00198 {
00199 ILOG_ERROR(hashID << ": (no hash value) -> [" <<
00200 *newHashIter << "] : Hash mismatch!");
00201 nrOfMismatches++;
00202 if (*newHashIter != Stream::RgbDataSrcInfo::MISSING_FRAME_HASH)
00203 newHashCount++;
00204 newHashIter++;
00205 }
00206 else
00207 break;
00208
00209 compared++;
00210 hashID++;
00211
00212 if (nrOfMismatches >= TEN && !triedFastForward)
00213 {
00214
00215 const int ffCount =
00216 Min(oldHashList.size(), newHashList.size()) - compared - TEN;
00217 if (ffCount > 0)
00218 {
00219 for (int i = 0; i < ffCount; i++)
00220 {
00221 oldHashIter++;
00222 newHashIter++;
00223 hashID++;
00224 newHashCount++;
00225 oldHashCount++;
00226 }
00227 ILOG_INFO("At " << TEN << " hash mismatches, skipping validation for " << ffCount << " frames");
00228 }
00229 triedFastForward = true;
00230 }
00231 }
00232 ILOG_INFO("Number of hash values compared: " << compared);
00233 if (nrOfMismatches > 0)
00234 ILOG_INFO("Number of mismatches: " << nrOfMismatches);
00235
00236
00237 if (oldHashCount > newHashCount)
00238 {
00239 ILOG_INFO("Less new hash values (" << newHashCount <<
00240 ") than old hash values (" << oldHashCount << ")");
00241 }
00242 else if (oldHashCount < newHashCount)
00243 {
00244 ILOG_INFO("More new hash values (" << newHashCount <<
00245 ") than old hash values (" << oldHashCount << ")");
00246 }
00247
00248 delete [] hashBufferNew;
00249 delete [] hashBufferOld;
00250 #else
00251 ILOG_ERROR("No AVC support included");
00252 #endif
00253 ILOG_INFO("Index validation for file nr. " << fileId << " completed");
00254 }
00255
00256 private:
00257
00258 ILOG_VAR_DECL;
00259
00260 String mSrcType;
00261 bool mEnabled;
00262
00263 };
00264
00265 ILOG_VAR_INIT(VideoIndexValidator, Impala.Core.VideoSet);
00266
00267 }}}
00268
00269 #endif