00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
00091
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
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
00172
00173
00174
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
00210 BaseDeltaArray = new DeltaEntry[DeltaCount];
00211 memcpy(BaseDeltaArray, DeltaArray, DeltaCount * sizeof(DeltaEntry));
00212
00213
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
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
00240 BaseDeltaArray = new DeltaEntry[DeltaCount];
00241
00242
00243 NSL = 0;
00244 NPE = 0;
00245 UInt32 Delta = 0;
00246 int i;
00247 for(i=0; i<DeltaCount; i++)
00248 {
00249
00250 PutU32(Delta, BaseDeltaArray[i].ElementDelta);
00251 Delta += ElementSizes[i];
00252 BaseDeltaArray[i].PosTableIndex = 0;
00253 BaseDeltaArray[i].Slice = NSL;
00254
00255
00256 if((i != (DeltaCount-1)) && (ElementSizes[i] == 0))
00257 {
00258 Delta = 0;
00259 NSL++;
00260 }
00261 }
00262
00263
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
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
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
00516 ManagedData.insert(std::pair<Position, IndexData*>(ProvisionalEditUnit, ProvisionalEntry));
00517 LastNewEditUnit = ProvisionalEditUnit;
00518
00519
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
00620
00621
00622
00623
00624
00625
00626
00627