index.h

Go to the documentation of this file.
00001 
00008 /*
00009  *  Copyright (c) 2003, Matt Beard
00010  *
00011  *  This software is provided 'as-is', without any express or implied warranty.
00012  *  In no event will the authors be held liable for any damages arising from
00013  *  the use of this software.
00014  *
00015  *  Permission is granted to anyone to use this software for any purpose,
00016  *  including commercial applications, and to alter it and redistribute it
00017  *  freely, subject to the following restrictions:
00018  *
00019  *    1. The origin of this software must not be misrepresented; you must
00020  *       not claim that you wrote the original software. If you use this
00021  *       software in a product, an acknowledgment in the product
00022  *       documentation would be appreciated but is not required.
00023  *  
00024  *    2. Altered source versions must be plainly marked as such, and must
00025  *       not be misrepresented as being the original software.
00026  *  
00027  *    3. This notice may not be removed or altered from any source
00028  *       distribution.
00029  */
00030 #ifndef MXFLIB__INDEX_H
00031 #define MXFLIB__INDEX_H
00032 
00033 
00034 namespace mxflib
00035 {
00037     class IndexPos : public RefCount<IndexPos>
00038     {
00039     public:
00040         UInt64 ThisPos;         
00041 
00047         Position Location;      
00048         Rational PosOffset;     
00049         bool Exact;             
00050 
00051         bool OtherPos;          
00052 
00055         bool Offset;            
00056         Int8 KeyFrameOffset;    
00057         Int64 KeyLocation;      
00058         UInt8 Flags;            
00059     };
00060 
00062     typedef SmartPtr<IndexPos> IndexPosPtr;
00063 
00065 
00066     struct DeltaEntry
00067     {
00068         Int8    PosTableIndex;
00069         UInt8   Slice;
00070         UInt8   ElementDelta[4];        
00071     };
00072 
00074     typedef std::map<Position, IndexSegmentPtr> IndexSegmentMap;
00075 
00077     class IndexEntry : public RefCount<IndexEntry>
00078     {
00079     public:
00080         int TemporalOffset;
00081         int AnchorOffset;
00082         UInt8 Flags;
00083         UInt64 StreamOffset;
00084     };
00085 
00087     typedef SmartPtr<IndexEntry> IndexEntryPtr;
00088 
00090 //typedef std::map<Int64, IndexEntryPtr> IndexEntryMap;
00091 //typedef SmartPtr<IndexEntryMap> IndexEntryMapPtr;
00092 
00094 
00099     class ReorderIndex : public RefCount<ReorderIndex>
00100     {
00101     protected:
00102         DataChunk IndexEntries;             
00103         int CompleteEntryCount;             
00104         int EntryCount;                     
00105 
00110         Position FirstPosition;             
00111         UInt32 IndexEntrySize;              
00112 
00113     public:
00115         ReorderIndex(int UseIndexEntrySize)
00116         {
00117             // Set a high granularity to reduce overhead of frequent reallocation
00118             IndexEntries.SetGranularity(1024 * 16);
00119 
00120             CompleteEntryCount = 0;
00121             EntryCount = 0;
00122 
00123             ASSERT(UseIndexEntrySize);
00124             IndexEntrySize = UseIndexEntrySize;
00125         }
00126 
00128         bool SetEntry(Position Pos, UInt8 Flags, Int8 AnchorOffset, UInt8 *Tables = NULL);
00129 
00131         bool SetStreamOffset(Position Pos, Position StreamOffset);
00132 
00134         bool SetTemporalOffset(Position Pos, Int8 TemporalOffset);
00135 
00137         Int32 GetEntryCount(void) { return CompleteEntryCount; };
00138 
00140         Int32 CommitEntries(IndexTablePtr Index, Int32 Count = -1);
00141     };
00142 
00143     typedef SmartPtr<ReorderIndex> ReorderIndexPtr;
00144     typedef std::map<UInt32, ReorderIndexPtr> ReorderMap;
00145 
00146 
00148     class IndexTable : public RefCount<IndexTable>
00149     {
00150     public:
00151         UInt32 IndexSID;
00152         UInt32 BodySID;
00153         Rational EditRate;
00154 
00156         UInt32 EditUnitByteCount;
00157 
00159         int BaseDeltaCount;
00160 
00162         DeltaEntry *BaseDeltaArray;
00163 
00165         IndexSegmentMap SegmentMap;
00166 
00167         int NSL;            
00168         int NPE;            
00169         int IndexEntrySize; 
00170 
00171 //      //! Map of index entries that may be out of order
00172 //      /*! The entries will be built into segments by function xxx() */
00173 //      IndexEntryMap IndexOrderEntryMap;
00174 //      IndexEntryMap EssenceOrderEntryMap;
00175 
00176         ReorderIndexPtr     Reorder;            
00177 
00178     public:
00180 
00182         static const Position IndexLowest;
00183 
00184     public:
00186         IndexTable() : IndexSID(0), BodySID(0), EditUnitByteCount(0) , BaseDeltaCount(0) 
00187         { 
00188             EditRate.Numerator=0; 
00189             EditUnitByteCount=0; 
00190             NSL=0; 
00191             NPE=0; 
00192             IndexEntrySize=11; 
00193         };
00194 
00196         ~IndexTable() 
00197         { 
00198             if(BaseDeltaCount) delete[] BaseDeltaArray; 
00199         };
00200 
00202         void DefineDeltaArray(int DeltaCount, DeltaEntry *DeltaArray)
00203         {
00204             if(BaseDeltaCount) delete[] BaseDeltaArray;
00205 
00206             BaseDeltaCount = DeltaCount;
00207             if(!DeltaCount) return;
00208             
00209             // Build the new array
00210             BaseDeltaArray = new DeltaEntry[DeltaCount];
00211             memcpy(BaseDeltaArray, DeltaArray, DeltaCount * sizeof(DeltaEntry));
00212 
00213             // Slice numbers start at zero, PosTable numbers start at 1
00214             NSL = 0;
00215             NPE = 0;
00216             int i;
00217             for(i=0; i<DeltaCount; i++)
00218             {
00219                 if(BaseDeltaArray[i].PosTableIndex > NPE) NPE = BaseDeltaArray[i].PosTableIndex;
00220                 if(BaseDeltaArray[i].Slice > NSL) NSL = BaseDeltaArray[i].Slice;
00221             }
00222         
00223             // Calculate the size of each IndexEntry
00224             IndexEntrySize = (11 + 4*NSL + 8*NPE);
00225         }
00226 
00228 
00232         void DefineDeltaArray(int DeltaCount, UInt32 *ElementSizes)
00233         {
00234             if(BaseDeltaCount) delete[] BaseDeltaArray;
00235 
00236             BaseDeltaCount = DeltaCount;
00237             if(!DeltaCount) return;
00238 
00239             // Build the new array
00240             BaseDeltaArray = new DeltaEntry[DeltaCount];
00241 
00242             // Slice numbers start at zero, PosTable numbers start at 1
00243             NSL = 0;
00244             NPE = 0;
00245             UInt32 Delta = 0;           
00246             int i;
00247             for(i=0; i<DeltaCount; i++)
00248             {
00249                 // Start of a new slice?
00250                 PutU32(Delta, BaseDeltaArray[i].ElementDelta);
00251                 Delta += ElementSizes[i];
00252                 BaseDeltaArray[i].PosTableIndex = 0;
00253                 BaseDeltaArray[i].Slice = NSL;
00254 
00255                 // End of a slice?
00256                 if((i != (DeltaCount-1)) && (ElementSizes[i] == 0))
00257                 {
00258                     Delta = 0;
00259                     NSL++;
00260                 }
00261             }
00262 
00263             // Calculate the size of each IndexEntry
00264             IndexEntrySize = (11 + 4*NSL + 8*NPE);
00265         }
00266 
00268         IndexSegmentPtr AddSegment(MDObjectPtr Segment);
00269 
00271         IndexSegmentPtr AddSegment(Int64 StartPosition);
00272 
00274         IndexSegmentPtr GetSegment(Position EditUnit);
00275 
00277         bool AddIndexEntry(Position EditUnit, Int8 TemporalOffset, Int8 KeyFrameOffset, UInt8 Flags, UInt64 StreamOffset, 
00278                            int SliceCount = 0, UInt32 *SliceOffsets = NULL, 
00279                            int PosCount = 0, Rational *PosTable = NULL);
00280 
00281 //#####
00282 //##### DRAGONS: Should Lookup also check the pending items?
00283 //#####
00285         IndexPosPtr Lookup(Position EditUnit, int SubItem = 0, bool Reorder = true);
00286 
00288         void Update(Position EditUnit, UInt64 StreamOffset);
00289 
00291         void Correct(Position EditUnit, Int8 TemporalOffset, Int8 KeyFrameOffset, UInt8 Flags);
00292 
00294         void Purge(UInt64 FirstPosition, UInt64 LastPosition);
00295 
00297         size_t WriteIndex(DataChunk &Buffer);
00298 
00300         ReorderIndexPtr GetReorder(void)
00301         {
00302             return Reorder;
00303         }
00304 
00306         ReorderIndexPtr EnableReorder(void)
00307         {
00308             if(!Reorder) Reorder = new ReorderIndex(IndexEntrySize);
00309 
00310             return Reorder;
00311         }
00312     };
00313 }
00314 
00315 
00316 namespace mxflib
00317 {
00318     class IndexSegment : public RefCount<IndexSegment>
00319     {
00320     private:
00321         static PrimerPtr IndexPrimer;
00322 
00323     public:
00325         IndexTableParent Parent;
00326     
00328         Int64 StartPosition;
00329 
00331         int DeltaCount;
00332 
00334         DeltaEntry *DeltaArray;
00335 
00337         int EntryCount;
00338 
00340 
00341         DataChunk IndexEntryArray;
00342 
00343     private:
00345         IndexSegment() : EntryCount(0) { };
00346 
00347     public:
00349         ~IndexSegment() { if(DeltaCount) delete[] DeltaArray; };
00350 
00352 
00353         static IndexSegmentPtr AddIndexSegmentToIndexTable(IndexTablePtr ParentTable, Int64 IndexStartPosition);
00354 
00356         bool AddIndexEntry(Int8 TemporalOffset, Int8 KeyFrameOffset, UInt8 Flags, UInt64 StreamOffset, 
00357                            int SliceCount = 0, UInt32 *SliceOffsets = NULL, 
00358                            int PosCount = 0, Rational *PosTable = NULL);
00359 
00361         bool AddIndexEntries(int Count, int Size, UInt8 *Entries);
00362 
00364         void Update(Position EditUnit, UInt64 StreamOffset);
00365     };
00366 }
00367 
00368 
00369 namespace mxflib
00370 {
00371     class IndexManager : public RefCount<IndexManager>
00372     {
00373     protected:
00374         bool UsesReordering;                
00375         bool FormatFixed;                   
00376 
00377         bool DataIsCBR;                     
00378         int StreamCount;                    
00379         int StreamListSize;                 
00380         int *PosTableList;                  
00381         UInt32 *ElementSizeList;            
00382 
00383         struct IndexData
00384         {
00385             int         Status;             
00386 
00387             int         Flags;              
00388             int         KeyOffset;          
00389             int         TemporalOffset;     
00390             int         TemporalDiff;       
00391 
00396             UInt64      StreamOffset[1];    
00397 
00398         };
00399 
00400         int ManagedDataEntrySize;           
00401 
00402         std::map<Position, IndexData*> ManagedData;
00404 
00405         /* DRAGONS: Provisional entries are not currently implemented */
00406         IndexData *ProvisionalEntry;        
00407         Position ProvisionalEditUnit;       
00408 
00409         std::map<Position, int> UnsatisfiedTemporalOffsets;
00411 
00412         std::map<Position, int> UnsatisfiedTemporalDiffs;
00414 
00415         UInt32 BodySID;                     
00416         UInt32 IndexSID;                    
00417         Rational EditRate;                  
00418 
00419         std::map<int, Position> EntryLog;   
00420         int NextLogID;                      
00421         bool LogWrapped;                    
00422         int LogNextEntry;                   
00423 
00424         bool AcceptNextEntry;               
00425 
00426         Position LastNewEditUnit;           
00427 
00428         bool ValueRelativeIndexing;         
00429 
00431         Position SubRangeOffset;            
00432 
00433     public:
00435         IndexManager(int PosTableIndex, UInt32 ElementSize);
00436 
00438         ~IndexManager()
00439         {
00440             delete[] PosTableList;
00441             delete[] ElementSizeList;
00442             
00443             std::map<Position, IndexData*>::iterator it = ManagedData.begin();
00444             while ( ! ManagedData.empty() )
00445             {
00446                 delete[] (UInt8*)(*it).second;
00447                 ManagedData.erase(it);
00448                 it = ManagedData.begin();
00449             }
00450             
00451             if(ProvisionalEntry) delete[] ProvisionalEntry;
00452         }
00453 
00455         void SetBodySID(UInt32 SID) { BodySID = SID; };
00456 
00458         void SetIndexSID(UInt32 SID) { IndexSID = SID; };
00459 
00461         void SetEditRate(Rational Rate) { EditRate = Rate; };
00462 
00464         void SetEditRate(Int32 Rate_n, Int32 Rate_d) { EditRate.Numerator = Rate_n;  EditRate.Denominator = Rate_d;};
00465 
00467         UInt32 GetBodySID(void) { return BodySID; };
00468 
00470         UInt32 GetIndexSID(void) { return IndexSID; };
00471 
00473         Rational GetEditRate(void) { return EditRate; };
00474 
00476 
00477         int AddSubStream(int PosTableIndex, UInt32 ElementSize);
00478 
00480         void SetPosTableIndex(int StreamID, int PosTableIndex)
00481         {
00482             if(StreamID < StreamCount) PosTableList[StreamID] = PosTableIndex;
00483         }
00484 
00486         void AddEditUnit(int SubStream, Position EditUnit, int KeyOffset = 0, int Flags = -1);
00487 
00489         void SetOffset(int SubStream, Position EditUnit, UInt64 Offset, int KeyOffset = 0, int Flags = -1);
00490 
00492         bool OfferEditUnit(int SubStream, Position EditUnit, int KeyOffset = 0, int Flags = -1);
00493 
00495         bool OfferOffset(int SubStream, Position EditUnit, UInt64 Offset, int KeyOffset = 0, int Flags = -1);
00496 
00498         void SetTemporalOffset(Position EditUnit, int Offset);
00499 
00501         bool OfferTemporalOffset(Position EditUnit, int Offset);
00502 
00504         void SetKeyOffset(Position EditUnit, int Offset);
00505 
00507         bool OfferKeyOffset(Position EditUnit, int Offset);
00508 
00510 
00511         Position AcceptProvisional(void)
00512         {
00513             if(!ProvisionalEntry) return IndexTable::IndexLowest;
00514 
00515             // Add the entry to the managed data
00516             ManagedData.insert(std::pair<Position, IndexData*>(ProvisionalEditUnit, ProvisionalEntry));
00517             LastNewEditUnit = ProvisionalEditUnit;
00518 
00519             // The entry no longer exists as a provisional entry
00520             ProvisionalEntry = NULL;
00521 
00522             return ProvisionalEditUnit;
00523         }
00524 
00526         Position GetLastNewEditUnit(void) { return  LastNewEditUnit; }
00527 
00529         void AcceptNext(void)
00530         {
00531             AcceptNextEntry = true;
00532         }
00533 
00535 
00538         int LogNext(void);
00539 
00541         int AcceptLogNext(void) { AcceptNext();  return LogNext(); }
00542 
00544         Position ReadLog(int LogID)
00545         {
00546             std::map<int, Position>::iterator it;
00547             it = EntryLog.find(LogID);
00548             if(it == EntryLog.end()) return IndexTable::IndexLowest;
00549             return (*it).second;
00550         }
00551 
00553         void Flush(Position FirstEditUnit, Position LastEditUnit);
00554 
00556         UInt64 GetFirstAvailable(void);
00557 
00559 
00560         UInt64 GetLastAvailable(void);
00561 
00563         IndexTablePtr MakeIndex(void);
00564 
00566 
00567         int AddEntriesToIndex(IndexTablePtr Index, Position FirstEditUnit = IndexTable::IndexLowest, Position LastEditUnit = UINT64_C(0x7fffffffffffffff))
00568         {
00569             return AddEntriesToIndex(false, Index, FirstEditUnit, LastEditUnit);
00570         }
00571 
00573         int AddEntriesToIndex(bool UndoReorder, IndexTablePtr Index, Position FirstEditUnit = IndexTable::IndexLowest, Position LastEditUnit = UINT64_C(0x7fffffffffffffff));
00574 
00576 
00577         void ForceVBR(void) { DataIsCBR = false; };
00578 
00580         bool IsCBR(void) { return DataIsCBR; };
00581 
00583 
00586         void SetValueRelativeIndexing(bool Val) { ValueRelativeIndexing = Val; }
00587 
00589 
00592         bool GetValueRelativeIndexing(void) { return ValueRelativeIndexing; }
00593 
00595         void SetSubRangeOffset(Position Offset) { SubRangeOffset = Offset; }
00596 
00597     protected:
00599         IndexData *GetArrayEntry(Position EditUnit);
00600 
00602         void Log(Position EditUnit)
00603         {
00604             if(LogNextEntry >= 0)
00605             {
00606                 EntryLog[LogNextEntry] = EditUnit;
00607                 LogNextEntry = -1;
00608             }
00609         }
00610     };
00611 
00612     typedef SmartPtr<IndexManager> IndexManagerPtr;
00613 }
00614 
00615 
00616 #endif // MXFLIB__INDEX_H
00617 
00618 
00619 // Temporary Notepad...
00620 //
00621 //
00622 //Criteria for accepting edit units:
00623 //
00624 // Making full index:  Accept all
00625 // Making index segment:   Accept if in range
00626 // Making sparse index (per n edit units): Accept if divisible by n
00627 // Making sparse index (per something else): Accpet first edit unit offered each section

Generated on Mon Apr 2 15:20:53 2007 for MXFLib by  doxygen 1.5.1-p1