-/****************************************************************************\r
-** libmatroska : parse Matroska files, see http://www.matroska.org/\r
-**\r
-** <file/class description>\r
-**\r
-** Copyright (C) 2002-2010 Steve Lhomme. All rights reserved.\r
-**\r
-** This library is free software; you can redistribute it and/or\r
-** modify it under the terms of the GNU Lesser General Public\r
-** License as published by the Free Software Foundation; either\r
-** version 2.1 of the License, or (at your option) any later version.\r
-** \r
-** This library is distributed in the hope that it will be useful,\r
-** but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
-** Lesser General Public License for more details.\r
-** \r
-** You should have received a copy of the GNU Lesser General Public\r
-** License along with this library; if not, write to the Free Software\r
-** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
-**\r
-** See http://www.matroska.org/license/lgpl/ for LGPL licensing information.**\r
-** Contact license@matroska.org if any conditions of this licensing are\r
-** not clear to you.\r
-**\r
-**********************************************************************/\r
-\r
-/*!\r
- \file\r
- \todo add a PureBlock class to group functionalities between Block and BlockVirtual\r
- \version \$Id: KaxBlock.h,v 1.24 2004/04/14 23:26:17 robux4 Exp $\r
- \author Steve Lhomme <robux4 @ users.sf.net>\r
- \author Julien Coloos <suiryc @ users.sf.net>\r
-*/\r
-#ifndef LIBMATROSKA_BLOCK_H\r
-#define LIBMATROSKA_BLOCK_H\r
-\r
-#include <vector>\r
-\r
-#include "matroska/KaxTypes.h"\r
-#include "ebml/EbmlBinary.h"\r
-#include "ebml/EbmlMaster.h"\r
-#include "matroska/KaxTracks.h"\r
-\r
-using namespace LIBEBML_NAMESPACE;\r
-\r
-START_LIBMATROSKA_NAMESPACE\r
-\r
-class KaxCluster;\r
-class KaxReferenceBlock;\r
-class KaxInternalBlock;\r
-class KaxBlockBlob;\r
-\r
-class MATROSKA_DLL_API DataBuffer {\r
- protected:\r
- binary * myBuffer;\r
- uint32 mySize;\r
- bool bValidValue;\r
- bool (*myFreeBuffer)(const DataBuffer & aBuffer); // method to free the internal buffer\r
-\r
- public:\r
- DataBuffer(binary * aBuffer, uint32 aSize, bool (*aFreeBuffer)(const DataBuffer & aBuffer) = NULL)\r
- :myBuffer(aBuffer)\r
- ,mySize(aSize)\r
- ,bValidValue(true) \r
- ,myFreeBuffer(aFreeBuffer)\r
- {}\r
- virtual ~DataBuffer() {}\r
- virtual binary * Buffer() {return myBuffer;}\r
- virtual uint32 & Size() {return mySize;};\r
- virtual const binary * Buffer() const {return myBuffer;}\r
- virtual const uint32 Size() const {return mySize;};\r
- bool FreeBuffer(const DataBuffer & aBuffer) {\r
- bool bResult = true;\r
- if (myBuffer != NULL && myFreeBuffer != NULL && bValidValue) {\r
- bResult = myFreeBuffer(aBuffer);\r
- myBuffer = NULL;\r
- bValidValue = false;\r
- }\r
- return bResult;\r
- }\r
-\r
- virtual DataBuffer * Clone();\r
-};\r
-\r
-class MATROSKA_DLL_API SimpleDataBuffer : public DataBuffer {\r
- public:\r
- SimpleDataBuffer(binary * aBuffer, uint32 aSize, uint32 aOffset, bool (*aFreeBuffer)(const DataBuffer & aBuffer) = myFreeBuffer)\r
- :DataBuffer(aBuffer + aOffset, aSize, aFreeBuffer)\r
- ,Offset(aOffset)\r
- ,BaseBuffer(aBuffer)\r
- {}\r
- virtual ~SimpleDataBuffer() {}\r
-\r
- DataBuffer * Clone() {return new SimpleDataBuffer(*this);}\r
-\r
- protected:\r
- uint32 Offset;\r
- binary * BaseBuffer;\r
-\r
- static bool myFreeBuffer(const DataBuffer & aBuffer)\r
- {\r
- binary *_Buffer = static_cast<const SimpleDataBuffer*>(&aBuffer)->BaseBuffer;\r
- if (_Buffer != NULL)\r
- free(_Buffer);\r
- return true;\r
- }\r
-\r
- SimpleDataBuffer(const SimpleDataBuffer & ToClone);\r
-};\r
-\r
-/*!\r
- \note the data is copied locally, it can be freed right away\r
-* /\r
-class MATROSKA_DLL_API NotSoSimpleDataBuffer : public SimpleDataBuffer {\r
- public:\r
- NotSoSimpleDataBuffer(binary * aBuffer, uint32 aSize, uint32 aOffset)\r
- :SimpleDataBuffer(new binary[aSize - aOffset], aSize, 0)\r
- {\r
- memcpy(BaseBuffer, aBuffer + aOffset, aSize - aOffset);\r
- }\r
-};\r
-*/\r
-\r
-class MATROSKA_DLL_API KaxBlockGroup : public EbmlMaster {\r
- public:\r
- KaxBlockGroup();\r
- KaxBlockGroup(const KaxBlockGroup & ElementToClone) :EbmlMaster(ElementToClone) {}\r
-\r
- ~KaxBlockGroup();\r
-\r
- /*!\r
- \brief Addition of a frame without references\r
- */\r
- bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing = LACING_AUTO);\r
- /*!\r
- \brief Addition of a frame with a backward reference (P frame)\r
- */\r
- bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, const KaxBlockGroup & PastBlock, LacingType lacing = LACING_AUTO);\r
-\r
- /*!\r
- \brief Addition of a frame with a backward+forward reference (B frame)\r
- */\r
- bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, const KaxBlockGroup & PastBlock, const KaxBlockGroup & ForwBlock, LacingType lacing = LACING_AUTO);\r
- bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, const KaxBlockBlob * PastBlock, const KaxBlockBlob * ForwBlock, LacingType lacing = LACING_AUTO);\r
-\r
- void SetParent(KaxCluster & aParentCluster);\r
-\r
- void SetParentTrack(const KaxTrackEntry & aParentTrack) {\r
- ParentTrack = &aParentTrack;\r
- }\r
-\r
- /*!\r
- \brief Set the duration of the contained frame(s) (for the total number of frames)\r
- */\r
- void SetBlockDuration(uint64 TimeLength);\r
- bool GetBlockDuration(uint64 &TheTimecode) const;\r
-\r
- /*!\r
- \return the global timecode of this Block (not just the delta to the Cluster)\r
- */\r
- uint64 GlobalTimecode() const;\r
- uint64 GlobalTimecodeScale() const {\r
- assert(ParentTrack != NULL);\r
- return ParentTrack->GlobalTimecodeScale();\r
- }\r
-\r
- uint16 TrackNumber() const;\r
-\r
- uint64 ClusterPosition() const;\r
- \r
- /*!\r
- \return the number of references to other frames\r
- */\r
- unsigned int ReferenceCount() const;\r
- const KaxReferenceBlock & Reference(unsigned int Index) const;\r
-\r
- /*!\r
- \brief release all the frames of all Blocks\r
- */\r
- void ReleaseFrames();\r
-\r
- operator KaxInternalBlock &();\r
-\r
- const KaxCluster *GetParentCluster() const { return ParentCluster; }\r
-\r
- protected:\r
- KaxCluster * ParentCluster;\r
- const KaxTrackEntry * ParentTrack;\r
- \r
- EBML_CONCRETE_CLASS(KaxBlockGroup)\r
-};\r
-\r
-class KaxInternalBlock : public EbmlBinary {\r
- public:\r
- KaxInternalBlock( bool bSimple ) :bLocalTimecodeUsed(false), mLacing(LACING_AUTO), mInvisible(false)\r
- ,ParentCluster(NULL), bIsSimple(bSimple), bIsKeyframe(true), bIsDiscardable(false)\r
- {}\r
- KaxInternalBlock(const KaxInternalBlock & ElementToClone);\r
- ~KaxInternalBlock();\r
- bool ValidateSize() const;\r
-\r
- uint16 TrackNum() const {return TrackNumber;}\r
- /*!\r
- \todo !!!! This method needs to be changes !\r
- */\r
- uint64 GlobalTimecode() const {return Timecode;}\r
-\r
- /*!\r
- \note override this function to generate the Data/Size on the fly, unlike the usual binary elements\r
- */\r
- filepos_t UpdateSize(bool bSaveDefault = false, bool bForceRender = false);\r
- filepos_t ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA);\r
- \r
- /*!\r
- \brief Only read the head of the Block (not internal data)\r
- \note convenient when you are parsing the file quickly\r
- */\r
- uint64 ReadInternalHead(IOCallback & input);\r
- \r
- unsigned int NumberFrames() const { return SizeList.size();}\r
- DataBuffer & GetBuffer(unsigned int iIndex) {return *myBuffers[iIndex];}\r
-\r
- bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing = LACING_AUTO, bool invisible = false);\r
-\r
- /*!\r
- \brief release all the frames of all Blocks\r
- */\r
- void ReleaseFrames();\r
-\r
- void SetParent(KaxCluster & aParentCluster);\r
-\r
- /*!\r
- \return Returns the lacing type that produces the smallest footprint.\r
- */\r
- LacingType GetBestLacingType() const;\r
-\r
- /*!\r
- \param FrameNumber 0 for the first frame\r
- \return the position in the stream for a given frame\r
- \note return -1 if the position doesn't exist\r
- */\r
- int64 GetDataPosition(size_t FrameNumber = 0);\r
-\r
- /*!\r
- \param FrameNumber 0 for the first frame\r
- \return the size of a given frame\r
- \note return -1 if the position doesn't exist\r
- */\r
- int64 GetFrameSize(size_t FrameNumber = 0);\r
- \r
- bool IsInvisible() const { return mInvisible; }\r
-\r
- uint64 ClusterPosition() const;\r
-\r
- protected:\r
- std::vector<DataBuffer *> myBuffers;\r
- std::vector<int32> SizeList;\r
- uint64 Timecode; // temporary timecode of the first frame, non scaled\r
- int16 LocalTimecode;\r
- bool bLocalTimecodeUsed;\r
- uint16 TrackNumber;\r
- LacingType mLacing;\r
- bool mInvisible;\r
- uint64 FirstFrameLocation;\r
-\r
- filepos_t RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false);\r
-\r
- KaxCluster * ParentCluster;\r
- bool bIsSimple;\r
- bool bIsKeyframe;\r
- bool bIsDiscardable;\r
-};\r
-\r
-class MATROSKA_DLL_API KaxBlock : public KaxInternalBlock {\r
- public:\r
- KaxBlock() :KaxInternalBlock(false) {}\r
- \r
- EBML_CONCRETE_CLASS(KaxBlock)\r
-};\r
-\r
-#if MATROSKA_VERSION >= 2\r
-class MATROSKA_DLL_API KaxSimpleBlock : public KaxInternalBlock {\r
- public:\r
- KaxSimpleBlock() :KaxInternalBlock(true) {}\r
-\r
- void SetKeyframe(bool b_keyframe) { bIsKeyframe = b_keyframe; }\r
- void SetDiscardable(bool b_discard) { bIsDiscardable = b_discard; }\r
-\r
- bool IsKeyframe() const { return bIsKeyframe; }\r
- bool IsDiscardable() const { return bIsDiscardable; }\r
-\r
- operator KaxInternalBlock &() { return *this; }\r
- \r
- EBML_CONCRETE_CLASS(KaxSimpleBlock)\r
-};\r
-#endif // MATROSKA_VERSION\r
-\r
-class MATROSKA_DLL_API KaxBlockBlob {\r
-public:\r
- KaxBlockBlob(BlockBlobType sblock_mode) :ParentCluster(NULL), SimpleBlockMode(sblock_mode) {\r
- bUseSimpleBlock = (sblock_mode != BLOCK_BLOB_NO_SIMPLE);\r
- Block.group = NULL;\r
- }\r
-\r
- ~KaxBlockBlob() {\r
-#if MATROSKA_VERSION >= 2\r
- if (bUseSimpleBlock)\r
- delete Block.simpleblock;\r
- else\r
-#endif // MATROSKA_VERSION\r
- delete Block.group;\r
- }\r
-\r
- operator KaxBlockGroup &();\r
- operator const KaxBlockGroup &() const;\r
-#if MATROSKA_VERSION >= 2\r
- operator KaxSimpleBlock &();\r
-#endif\r
- operator KaxInternalBlock &();\r
- operator const KaxInternalBlock &() const;\r
-\r
- void SetBlockGroup( KaxBlockGroup &BlockRef );\r
-\r
- void SetBlockDuration(uint64 TimeLength);\r
-\r
- void SetParent(KaxCluster & aParentCluster);\r
- bool AddFrameAuto(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing = LACING_AUTO, const KaxBlockBlob * PastBlock = NULL, const KaxBlockBlob * ForwBlock = NULL);\r
-\r
- bool IsSimpleBlock() const {return bUseSimpleBlock;}\r
-\r
- bool ReplaceSimpleByGroup();\r
-protected:\r
- KaxCluster * ParentCluster;\r
- union {\r
- KaxBlockGroup *group;\r
-#if MATROSKA_VERSION >= 2\r
- KaxSimpleBlock *simpleblock;\r
-#endif // MATROSKA_VERSION\r
- } Block;\r
- bool bUseSimpleBlock;\r
- BlockBlobType SimpleBlockMode;\r
-};\r
-\r
-class MATROSKA_DLL_API KaxBlockDuration : public EbmlUInteger {\r
- public:\r
- KaxBlockDuration() {}\r
- KaxBlockDuration(const KaxBlockDuration & ElementToClone) :EbmlUInteger(ElementToClone) {}\r
- \r
- EBML_CONCRETE_CLASS(KaxBlockDuration)\r
-};\r
-\r
-#if MATROSKA_VERSION >= 2\r
-class MATROSKA_DLL_API KaxBlockVirtual : public EbmlBinary {\r
- public:\r
- KaxBlockVirtual() :ParentCluster(NULL) {SetBuffer(DataBlock,sizeof(DataBlock)); SetValueIsSet(false);}\r
- KaxBlockVirtual(const KaxBlockVirtual & ElementToClone);\r
- bool ValidateSize() const {return true;}\r
-\r
- /*!\r
- \note override this function to generate the Data/Size on the fly, unlike the usual binary elements\r
- */\r
- filepos_t UpdateSize(bool bSaveDefault = false, bool bForceRender = false);\r
-\r
- void SetParent(const KaxCluster & aParentCluster) {ParentCluster = &aParentCluster;}\r
-\r
- protected:\r
- uint64 Timecode; // temporary timecode of the first frame if there are more than one\r
- uint16 TrackNumber;\r
- binary DataBlock[5];\r
-\r
- const KaxCluster * ParentCluster;\r
- \r
- EBML_CONCRETE_CLASS(KaxBlockVirtual)\r
-};\r
-#endif // MATROSKA_VERSION\r
-\r
-class MATROSKA_DLL_API KaxBlockAdditional : public EbmlBinary {\r
- public:\r
- KaxBlockAdditional() {}\r
- KaxBlockAdditional(const KaxBlockAdditional & ElementToClone) :EbmlBinary(ElementToClone){}\r
- bool ValidateSize() const {return true;}\r
-\r
- EBML_CONCRETE_CLASS(KaxBlockAdditional)\r
-};\r
-\r
-class MATROSKA_DLL_API KaxBlockAdditions : public EbmlMaster {\r
- public:\r
- KaxBlockAdditions();\r
- KaxBlockAdditions(const KaxBlockAdditions & ElementToClone) :EbmlMaster(ElementToClone) {}\r
- \r
- EBML_CONCRETE_CLASS(KaxBlockAdditions)\r
-};\r
-\r
-class MATROSKA_DLL_API KaxBlockMore : public EbmlMaster {\r
- public:\r
- KaxBlockMore();\r
- KaxBlockMore(const KaxBlockMore & ElementToClone) :EbmlMaster(ElementToClone) {}\r
- \r
- EBML_CONCRETE_CLASS(KaxBlockMore)\r
-};\r
-\r
-class MATROSKA_DLL_API KaxBlockAddID : public EbmlUInteger {\r
- public:\r
- KaxBlockAddID() :EbmlUInteger(1) {}\r
- KaxBlockAddID(const KaxBlockAddID & ElementToClone) :EbmlUInteger(ElementToClone) {}\r
- \r
- EBML_CONCRETE_CLASS(KaxBlockAddID)\r
-};\r
-\r
-class MATROSKA_DLL_API KaxCodecState : public EbmlBinary {\r
- public:\r
- KaxCodecState() {}\r
- KaxCodecState(const KaxCodecState & ElementToClone) :EbmlBinary(ElementToClone){}\r
-\r
- bool ValidateSize() const {return true;}\r
-\r
- EBML_CONCRETE_CLASS(KaxCodecState)\r
-};\r
-\r
-END_LIBMATROSKA_NAMESPACE\r
-\r
-#endif // LIBMATROSKA_BLOCK_H\r
+/****************************************************************************
+** libmatroska : parse Matroska files, see http://www.matroska.org/
+**
+** <file/class description>
+**
+** Copyright (C) 2002-2010 Steve Lhomme. All rights reserved.
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+**
+** See http://www.matroska.org/license/lgpl/ for LGPL licensing information.**
+** Contact license@matroska.org if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+/*!
+ \file
+ \todo add a PureBlock class to group functionalities between Block and BlockVirtual
+ \version \$Id: KaxBlock.h,v 1.24 2004/04/14 23:26:17 robux4 Exp $
+ \author Steve Lhomme <robux4 @ users.sf.net>
+ \author Julien Coloos <suiryc @ users.sf.net>
+*/
+#ifndef LIBMATROSKA_BLOCK_H
+#define LIBMATROSKA_BLOCK_H
+
+#include <vector>
+
+#include "matroska/KaxTypes.h"
+#include "ebml/EbmlBinary.h"
+#include "ebml/EbmlMaster.h"
+#include "matroska/KaxTracks.h"
+
+using namespace LIBEBML_NAMESPACE;
+
+START_LIBMATROSKA_NAMESPACE
+
+class KaxCluster;
+class KaxReferenceBlock;
+class KaxInternalBlock;
+class KaxBlockBlob;
+
+class MATROSKA_DLL_API DataBuffer {
+ protected:
+ binary * myBuffer;
+ uint32 mySize;
+ bool bValidValue;
+ bool (*myFreeBuffer)(const DataBuffer & aBuffer); // method to free the internal buffer
+
+ public:
+ DataBuffer(binary * aBuffer, uint32 aSize, bool (*aFreeBuffer)(const DataBuffer & aBuffer) = NULL)
+ :myBuffer(aBuffer)
+ ,mySize(aSize)
+ ,bValidValue(true)
+ ,myFreeBuffer(aFreeBuffer)
+ {}
+ virtual ~DataBuffer() {}
+ virtual binary * Buffer() {return myBuffer;}
+ virtual uint32 & Size() {return mySize;};
+ virtual const binary * Buffer() const {return myBuffer;}
+ virtual const uint32 Size() const {return mySize;};
+ bool FreeBuffer(const DataBuffer & aBuffer) {
+ bool bResult = true;
+ if (myBuffer != NULL && myFreeBuffer != NULL && bValidValue) {
+ bResult = myFreeBuffer(aBuffer);
+ myBuffer = NULL;
+ bValidValue = false;
+ }
+ return bResult;
+ }
+
+ virtual DataBuffer * Clone();
+};
+
+class MATROSKA_DLL_API SimpleDataBuffer : public DataBuffer {
+ public:
+ SimpleDataBuffer(binary * aBuffer, uint32 aSize, uint32 aOffset, bool (*aFreeBuffer)(const DataBuffer & aBuffer) = myFreeBuffer)
+ :DataBuffer(aBuffer + aOffset, aSize, aFreeBuffer)
+ ,Offset(aOffset)
+ ,BaseBuffer(aBuffer)
+ {}
+ virtual ~SimpleDataBuffer() {}
+
+ DataBuffer * Clone() {return new SimpleDataBuffer(*this);}
+
+ protected:
+ uint32 Offset;
+ binary * BaseBuffer;
+
+ static bool myFreeBuffer(const DataBuffer & aBuffer)
+ {
+ binary *_Buffer = static_cast<const SimpleDataBuffer*>(&aBuffer)->BaseBuffer;
+ if (_Buffer != NULL)
+ free(_Buffer);
+ return true;
+ }
+
+ SimpleDataBuffer(const SimpleDataBuffer & ToClone);
+};
+
+/*!
+ \note the data is copied locally, it can be freed right away
+* /
+class MATROSKA_DLL_API NotSoSimpleDataBuffer : public SimpleDataBuffer {
+ public:
+ NotSoSimpleDataBuffer(binary * aBuffer, uint32 aSize, uint32 aOffset)
+ :SimpleDataBuffer(new binary[aSize - aOffset], aSize, 0)
+ {
+ memcpy(BaseBuffer, aBuffer + aOffset, aSize - aOffset);
+ }
+};
+*/
+
+class MATROSKA_DLL_API KaxBlockGroup : public EbmlMaster {
+ public:
+ KaxBlockGroup();
+ KaxBlockGroup(const KaxBlockGroup & ElementToClone) :EbmlMaster(ElementToClone) {}
+
+ ~KaxBlockGroup();
+
+ /*!
+ \brief Addition of a frame without references
+ */
+ bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing = LACING_AUTO);
+ /*!
+ \brief Addition of a frame with a backward reference (P frame)
+ */
+ bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, const KaxBlockGroup & PastBlock, LacingType lacing = LACING_AUTO);
+
+ /*!
+ \brief Addition of a frame with a backward+forward reference (B frame)
+ */
+ bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, const KaxBlockGroup & PastBlock, const KaxBlockGroup & ForwBlock, LacingType lacing = LACING_AUTO);
+ bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, const KaxBlockBlob * PastBlock, const KaxBlockBlob * ForwBlock, LacingType lacing = LACING_AUTO);
+
+ void SetParent(KaxCluster & aParentCluster);
+
+ void SetParentTrack(const KaxTrackEntry & aParentTrack) {
+ ParentTrack = &aParentTrack;
+ }
+
+ /*!
+ \brief Set the duration of the contained frame(s) (for the total number of frames)
+ */
+ void SetBlockDuration(uint64 TimeLength);
+ bool GetBlockDuration(uint64 &TheTimecode) const;
+
+ /*!
+ \return the global timecode of this Block (not just the delta to the Cluster)
+ */
+ uint64 GlobalTimecode() const;
+ uint64 GlobalTimecodeScale() const {
+ assert(ParentTrack != NULL);
+ return ParentTrack->GlobalTimecodeScale();
+ }
+
+ uint16 TrackNumber() const;
+
+ uint64 ClusterPosition() const;
+
+ /*!
+ \return the number of references to other frames
+ */
+ unsigned int ReferenceCount() const;
+ const KaxReferenceBlock & Reference(unsigned int Index) const;
+
+ /*!
+ \brief release all the frames of all Blocks
+ */
+ void ReleaseFrames();
+
+ operator KaxInternalBlock &();
+
+ const KaxCluster *GetParentCluster() const { return ParentCluster; }
+
+ protected:
+ KaxCluster * ParentCluster;
+ const KaxTrackEntry * ParentTrack;
+
+ EBML_CONCRETE_CLASS(KaxBlockGroup)
+};
+
+class KaxInternalBlock : public EbmlBinary {
+ public:
+ KaxInternalBlock( bool bSimple ) :bLocalTimecodeUsed(false), mLacing(LACING_AUTO), mInvisible(false)
+ ,ParentCluster(NULL), bIsSimple(bSimple), bIsKeyframe(true), bIsDiscardable(false)
+ {}
+ KaxInternalBlock(const KaxInternalBlock & ElementToClone);
+ ~KaxInternalBlock();
+ bool ValidateSize() const;
+
+ uint16 TrackNum() const {return TrackNumber;}
+ /*!
+ \todo !!!! This method needs to be changes !
+ */
+ uint64 GlobalTimecode() const {return Timecode;}
+
+ /*!
+ \note override this function to generate the Data/Size on the fly, unlike the usual binary elements
+ */
+ filepos_t UpdateSize(bool bSaveDefault = false, bool bForceRender = false);
+ filepos_t ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA);
+
+ /*!
+ \brief Only read the head of the Block (not internal data)
+ \note convenient when you are parsing the file quickly
+ */
+ uint64 ReadInternalHead(IOCallback & input);
+
+ unsigned int NumberFrames() const { return SizeList.size();}
+ DataBuffer & GetBuffer(unsigned int iIndex) {return *myBuffers[iIndex];}
+
+ bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing = LACING_AUTO, bool invisible = false);
+
+ /*!
+ \brief release all the frames of all Blocks
+ */
+ void ReleaseFrames();
+
+ void SetParent(KaxCluster & aParentCluster);
+
+ /*!
+ \return Returns the lacing type that produces the smallest footprint.
+ */
+ LacingType GetBestLacingType() const;
+
+ /*!
+ \param FrameNumber 0 for the first frame
+ \return the position in the stream for a given frame
+ \note return -1 if the position doesn't exist
+ */
+ int64 GetDataPosition(size_t FrameNumber = 0);
+
+ /*!
+ \param FrameNumber 0 for the first frame
+ \return the size of a given frame
+ \note return -1 if the position doesn't exist
+ */
+ int64 GetFrameSize(size_t FrameNumber = 0);
+
+ bool IsInvisible() const { return mInvisible; }
+
+ uint64 ClusterPosition() const;
+
+ protected:
+ std::vector<DataBuffer *> myBuffers;
+ std::vector<int32> SizeList;
+ uint64 Timecode; // temporary timecode of the first frame, non scaled
+ int16 LocalTimecode;
+ bool bLocalTimecodeUsed;
+ uint16 TrackNumber;
+ LacingType mLacing;
+ bool mInvisible;
+ uint64 FirstFrameLocation;
+
+ filepos_t RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false);
+
+ KaxCluster * ParentCluster;
+ bool bIsSimple;
+ bool bIsKeyframe;
+ bool bIsDiscardable;
+};
+
+class MATROSKA_DLL_API KaxBlock : public KaxInternalBlock {
+ public:
+ KaxBlock() :KaxInternalBlock(false) {}
+
+ EBML_CONCRETE_CLASS(KaxBlock)
+};
+
+#if MATROSKA_VERSION >= 2
+class MATROSKA_DLL_API KaxSimpleBlock : public KaxInternalBlock {
+ public:
+ KaxSimpleBlock() :KaxInternalBlock(true) {}
+
+ void SetKeyframe(bool b_keyframe) { bIsKeyframe = b_keyframe; }
+ void SetDiscardable(bool b_discard) { bIsDiscardable = b_discard; }
+
+ bool IsKeyframe() const { return bIsKeyframe; }
+ bool IsDiscardable() const { return bIsDiscardable; }
+
+ operator KaxInternalBlock &() { return *this; }
+
+ EBML_CONCRETE_CLASS(KaxSimpleBlock)
+};
+#endif // MATROSKA_VERSION
+
+class MATROSKA_DLL_API KaxBlockBlob {
+public:
+ KaxBlockBlob(BlockBlobType sblock_mode) :ParentCluster(NULL), SimpleBlockMode(sblock_mode) {
+ bUseSimpleBlock = (sblock_mode != BLOCK_BLOB_NO_SIMPLE);
+ Block.group = NULL;
+ }
+
+ ~KaxBlockBlob() {
+#if MATROSKA_VERSION >= 2
+ if (bUseSimpleBlock)
+ delete Block.simpleblock;
+ else
+#endif // MATROSKA_VERSION
+ delete Block.group;
+ }
+
+ operator KaxBlockGroup &();
+ operator const KaxBlockGroup &() const;
+#if MATROSKA_VERSION >= 2
+ operator KaxSimpleBlock &();
+#endif
+ operator KaxInternalBlock &();
+ operator const KaxInternalBlock &() const;
+
+ void SetBlockGroup( KaxBlockGroup &BlockRef );
+
+ void SetBlockDuration(uint64 TimeLength);
+
+ void SetParent(KaxCluster & aParentCluster);
+ bool AddFrameAuto(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing = LACING_AUTO, const KaxBlockBlob * PastBlock = NULL, const KaxBlockBlob * ForwBlock = NULL);
+
+ bool IsSimpleBlock() const {return bUseSimpleBlock;}
+
+ bool ReplaceSimpleByGroup();
+protected:
+ KaxCluster * ParentCluster;
+ union {
+ KaxBlockGroup *group;
+#if MATROSKA_VERSION >= 2
+ KaxSimpleBlock *simpleblock;
+#endif // MATROSKA_VERSION
+ } Block;
+ bool bUseSimpleBlock;
+ BlockBlobType SimpleBlockMode;
+};
+
+class MATROSKA_DLL_API KaxBlockDuration : public EbmlUInteger {
+ public:
+ KaxBlockDuration() {}
+ KaxBlockDuration(const KaxBlockDuration & ElementToClone) :EbmlUInteger(ElementToClone) {}
+
+ EBML_CONCRETE_CLASS(KaxBlockDuration)
+};
+
+#if MATROSKA_VERSION >= 2
+class MATROSKA_DLL_API KaxBlockVirtual : public EbmlBinary {
+ public:
+ KaxBlockVirtual() :ParentCluster(NULL) {SetBuffer(DataBlock,sizeof(DataBlock)); SetValueIsSet(false);}
+ KaxBlockVirtual(const KaxBlockVirtual & ElementToClone);
+ ~KaxBlockVirtual() { if( Data == DataBlock ) SetBuffer( NULL, 0 ); };
+ bool ValidateSize() const {return true;}
+
+ /*!
+ \note override this function to generate the Data/Size on the fly, unlike the usual binary elements
+ */
+ filepos_t UpdateSize(bool bSaveDefault = false, bool bForceRender = false);
+
+ void SetParent(const KaxCluster & aParentCluster) {ParentCluster = &aParentCluster;}
+
+ protected:
+ uint64 Timecode; // temporary timecode of the first frame if there are more than one
+ uint16 TrackNumber;
+ binary DataBlock[5];
+
+ const KaxCluster * ParentCluster;
+
+ EBML_CONCRETE_CLASS(KaxBlockVirtual)
+};
+#endif // MATROSKA_VERSION
+
+class MATROSKA_DLL_API KaxBlockAdditional : public EbmlBinary {
+ public:
+ KaxBlockAdditional() {}
+ KaxBlockAdditional(const KaxBlockAdditional & ElementToClone) :EbmlBinary(ElementToClone){}
+ bool ValidateSize() const {return true;}
+
+ EBML_CONCRETE_CLASS(KaxBlockAdditional)
+};
+
+class MATROSKA_DLL_API KaxBlockAdditions : public EbmlMaster {
+ public:
+ KaxBlockAdditions();
+ KaxBlockAdditions(const KaxBlockAdditions & ElementToClone) :EbmlMaster(ElementToClone) {}
+
+ EBML_CONCRETE_CLASS(KaxBlockAdditions)
+};
+
+class MATROSKA_DLL_API KaxBlockMore : public EbmlMaster {
+ public:
+ KaxBlockMore();
+ KaxBlockMore(const KaxBlockMore & ElementToClone) :EbmlMaster(ElementToClone) {}
+
+ EBML_CONCRETE_CLASS(KaxBlockMore)
+};
+
+class MATROSKA_DLL_API KaxBlockAddID : public EbmlUInteger {
+ public:
+ KaxBlockAddID() :EbmlUInteger(1) {}
+ KaxBlockAddID(const KaxBlockAddID & ElementToClone) :EbmlUInteger(ElementToClone) {}
+
+ EBML_CONCRETE_CLASS(KaxBlockAddID)
+};
+
+class MATROSKA_DLL_API KaxCodecState : public EbmlBinary {
+ public:
+ KaxCodecState() {}
+ KaxCodecState(const KaxCodecState & ElementToClone) :EbmlBinary(ElementToClone){}
+
+ bool ValidateSize() const {return true;}
+
+ EBML_CONCRETE_CLASS(KaxCodecState)
+};
+
+END_LIBMATROSKA_NAMESPACE
+
+#endif // LIBMATROSKA_BLOCK_H