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

void Impala::Core::Stream::RgbDataSrcLavc_old::PopulateMpegIndexBase (  )  [inline, private]

Definition at line 688 of file RgbDataSrcLavc_old.h.

References ILOG_DEBUG, ILOG_ERROR, and Impala::Core::Array::MD5Hash().

00689     {
00690         AVIndexEntry *idx = mVideoStream->index_entries;
00691 
00692         typedef Column::FixedStringColumn::ColElemType FixedString;
00693 
00694         // frame nr | key frame nr | hash
00695         typedef Table::TableTem< Column::ColumnTem<Int32>,
00696                                  Column::ColumnTem<Int32>,
00697                                  Column::FixedStringColumn > FrameTable;
00698 
00699         // frame nr | seek position | recurrence | hash
00700         typedef Table::TableTem< Column::ColumnTem<Int32>,
00701                                  Column::ColumnTem<Real64>,
00702                                  Column::ColumnTem<Int32>,
00703                                  Column::FixedStringColumn > KeyFrameTable;
00704 
00705         // seek position (unique)
00706         typedef Table::TableTem< Column::ColumnTem<Real64> > SeekPositionTable;
00707 
00708         static const int HASH_SIZE = 32;
00709 
00710         FrameTable frameTable(Column::ColumnTem<Int32>(1000),
00711                               Column::ColumnTem<Int32>(1000),
00712                               Column::FixedStringColumn(HASH_SIZE, 1000));
00713 
00714         KeyFrameTable keyFrameTable(Column::ColumnTem<Int32>(1000),
00715                                     Column::ColumnTem<Real64>(1000),
00716                                     Column::ColumnTem<Int32>(1000),
00717                                     Column::FixedStringColumn(HASH_SIZE, 1000));
00718 
00719         SeekPositionTable seekPosTable(Column::ColumnTem<Real64>(1000));
00720 
00721 
00722         // list frames, key frames and candidate seek positions;
00723         // note that values of mCurrentFrameNr and mBufferedFrameNr follow from the search for leading bad frames ("blank frames")
00724 
00725         int64_t startPosOfBuffer = 0;
00726         int64_t lastEndPosOfBuffer = 0;
00727 
00728         String prevHash = "";
00729         int lastKeyFrameNr = -1;
00730         while (mCurrentFrameNr < mLastFrame)
00731         //while (mCurrentFrameNr < 500)
00732         {
00733 #ifdef FFMPEG_52
00734             const int64_t& actualEndPosOfBuffer = mFormatCtx->pb->pos;
00735 #else
00736             const int64_t& actualEndPosOfBuffer = mFormatCtx->pb.pos;
00737 #endif
00738             if (actualEndPosOfBuffer < lastEndPosOfBuffer)
00739             {
00740                 ILOG_ERROR("Unexpected buffer position change (from " <<
00741                     lastEndPosOfBuffer << " to " << actualEndPosOfBuffer << ")");
00742                 return;
00743             }
00744 
00745             const bool bufferAdvanced = (actualEndPosOfBuffer > lastEndPosOfBuffer);
00746             if (bufferAdvanced)
00747             {
00748                 startPosOfBuffer = lastEndPosOfBuffer;
00749                 lastEndPosOfBuffer = actualEndPosOfBuffer;
00750 
00751                 seekPosTable.Add(startPosOfBuffer);
00752             }
00753 
00754             // did reading a frame result in a valid frame?
00755             if  (mCurrentFrameNr > mBufferedFrameNr)
00756             {
00757                 MarkBadFrame(mCurrentFrameNr);
00758                 ILOG_DEBUG("Found a bad frame where mCurrentFrameNr = " << mCurrentFrameNr << " (and mBufferedFrameNr = " << mBufferedFrameNr << ")");
00759             }
00760             else
00761             {
00762                 const String hash = CalcHash();
00763                 const FixedString hashAsFixedStr(HASH_SIZE, (char*) hash.c_str(), false);
00764 
00765                 if (mFrame->pict_type == FF_I_TYPE) // I-frames only
00766                 {
00767                     int recurrence = 1;
00768                     if (hash == prevHash) // (adjacent) duplicate frames/hashes
00769                     {
00770                         recurrence = 1 + keyFrameTable.Get3(keyFrameTable.Size() - 1);
00771                         //keyFrameTable.Set3(keyFrameTable.Size() - 1, recurrence + 1);
00772                     }
00773                     else
00774                     {
00775                         prevHash = hash;
00776                     }
00777                     const Int64 position = 0;
00778                     keyFrameTable.Add(mCurrentFrameNr, position, recurrence, hashAsFixedStr);
00779                     lastKeyFrameNr = mCurrentFrameNr;
00780                 }
00781                 else if (mFrame->pict_type != FF_P_TYPE &&
00782                     mFrame->pict_type != FF_B_TYPE)
00783                 {
00784                     ILOG_ERROR("Unexpected picture type: " << mFrame->pict_type);
00785                     return;
00786                 }
00787 
00788                 frameTable.Add(mCurrentFrameNr, lastKeyFrameNr, hashAsFixedStr);
00789                 ILOG_DEBUG("Added frame to frame table: " << mCurrentFrameNr << " : " << lastKeyFrameNr << " : " << hashAsFixedStr);
00790             }
00791 
00792             NextFrame();
00793         }
00794 
00795 
00796         keyFrameTable.Dump(0, 25);
00797 
00798 
00799         // match candidate jump positions to key frames:
00800 
00801         int keyFrameTableIndexMin = 0;
00802         int64_t topSafeSeekPos = 0;
00803 
00804         for (int seekPosTableIndex = 0; seekPosTableIndex < seekPosTable.Size(); seekPosTableIndex++)
00805         {
00806             const int64_t seekPos = seekPosTable.Get1(seekPosTableIndex);
00807 
00808             // reset (without using the index)
00809             const int posZero = 0;
00810             const int flush = 2;
00811             const int no_sync = 1;
00812             const int sync = 2;
00813             Jump(posZero, mJumpFlags, flush, (seekPos == posZero) ? sync : no_sync);
00814             ILOG_DEBUG("Jumped to head of file for seekPosTableIndex " << seekPosTableIndex);
00815             if (seekPos != posZero)
00816                 Jump(seekPos, mJumpFlags, flush, sync);
00817             ILOG_DEBUG("Jumped to seekPos " << seekPos);
00818 
00819             Array2dVec3UInt8* arr = 
00820                 new Array2dVec3UInt8(FrameWidth(), FrameHeight(), 0, 0,
00821                 mData, true, false);
00822             const String hashOfKeyFrameJumpedTo = Array::MD5Hash(arr);
00823             delete arr;
00824 
00825             int k = keyFrameTableIndexMin;
00826 
00827             for (; k < keyFrameTable.Size(); k++)
00828             {
00829                 const String hash(keyFrameTable.Get4(k).GetData(), HASH_SIZE);
00830                 if (hash == hashOfKeyFrameJumpedTo)
00831                 {
00832                     ILOG_DEBUG("Key frame " << k << " matches hash of first key frame found");
00833                     break;
00834                 }
00835 
00836                 keyFrameTable.Set2(k, topSafeSeekPos);
00837                 keyFrameTableIndexMin++;
00838             }
00839             if (k >= keyFrameTable.Size())
00840             {
00841                 ILOG_DEBUG("At end of key frame table; no matching key frame for seek pos jumped to");
00842                 break; // ready
00843             }
00844 
00845 
00846 
00847             // A: how many remaining, consecutive key frame entries have this hash as well (and so are identical images)? 
00848 
00849             int recurrence = 0;
00850             k = keyFrameTableIndexMin + 1;
00851             for (; k < keyFrameTable.Size(); k++)
00852             {
00853                 const String hash(keyFrameTable.Get4(k).GetData(), HASH_SIZE);
00854                 if (hash != hashOfKeyFrameJumpedTo)
00855                     break;
00856 
00857                 recurrence++;
00858             }
00859 
00860 
00861             // B: how many key frames can be read with this hash?
00862 
00863             mCurrentFrameNr = mBlankFrames; // mCurrentFrame is used by CalcHash_protected to check if current frame is valid
00864             int distanceToDifferentHash = 1; // in number of keyframes
00865             bool foundNextKeyFrame = false;
00866             while (true)
00867             {
00868                 foundNextKeyFrame = FindNextDecodedFrame(true);
00869                 if (!foundNextKeyFrame)
00870                     break;
00871 
00872                 const String hash = CalcHash();
00873                 if (hash != hashOfKeyFrameJumpedTo) // what if at eof?
00874                     break;
00875 
00876                 //for (int f = keyFrameTableIndexMin; f < keyFrameTable.Size(); f++)
00877                 //    if (keyFrameTable.Get1(f) == // shit; wat 
00878 
00879                 distanceToDifferentHash++;
00880             }
00881 
00882 
00883 
00884             // now resolve using A and B!
00885 
00886             int keyFramesWithOldSafePos = 0;
00887             if (distanceToDifferentHash <= recurrence)
00888             {
00889                 keyFramesWithOldSafePos = (1 + recurrence) - distanceToDifferentHash;
00890                 for (int kk = 0; kk < keyFramesWithOldSafePos; kk++)
00891                 {
00892                     keyFrameTable.Set2(keyFrameTableIndexMin, topSafeSeekPos);
00893                     keyFrameTableIndexMin++;
00894                 }
00895             }
00896 
00897             keyFrameTable.Set2(keyFrameTableIndexMin, seekPos);
00898             topSafeSeekPos = seekPos;
00899 
00900 
00901             if (!foundNextKeyFrame)
00902             {
00903                 break; // assumed this only occurs at eof
00904             }
00905         }
00906 
00907         // frameTable aanpassen zodat alleen gewezen wordt naar key frames met een seek position
00908         int64_t lastProperSeekPos = -1;
00909         int frameIndex = 0;
00910         int keyFrameIndex = 0;
00911         int nextProperKeyFrameIndex = 0;
00912         while (keyFrameIndex < keyFrameTable.Size())
00913         {
00914             int seekFrameNr = keyFrameTable.Get1(keyFrameIndex);
00915             lastProperSeekPos = keyFrameTable.Get2(keyFrameIndex);
00916             nextProperKeyFrameIndex = keyFrameIndex;
00917             while (nextProperKeyFrameIndex < keyFrameTable.Size() && keyFrameTable.Get2(nextProperKeyFrameIndex) == lastProperSeekPos)
00918                 nextProperKeyFrameIndex++;
00919 
00920             int nextProperSeekFrame = 1000000;
00921             if (nextProperKeyFrameIndex < keyFrameTable.Size())
00922             {
00923                 nextProperSeekFrame = keyFrameTable.Get1(nextProperKeyFrameIndex);
00924             }
00925 
00926             while (frameIndex < frameTable.Size() && frameTable.Get2(frameIndex) < nextProperSeekFrame)
00927             {
00928                 frameTable.Set2(frameIndex, seekFrameNr);
00929                 frameIndex++;
00930             }
00931 
00932             keyFrameIndex = nextProperKeyFrameIndex;
00933         }
00934 
00935 
00936         // Add results to the index
00937         keyFrameIndex = 0;
00938         for (int i = 0; i < frameTable.Size(); i++)
00939         {
00940             const int frameNr = frameTable.Get1(i);
00941             const int keyFrameNr = frameTable.Get2(i);
00942             const String hash(frameTable.Get3(i).GetData(), HASH_SIZE);
00943             while (keyFrameTable.Get1(keyFrameIndex) < keyFrameNr)
00944                 keyFrameIndex++;
00945             const int64_t seekPos = keyFrameTable.Get2(keyFrameIndex);
00946             ILOG_DEBUG("AddIndex(" << frameNr << ", " << keyFrameNr << ", " << seekPos << ", " << hash << ")");
00947             AddIndex(frameNr, keyFrameNr, seekPos, hash);
00948         }
00949     }

Here is the call graph for this function:


Generated on Thu Jan 13 09:20:34 2011 for ImpalaSrc by  doxygen 1.5.1