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

VideoAccessStrategy.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Stream_Lavc_VideoAccessStrategy_h
00002 #define Impala_Core_Stream_Lavc_VideoAccessStrategy_h
00003 
00004 #include "Core/Table/TableTem.h"
00005 #include "Core/Stream/Lavc/VideoAccessObject.h"
00006 #include "Core/Stream/Lavc/VideoIndex.h"
00007 
00008 #include "Util/IOBufferFile.h"
00009 #include "Core/Table/Write.h"
00010 
00011 namespace Impala
00012 {
00013 namespace Core
00014 {
00015 namespace Stream
00016 {
00017 namespace Lavc
00018 {
00019 
00025 class VideoAccessStrategy
00026 {
00027 
00028 protected:
00029 
00030     // packet idx nr | size | flags | file position after read 
00031     typedef Table::TableTem< Column::ColumnTem<Int32>,
00032                              Column::ColumnTem<Int32>,
00033                              Column::ColumnTem<Int32>,
00034                              Column::ColumnTem<UInt64> > PacketTable;
00035 
00036     typedef Column::FixedStringColumn::ColElemType FixedString;
00037 
00038     // frame idx nr | packet idx nr | is valid | is key frame | hash 
00039     typedef Table::TableTem< Column::ColumnTem<Int32>,
00040                              Column::ColumnTem<Int32>,
00041                              Column::ColumnTem<Int32>,
00042                              Column::ColumnTem<Int32>,
00043                              Column::FixedStringColumn > FrameTable;
00044 
00045 public:
00046 
00047     static const int HASH_SIZE = 32;
00048     static const String INVALID_FRAME_HASH;
00049     static const String UNSTABLE_FRAME_HASH;
00050 
00051 
00052     VideoAccessStrategy(const Lavc::VideoAccessObject* const vao) : mVao(vao)
00053     {
00054         mVideoIsValid = false;
00055         mFailingKeyFrameNr = -1;
00056         mPackets = 0;
00057         mFrames = 0;
00058         mScanDataPresent = false;
00059         mNrOfFrames = -1;
00060         mBadFrameCount = -1;
00061         mLeadingBadFrameCount = -1;
00062     }
00063 
00064     virtual
00065     ~VideoAccessStrategy()
00066     {
00067         CleanUp();
00068         if (mVao != 0)
00069             delete mVao;
00070     }
00071 
00075     bool
00076     Scan()
00077     {
00078         if (!ResetVideoSrc())
00079             return false;
00080 
00081         ILOG_INFO("Scanning video data...");
00082         mPackets = new PacketTable(1);
00083         mFrames = new FrameTable(Column::ColumnTem<Int32>(1),
00084                              Column::ColumnTem<Int32>(1),
00085                              Column::ColumnTem<Int32>(1),
00086                              Column::ColumnTem<Int32>(1),
00087                              Column::FixedStringColumn(HASH_SIZE, 1));
00088         mNrOfFrames = 0;
00089         mBadFrameCount = 0;
00090         mLeadingBadFrameCount = 0;
00091 
00092         bool scanSuccess = ScanProtected();
00093         ResetVideoSrc();
00094         if (!scanSuccess)
00095         {
00096             CleanUp();
00097             return false;
00098         }
00099 
00100         mScanDataPresent = true;
00101         mNrOfFrames = mFrames->Size();
00102         ILOG_INFO("Finished video scan; frame count established: " << 
00103             NrOfFrames());
00104         return true;
00105     }
00106 
00107     // Should not be used, in order to isolate knowledge of the vao class
00108     const VideoAccessObject* const
00109     VideoAccessObj() const
00110     {
00111         return mVao;
00112     }
00113 
00114     virtual bool
00115     ResetVideoSrc() const
00116     {
00117         return mVao->Reset();
00118     }
00119 
00120     bool
00121     VideoIsValid() const
00122     {
00123         return mVideoIsValid;
00124     }
00125 
00126     virtual int
00127     NrOfFrames() const
00128     {
00129         return mNrOfFrames;
00130     }
00131 
00132     int
00133     LeadingBadFrames() const
00134     {
00135         return mLeadingBadFrameCount;
00136     }
00137 
00138     bool
00139     FrameIsValid(int frameNr) const
00140     {
00141         return mFrames->Get3(frameNr) != 0;
00142     }
00143     
00144     char
00145     FrameType() const
00146     {
00147         return mVao->FrameType();
00148     }
00149 
00150     UInt8*
00151     RgbDataPtr() const
00152     {
00153         return mVao->RgbDataPtr();
00154     }
00155 
00159     VideoIndex*
00160     ConstructIndex() 
00161     {
00162         if (!mScanDataPresent)
00163         {
00164             ILOG_ERROR("[ConstructIndex] No scan data");
00165             return 0;
00166         }
00167 
00168         ResetVideoSrc();
00169         VideoIndex* videoIndex = ConstructIndexPrivate();
00170         if (videoIndex == 0)
00171             return 0;
00172 
00173         const double percIndexedFrames = 100.0 *
00174             videoIndex->NrOfEntries() / NrOfFrames();
00175         const double percentageSeekable = 100.0 * 
00176             videoIndex->NrOfSeekableFrames() / videoIndex->NrOfEntries();
00177         const int maxNonTargetFrameReads = videoIndex->MaxNonTargetFrameReads();
00178 
00179         ILOG_INFO("Number of entries in index: " << 
00180             videoIndex->NrOfEntries() << " (" << percIndexedFrames <<
00181             " %)");
00182         ILOG_INFO("Number of seekable entries in index: " << 
00183             videoIndex->NrOfSeekableFrames() << " (" << percentageSeekable <<
00184             " %)");
00185         ILOG_INFO("Max. frame reads required to get to any frame: " << 
00186             maxNonTargetFrameReads + 1);
00187 
00188         return videoIndex;
00189     }
00190 
00191     virtual void
00192     CleanUp()
00193     {
00194         if (mPackets != 0)
00195         {
00196             delete mPackets;
00197             mPackets = 0;
00198         }
00199         if (mFrames != 0)
00200         {
00201             delete mFrames;
00202             mFrames = 0;
00203         }
00204         mScanDataPresent = false;
00205         mFailingKeyFrameNr = -1;
00206     }
00207 
00211     virtual int
00212     DecodeNextFrame(bool* isValidFrame, bool* isKeyFrame, PacketTrace* pktTrace) const
00213     {
00214         //avcodec_get_frame_defaults(mFrame);
00215 
00216         const int MAX_READ_FAILURES = Max(15, 5 * mVao->GopSize());
00217         int nrOfReadFailures = 0;
00218         bool atEndOfFile = mVao->AtEof();
00219 
00220         bool readPacketFailed = false;
00221         *isValidFrame = false;
00222         *isKeyFrame = false;
00223         int rc = 0;
00224         while (true)
00225         {
00226             int readPacketResult = mVao->ReadPacket();
00227             readPacketFailed = (readPacketResult < 0);
00228             if (readPacketFailed)
00229             {
00230                 // upon a negative value, there may still be 
00231                 // valid frames left to decode
00232                 ILOG_DEBUG("ReadPacket() failed and returned: " << 
00233                     readPacketResult);
00234             }
00235             else if (pktTrace)
00236                 pktTrace->Add(mVao->CurrentPacketSize(), mVao->CurrentPacketFlags(), 
00237                     mVao->CurrentFilePosition(), mVao->CurrentPacketIsVideo());
00238 
00239             if (mVao->CurrentPacketIsVideo()) 
00240             {
00241                 int frameDecoded = -1;
00242                 int len = mVao->DecodeFrame(&frameDecoded);
00243 
00244                 // SK: used for problem analysis
00245                 int doDecodeTwice = false;
00246                 if (doDecodeTwice)
00247                 {
00248                     //int frameDecoded2nd = -1;
00249                     //int len2 = DecodeFrame(&frameDecoded2nd);
00250                     //if (frameDecoded && frameDecoded2nd)
00251                     //    ...
00252                     len = mVao->DecodeFrame(&frameDecoded);
00253                 }
00254 
00255                 if (frameDecoded != 0)
00256                 {
00257                     *isValidFrame = true;
00258                     *isKeyFrame = 
00259                         (mVao->FrameType() == 'I' && mVao->FrameIsKey());
00260                     break;
00261                 }
00262                 else
00263                 {
00264                     // do not continue if reading reached eof
00265                     if (atEndOfFile)
00266                     {
00267                         rc = -3;
00268                         break;
00269                     }
00270 
00271                     // mPacket->flags unequal zero seems to indicate incomplete
00272                     // frames other than P or B frames missing I or P frame data
00273                     if (mVao->CurrentPacketFlags() == 0)
00274                         break;
00275                 }
00276             }
00277  
00278             // while the read buffer already reached eof, there may
00279             // still be some valid frames left to decode!
00280             nrOfReadFailures++;
00281             if ((atEndOfFile || readPacketFailed) 
00282                 && (nrOfReadFailures > MAX_READ_FAILURES))
00283             {
00284                 ILOG_WARN("Max. nr of frame read failures reached (" <<
00285                     MAX_READ_FAILURES << "); probably at end of file");
00286                 rc = -1;
00287                 break;
00288             }
00289         } // while (true)
00290 
00291         return rc;
00292     }
00293 
00294     int
00295     CurrentFrameToRgb() const
00296     {
00297         return mVao->CurrentFrameToRgb();
00298     }
00299 
00300     String
00301     FrameHash(int frameNr) const
00302     {
00303         if (mScanDataPresent)
00304             return String(mFrames->Get5(frameNr).GetData(), HASH_SIZE);
00305 
00306         ILOG_ERROR("[FrameHash] No scan data");
00307         return "";
00308     }
00309 
00310     bool
00311     JumpToFramePosition(const UInt64& target) const
00312     {
00313         const bool mustBeKey = true;
00314         const int flushMode = 2; // flush (if applies) after the jump
00315         return Jump(target, GetJumpFlags(), mustBeKey, flushMode);
00316     }
00317 
00318     bool
00319     FrameIsStable(int frameNr) const
00320     {
00321         if (mScanDataPresent)
00322             return FrameHash(frameNr) != UNSTABLE_FRAME_HASH;
00323         else
00324             ILOG_ERROR("[FrameHash] No scan data");
00325         return true;
00326     }
00327 
00328     // Returns whether a frame's data can be read from the stream
00329     virtual bool
00330     FrameCanBeRead(int frameNr) const = 0;
00331 
00332 
00333 protected:
00334 
00335     virtual int
00336     GetJumpFlags() const = 0;
00337 
00338     virtual bool
00339     ScanProtected() = 0;
00340 
00341     // Caller assumes responsibility for the returned object.
00342     virtual VideoIndex*
00343     ConstructIndexProtected() const = 0;
00344 
00353     virtual bool
00354     Jump(const UInt64& target, int flags, bool mustBeKey = false, 
00355         int flush = 0, PacketTrace* trace = 0) const
00356     {
00357         if (flush & 1) // flush before seek
00358             mVao->FlushCodecContext();
00359 
00360         if (!mVao->Seek(target, flags))
00361             return false;
00362 
00363         if (flush & 2) // flush after seek
00364             mVao->FlushCodecContext();
00365 
00366         return DecodeNextValidFrame(mustBeKey, trace);
00367     }
00368 
00369     virtual bool
00370     DecodeNextValidFrame(bool lookForKeyFrame, PacketTrace* pktTrace = 0)  const
00371     {
00372         bool isValidFrame;
00373         bool isKeyFrame;
00374         do
00375         {
00376             if (DecodeNextFrame(&isValidFrame, &isKeyFrame, pktTrace) != 0) 
00377                 // eof or error
00378                 return false; 
00379             if (!isValidFrame)
00380             {
00381                 //ILOG_DEBUG("Skipping invalid frame");
00382                 continue;
00383             }
00384             if (lookForKeyFrame && !isKeyFrame)
00385             {
00386                 //ILOG_DEBUG("Skipping non-keyframe");
00387                 continue;
00388             }
00389             break;
00390         } while (true);
00391 
00392         return true;
00393     }
00394 
00395     // Processes the currently read frame
00396     void
00397     ProcessFrame(bool isValid, bool isKey, int frameNr, bool validating = false)
00398     {
00399         static const FixedString invalidAsFixedStr(
00400             HASH_SIZE, (char*) INVALID_FRAME_HASH.c_str(), true);
00401 
00402         if (validating)
00403         {
00404             if (isValid)
00405             {
00406                 if (!FrameIsValid(frameNr) || 
00407                     (isKey && !FrameIsKey(frameNr)) ||
00408                     (!isKey && FrameIsKey(frameNr)))
00409                 {
00410                     ILOG_ERROR("Unsupported instability type detected for" <<
00411                         " frame " << frameNr << " (" << FrameIsValid(frameNr) <<
00412                         "->" << isValid << ", " << FrameIsKey(frameNr) << 
00413                         "->" << isKey << ")");
00414                 }
00415                 else
00416                 {
00417                     mVao->CurrentFrameToRgb();
00418                     if (!CurrentHashMatchesFrame(frameNr))
00419                         MarkFrameUnstable(frameNr);
00420                 }
00421             }
00422             else if (FrameIsValid(frameNr))
00423                 ILOG_ERROR("Unsupported instability type detected for" <<
00424                     " frame " << frameNr << " (" << FrameIsValid(frameNr) <<
00425                         "->" << isValid << ")");
00426 
00427             ILOG_DEBUG("Re-scanned frame " << frameNr);
00428         }
00429 
00430         else 
00431         {
00432             String hash = INVALID_FRAME_HASH;
00433             if (isValid)
00434             {
00435                 mVao->CurrentFrameToRgb();
00436                 hash = mVao->CurrentHash();
00437                 FixedString hashAsFixedStr(HASH_SIZE, (char*) hash.c_str(), true);
00438                 AddFrameToTable(isValid, isKey, hash, hashAsFixedStr);
00439             }
00440             else
00441                 AddFrameToTable(false, false, INVALID_FRAME_HASH, invalidAsFixedStr);
00442 
00443             ILOG_DEBUG("Scanned frame " << frameNr << " [" << 
00444                 (isValid ? mVao->FrameType() : '?') << "] " << hash);
00445         }
00446     }
00447 
00448     bool
00449     FrameIsKey(int frameNr) const
00450     {
00451         return mFrames->Get4(frameNr) != 0;
00452     }
00453 
00454     bool
00455     CurrentFrameMatchesFrame(int frameNr, const PacketTrace* trace = 0) const
00456     {
00457         if (mPackets != 0 && mPackets->Size() > 0)
00458         {
00459             const int packetNr = mFrames->Get2(frameNr);
00460             const int packetSize = mPackets->Get2(packetNr);
00461             if (mVao->CurrentPacketSize() != packetSize)
00462                 return false;
00463         }
00464 
00465         if (!CurrentHashMatchesFrame(frameNr))
00466             return false;
00467 
00468         if (trace && !PacketTraceMatchesFrame(*trace, frameNr))
00469         {
00470             ILOG_DEBUG("Packet trace does not match for frame " << frameNr);
00471             return false;
00472         }
00473 
00474         return true;
00475     }
00476 
00477     bool
00478     CurrentHashMatchesFrame(int frameNr) const
00479     {
00480         bool matched = false;
00481         const String currentHash = mVao->CurrentHash();
00482         if (currentHash.size() == HASH_SIZE)
00483         {
00484             const char* currentHashStr = currentHash.c_str();
00485             const char* frameHash = 
00486                 mFrames->GetColumn5()->GetVectorData(frameNr);
00487             matched = true;
00488             for (int i = 0; i < HASH_SIZE; i++)
00489                 if (frameHash[i] != currentHashStr[i])
00490                 {
00491                     matched = false;
00492                     break;
00493                 }
00494         }
00495 
00496         if (!matched)
00497             ILOG_DEBUG("Hash does not match for frame " << 
00498                 frameNr << "; found: " << mVao->CurrentHash());
00499         return matched;
00500     }
00501 
00502     virtual bool
00503     NextFrameMatchesFrame(int frameNr, const VideoIndex& videoIndex) const = 0;
00504 
00505     bool
00506     ScanDataPresent()
00507     {
00508         return mScanDataPresent;
00509     }
00510 
00511     virtual void
00512     MarkFrameUnstable(int frameNr)
00513     {
00514         ILOG_INFO("Instability detected for frame: " << frameNr);
00515         static const FixedString unstableAsFixedStr(
00516             HASH_SIZE, (char*) UNSTABLE_FRAME_HASH.c_str(), true);
00517         mFrames->Set5(frameNr, unstableAsFixedStr);
00518     }
00519 
00520     // for dev/debug purposes only
00521     void
00522     WriteScanData(CString fileName)
00523     {
00524         Util::IOBufferFile buf(fileName, false, false);
00525         Table::Write(mPackets, &buf, true);
00526         ILOG_INFO("Wrote " << mPackets->Size() << " packets to file");
00527         Table::Write(mFrames, &buf, true);
00528         ILOG_INFO("Wrote " << mFrames->Size() << " frames to file");
00529     }
00530 
00531     // for dev/debug purposes only
00532     void
00533     ReadScanData(CString fileName)
00534     {
00535         Util::IOBufferFile buf(fileName, true, false);
00536 
00537         if (mPackets)
00538             mPackets->SetEmpty();
00539         else
00540             mPackets = new PacketTable(1);
00541         Table::Read(mPackets, &buf);
00542         ILOG_INFO("Read " << mPackets->Size() << " packets from file");
00543 
00544         if (mFrames)
00545             mFrames->SetEmpty();
00546         else
00547             mFrames = new FrameTable(Column::ColumnTem<Int32>(1),
00548                                      Column::ColumnTem<Int32>(1),
00549                                      Column::ColumnTem<Int32>(1),
00550                                      Column::ColumnTem<Int32>(1),
00551                                      Column::FixedStringColumn(HASH_SIZE, 1));
00552         Table::Read(mFrames, &buf);
00553         ILOG_INFO("Read " << mFrames->Size() << " frames from file");
00554 
00555         bool oldScanDataPresent = mScanDataPresent;
00556         mScanDataPresent = true;
00557         mNrOfFrames = mFrames->Size();
00558         mBadFrameCount = 0;
00559         mLeadingBadFrameCount = 0;
00560         for (int f = 0; f < mNrOfFrames; f++)
00561             if (!FrameIsValid(f))
00562             {
00563                 mBadFrameCount++;
00564                 if (mBadFrameCount > f)
00565                     mLeadingBadFrameCount++;
00566             }
00567         mVideoIsValid = true;
00568         mScanDataPresent = oldScanDataPresent;
00569     }
00570 
00571     void
00572     SetNrOfFrames(int count)
00573     {
00574         mNrOfFrames = count;
00575     }
00576 
00577     const VideoAccessObject* const mVao;
00578 
00579     PacketTable* mPackets;
00580     FrameTable* mFrames;
00581 
00582     int mBadFrameCount;
00583     int mLeadingBadFrameCount;
00584 
00585     bool mScanDataPresent;
00586 
00587     //int mPacketTeller;
00588     //int mFrameTeller;
00589 
00590 
00591 private:
00592 
00593     void
00594     AddFrameToTable(bool isValid, bool isKey, CString hash, 
00595         const FixedString& hashAsFixedStr)
00596     {
00597         int frameIdx = mFrames->Size();
00598         const int lastPacketEntry = mPackets->Size() - 1;
00599         mFrames->Add(frameIdx, lastPacketEntry, isValid, isKey, 
00600             hashAsFixedStr);
00601     }
00602 
00603     // Caller assumes responsibility for the returned object.
00604     VideoIndex*
00605     ConstructIndexPrivate() 
00606     {
00607         VideoIndex* videoIndex = ConstructIndexProtected();
00608         if (videoIndex == 0)
00609             return 0;
00610 
00611         // disable the index' seekable entries that appear to be invalid
00612         while (!IndexValid(*videoIndex))
00613         {
00614             int failingFrameNr = mFailingKeyFrameNr;
00615             ILOG_DEBUG("Disabling invalid video index entry for frame " << 
00616                 failingFrameNr);
00617             if (!videoIndex->SetNotSeekable(failingFrameNr))
00618             {
00619                 ILOG_ERROR("Index entry could not be disabled for frame " << 
00620                     failingFrameNr);
00621                 delete videoIndex;
00622                 return 0;
00623             }
00624         }
00625 
00626         ILOG_DEBUG("Index validated");
00627 
00628         return videoIndex;
00629     }
00630 
00631     bool 
00632     IndexValid(const VideoIndex& idx) const
00633     {
00634         ILOG_DEBUG("Validating index...");
00635         return IndexValidTraversingBackwards(idx) &&
00636             IndexValidTraversingForwards(idx);
00637     }
00638     
00639     bool
00640     IndexValidTraversingBackwards(const VideoIndex& idx) const
00641     {
00642         const int startFrame = 
00643             (mFailingKeyFrameNr < 0) ? NrOfFrames() : mFailingKeyFrameNr;
00644         for (int f = startFrame; f > 0 ; )
00645             if (idx.IsSeekable(--f))
00646             {
00647                 //ResetVideoSrc();
00648                 if (!JumpValidForFrame(f, idx))
00649                 {
00650                     mFailingKeyFrameNr = f;
00651                     return false;
00652                 }
00653             }
00654         return true;
00655     }
00656 
00657     bool
00658     IndexValidTraversingForwards(const VideoIndex& idx) const
00659     {
00660         int startFrame = 0;
00661         for (int f = startFrame; f < mFailingKeyFrameNr; f++)
00662             if (idx.IsSeekable(f))
00663                 startFrame = f;
00664 
00665         ResetVideoSrc();
00666         for (int f = startFrame; f < NrOfFrames(); f++)
00667             if (idx.IsSeekable(f) && !JumpValidForFrame(f, idx))
00668             {
00669                 mFailingKeyFrameNr = f;
00670                 return false;
00671             }
00672         return true;
00673     }
00674 
00679     bool
00680     JumpValidForFrame(int frameNr, const VideoIndex& videoIndex) const
00681     {
00682         int seekableFrame = -1;
00683         UInt64 seekTarget = -1;
00684         videoIndex.GetSeekInfo(frameNr, &seekableFrame, &seekTarget);
00685         static const bool MUST_BE_KEY = true;
00686         const int flushMode = 2; // flush (if applies) after the jump
00687         Jump(seekTarget, GetJumpFlags(), MUST_BE_KEY, flushMode);
00688         mVao->CurrentFrameToRgb();
00689         if (!CurrentFrameMatchesFrame(seekableFrame))
00690         {
00691             ILOG_DEBUG("Index failed for (seekable) frame " << frameNr);
00692             return false;
00693         }
00694         ILOG_DEBUG("Jump validated for (seekable) frame " << frameNr);
00695 
00696         // now read sequentially some frames and validate these as well
00697         bool includedOneSeekable = false;
00698         while (++frameNr < NrOfFrames())
00699         {
00700             if (videoIndex.IsSeekable(frameNr))
00701                 if (includedOneSeekable)
00702                     break;
00703                 else
00704                     includedOneSeekable = true;
00705 
00706             if (!NextFrameMatchesFrame(frameNr, videoIndex))
00707                 return false;
00708         }
00709 
00710         return true;
00711     }
00712 
00727     bool
00728     PacketTraceMatchesFrame(const PacketTrace& trace, int frameNr) const
00729     {
00730         const int nrOfFrames = mFrames->Size();
00731         if (frameNr < 0 || frameNr >= nrOfFrames)
00732             return false;
00733 
00734         //if (!FrameIsKey(frameNr))
00735         //    return false;
00736 
00737         const int traceLen = trace.Size();
00738 
00739         int nrOfVideoPackets = 0;
00740         for (int t = 0; t < traceLen; t++)
00741             if (trace.Get4(t))
00742                 nrOfVideoPackets++;
00743         int nrOfNonVideoPackets = traceLen - nrOfVideoPackets;
00744 
00745         int packetIdx = mFrames->Get2(frameNr);
00746         for (int t = traceLen - 1; t >= 0; t--)
00747         {
00748             if (packetIdx < 0)
00749                 return false;
00750 
00751             const int sizeFromPackets = mPackets->Get2(packetIdx);
00752             const int sizeFromTrace = trace.Get1(t);
00753             const int flagsFromPackets = mPackets->Get3(packetIdx);
00754             const int flagsFromTrace = trace.Get2(t);
00755             bool sizeAndFlagsMatch = 
00756                 (sizeFromPackets == sizeFromTrace &&
00757                 flagsFromPackets == flagsFromTrace);
00758 
00759             if (trace.Get4(t)) // from video stream?
00760             {
00761                 if (--nrOfVideoPackets <= 0)
00762                     sizeAndFlagsMatch = true;
00763             }
00764             else
00765                 if (--nrOfNonVideoPackets <= 0)
00766                     sizeAndFlagsMatch = true;
00767 
00768             if (!sizeAndFlagsMatch)
00769             {
00770                 ILOG_DEBUG("Size and/or flags don't match at trace pos " << t << 
00771                     " of " << traceLen << " : " << sizeFromPackets <<
00772                     " vs. " << sizeFromTrace << " ; " << flagsFromPackets <<
00773                     " vs. " << flagsFromTrace);
00774                 return false;
00775             }
00776 
00777             packetIdx--;
00778 
00779             // SK: trace matching appears not to be trivial; use only last trace entry 
00780             break; 
00781         }
00782 
00783         // test match for post-read file position 
00784         packetIdx = mFrames->Get2(frameNr);
00785         const UInt64 postReadPosOfFrame = mPackets->Get4(packetIdx);
00786         const UInt64 lastPosOfTrace = trace.Get3(traceLen - 1);
00787         if (lastPosOfTrace > postReadPosOfFrame)
00788         {
00789             // locate next key frame
00790             int nextKeyFrame = frameNr + 1;
00791             for ( ; nextKeyFrame < nrOfFrames; nextKeyFrame++)
00792                 if (mFrames->Get4(nextKeyFrame)) // is key frame?
00793                     break; 
00794             if (nextKeyFrame >= nrOfFrames) 
00795                 return true; // assume a match if no more key frames
00796 
00797             // check current (post-read) file position against 
00798             // post-read-position of next key frame
00799             packetIdx = mFrames->Get2(nextKeyFrame);
00800             const UInt64 nextKeyFramesFilePos = mPackets->Get4(packetIdx);
00801             if (lastPosOfTrace > nextKeyFramesFilePos)
00802                 return false;
00803         }
00804 
00805         return true;
00806     }
00807 
00808 
00809     bool mVideoIsValid;
00810     int mNrOfFrames;
00811     mutable int mFailingKeyFrameNr;
00812 
00813     ILOG_VAR_DECL;
00814 
00815 }; //class
00816 
00817 ILOG_VAR_INIT(VideoAccessStrategy, Impala.Core.Stream.Lavc);
00818 
00819 const String VideoAccessStrategy::INVALID_FRAME_HASH =  "INVALID_FRAME___________________";
00820 const String VideoAccessStrategy::UNSTABLE_FRAME_HASH = "UNSTABLE_FRAME__________________";
00821 
00822 }}}} // namespace Impala::Core::Stream::Lavc
00823 
00824 #endif

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