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_protected(); 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_protected(); 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:
|