essence.h

Go to the documentation of this file.
00001 
00007 /*
00008  *  Copyright (c) 2003, Matt Beard
00009  *
00010  *  This software is provided 'as-is', without any express or implied warranty.
00011  *  In no event will the authors be held liable for any damages arising from
00012  *  the use of this software.
00013  *
00014  *  Permission is granted to anyone to use this software for any purpose,
00015  *  including commercial applications, and to alter it and redistribute it
00016  *  freely, subject to the following restrictions:
00017  *
00018  *    1. The origin of this software must not be misrepresented; you must
00019  *       not claim that you wrote the original software. If you use this
00020  *       software in a product, an acknowledgment in the product
00021  *       documentation would be appreciated but is not required.
00022  *  
00023  *    2. Altered source versions must be plainly marked as such, and must
00024  *       not be misrepresented as being the original software.
00025  *  
00026  *    3. This notice may not be removed or altered from any source
00027  *       distribution.
00028  */
00029 #ifndef MXFLIB__ESSENCE_H
00030 #define MXFLIB__ESSENCE_H
00031 
00032 
00033 #include <map>
00034 #include <list>
00035 
00036 
00037 // Forward refs
00038 namespace mxflib
00039 {
00041     class GCWriter;
00042     typedef SmartPtr<GCWriter> GCWriterPtr;
00043 
00044     class GCReader;
00045     typedef SmartPtr<GCReader> GCReaderPtr;
00046 
00047     // Type used to identify stream
00048     typedef int GCStreamID;
00049 }
00050 
00051 
00052 /* Global definitions */
00053 namespace mxflib
00054 {
00056 
00071     extern bool AllowFastClipWrap;
00072 
00074     inline void SetFastClipWrap(bool Flag) { AllowFastClipWrap = Flag; }
00075 
00077     inline bool GetFastClipWrap(void) { return AllowFastClipWrap; }
00078 }
00079 
00080 
00081 namespace mxflib
00082 {
00084 
00087     class EssenceSource : public RefCount<EssenceSource>
00088     {
00089     protected:
00091 
00094         GCStreamID StreamID;
00095         
00097         IndexManagerPtr IndexMan;
00098 
00100         int IndexStreamID;
00101 
00103         DataChunkPtr SpecifiedKey;
00104 
00106         bool NonGC;
00107 
00108     public:
00109         // Base constructor
00110         EssenceSource() : StreamID(-1) {};
00111 
00113         virtual ~EssenceSource() { };
00114 
00116 
00117         virtual size_t GetEssenceDataSize(void) = 0;
00118 
00120 
00130         virtual DataChunkPtr GetEssenceData(size_t Size = 0, size_t MaxSize = 0) = 0;
00131 
00133 
00139         virtual bool EndOfItem(void) = 0;
00140 
00142 
00144         virtual bool EndOfData(void) = 0;
00145 
00147         virtual UInt8 GetGCEssenceType(void) = 0;
00148 
00150         virtual UInt8 GetGCElementType(void) = 0;
00151 
00153         void SetStreamID(GCStreamID NewID) { StreamID = NewID; }
00154 
00156         GCStreamID GetStreamID(void) { return StreamID; }
00157 
00159         virtual bool IsEditPoint(void) { return true; }
00160 
00162 
00165         virtual Rational GetEditRate(void) = 0;
00166 
00168 
00172         virtual Position GetCurrentPosition(void) = 0;
00173 
00175         virtual int GetBERSize(void) { return 0; }
00176 
00178 
00179         virtual bool SetOption(std::string Option, Int64 Param = 0) { return false; } ;
00180 
00182 
00184         virtual UInt32 GetBytesPerEditUnit(UInt32 KAGSize = 1) { return 0; }
00185 
00187 
00189         virtual bool CanIndex() { return false; }
00190 
00192 
00194         virtual void SetIndexManager(IndexManagerPtr &Manager, int StreamID)
00195         {
00196             IndexMan = Manager;
00197             IndexStreamID = StreamID;
00198         }
00199 
00201         virtual IndexManagerPtr &GetIndexManager(void) { return IndexMan; }
00202 
00204         virtual int GetIndexStreamID(void) { return IndexStreamID; }
00205 
00207         virtual void SetKey(DataChunkPtr &Key, bool NonGC = false)
00208         {
00209             ASSERT(Key->Size == 16);
00210 
00211             SpecifiedKey = Key;
00212             this->NonGC = NonGC;
00213         }
00214 
00216 
00220         virtual DataChunkPtr &GetKey(void) { return SpecifiedKey; }
00221 
00223         /*  \note Defined EssenceSource sub-classes may always use a non-GC-type key, in which case
00224          *        they will always return true from this function
00225          */
00226         virtual bool GetNonGC(void) { return NonGC; }
00227 
00228         /* Essence type identification */
00229         /* These functions can be overwridden, or use the base versions to parse GetGCEssenceType() */
00230 
00232         virtual bool IsPictureEssence(void)
00233         {
00234             UInt8 Type = GetGCEssenceType();
00235             if((Type == 0x05) || (Type == 0x15)) return true;
00236             return false;
00237         }
00238 
00240         virtual bool IsSoundEssence(void)
00241         {
00242             UInt8 Type = GetGCEssenceType();
00243             if((Type == 0x06) || (Type == 0x16)) return true;
00244             return false;
00245         }
00246 
00248         virtual bool IsDataEssence(void)
00249         {
00250             UInt8 Type = GetGCEssenceType();
00251             if((Type == 0x07) || (Type == 0x17)) return true;
00252             return false;
00253         }
00254 
00256         virtual bool IsCompoundEssence(void)
00257         {
00258             return (GetGCEssenceType() == 0x18);
00259         }
00260 
00262 
00285         virtual Int32 RelativeWriteOrder(void) { return 0; }
00286 
00288 
00290         virtual int RelativeWriteOrderType(void) { return 0; }
00291 
00293 
00295         virtual Length GetPrechargeSize(void) { return 0; }
00296 
00298 
00300         virtual Position GetRangeStart(void) { return 0; }
00301 
00303 
00305         virtual Position GetRangeEnd(void) { return 0; }
00306 
00308 
00310         virtual Length GetRangeDuration(void) { return 0; }
00311     };
00312 
00313     // Smart pointer to an EssenceSource object
00314     typedef SmartPtr<EssenceSource> EssenceSourcePtr;
00315 
00316     // Parent pointer to an EssenceSource object
00317     typedef ParentPtr<EssenceSource> EssenceSourceParent;
00318 
00319     // List of smart pointer to EssenceSource objects
00320     typedef std::list<EssenceSourcePtr> EssenceSourceList;
00321 }
00322 
00323 
00324 
00325 namespace mxflib
00326 {
00328 
00330     class EssenceSink : public RefCount<EssenceSink>
00331     {
00332     protected:
00333 
00334     public:
00335         // Base constructor
00336         EssenceSink() {};
00337 
00339         virtual ~EssenceSink() {};
00340 
00342 
00350         virtual bool PutEssenceData(UInt8 *const Buffer, size_t BufferSize, bool EndOfItem = true) = 0;
00351 
00353         bool PutEssenceData(DataChunkPtr &Buffer, bool EndOfItem = true) { return PutEssenceData(Buffer->Data, Buffer->Size, EndOfItem); }
00354 
00356         bool PutEssenceData(DataChunk &Buffer, bool EndOfItem = true) { return PutEssenceData(Buffer.Data, Buffer.Size, EndOfItem); }
00357 
00359 
00362         virtual bool EndOfData(void) = 0;
00363     };
00364 
00365     // Smart pointer to an EssenceSink object
00366     typedef SmartPtr<EssenceSink> EssenceSinkPtr;
00367 
00368     // Parent pointer to an EssenceSink object
00369     typedef ParentPtr<EssenceSink> EssenceSinkParent;
00370 
00371     // List of smart pointer to EssenceSink objects
00372     typedef std::list<EssenceSinkPtr> EssenceSinkList;
00373 }
00374 
00375 
00376 
00377 namespace mxflib
00378 {
00380     const UInt8 GCMulti_Data[16] = { 0x06, 0x0E, 0x2B, 0x34, 0x04, 0x01, 0x01, 0x03, 0x0d, 0x01, 0x03, 0x01, 0x02, 0x7F, 0x01, 0x00 };
00381 }
00382 
00383 
00384 namespace mxflib
00385 {
00387     struct GCStreamData
00388     {
00389         DataChunkPtr SpecifiedKey;          
00390         bool NonGC;                         
00391         UInt8 Type;                         
00392         UInt8 SchemeOrCount;                
00393         UInt8 Element;                      
00394         UInt8 SubOrNumber;                  
00395         UInt8 RegDes;                       
00396         UInt8 RegVer;                       
00397         int LenSize;                        
00398         IndexManagerPtr IndexMan;           
00399         int IndexSubStream;                 
00400         bool IndexFiller;                   
00401         bool IndexClip;                     
00402         bool CountFixed;                    
00403 
00405         UInt32 WriteOrder;                  
00406 
00408     };
00409 
00411     class GCWriter : public RefCount<GCWriter>
00412     {
00413     protected:
00414         MXFFilePtr LinkedFile;              
00415         UInt32 TheBodySID;                  
00416 
00417         int StreamTableSize;                
00418         int StreamCount;                    
00419 
00420         int StreamBase;                     
00421 
00422         GCStreamData *StreamTable;          
00423 
00424         UInt32 KAGSize;                     
00425         bool ForceFillerBER4;               
00426 
00427         Int32 NextWriteOrder;               
00428 
00429         Position IndexEditUnit;             
00430 
00434         UInt64 StreamOffset;                
00435 
00437         std::map<UInt32, GCStreamID> WriteOrderMap;
00438 
00439     public:
00441         GCWriter(MXFFilePtr File, UInt32 BodySID = 0, int Base = 0);
00442 
00444         ~GCWriter();
00445 
00447         void SetKAG(UInt32 KAG, bool ForceBER4 = false) { KAGSize = KAG; ForceFillerBER4 = ForceBER4; };
00448 
00450         UInt32 GetKAG(void) { return KAGSize; }
00451 
00453         GCStreamID AddSystemElement(unsigned int RegistryDesignator, unsigned int SchemeID, unsigned int ElementID, unsigned int SubID = 0) { return AddSystemElement(false, RegistryDesignator, SchemeID, ElementID, SubID); }
00454 
00456         GCStreamID AddCPSystemElement(unsigned int RegistryDesignator, unsigned int SchemeID, unsigned int ElementID, unsigned int SubID = 0)   { return AddSystemElement(true, RegistryDesignator, SchemeID, ElementID, SubID); }
00457 
00459         GCStreamID AddSystemElement(bool CPCompatible, unsigned int RegistryDesignator, unsigned int SchemeID, unsigned int ElementID, unsigned int SubID = 0);
00460         
00462         GCStreamID AddPictureElement(unsigned int ElementType) { return AddPictureElement(false, ElementType); }
00463 
00465         GCStreamID AddCPPictureElement(unsigned int ElementType) { return AddPictureElement(true, ElementType); }
00466 
00468         GCStreamID AddPictureElement(bool CPCompatible, unsigned int ElementType) { return AddEssenceElement( CPCompatible ? 0x05 : 0x15, ElementType); }
00469 
00471         GCStreamID AddSoundElement(unsigned int ElementType) { return AddPictureElement(false, ElementType); }
00472 
00474         GCStreamID AddCPSoundElement(unsigned int ElementType) { return AddPictureElement(true, ElementType); }
00475 
00477         GCStreamID AddSoundElement(bool CPCompatible, unsigned int ElementType) { return AddEssenceElement( CPCompatible ? 0x06 : 0x16, ElementType); }
00478 
00480         GCStreamID AddDataElement(unsigned int ElementType) { return AddDataElement(false, ElementType); }
00481 
00483         GCStreamID AddCPDataElement(unsigned int ElementType) { return AddDataElement(true, ElementType); }
00484 
00486         GCStreamID AddDataElement(bool CPCompatible, unsigned int ElementType) { return AddEssenceElement( CPCompatible ? 0x07 : 0x17, ElementType); }
00487 
00489         GCStreamID AddCompoundElement(unsigned int ElementType) { return AddEssenceElement( 0x18, ElementType); }
00490 
00492         GCStreamID AddEssenceElement(unsigned int EssenceType, unsigned int ElementType, int LenSize = 0);
00493 
00495         GCStreamID AddEssenceElement(DataChunkPtr &Key, int LenSize = 0, bool NonGC = false);
00496 
00498         GCStreamID AddEssenceElement(int KeySize, UInt8 *KeyData, int LenSize = 0, bool NonGC = false)
00499         {
00500             DataChunkPtr Key = new DataChunk(KeySize, KeyData);
00501             return AddEssenceElement(Key, LenSize, NonGC);
00502         }
00503 
00505         void AddStreamIndex(GCStreamID ID, IndexManagerPtr &IndexMan, int IndexSubStream, bool IndexFiller = false, bool IndexClip = false);
00506 
00508         UInt32 GetTrackNumber(GCStreamID ID);
00509 
00511         void AssignEssenceUL(GCStreamID ID, ULPtr EssenceUL);
00512 
00514         void StartNewCP(void);
00515 
00517         UInt64 CalcWriteSize(void);
00518 
00520         void Flush(void);
00521 
00523         Int64 GetStreamOffset(void) { return StreamOffset; }
00524 
00526         void SetIndexEditUnit(Position EditUnit) { IndexEditUnit = EditUnit; }
00527 
00529         Position GetIndexEditUnit(void) { return IndexEditUnit; }
00530 
00532         void AddSystemData(GCStreamID ID, UInt64 Size, const UInt8 *Data);
00533 
00535         void AddSystemData(GCStreamID ID, DataChunkPtr Chunk) { AddSystemData(ID, Chunk->Size, Chunk->Data); }
00536 
00538         void AddSystemData(GCStreamID ID, UInt64 Size, const UInt8 *Data, UUIDPtr ContextID, Length PlaintextOffset = 0);
00539         
00541         void AddSystemData(GCStreamID ID, DataChunkPtr Chunk, UUIDPtr ContextID, Length PlaintextOffset = 0) { AddSystemData(ID, Chunk->Size, Chunk->Data, ContextID, PlaintextOffset); }
00542 
00544         void AddEssenceData(GCStreamID ID, UInt64 Size, const UInt8 *Data);
00545 
00547         void AddEssenceData(GCStreamID ID, DataChunkPtr Chunk) { AddEssenceData(ID, Chunk->Size, Chunk->Data); }
00548 
00550         void AddEssenceData(GCStreamID ID, EssenceSourcePtr Source, bool FastClipWrap = false);
00551 
00552 /*      //! Add encrypted essence data to the current CP
00553         void AddEssenceData(GCStreamID ID, UInt64 Size, const UInt8 *Data, UUIDPtr ContextID, Length PlaintextOffset = 0);
00554         
00556         void AddEssenceData(GCStreamID ID, DataChunkPtr Chunk, UUIDPtr ContextID, Length PlaintextOffset = 0)  { AddEssenceData(ID, Chunk->Size, Chunk->Data, ContextID, PlaintextOffset); }
00557 
00559         void AddEssenceData(GCStreamID ID, EssenceSource* Source, UUIDPtr ContextID, Length PlaintextOffset = 0, bool FastClipWrap = false);
00560 */
00562         void AddEssenceData(GCStreamID ID, KLVObjectPtr Source, bool FastClipWrap = false);
00563 
00564 
00566         Length CalcRawSize(KLVObjectPtr Object);
00567 
00569         void WriteRaw(KLVObjectPtr Object);
00570 
00571 
00573         struct WriteBlock
00574         {
00575             UInt64 Size;                
00576             UInt8 *Buffer;              
00577             EssenceSourcePtr Source;    
00578             KLVObjectPtr KLVSource;     
00579             int LenSize;                
00580             IndexManagerPtr IndexMan;   
00581             int IndexSubStream;         
00582             bool IndexFiller;           
00583             bool IndexClip;             
00584             bool WriteEncrypted;        
00585             bool FastClipWrap;          
00586         };
00587 
00589         typedef std::map<UInt32,WriteBlock> WriteQueueMap;
00590 
00592         WriteQueueMap WriteQueue;
00593 
00594 
00596         void SetWriteOrder(GCStreamID ID, Int32 WriteOrder = -1, int Type =-1);
00597 
00599         void SetRelativeWriteOrder(GCStreamID ID, int Type, Int32 Position);
00600 
00602         Int32 GetWriteOrder(GCStreamID ID);
00603 
00605         int GetStreamCount(void) { return StreamCount; };
00606     };
00607 }
00608 
00609 
00610 namespace mxflib
00611 {
00612     class EssenceSubParser;
00613     typedef SmartPtr<EssenceSubParser> EssenceSubParserPtr;
00614     typedef ParentPtr<EssenceSubParser> EssenceSubParserParent;
00615 
00616     class WrappingOption : public RefCount<WrappingOption>
00617     {
00618     public:
00620 
00621         enum WrapType { None, Frame, Clip, Line, Other } ;
00622 
00623         EssenceSubParserParent Handler;         
00624         std::string Name;                       
00625         std::string Description;                
00626         ULPtr   WrappingID;                     
00627 
00628         ULPtr   WrappingUL;                     
00629         ULList  RequiredPartners;               
00630         UInt8   GCEssenceType;                  
00631         UInt8   GCElementType;                  
00632         WrapType ThisWrapType;                  
00633         bool    CanSlave;                       
00634         bool    CanIndex;                       
00635         bool    CBRIndex;                       
00636         UInt8   BERSize;                        
00637         UInt32 BytesPerEditUnit;                
00638     };
00639 
00640     typedef SmartPtr<WrappingOption> WrappingOptionPtr;
00641     typedef std::list<WrappingOptionPtr> WrappingOptionList;
00642 
00644     class EssenceStreamDescriptor;
00645 
00647     typedef SmartPtr<EssenceStreamDescriptor> EssenceStreamDescriptorPtr;
00648 
00650     typedef std::list<EssenceStreamDescriptorPtr> EssenceStreamDescriptorList;
00651 
00685     class EssenceStreamDescriptor : public RefCount<EssenceStreamDescriptor>
00686     {
00687     public:
00688         UInt32 ID;                              
00689         std::string Description;                
00690         UUID SourceFormat;                      
00691         MDObjectPtr Descriptor;                 
00692         EssenceStreamDescriptorList SubStreams; 
00693     };
00694 
00695 
00697     class EssenceSubParserFactory : public RefCount<EssenceSubParserFactory>
00698     {
00699     public:
00701         virtual EssenceSubParserPtr NewParser(void) const = 0;
00702     };
00703 
00705     typedef SmartPtr<EssenceSubParserFactory> EssenceSubParserFactoryPtr;
00706 
00707 
00709 
00710     class EssenceSubParser : public RefCount<EssenceSubParser>
00711     {
00712     protected:
00714         WrappingOptionPtr SelectedWrapping;
00715 
00717         IndexManagerPtr Manager;
00718 
00720         int ManagedStreamID;
00721 
00722     public:
00723 
00725 
00726         class ESP_EssenceSource : public EssenceSource
00727         {
00728         protected:
00729             EssenceSubParserPtr Caller;
00730             FileHandle File;
00731             UInt32 Stream;
00732             UInt64 RequestedCount;
00733             IndexTablePtr Index;
00734             DataChunkPtr RemainingData;
00735             bool AtEndOfData;
00736             bool Started;
00737 
00738         public:
00740             ESP_EssenceSource(EssenceSubParserPtr TheCaller, FileHandle InFile, UInt32 UseStream, UInt64 Count = 1)
00741             {
00742                 Caller = TheCaller;
00743                 File = InFile;
00744                 Stream = UseStream;
00745                 RequestedCount = Count;
00746                 AtEndOfData = false;
00747                 Started = false;
00748             };
00749 
00751 
00761             virtual DataChunkPtr GetEssenceData(size_t Size = 0, size_t MaxSize = 0) { return BaseGetEssenceData(Size, MaxSize); };
00762 
00764 
00766             DataChunkPtr BaseGetEssenceData(size_t Size = 0, size_t MaxSize = 0)
00767             {
00768                 // Allow us to differentiate the first call
00769                 if(!Started) Started = true;
00770 
00771                 DataChunkPtr Data;
00772 
00773                 if(RemainingData)
00774                 {
00775                     Data = RemainingData;
00776                     RemainingData = NULL;
00777                 }
00778                 else
00779                 {
00780                     Data = Caller->Read(File, Stream, 1);
00781                 }
00782                 if(Data)
00783                 {
00784                     if(Data->Size == 0) Data = NULL;
00785                     else
00786                     {
00787                         if((MaxSize) && (Data->Size > MaxSize))
00788                         {
00789                             RemainingData = new DataChunk(Data->Size - MaxSize, &Data->Data[MaxSize]);
00790                             Data->Resize((UInt32)MaxSize);
00791                         }
00792                     }
00793                 }
00794 
00795                 // Record when we hit the end of all data
00796                 if(!Data) AtEndOfData = true;
00797 
00798                 return Data;
00799             }
00800 
00802 
00808             virtual bool EndOfItem(void) 
00809             { 
00810                 // If we are clip wrapping then we only end when no more data
00811                 if(Caller->GetWrapType() == WrappingOption::Clip) return AtEndOfData;
00812 
00813                 // Otherwise items end when there is no data remaining from the last read
00814                 return !RemainingData;
00815             }
00816 
00818 
00820             virtual bool EndOfData(void) { return AtEndOfData; }
00821 
00823             virtual UInt8 GetGCEssenceType(void) { return Caller->GetGCEssenceType(); }
00824 
00826             virtual UInt8 GetGCElementType(void) { return Caller->GetGCElementType(); }
00827 
00829             virtual bool IsEditPoint(void) { return true; }
00830 
00832 
00835             virtual Rational GetEditRate(void) { return Caller->GetEditRate(); }
00836 
00838 
00842             virtual Position GetCurrentPosition(void) { return Caller->GetCurrentPosition(); }
00843 
00845 
00846             virtual bool SetOption(std::string Option, Int64 Param = 0) { return Caller->SetOption(Option, Param); } ;
00847 
00849 
00851             virtual UInt32 GetBytesPerEditUnit(UInt32 KAGSize = 1) { return Caller->GetBytesPerEditUnit(KAGSize); }
00852 
00854 
00856             virtual bool CanIndex() { return Caller->SelectedWrapping->CanIndex; }
00857 
00859             virtual void SetIndexManager(IndexManagerPtr &Manager, int StreamID)
00860             {
00861                 // Set the manager in our containing parser
00862                 Caller->SetIndexManager(Manager, StreamID);
00863             }
00864         };
00865 
00866         // Allow embedded essence source to access our protected properties
00867         friend class ESP_EssenceSource;
00868 
00869 
00870     protected:
00871 
00872     public:
00874         virtual ~EssenceSubParser() {};
00875 
00877         virtual StringList HandledExtensions(void) { StringList Ret; return Ret; };
00878 
00880 
00884         virtual EssenceStreamDescriptorList IdentifyEssence(FileHandle InFile)
00885         {
00886             EssenceStreamDescriptorList Ret;
00887             return Ret;
00888         }
00889 
00891 
00896         virtual WrappingOptionList IdentifyWrappingOptions(FileHandle InFile, EssenceStreamDescriptor &Descriptor)
00897         {
00898             WrappingOptionList Ret;
00899             return Ret;
00900         }
00901 
00903         virtual void Use(UInt32 Stream, WrappingOptionPtr &UseWrapping)
00904         {
00905             // DRAGONS: Any derived version of Use() must also set SelectedWrapping
00906             SelectedWrapping = UseWrapping;
00907         }
00908 
00910         virtual bool CanReValidate(void) { return false; }
00911 
00913 
00918         virtual bool ReValidate(FileHandle Infile, UInt32 Stream, MDObjectPtr &Descriptor, WrappingOptionPtr &UseWrapping)
00919         {
00920             return false;
00921         }
00922 
00924         WrappingOption::WrapType GetWrapType(void)
00925         {
00926             if(!SelectedWrapping) return WrappingOption::None;
00927 
00928             return SelectedWrapping->ThisWrapType;
00929         }
00930 
00932 
00933         virtual bool SetEditRate(Rational EditRate)
00934         {
00935             // Default action is to not allow the edit rate to be changed
00936             return (EditRate == GetEditRate());
00937         }
00938 
00940         virtual Rational GetEditRate(void) = 0;
00941 
00943 
00945         virtual Rational GetPreferredEditRate(void)
00946         {
00947             // By default we don't know the preferred rate
00948             return Rational(0,0);
00949         }
00950 
00952 
00953         virtual UInt32 GetBytesPerEditUnit(UInt32 KAGSize = 1) { return KAGSize * 0; }
00954 
00956 
00960         virtual Position GetCurrentPosition(void) = 0;
00961 
00963         virtual void SetIndexManager(IndexManagerPtr &TheManager, int StreamID = 0)
00964         {
00965             Manager = TheManager;
00966             ManagedStreamID = StreamID;
00967         }
00968 
00970         virtual IndexManagerPtr &GetIndexManager(void) { return Manager; };
00971 
00973         virtual int GetIndexStreamID(void) { return ManagedStreamID; };
00974 
00976         virtual void SetStreamOffset(Position EditUnit, UInt64 Offset)
00977         {
00978             if(Manager) Manager->SetOffset(ManagedStreamID, EditUnit, Offset);
00979         }
00980 
00982         virtual bool OfferStreamOffset(Position EditUnit, UInt64 Offset)
00983         {
00984             if(!Manager) return false;
00985             return Manager->OfferOffset(ManagedStreamID, EditUnit, Offset);
00986         }
00987 
00989         virtual void IndexNext(void)
00990         {
00991             if(Manager) Manager->AcceptNext();
00992         }
00993 
00995         virtual int IndexLogNext(void)
00996         {
00997             if(Manager) return Manager->AcceptLogNext();
00998             return -1;
00999         }
01000 
01002         virtual int LogNext(void)
01003         {
01004             if(Manager) return Manager->LogNext();
01005             return -1;
01006         }
01007 
01009         virtual Position ReadLog(int LogID)
01010         {
01011             if(Manager) return Manager->ReadLog(LogID);
01012             return IndexTable::IndexLowest;
01013         }
01014 
01016 
01017         virtual Position AcceptProvisional(void)
01018         {
01019             if(Manager) return Manager->AcceptProvisional();
01020             return IndexTable::IndexLowest;
01021         }
01022 
01024         Position GetLastNewEditUnit(void) 
01025         { 
01026             if(Manager) return Manager->GetLastNewEditUnit();
01027             return IndexTable::IndexLowest;
01028         }
01029 
01031         virtual UInt8 GetGCEssenceType(void) { return SelectedWrapping->GCEssenceType; }
01032 
01034         virtual UInt8 GetGCElementType(void) { return SelectedWrapping->GCElementType; }
01035 
01036 
01038 
01044         virtual DataChunkPtr Read(FileHandle InFile, UInt32 Stream, UInt64 Count = 1) = 0;
01045 
01047         virtual EssenceSourcePtr GetEssenceSource(FileHandle InFile, UInt32 Stream, UInt64 Count = 1) = 0;
01048 
01050 
01057         virtual Length Write(FileHandle InFile, UInt32 Stream, MXFFilePtr OutFile, UInt64 Count = 1) = 0;
01058 
01060 
01061         virtual bool SetOption(std::string Option, Int64 Param = 0) { return false; } ;
01062 
01064 
01068         virtual std::string GetParserName(void) const { return ""; }
01069 
01070 
01072 
01075         virtual EssenceSubParserPtr NewParser(void) const = 0;
01076     };
01077 
01079     typedef EssenceSubParser EssenceSubParserBase;
01080 
01081 
01082 
01084 
01086     class EssenceSubParserSelfFactory : public EssenceSubParserFactory
01087     {
01088     protected:
01090         EssenceSubParserPtr Parser;
01091 
01092     public:
01094         EssenceSubParserSelfFactory(EssenceSubParserPtr Parser) : Parser(Parser) {};
01095 
01097         virtual EssenceSubParserPtr NewParser(void) const { return Parser->NewParser(); }
01098     };
01099 
01100 }
01101 
01102 
01103 namespace mxflib
01104 {
01106     typedef std::pair<EssenceSubParserPtr, EssenceStreamDescriptorList> ParserDescriptorPair;
01108     typedef std::list<EssenceSubParserPtr> EssenceParserList;
01109 
01110 
01112     class ParserDescriptorList : public RefCount<ParserDescriptorList>, public std::list<ParserDescriptorPair> {};
01113     typedef SmartPtr<ParserDescriptorList> ParserDescriptorListPtr;
01114 
01115 
01117     class EssenceParser
01118     {
01119     public:
01121         typedef std::list<EssenceSubParserFactoryPtr> EssenceSubParserFactoryList;
01122 
01123     protected:
01125 
01128         static EssenceSubParserFactoryList EPList;
01129         
01131         static bool Inited;
01132 
01133     private:
01135         EssenceParser();
01136 
01137     public:
01139 
01142         static void AddNewSubParserType(EssenceSubParserFactoryPtr Factory)
01143         {
01144             EPList.push_back(Factory);
01145         }
01146 
01148 
01152         static void AddNewSubParserType(EssenceSubParserPtr SubParser)
01153         {
01154             EssenceSubParserFactoryPtr Factory = new EssenceSubParserSelfFactory(SubParser);
01155 
01156             EPList.push_back(Factory);
01157         }
01158 
01160         static ParserDescriptorListPtr IdentifyEssence(FileHandle InFile);
01161 
01163         class WrappingConfig;
01164         
01166         typedef SmartPtr<WrappingConfig> WrappingConfigPtr;
01167 
01169         typedef std::list<WrappingConfigPtr> WrappingConfigList;
01170 
01172 
01174         class WrappingConfig : public RefCount<WrappingConfig>
01175         {
01176         public:
01177             EssenceSubParserPtr Parser;                 
01178             WrappingOptionPtr WrapOpt;                  
01179             MDObjectPtr EssenceDescriptor;              
01180             UInt32 Stream;                              
01181             Rational EditRate;                          
01182             WrappingConfigList SubStreams;              
01183         };
01184 
01186         static WrappingConfigList ListWrappingOptions(bool AllowMultiples, FileHandle InFile, ParserDescriptorListPtr PDList, Rational ForceEditRate, WrappingOption::WrapType ForceWrap = WrappingOption::None);
01187 
01189         static WrappingConfigList ListWrappingOptions(FileHandle InFile, ParserDescriptorListPtr PDList, Rational ForceEditRate, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01190         {
01191             return ListWrappingOptions(false, InFile, PDList, ForceEditRate, ForceWrap);
01192         }
01193 
01195         static WrappingConfigList ListWrappingOptions(bool AllowMultiples, FileHandle InFile, Rational ForceEditRate, WrappingOption::WrapType ForceWrap = WrappingOption::None);
01196 
01198         static WrappingConfigList ListWrappingOptions(FileHandle InFile, Rational ForceEditRate, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01199         {
01200             return ListWrappingOptions(false, InFile, ForceEditRate, ForceWrap);
01201         }
01202 
01204         static WrappingConfigList ListWrappingOptions(bool AllowMultiples, FileHandle InFile, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01205         {
01206             Rational ForceEditRate(0,0);
01207             return ListWrappingOptions(AllowMultiples, InFile, ForceEditRate, ForceWrap);
01208         }
01209 
01211         static WrappingConfigList ListWrappingOptions(FileHandle InFile, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01212         {
01213             Rational ForceEditRate(0,0);
01214             return ListWrappingOptions(false, InFile, ForceEditRate, ForceWrap);
01215         }
01216 
01218         static WrappingConfigPtr SelectWrappingOption(FileHandle InFile, ParserDescriptorListPtr PDList, Rational ForceEditRate, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01219         {
01220             return SelectWrappingOption(false, InFile, PDList, ForceEditRate, ForceWrap);
01221         }
01222 
01224         static WrappingConfigPtr SelectWrappingOption(FileHandle InFile, ParserDescriptorListPtr PDList, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01225         {
01226             Rational ForceEditRate(0,0);
01227             return SelectWrappingOption(false, InFile, PDList, ForceEditRate, ForceWrap);
01228         }
01229 
01231         static WrappingConfigPtr SelectWrappingOption(bool AllowMultiples, FileHandle InFile, ParserDescriptorListPtr PDList, Rational ForceEditRate, WrappingOption::WrapType ForceWrap = WrappingOption::None);
01232 
01234         static WrappingConfigPtr SelectWrappingOption(bool AllowMultiples, FileHandle InFile, ParserDescriptorListPtr PDList, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01235         {
01236             Rational ForceEditRate(0,0);
01237             return SelectWrappingOption(AllowMultiples, InFile, PDList, ForceEditRate, ForceWrap);
01238         }
01239 
01241         static WrappingConfigPtr SelectWrappingOption(FileHandle InFile, Rational ForceEditRate, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01242         {
01243             return SelectWrappingOption(false, InFile, ForceEditRate, ForceWrap);
01244         }
01245 
01247         static WrappingConfigPtr SelectWrappingOption(FileHandle InFile, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01248         {
01249             Rational ForceEditRate(0,0);
01250             return SelectWrappingOption(false, InFile, ForceEditRate, ForceWrap);
01251         }
01252 
01254         static WrappingConfigPtr SelectWrappingOption(bool AllowMultiples, FileHandle InFile, Rational ForceEditRate, WrappingOption::WrapType ForceWrap = WrappingOption::None);
01255 
01257         static WrappingConfigPtr SelectWrappingOption(bool AllowMultiples, FileHandle InFile, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01258         {
01259             Rational ForceEditRate(0,0);
01260             return SelectWrappingOption(AllowMultiples, InFile, ForceEditRate, ForceWrap);
01261         }
01262 
01264         static void SelectWrappingOption(EssenceParser::WrappingConfigPtr Config);
01265 
01267         static WrappingConfigPtr SelectWrappingOption(FileHandle InFile)
01268         {
01269             Rational ForceEditRate(0,0);
01270             return SelectWrappingOption(InFile, ForceEditRate);
01271         }
01272 
01274         static WrappingConfigPtr SelectWrappingOption(FileHandle InFile, std::string WrappingName, Rational ForceEditRate);
01275 
01277         static WrappingConfigPtr SelectWrappingOption(FileHandle InFile, std::string WrappingName)
01278         {
01279             Rational ForceEditRate(0,0);
01280             return SelectWrappingOption(InFile, WrappingName, ForceEditRate);
01281         }
01282 
01284         static WrappingConfigPtr SelectWrappingOption(FileHandle InFile, std::list<std::string> WrappingNameList, Rational ForceEditRate);
01285 
01287         static WrappingConfigPtr SelectWrappingOption(FileHandle InFile, std::list<std::string> WrappingNameList)
01288         {
01289             Rational ForceEditRate(0,0);
01290             return SelectWrappingOption(InFile, WrappingNameList, ForceEditRate);
01291         }
01292 
01294         static WrappingConfigPtr SelectWrappingOption(FileHandle InFile, ULPtr &WrappingID, Rational ForceEditRate);
01295 
01297         static WrappingConfigPtr SelectWrappingOption(FileHandle InFile, ULPtr &WrappingID)
01298         {
01299             Rational ForceEditRate(0,0);
01300             return SelectWrappingOption(InFile, WrappingID, ForceEditRate);
01301         }
01302 
01304         static WrappingConfigPtr SelectWrappingOption(FileHandle InFile, ULList &WrappingIDList, Rational ForceEditRate);
01305 
01307         static WrappingConfigPtr SelectWrappingOption(FileHandle InFile, ULList &WrappingIDList)
01308         {
01309             Rational ForceEditRate(0,0);
01310             return SelectWrappingOption(InFile, WrappingIDList, ForceEditRate);
01311         }
01312 
01313     protected:
01315 
01318         static void ExtractValidWrappingOptions(WrappingConfigList &Ret, FileHandle InFile, EssenceStreamDescriptorPtr &ESDescriptor, WrappingOptionList &WO, Rational &ForceEditRate, WrappingOption::WrapType ForceWrap);
01319 
01320     
01321     protected:
01323         static void Init(void);
01324     };
01325 
01326 
01327     /* Make top-level versions of EssenceParser::WrappingConfig typedefs */
01328 
01330     typedef EssenceParser::WrappingConfigPtr WrappingConfigPtr;
01331 
01333     typedef EssenceParser::WrappingConfigList WrappingConfigList;
01334 }
01335 
01336 
01337 namespace mxflib
01338 {
01340     class NewFileHandler : public RefCount<NewFileHandler>
01341     {
01342     public:
01343         virtual ~NewFileHandler() {};
01344 
01346 
01348         virtual void NewFile(std::string &FileName) = 0;
01349     };
01350 
01352     typedef SmartPtr<NewFileHandler> NewFileHandlerPtr;
01353 
01354     // Forware declare the file parser
01355     class FileParser;
01356 
01358     typedef SmartPtr<FileParser> FileParserPtr;
01359 
01360 
01362     class ListOfFiles
01363     {
01364     protected:
01365         NewFileHandlerPtr Handler;              
01366         std::string BaseFileName;               
01367         std::list<std::string> FollowingNames;  
01368         bool FileList;                          
01369         int ListOrigin;                         
01370         int ListIncrement;                      
01371         int ListNumber;                         
01372         int ListEnd;                            
01373         int FileNumber;                         
01374         int FilesRemaining;                     
01375         bool AtEOF;                             
01376         std::string CurrentFileName;            
01377 
01378         Position RangeStart;                    
01379         Position RangeEnd;                      
01380         Length RangeDuration;                   
01381 
01382     public:
01384         ListOfFiles(std::string FileName = "") : RangeStart(-1), RangeEnd(-1), RangeDuration(-1)
01385         {
01386             AtEOF = false;
01387 
01388             // Set the filename pattern if required
01389             if(FileName.size())
01390             {
01391                 ParseFileName(FileName); 
01392             }
01393             else
01394             {
01395                 BaseFileName = "";
01396                 FileList = false; 
01397             }
01398         }
01399 
01401         virtual ~ListOfFiles() {}
01402 
01404         void SetFileName(std::string &FileName) 
01405         { 
01406             FollowingNames.clear();
01407             ParseFileName(FileName); 
01408         }
01409 
01411         void AddFileName(std::string &FileName) 
01412         { 
01413             if(BaseFileName.empty())
01414             {
01415                 ParseFileName(FileName); 
01416             }
01417             else
01418             {
01419                 FollowingNames.push_back(FileName);
01420             }
01421         }
01422 
01424         void SetNewFileHandler(NewFileHandlerPtr &NewHandler) { Handler = NewHandler; }
01425 
01427         void SetNewFileHandler(NewFileHandler *NewHandler) { Handler = NewHandler; }
01428 
01430         Position GetRangeStart(void) const { return RangeStart; }
01431 
01433         Position GetRangeEnd(void) const { return RangeEnd; }
01434 
01436         Position GetRangeDuration(void) const { return RangeDuration; }
01437 
01439         std::string FileName(void) { return CurrentFileName; }
01440 
01442 
01445         virtual bool OpenFile(void) = 0;
01446 
01448 
01449         virtual void CloseFile(void) = 0;
01450 
01452 
01453         virtual bool IsFileOpen(void) = 0;
01454 
01456         bool IsFileList(void) { return FileList; }
01457 
01459 
01461         bool GetNextFile(void);
01462 
01463     protected:
01465         void ParseFileName(std::string FileName);
01466 
01467     };
01468 
01469 
01471     class FileParser : public ListOfFiles, public RefCount<FileParser>
01472     {
01473     protected:
01474         bool CurrentFileOpen;                   
01475         FileHandle CurrentFile;                 
01476         EssenceSubParserPtr SubParser;          
01477         UInt32 CurrentStream;                   
01478         MDObjectPtr CurrentDescriptor;          
01479         WrappingOptionPtr CurrentWrapping;      
01480         EssenceSourceParent SeqSource;          
01481 
01482         DataChunkPtr PendingData;               
01483 
01485         struct SubStreamInfo
01486         {
01487             UInt32 StreamID;                    
01488             EssenceSourcePtr Source;            
01489         };
01490 
01492         typedef std::list<SubStreamInfo> SubStreamList;
01493 
01494         SubStreamList SubStreams;               
01495 
01496 
01497     public:
01499         FileParser(std::string FileName = "") : ListOfFiles(FileName)
01500         {
01501             // Let our sequential source know who we are
01502             SeqSource = new SequentialEssenceSource(this);
01503 
01504             CurrentFileOpen = false;
01505         }
01506 
01508         ParserDescriptorListPtr IdentifyEssence(void);
01509 
01511         EssenceParser::WrappingConfigList ListWrappingOptions(bool AllowMultiples, ParserDescriptorListPtr PDList, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01512         {
01513             Rational Zero(0,0);
01514             return ListWrappingOptions(AllowMultiples, PDList, Zero, ForceWrap);
01515         }
01516 
01518         EssenceParser::WrappingConfigList ListWrappingOptions(ParserDescriptorListPtr PDList, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01519         {
01520             Rational Zero(0,0);
01521             return ListWrappingOptions(false, PDList, Zero, ForceWrap);
01522         }
01523 
01525         EssenceParser::WrappingConfigList ListWrappingOptions(bool AllowMultiples, ParserDescriptorListPtr PDList, Rational ForceEditRate, WrappingOption::WrapType ForceWrap = WrappingOption::None);
01526 
01528         EssenceParser::WrappingConfigList ListWrappingOptions(ParserDescriptorListPtr PDList, Rational ForceEditRate, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01529         {
01530             return ListWrappingOptions(false, PDList, ForceEditRate, ForceWrap);
01531         }
01532 
01534         EssenceParser::WrappingConfigPtr SelectWrappingOption(ParserDescriptorListPtr PDList, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01535         {
01536             Rational Zero(0,0);
01537             return SelectWrappingOption(false, PDList, Zero, ForceWrap);
01538         }
01539 
01541         EssenceParser::WrappingConfigPtr SelectWrappingOption(ParserDescriptorListPtr PDList, Rational ForceEditRate, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01542         {
01543             return SelectWrappingOption(false, PDList, ForceEditRate, ForceWrap);
01544         }
01545 
01547         EssenceParser::WrappingConfigPtr SelectWrappingOption(bool AllowMultiples, ParserDescriptorListPtr PDList, WrappingOption::WrapType ForceWrap = WrappingOption::None)
01548         {
01549             Rational Zero(0,0);
01550             return SelectWrappingOption(AllowMultiples, PDList, Zero, ForceWrap);
01551         }
01552 
01554         EssenceParser::WrappingConfigPtr SelectWrappingOption(bool AllowMultiples, ParserDescriptorListPtr PDList, Rational ForceEditRate, WrappingOption::WrapType ForceWrap = WrappingOption::None);
01555 
01557         void SelectWrappingOption(EssenceParser::WrappingConfigPtr Config);
01558 
01560 
01562         void Use(UInt32 Stream, WrappingOptionPtr &UseWrapping);
01563 
01565         EssenceSourcePtr GetEssenceSource(UInt32 Stream);
01566 
01568         EssenceSourcePtr GetSubSource(UInt32 Stream);
01569 
01571 
01574         bool OpenFile(void)
01575         {
01576             CurrentFile = FileOpenRead(CurrentFileName.c_str());
01577             CurrentFileOpen = FileValid(CurrentFile);
01578             return CurrentFileOpen;
01579         }
01580 
01582 
01583         void CloseFile(void)
01584         {
01585             if(CurrentFileOpen) FileClose(CurrentFile);
01586             CurrentFileOpen = false;
01587         }
01588 
01590 
01591         bool IsFileOpen(void) { return CurrentFileOpen; }
01592 
01593     protected:
01595 
01597         bool GetFirstSource(void);
01598 
01600 
01602         bool GetNextSource(void);
01603 
01605         class SequentialEssenceSource : public EssenceSource
01606         {
01607         protected:
01608             EssenceSourcePtr CurrentSource;             
01609             FileParserPtr Outer;                        
01610             Length PreviousLength;                      
01611             
01613             typedef std::pair<std::string, Int64> OptionPair;
01614             
01616             std::list<OptionPair> OptionList;
01617 
01619             SequentialEssenceSource();
01620 
01621         public:
01623             SequentialEssenceSource(FileParser *Outer) : Outer(Outer), PreviousLength(0) {}
01624 
01626             void SetSource(EssenceSourcePtr NewSource) 
01627             { 
01628                 CurrentSource = NewSource;
01629 
01630                 // Set all options
01631                 std::list<OptionPair>::iterator it = OptionList.begin();
01632                 while(it != OptionList.end())
01633                 {
01634                     NewSource->SetOption((*it).first, (*it).second);
01635                     it++;
01636                 }
01637 
01638                 // Set the index manager
01639                 if(IndexMan) NewSource->SetIndexManager(IndexMan, IndexStreamID);
01640             }
01641 
01643             virtual size_t GetEssenceDataSize(void) 
01644             { 
01645                 if(!ValidSource()) return 0;
01646 
01647                 // If we have emptied all files then exit now
01648                 if(Outer->AtEOF) return 0;
01649 
01650                 size_t Ret = CurrentSource->GetEssenceDataSize();
01651 
01652                 // If no more data move to the next source file
01653                 if(!Ret)
01654                 {
01655                     // Work out how much was read from this file
01656                     Length CurrentSize = (Length)CurrentSource->GetCurrentPosition();
01657 
01658                     if(Outer->GetNextSource())
01659                     {
01660                         // Add this length to the previous lengths
01661                         PreviousLength += CurrentSize;
01662 
01663                         return GetEssenceDataSize();
01664                     }
01665                 }
01666 
01667                 // Return the source size
01668                 return Ret;
01669             }
01670 
01672             virtual DataChunkPtr GetEssenceData(size_t Size = 0, size_t MaxSize = 0);
01673 
01675             virtual bool EndOfItem(void) { if(ValidSource()) return CurrentSource->EndOfItem(); else return true; }
01676 
01678             virtual bool EndOfData(void) { if(ValidSource()) return CurrentSource->EndOfItem(); else return true; }
01679 
01681             virtual UInt8 GetGCEssenceType(void) { if(ValidSource()) return CurrentSource->GetGCEssenceType(); else return 0; }
01682 
01684             virtual UInt8 GetGCElementType(void) { if(ValidSource()) return CurrentSource->GetGCElementType(); else return 0; }
01685 
01687             virtual bool IsEditPoint(void) { if(ValidSource()) return CurrentSource->IsEditPoint(); else return true; }
01688 
01690             virtual Rational GetEditRate(void) { if(ValidSource()) return CurrentSource->GetEditRate(); else return Rational(0,0); }
01691 
01693             virtual Position GetCurrentPosition(void)
01694             { 
01695                 if(!ValidSource()) return 0;
01696 
01697                 return CurrentSource->GetCurrentPosition() + (Position)PreviousLength;
01698             }
01699 
01701             virtual int GetBERSize(void) 
01702             { 
01703                 if(!ValidSource()) return 0;
01704 
01705                 return CurrentSource->GetBERSize();
01706             }
01707 
01709             virtual bool SetOption(std::string Option, Int64 Param = 0) 
01710             { 
01711                 if(!ValidSource()) return false;
01712 
01713                 // Record this option to allow us to reconfigure sources if we switch source
01714                 OptionList.push_back(OptionPair(Option, Param));
01715 
01716                 return CurrentSource->SetOption(Option, Param);
01717             }
01718 
01720             virtual UInt32 GetBytesPerEditUnit(UInt32 KAGSize = 1) { if(ValidSource()) return CurrentSource->GetBytesPerEditUnit(KAGSize); else return 0; }
01721 
01723             virtual bool CanIndex() { if(ValidSource()) return CurrentSource->CanIndex(); else return false; }
01724 
01726             virtual void SetIndexManager(IndexManagerPtr &Manager, int StreamID) 
01727             { 
01728                 IndexMan = Manager;
01729                 IndexStreamID = StreamID;
01730 
01731                 if(ValidSource()) CurrentSource->SetIndexManager(Manager, StreamID); 
01732             }
01733 
01735             virtual IndexManagerPtr &GetIndexManager(void) { return IndexMan; }
01736 
01738             virtual int GetIndexStreamID(void) { return IndexStreamID; }
01739 
01741 
01743             virtual Length GetPrechargeSize(void) 
01744             { 
01745                 if(!ValidSource()) return 0;
01746 
01747                 return CurrentSource->GetPrechargeSize();
01748             }
01749 
01751             virtual Position GetRangeStart(void) { return Outer->GetRangeStart(); }
01752 
01754             virtual Position GetRangeEnd(void) { return Outer->GetRangeEnd(); }
01755 
01757             virtual Length GetRangeDuration(void) { return Outer->GetRangeDuration(); }
01758 
01759 
01760         protected:
01762 
01764             bool ValidSource(void)
01765             {
01766                 if(CurrentSource) return true;
01767 
01768                 // If this is the first time through when we will have a file open but no source set to get current not text source
01769                 if(Outer->CurrentFileOpen) return Outer->GetFirstSource(); 
01770                 
01771                 return Outer->GetNextSource();
01772             }
01773 
01774             // Allow the parser to access our internals
01775             friend class FileParser;
01776         };
01777         
01778         // Allow our protected member to access our internals
01779         friend class SequentialEssenceSource;
01780     };
01781 }
01782 
01783 
01784 
01785 // GCReader and associated structures
01786 namespace mxflib
01787 {
01789 
01791     class GCReadHandler_Base : public RefCount<GCReadHandler_Base>
01792     {
01793     public:
01795         virtual ~GCReadHandler_Base() {};
01796 
01798 
01800         virtual bool HandleData(GCReaderPtr Caller, KLVObjectPtr Object) = 0;
01801     };
01802 
01803     // Smart pointer for the base GCReader read handler
01804     typedef SmartPtr<GCReadHandler_Base> GCReadHandlerPtr;
01805 
01807     class GCReader : public RefCount<GCReader>
01808     {
01809     protected:
01810         MXFFilePtr File;                                
01811         Position FileOffset;                            
01812         Position StreamOffset;                          
01813 
01814         bool StopNow;                                   
01815         bool StopCalled;                                
01816         bool PushBackRequested;                         
01817 
01818         GCReadHandlerPtr DefaultHandler;                
01819         GCReadHandlerPtr FillerHandler;                 
01820         GCReadHandlerPtr EncryptionHandler;             
01821 
01822         std::map<UInt32, GCReadHandlerPtr> Handlers;    
01823 
01824     public:
01826 
01829         GCReader( MXFFilePtr File, GCReadHandlerPtr DefaultHandler = NULL, GCReadHandlerPtr FillerHandler = NULL );
01830 
01832 
01836         void SetDefaultHandler(GCReadHandlerPtr DefaultHandler = NULL)
01837         {
01838             this->DefaultHandler = DefaultHandler;
01839         }
01840 
01842 
01846         void SetFillerHandler(GCReadHandlerPtr FillerHandler = NULL)
01847         {
01848             this->FillerHandler = FillerHandler;
01849         }
01850 
01852 
01855         void SetEncryptionHandler(GCReadHandlerPtr EncryptionHandler = NULL)
01856         {
01857             this->EncryptionHandler = EncryptionHandler;
01858         }
01859 
01861         void SetDataHandler(UInt32 TrackNumber, GCReadHandlerPtr DataHandler = NULL)
01862         {
01863             if(DataHandler)
01864             {
01865                 Handlers[TrackNumber] = DataHandler;
01866             }
01867             else
01868             {
01869                 Handlers.erase(TrackNumber);
01870             }
01871         }
01872 
01874 
01881         bool ReadFromFile(Position FilePos, Position StreamPos, bool SingleKLV = false)
01882         {
01883             FileOffset = FilePos;                   // Record the file location
01884             StreamOffset = StreamPos;               // Record the stream location
01885 
01886             return ReadFromFile(SingleKLV);         // Then do a "continue" read
01887         }
01888 
01890 
01894         bool ReadFromFile(bool SingleKLV = false);
01895 
01897 
01901         void SetStreamOffset(Position NewOffset) 
01902         { 
01903             StreamOffset = NewOffset; 
01904         };
01905 
01907 
01910         Position GetFileOffset(void) { return FileOffset; }
01911 
01912 
01913         /*** Functions for use by read handlers ***/
01914 
01916 
01920         bool HandleData(KLVObjectPtr Object);
01921 
01923 
01927         void StopReading(bool PushBackKLV = false);
01928 
01930         Position GetStreamOffset(void) { return StreamOffset; };
01931     };
01932 }
01933 
01934 
01935 // BodyReader and associated structures
01936 namespace mxflib
01937 {
01939     class BodyReader : public RefCount<BodyReader>
01940     {
01941     protected:
01942         MXFFilePtr File;                        
01943         Position CurrentPos;                    
01944 
01945         bool NewPos;                            
01946         bool SeekInited;                        
01947         bool AtPartition;                       
01948         bool AtEOF;                             
01949 
01950         UInt32 CurrentBodySID;                  
01951         
01952         GCReadHandlerPtr GCRDefaultHandler;     
01953         GCReadHandlerPtr GCRFillerHandler;      
01954         GCReadHandlerPtr GCREncryptionHandler;  
01955 
01956         std::map<UInt32, GCReaderPtr> Readers;  
01957 
01958     public:
01960         BodyReader(MXFFilePtr File);
01961 
01963 
01965         Position Seek(Position Pos = 0);
01966 
01968         Position Tell(void) { return CurrentPos; };
01969 
01971 
01973         Position Seek(UInt32 BodySID, Position Pos);
01974 
01976 
01978         Position Tell(UInt32 BodySID);
01979 
01981 
01983         void SetDefaultHandler(GCReadHandlerPtr DefaultHandler = NULL) { GCRDefaultHandler = DefaultHandler; };
01984 
01986 
01988         void SetFillerHandler(GCReadHandlerPtr FillerHandler = NULL) { GCRFillerHandler = FillerHandler; };
01989 
01991 
01993         void SetEncryptionHandler(GCReadHandlerPtr EncryptionHandler = NULL) { GCREncryptionHandler = EncryptionHandler; };
01994 
01996 
01998         bool MakeGCReader(UInt32 BodySID, GCReadHandlerPtr DefaultHandler = NULL, GCReadHandlerPtr FillerHandler = NULL);
01999 
02001         GCReaderPtr GetGCReader(UInt32 BodySID)
02002         {
02003             // See if we have a GCReader for this BodySID
02004             std::map<UInt32, GCReaderPtr>::iterator it = Readers.find(BodySID);
02005 
02006             // If not found return NULL
02007             if(it == Readers.end()) return NULL;
02008 
02009             // Return the pointer
02010             return (*it).second;
02011         }
02012 
02014 
02019         bool ReadFromFile(bool SingleKLV = false);
02020 
02022 
02025         bool ReSync();
02026 
02028         bool IsAtPartition(void);
02029 
02031         bool Eof(void);
02032 
02033 
02034         /*** Functions for use by read handlers ***/
02035 
02037         UInt32 GetBodySID(void) { return CurrentBodySID; }
02038 
02039 
02040     protected:
02042 
02046         bool InitSeek(void);
02047     };
02048 
02050     typedef SmartPtr<BodyReader> BodyReaderPtr;
02051 }
02052 
02053 
02054 //*********************************************
02055 //**                                         **
02056 //**        General essence functions        **
02057 //**                                         **
02058 //*********************************************
02059 
02060 namespace mxflib
02061 {
02063     struct GCElementKind
02064     {
02065         bool    IsValid;                    
02066         UInt8   Item;                       
02067         UInt8   Count;                      
02068         UInt8   ElementType;                
02069         UInt8   Number;                     
02070     };
02071 
02073 
02076     void RegisterGCElementKey(DataChunkPtr &Key);
02077 
02079     GCElementKind GetGCElementKind(ULPtr TheUL);
02080 
02082 
02084     UInt32 GetGCTrackNumber(ULPtr TheUL);
02085 }
02086 
02087 
02088 /* BodyWriter and related classes */
02089 
02090 namespace mxflib
02091 {
02093 
02097     class BodyStream : public RefCount<BodyStream>, public EssenceSourceList
02098     {
02099     public:
02101         enum StateType
02102         {
02103             BodyStreamStart = 0,                                    
02104             BodyStreamHeadIndex,                                    
02105             BodyStreamPreBodyIndex,                                 
02106             BodyStreamBodyWithIndex,                                
02107             BodyStreamBodyNoIndex,                                  
02108             BodyStreamPostBodyIndex,                                
02109             BodyStreamFootIndex,                                    
02110             BodyStreamDone                                          
02111         };
02112 
02114         enum IndexType
02115         {
02116             StreamIndexNone = 0,                                    
02117             StreamIndexFullFooter = 1,                              
02118             StreamIndexSparseFooter = 2,                            
02119             StreamIndexSprinkled = 4,                               
02120             StreamIndexSprinkledIsolated = 8,                       
02121             StreamIndexCBRHeader = 16,                              
02122             StreamIndexCBRHeaderIsolated = 32,                      
02123             StreamIndexCBRFooter = 64,                              
02124             StreamIndexCBRBody = 128,                               
02125             StreamIndexCBRIsolated = 256,                           
02126             StreamIndexCBRPreIsolated = 512                         
02127         };
02128 
02130         enum WrapType
02131         {
02132             StreamWrapOther = 0,                                    
02133             StreamWrapFrame,                                        
02134             StreamWrapClip                                          
02135         };
02136 
02137     protected:
02138         EssenceSourcePtr Source;                                    
02139         EssenceSourceList SubStreams;                               
02140         EssenceSourceList::iterator SubStream_it;                   
02141         bool SubStreamRestart;                                      
02142 
02143         StateType State;                                            
02144 
02145         IndexType StreamIndex;                                      
02146         IndexType FooterIndexFlags;                                 
02147 
02148         UInt32 BodySID;                                             
02149         UInt32 IndexSID;                                            
02150 
02151         WrapType StreamWrap;                                        
02152 
02153         GCWriterPtr StreamWriter;                                   
02154 
02155         bool EssencePendingData;                                    
02156 
02157         bool EndOfStream;                                           
02158 
02159         IndexManagerPtr IndexMan;                                   
02160         
02161         Position NextSprinkled;                                     
02162 
02163         bool FreeSpaceIndex;                                        
02164 
02169         bool ValueRelativeIndexing;                                 
02170 
02172         Length PrechargeSize;                                       
02173 
02177 
02178         UInt32 KAG;
02179 
02181         bool ForceBER4;
02182 
02184 
02185         bool EditAlign;
02186 
02188         BodyStream();
02189 
02191         BodyStream(BodyStream &);
02192 
02193     /* Public properties */
02194     public:
02195         std::list<Position> SparseList;                             
02196 
02197     public:
02199         BodyStream(UInt32 SID, EssenceSourcePtr &EssSource, DataChunkPtr Key = NULL, bool NonGC = false)
02200         {
02201             BodySID = SID;
02202             IndexSID = 0;
02203             Source = EssSource;
02204             State = BodyStreamStart;
02205             StreamIndex = StreamIndexNone;
02206             FooterIndexFlags = StreamIndexNone;
02207             StreamWrap = StreamWrapOther;
02208             SubStreamRestart = true;
02209             NextSprinkled = 0;
02210             EssencePendingData = false;
02211             EndOfStream = false;
02212             FreeSpaceIndex = false;
02213             ValueRelativeIndexing = false;
02214             PrechargeSize = 0;
02215 
02216             KAG = 0;
02217             ForceBER4 = false;
02218             EditAlign = false;
02219 
02220             // Set the non-standard key if requested
02221             if(Key) EssSource->SetKey(Key, NonGC);
02222 
02223             // Set the master stream as one of the essence streams
02224             push_back(Source);
02225         }
02226 
02228         EssenceSourcePtr &GetSource(void) { return Source; }
02229 
02231         size_type SubStreamCount(void) { return size(); }
02232 
02234         void AddSubStream(EssenceSourcePtr &SubSource, DataChunkPtr Key = NULL, bool NonGC = false);
02235 
02237         UInt32 GetBodySID(void) { return BodySID; }
02238 
02240         void SetIndexSID(UInt32 SID) { IndexSID = SID; }
02241 
02243         UInt32 GetIndexSID(void) { return IndexSID; }
02244 
02246         void SetState(StateType NewState) { State = NewState; }
02247 
02249         StateType GetState(void) 
02250         {
02251             if(State == BodyStreamStart) GetNextState();
02252             return State;
02253         }
02254 
02256 
02259         StateType GetNextState(void);
02260 
02262         void AddIndexType(IndexType NewIndexType) { StreamIndex = (IndexType) (StreamIndex | NewIndexType); }
02263 
02265 
02267         void SetIndexType(IndexType NewIndexType) { StreamIndex = NewIndexType; }
02268 
02270         IndexType GetIndexType(void) { return StreamIndex; }
02271 
02273 
02275         void SetFooterIndex(IndexType NewIndexType) { FooterIndexFlags = NewIndexType; }
02276 
02278         IndexType GetFooterIndex(void) { return FooterIndexFlags; }
02279 
02281         void SetWrapType(WrapType NewWrapType) { StreamWrap = NewWrapType; }
02282 
02284         void SetWrapType(WrappingOption::WrapType NewWrapType) 
02285         { 
02286             if(NewWrapType == WrappingOption::Frame) StreamWrap = StreamWrapFrame; 
02287             else if(NewWrapType == WrappingOption::Clip) StreamWrap = StreamWrapClip; 
02288             else StreamWrap = StreamWrapOther;
02289         }
02290 
02292         WrapType GetWrapType(void) { return StreamWrap; }
02293 
02295         void SetWriter(GCWriterPtr &Writer);
02296 
02298         IndexManagerPtr &GetIndexManager(void) 
02299         { 
02300             if(!IndexMan) InitIndexManager();
02301             return IndexMan; 
02302         }
02303 
02305         GCWriterPtr &GetWriter(void) { return StreamWriter; }
02306 
02308         UInt32 GetTrackNumber(void) 
02309         { 
02310             if(!Source) return 0;
02311             return StreamWriter->GetTrackNumber(Source->GetStreamID());
02312         }
02313 
02315         Uint32 GetTrackNumber(GCStreamID ID)
02316         { 
02317             if(!Source) return 0;
02318             return StreamWriter->GetTrackNumber(ID);
02319         }
02320 
02322         void SetPendingData(bool Value = true) { EssencePendingData = Value; }
02323 
02325         bool HasPendingData(void) { return EssencePendingData; }
02326         
02328         void SetEndOfStream(bool Value = true) { EndOfStream = Value; }
02329 
02331         bool GetEndOfStream(void) { return EndOfStream; }
02332         
02334         void SetNextSprinkled(Position Sprinkled) { NextSprinkled = Sprinkled; }
02335 
02337         Position GetNextSprinkled(void) { return NextSprinkled; }
02338 
02340         // FIXME: This will break CBR indexing if changed during writing!
02341         void SetKAG(UInt32 NewKAG) { KAG = NewKAG; }
02342 
02344         UInt32 GetKAG(void) { return KAG; }
02345 
02347         void SetForceBER4(bool Force) { ForceBER4 = Force; }
02348 
02350         bool GetForceBER4(void) { return ForceBER4; }
02351 
02353         void SetEditAlign(bool Align) { EditAlign = Align; }
02354 
02356         bool GetEditAlign(void) { return EditAlign; }
02357 
02359 
02360         void SetFreeSpaceIndex(bool Flag) { FreeSpaceIndex = Flag; }
02361 
02363         bool GetFreeSpaceIndex(void) { return FreeSpaceIndex; }
02364 
02366 
02369         void SetValueRelativeIndexing(bool Val) 
02370         { 
02371             ValueRelativeIndexing = Val; 
02372             if(IndexMan) IndexMan->SetValueRelativeIndexing(Val);
02373         }
02374 
02376 
02379         bool GetValueRelativeIndexing(void) { return ValueRelativeIndexing; }
02380 
02382         Length GetPrechargeSize(void) const { return PrechargeSize; }
02383 
02385         void DecrementPrecharge(void) { if(PrechargeSize) PrechargeSize--; }
02386 
02388         void InitIndexManager(void);
02389     };
02390 
02392     typedef SmartPtr<BodyStream> BodyStreamPtr;
02393 
02395     typedef std::list<BodyStreamPtr> BodyStreamList;
02396 
02397     // Forward declare BodyWriterPtr to allow it to be used in BodyWriterHandler
02398     class BodyWriter;
02399     typedef SmartPtr<BodyWriter> BodyWriterPtr;
02400 
02402     class BodyWriterHandler : public RefCount<BodyWriterHandler>
02403     {
02404     public:
02406         virtual ~BodyWriterHandler();
02407 
02409 
02417         virtual bool HandlePartition(BodyWriterPtr Caller, UInt32 BodySID, UInt32 IndexSID) = 0;
02418     };
02419 
02421     typedef SmartPtr<BodyWriterHandler> BodyWriterHandlerPtr;
02422 
02423 
02425     class BodyWriter : public RefCount<BodyWriter>
02426     {
02427     protected:
02428         // States for BodyWriter
02429         enum BodyState
02430         {
02431             BodyStateStart = 0,                                     
02432             BodyStateHeader,                                        
02433             BodyStateBody,                                          
02434             BodyStateFooter,                                        
02435             BodyStateDone                                           
02436         };
02437 
02439         BodyState State;
02440 
02442 
02448         class StreamInfo : public RefCount<StreamInfo>
02449         {
02450         public:
02451             bool Active;                                            
02452             BodyStreamPtr Stream;                                   
02453             Length StopAfter;                                       
02454 
02455         public:
02457             StreamInfo() { Active = false; }
02458 
02460             StreamInfo(const StreamInfo &rhs)
02461             {
02462                 Active = rhs.Active;
02463                 Stream = rhs.Stream;
02464                 StopAfter = rhs.StopAfter;
02465             }
02466         };
02467 
02469         typedef SmartPtr<StreamInfo> StreamInfoPtr;
02470 
02472 
02474         typedef std::list<StreamInfoPtr> StreamInfoList;
02475 
02477         MXFFilePtr File;
02478 
02480         StreamInfoList StreamList;
02481 
02483         UInt32 KAG;
02484 
02486         bool ForceBER4;
02487 
02489         PartitionPtr BasePartition;
02490 
02491         BodyWriterHandlerPtr PartitionHandler;                  
02492 
02493         UInt32 MinPartitionSize;                                
02494         UInt32 MinPartitionFiller;                              
02495 
02496         bool IndexSharesWithMetadata;                           
02497         bool EssenceSharesWithMetadata;                         
02498 
02500         UInt32 CurrentBodySID;
02501 
02503         bool PartitionDone;
02504 
02506         StreamInfoList::iterator CurrentStream;
02507 
02508 
02509         /* Details about the pending partition, set but not yet written
02510          * This is because the value of BodySID depends on whether any
02511          * essence is going to be written in this partition which won't
02512          * be known for certain until we are about to write the essence
02513          */
02514 
02516         bool PartitionWritePending;
02517 
02519         bool PendingHeader;
02520 
02522         bool PendingFooter;
02523 
02525         bool PendingMetadata;
02526 
02528         DataChunkPtr PendingIndexData;
02529 
02531 
02534         UInt32 PartitionBodySID;
02535 
02537         BodyWriter();
02538 
02540         BodyWriter(BodyWriter &);
02541 
02542     public:
02544         BodyWriter(MXFFilePtr &DestFile)
02545         {
02546             State = BodyStateStart;
02547             CurrentBodySID = 0;
02548             PartitionDone = false;
02549 
02550             File = DestFile;
02551 
02552             // By default index tables may share with metadata, but not essence
02553             IndexSharesWithMetadata = true;
02554             EssenceSharesWithMetadata = false;
02555 
02556             KAG = 0;
02557             ForceBER4 = false;
02558 
02559             MinPartitionSize = 0;
02560             MinPartitionFiller = 0;
02561 
02562             PartitionWritePending = false;
02563             PendingHeader = 0;
02564             PendingFooter = 0;
02565             PendingMetadata = false;
02566             PartitionBodySID = 0;
02567         }
02568 
02570 
02572         void ClearStreams(void) { StreamList.clear(); CurrentBodySID = 0; }
02573 
02575 
02580         bool AddStream(BodyStreamPtr &Stream, Length StopAfter = 0);
02581 
02583         void SetKAG(UInt32 NewKAG) 
02584         { 
02585             // TODO: This is probably not the best way - but is the only way to currently ensure correct CBR indexing!
02586             if(StreamList.size()) warning("KAG size changed after adding streams - CBR indexing may be incorrect\n");
02587             KAG = NewKAG; 
02588         }
02589 
02591         UInt32 GetKAG(void) { return KAG; }
02592 
02594         void SetForceBER4(bool Force) { ForceBER4 = Force; }
02595 
02597         bool GetForceBER4(void) { return ForceBER4; }
02598 
02600         void SetMetadataSharing(bool IndexMayShare = true, bool EssenceMayShare = false)
02601         {
02602             IndexSharesWithMetadata = IndexMayShare;
02603             EssenceSharesWithMetadata = EssenceMayShare;
02604         }
02605 
02607 
02612         void SetPartition(PartitionPtr &ThePartition) { BasePartition = ThePartition; }
02613 
02615         PartitionPtr GetPartition(void) { return BasePartition; }
02616 
02618 
02622         void WriteHeader(bool IsClosed, bool IsComplete);
02623 
02625 
02629         void EndPartition(void);
02630 
02632 
02636         void WriteBody(Length Duration = 0, Length MaxPartitionSize = 0);
02637 
02639 
02641         Length WritePartition(Length Duration = 0, Length MaxPartitionSize = 0);
02642 
02644 
02646         bool BodyDone(void) { return (State == BodyStateFooter) || (State == BodyStateDone); }
02647 
02649 
02651         void WriteFooter(bool WriteMetadata = false, bool IsComplete = true);
02652 
02654 
02656         void SetPartitionHandler(BodyWriterHandlerPtr &NewBodyHandler) { PartitionHandler = NewBodyHandler; }
02657 
02659 
02668         void SetPartitionSize(UInt32 PartitionSize) { MinPartitionSize = PartitionSize; }
02669 
02671 
02680         void SetPartitionFiller(UInt32 PartitionFiller) { MinPartitionFiller = PartitionFiller; }
02681 
02683         void InitIndexManagers(void);
02684 
02685     protected:
02687 
02689         void SetNextStream(void);
02690 
02692 
02696         Length WriteEssence(StreamInfoPtr &Info, Length Duration = 0, Length MaxPartitionSize = 0);
02697     };
02698 
02700     typedef SmartPtr<BodyWriter> BodyWriterPtr;
02701 }
02702 
02703 #endif // MXFLIB__ESSENCE_H

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