1/**************************************************************************** 2** libmatroska : parse Matroska files, see http://www.matroska.org/ 3** 4** <file/class description> 5** 6** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. 7** 8** This library is free software; you can redistribute it and/or 9** modify it under the terms of the GNU Lesser General Public 10** License as published by the Free Software Foundation; either 11** version 2.1 of the License, or (at your option) any later version. 12** 13** This library is distributed in the hope that it will be useful, 14** but WITHOUT ANY WARRANTY; without even the implied warranty of 15** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16** Lesser General Public License for more details. 17** 18** You should have received a copy of the GNU Lesser General Public 19** License along with this library; if not, write to the Free Software 20** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21** 22** See http://www.matroska.org/license/lgpl/ for LGPL licensing information.** 23** Contact license@matroska.org if any conditions of this licensing are 24** not clear to you. 25** 26**********************************************************************/ 27 28/*! 29 \file 30 \version \$Id: KaxCluster.h,v 1.10 2004/04/14 23:26:17 robux4 Exp $ 31 \author Steve Lhomme <robux4 @ users.sf.net> 32 \author Julien Coloos <suiryc @ users.sf.net> 33 34*/ 35#ifndef LIBMATROSKA_CLUSTER_H 36#define LIBMATROSKA_CLUSTER_H 37 38#include "matroska/KaxTypes.h" 39#include "ebml/EbmlMaster.h" 40#include "matroska/KaxTracks.h" 41#include "matroska/KaxBlock.h" 42#include "matroska/KaxCues.h" 43#include "matroska/KaxClusterData.h" 44 45using namespace LIBEBML_NAMESPACE; 46 47START_LIBMATROSKA_NAMESPACE 48 49class KaxSegment; 50 51class MATROSKA_DLL_API KaxCluster : public EbmlMaster { 52 public: 53 KaxCluster(); 54 KaxCluster(const KaxCluster & ElementToClone); 55 static EbmlElement & Create() {return *(new KaxCluster);} 56 const EbmlCallbacks & Generic() const {return ClassInfos;} 57 static const EbmlCallbacks ClassInfos; 58 operator const EbmlId &() const {return ClassInfos.GlobalId;} 59 EbmlElement * Clone() const {return new KaxCluster(*this);} 60 61 /*! 62 \brief Addition of a frame without references 63 64 \param the timecode is expressed in nanoseconds, relative to the beggining of the Segment 65 */ 66 bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, LacingType lacing = LACING_AUTO); 67 /*! 68 \brief Addition of a frame with a backward reference (P frame) 69 \param the timecode is expressed in nanoseconds, relative to the beggining of the Segment 70 71 */ 72 bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, const KaxBlockGroup & PastBlock, LacingType lacing = LACING_AUTO); 73 74 /*! 75 \brief Addition of a frame with a backward+forward reference (B frame) 76 \param the timecode is expressed in nanoseconds, relative to the beggining of the Segment 77 78 */ 79 bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, const KaxBlockGroup & PastBlock, const KaxBlockGroup & ForwBlock, LacingType lacing = LACING_AUTO); 80 81 /*! 82 \brief Render the data to the stream and retrieve the position of BlockGroups for later cue entries 83 */ 84 uint32 Render(IOCallback & output, KaxCues & CueToUpdate, bool bSaveDefault = false); 85 86 /*! 87 \return the global timecode of this Cluster 88 */ 89 uint64 GlobalTimecode() const; 90 91 KaxBlockGroup & GetNewBlock(); 92 93 /*! 94 \brief release all the frames of all Blocks 95 \note this is a convenience to be able to keep Clusters+Blocks in memory (for future reference) withouht being a memory hog 96 */ 97 void ReleaseFrames(); 98 99 /*! 100 \brief return the position offset compared to the beggining of the Segment 101 */ 102 uint64 GetPosition() const; 103 104 void SetParent(const KaxSegment & aParentSegment) {ParentSegment = &aParentSegment;} 105 106 void SetPreviousTimecode(uint64 aPreviousTimecode, int64 aTimecodeScale) { 107 bPreviousTimecodeIsSet = true; 108 PreviousTimecode = aPreviousTimecode; 109 SetGlobalTimecodeScale(aTimecodeScale); 110 } 111 112 /*! 113 \note dirty hack to get the mandatory data back after reading 114 \todo there should be a better way to get mandatory data 115 */ 116 void InitTimecode(uint64 aTimecode, int64 aTimecodeScale) { 117 SetGlobalTimecodeScale(aTimecodeScale); 118 MinTimecode = MaxTimecode = PreviousTimecode = aTimecode * TimecodeScale; 119 bFirstFrameInside = bPreviousTimecodeIsSet = true; 120 } 121 122 int16 GetBlockLocalTimecode(uint64 GlobalTimecode) const; 123 124 uint64 GetBlockGlobalTimecode(int16 LocalTimecode); 125 126 void SetGlobalTimecodeScale(uint64 aGlobalTimecodeScale) { 127 TimecodeScale = aGlobalTimecodeScale; 128 bTimecodeScaleIsSet = true; 129 } 130 uint64 GlobalTimecodeScale() const { 131 assert(bTimecodeScaleIsSet); 132 return TimecodeScale; 133 } 134 135 bool SetSilentTrackUsed() 136 { 137 bSilentTracksUsed = true; 138 return FindFirstElt(KaxClusterSilentTracks::ClassInfos, true) != NULL; 139 } 140 141 bool AddBlockBlob(KaxBlockBlob * NewBlob); 142 143 const KaxSegment *GetParentSegment() const { return ParentSegment; } 144 145 protected: 146 KaxBlockBlob * currentNewBlob; 147 std::vector<KaxBlockBlob*> Blobs; 148 KaxBlockGroup * currentNewBlock; 149 const KaxSegment * ParentSegment; 150 151 uint64 MinTimecode, MaxTimecode, PreviousTimecode; 152 int64 TimecodeScale; 153 154 bool bFirstFrameInside; // used to speed research 155 bool bPreviousTimecodeIsSet; 156 bool bTimecodeScaleIsSet; 157 bool bSilentTracksUsed; 158 159 /*! 160 \note method used internally 161 */ 162 bool AddFrameInternal(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, const KaxBlockGroup * PastBlock, const KaxBlockGroup * ForwBlock, LacingType lacing); 163 164}; 165 166END_LIBMATROSKA_NAMESPACE 167 168#endif // LIBMATROSKA_CLUSTER_H 169