[matroska] r955 - in trunk/libmatroska: matroska src

[email protected]
Newsgroups gmane.comp.multimedia.matroska.cvs
Message-ID <[email protected]>
Author: robux4
Date: 2004-11-28 18:24:37 +0300 (Sun, 28 Nov 2004)
New Revision: 955

Modified:
   trunk/libmatroska/matroska/KaxCluster.h
   trunk/libmatroska/src/KaxCluster.cpp
   trunk/libmatroska/src/KaxClusterData.cpp
Log:
add almost automatic handling of SilentTracks

Modified: trunk/libmatroska/matroska/KaxCluster.h
===================================================================
--- trunk/libmatroska/matroska/KaxCluster.h	2004-11-19 12:17:47 UTC (rev 954)
+++ trunk/libmatroska/matroska/KaxCluster.h	2004-11-28 15:24:37 UTC (rev 955)
@@ -1,154 +1,162 @@
-/****************************************************************************
-** libmatroska : parse Matroska files, see http://www.matroska.org/
-**
-** <file/class description>
-**
-** Copyright (C) 2002-2004 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 [email protected] if any conditions of this licensing are
-** not clear to you.
-**
-**********************************************************************/
-
-/*!
-	\file
-	\version \$Id: KaxCluster.h,v 1.10 2004/04/14 23:26:17 robux4 Exp $
-	\author Steve Lhomme     <robux4 @ users.sf.net>
-	\author Julien Coloos    <suiryc @ users.sf.net>
-
-*/
-#ifndef LIBMATROSKA_CLUSTER_H
-#define LIBMATROSKA_CLUSTER_H
-
-#include "matroska/KaxTypes.h"
-#include "ebml/EbmlMaster.h"
-#include "matroska/KaxTracks.h"
-#include "matroska/KaxBlock.h"
-#include "matroska/KaxCues.h"
-
-using namespace LIBEBML_NAMESPACE;
-
-START_LIBMATROSKA_NAMESPACE
-
-class KaxSegment;
-
-class MATROSKA_DLL_API KaxCluster : public EbmlMaster {
-	public:
-		KaxCluster();
-		KaxCluster(const KaxCluster & ElementToClone);
-		static EbmlElement & Create() {return *(new KaxCluster);}
-		const EbmlCallbacks & Generic() const {return ClassInfos;}
-		static const EbmlCallbacks ClassInfos;
-		operator const EbmlId &() const {return ClassInfos.GlobalId;}
-		EbmlElement * Clone() const {return new KaxCluster(*this);}
-
-		/*!
-			\brief Addition of a frame without references
-
-			\param the timecode is expressed in nanoseconds, relative to the beggining of the Segment
-		*/
-		bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, LacingType lacing = LACING_AUTO);
-		/*!
-			\brief Addition of a frame with a backward reference (P frame)
-			\param the timecode is expressed in nanoseconds, relative to the beggining of the Segment
-
-		*/
-		bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, const KaxBlockGroup & PastBlock, LacingType lacing = LACING_AUTO);
-
-		/*!
-			\brief Addition of a frame with a backward+forward reference (B frame)
-			\param the timecode is expressed in nanoseconds, relative to the beggining of the Segment
-
-		*/
-		bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, const KaxBlockGroup & PastBlock, const KaxBlockGroup & ForwBlock, LacingType lacing = LACING_AUTO);
-
-		/*!
-			\brief Render the data to the stream and retrieve the position of BlockGroups for later cue entries
-		*/
-		uint32 Render(IOCallback & output, KaxCues & CueToUpdate, bool bSaveDefault = false);
-
-		/*!
-			\return the global timecode of this Cluster
-		*/
-		uint64 GlobalTimecode() const;
-
-		KaxBlockGroup & GetNewBlock();
-		
-		/*!
-			\brief release all the frames of all Blocks
-			\note this is a convenience to be able to keep Clusters+Blocks in memory (for future reference) withouht being a memory hog
-		*/
-		void ReleaseFrames();
-
-		/*!
-			\brief return the position offset compared to the beggining of the Segment
-		*/
-		uint64 GetPosition() const;
-
-		void SetParent(const KaxSegment & aParentSegment) {ParentSegment = &aParentSegment;}
-
-		void SetPreviousTimecode(uint64 aPreviousTimecode, int64 aTimecodeScale) {
-			bPreviousTimecodeIsSet = true; 
-			PreviousTimecode = aPreviousTimecode;
-			SetGlobalTimecodeScale(aTimecodeScale);
-		}
-
-		/*!
-			\note dirty hack to get the mandatory data back after reading
-			\todo there should be a better way to get mandatory data
-		*/
-		void InitTimecode(uint64 aTimecode, int64 aTimecodeScale) {
-			SetGlobalTimecodeScale(aTimecodeScale);
-			MinTimecode = MaxTimecode = PreviousTimecode = aTimecode * TimecodeScale;
-			bFirstFrameInside = bPreviousTimecodeIsSet = true;
-		}
-
-		int16 GetBlockLocalTimecode(uint64 GlobalTimecode) const;
-
-		uint64 GetBlockGlobalTimecode(int16 LocalTimecode);
-
-		void SetGlobalTimecodeScale(uint64 aGlobalTimecodeScale) {
-			TimecodeScale = aGlobalTimecodeScale;
-			bTimecodeScaleIsSet = true;
-		}
-		uint64 GlobalTimecodeScale() const {
-			assert(bTimecodeScaleIsSet); 
-			return TimecodeScale;
-		}
-
-	protected:
-		KaxBlockGroup    * currentNewBlock;
-		const KaxSegment * ParentSegment;
-
-		uint64 MinTimecode, MaxTimecode, PreviousTimecode;
-		int64  TimecodeScale;
-
-		bool bFirstFrameInside; // used to speed research
-		bool bPreviousTimecodeIsSet;
-		bool bTimecodeScaleIsSet;
-
-		/*!
-			\note method used internally
-		*/
-		bool AddFrameInternal(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, const KaxBlockGroup * PastBlock, const KaxBlockGroup * ForwBlock, LacingType lacing);
-
-};
-
-END_LIBMATROSKA_NAMESPACE
-
-#endif // LIBMATROSKA_CLUSTER_H
+/****************************************************************************
+** libmatroska : parse Matroska files, see http://www.matroska.org/
+**
+** <file/class description>
+**
+** Copyright (C) 2002-2004 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 [email protected] if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+/*!
+	\file
+	\version \$Id: KaxCluster.h,v 1.10 2004/04/14 23:26:17 robux4 Exp $
+	\author Steve Lhomme     <robux4 @ users.sf.net>
+	\author Julien Coloos    <suiryc @ users.sf.net>
+
+*/
+#ifndef LIBMATROSKA_CLUSTER_H
+#define LIBMATROSKA_CLUSTER_H
+
+#include "matroska/KaxTypes.h"
+#include "ebml/EbmlMaster.h"
+#include "matroska/KaxTracks.h"
+#include "matroska/KaxBlock.h"
+#include "matroska/KaxCues.h"
+#include "matroska/KaxClusterData.h"
+
+using namespace LIBEBML_NAMESPACE;
+
+START_LIBMATROSKA_NAMESPACE
+
+class KaxSegment;
+
+class MATROSKA_DLL_API KaxCluster : public EbmlMaster {
+	public:
+		KaxCluster();
+		KaxCluster(const KaxCluster & ElementToClone);
+		static EbmlElement & Create() {return *(new KaxCluster);}
+		const EbmlCallbacks & Generic() const {return ClassInfos;}
+		static const EbmlCallbacks ClassInfos;
+		operator const EbmlId &() const {return ClassInfos.GlobalId;}
+		EbmlElement * Clone() const {return new KaxCluster(*this);}
+
+		/*!
+			\brief Addition of a frame without references
+
+			\param the timecode is expressed in nanoseconds, relative to the beggining of the Segment
+		*/
+		bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, LacingType lacing = LACING_AUTO);
+		/*!
+			\brief Addition of a frame with a backward reference (P frame)
+			\param the timecode is expressed in nanoseconds, relative to the beggining of the Segment
+
+		*/
+		bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, const KaxBlockGroup & PastBlock, LacingType lacing = LACING_AUTO);
+
+		/*!
+			\brief Addition of a frame with a backward+forward reference (B frame)
+			\param the timecode is expressed in nanoseconds, relative to the beggining of the Segment
+
+		*/
+		bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, const KaxBlockGroup & PastBlock, const KaxBlockGroup & ForwBlock, LacingType lacing = LACING_AUTO);
+
+		/*!
+			\brief Render the data to the stream and retrieve the position of BlockGroups for later cue entries
+		*/
+		uint32 Render(IOCallback & output, KaxCues & CueToUpdate, bool bSaveDefault = false);
+
+		/*!
+			\return the global timecode of this Cluster
+		*/
+		uint64 GlobalTimecode() const;
+
+		KaxBlockGroup & GetNewBlock();
+		
+		/*!
+			\brief release all the frames of all Blocks
+			\note this is a convenience to be able to keep Clusters+Blocks in memory (for future reference) withouht being a memory hog
+		*/
+		void ReleaseFrames();
+
+		/*!
+			\brief return the position offset compared to the beggining of the Segment
+		*/
+		uint64 GetPosition() const;
+
+		void SetParent(const KaxSegment & aParentSegment) {ParentSegment = &aParentSegment;}
+
+		void SetPreviousTimecode(uint64 aPreviousTimecode, int64 aTimecodeScale) {
+			bPreviousTimecodeIsSet = true; 
+			PreviousTimecode = aPreviousTimecode;
+			SetGlobalTimecodeScale(aTimecodeScale);
+		}
+
+		/*!
+			\note dirty hack to get the mandatory data back after reading
+			\todo there should be a better way to get mandatory data
+		*/
+		void InitTimecode(uint64 aTimecode, int64 aTimecodeScale) {
+			SetGlobalTimecodeScale(aTimecodeScale);
+			MinTimecode = MaxTimecode = PreviousTimecode = aTimecode * TimecodeScale;
+			bFirstFrameInside = bPreviousTimecodeIsSet = true;
+		}
+
+		int16 GetBlockLocalTimecode(uint64 GlobalTimecode) const;
+
+		uint64 GetBlockGlobalTimecode(int16 LocalTimecode);
+
+		void SetGlobalTimecodeScale(uint64 aGlobalTimecodeScale) {
+			TimecodeScale = aGlobalTimecodeScale;
+			bTimecodeScaleIsSet = true;
+		}
+		uint64 GlobalTimecodeScale() const {
+			assert(bTimecodeScaleIsSet); 
+			return TimecodeScale;
+		}
+
+		bool SetSilentTrackUsed()
+		{
+			bSilentTracksUsed = true;
+			return FindFirstElt(KaxClusterSilentTracks::ClassInfos, true) != NULL;
+		}
+
+	protected:
+		KaxBlockGroup    * currentNewBlock;
+		const KaxSegment * ParentSegment;
+
+		uint64 MinTimecode, MaxTimecode, PreviousTimecode;
+		int64  TimecodeScale;
+
+		bool bFirstFrameInside; // used to speed research
+		bool bPreviousTimecodeIsSet;
+		bool bTimecodeScaleIsSet;
+		bool bSilentTracksUsed;
+
+		/*!
+			\note method used internally
+		*/
+		bool AddFrameInternal(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, const KaxBlockGroup * PastBlock, const KaxBlockGroup * ForwBlock, LacingType lacing);
+
+};
+
+END_LIBMATROSKA_NAMESPACE
+
+#endif // LIBMATROSKA_CLUSTER_H

Modified: trunk/libmatroska/src/KaxCluster.cpp
===================================================================
--- trunk/libmatroska/src/KaxCluster.cpp	2004-11-19 12:17:47 UTC (rev 954)
+++ trunk/libmatroska/src/KaxCluster.cpp	2004-11-28 15:24:37 UTC (rev 955)
@@ -60,10 +60,12 @@
 	,bFirstFrameInside(false)
 	,bPreviousTimecodeIsSet(false)
 	,bTimecodeScaleIsSet(false)
+	,bSilentTracksUsed(false)
 {}
 
 KaxCluster::KaxCluster(const KaxCluster & ElementToClone) 
  :EbmlMaster(ElementToClone)
+ ,bSilentTracksUsed(ElementToClone.bSilentTracksUsed)
 {
 	// update the parent of each children
 	std::vector<EbmlElement *>::const_iterator Itr = ElementList.begin();
@@ -159,9 +161,39 @@
 	KaxClusterTimecode * Timecode = static_cast<KaxClusterTimecode *>(this->FindElt(KaxClusterTimecode::ClassInfos));
 	*static_cast<EbmlUInteger *>(Timecode) = GlobalTimecode() / GlobalTimecodeScale();
 
+	size_t TrkIndex, Index;
+
+	// SilentTracks handling
+	// check the parent cluster for existing tracks and see if they are contained in this cluster or not
+	if (bSilentTracksUsed)
+	{
+		KaxTracks & MyTracks = *static_cast<KaxTracks *>(ParentSegment->FindElt(KaxTracks::ClassInfos));
+		for (TrkIndex = 0; TrkIndex < MyTracks.ListSize(); TrkIndex++) {
+			if (EbmlId(*MyTracks[TrkIndex]) == KaxTrackEntry::ClassInfos.GlobalId)
+			{
+				KaxTrackEntry & entry = *static_cast<KaxTrackEntry *>(MyTracks[TrkIndex]);
+				uint32 tracknum = entry.TrackNumber();
+				for (Index = 0; Index < ElementList.size(); Index++) {
+					if (EbmlId(*ElementList[Index]) == KaxBlockGroup::ClassInfos.GlobalId) {
+						KaxBlockGroup & group = *static_cast<KaxBlockGroup *>(ElementList[Index]);
+						if (group.TrackNumber() == tracknum)
+							break; // this track is used
+					}
+				}
+				// the track wasn't found in this cluster
+				if (Index == ElementList.size())
+				{
+					KaxClusterSilentTracks * SilentTracks = static_cast<KaxClusterSilentTracks *>(this->FindFirstElt(KaxClusterSilentTracks::ClassInfos));
+					assert(SilentTracks != NULL); // the flag bSilentTracksUsed should be set when creating the Cluster
+					KaxClusterSilentTrackNumber * trackelt = static_cast<KaxClusterSilentTrackNumber *>(SilentTracks->AddNewElt(KaxClusterSilentTrackNumber::ClassInfos));
+					*static_cast<EbmlUInteger *>(trackelt) = tracknum;
+				}
+			}
+		}
+	}
+
 	uint32 Result = EbmlMaster::Render(output, bSaveDefault);
 	// For all Blocks add their position on the CueEntry
-	size_t Index;
 	
 	for (Index = 0; Index < ElementList.size(); Index++) {
 		if (EbmlId(*ElementList[Index]) == KaxBlockGroup::ClassInfos.GlobalId) {

Modified: trunk/libmatroska/src/KaxClusterData.cpp
===================================================================
--- trunk/libmatroska/src/KaxClusterData.cpp	2004-11-19 12:17:47 UTC (rev 954)
+++ trunk/libmatroska/src/KaxClusterData.cpp	2004-11-28 15:24:37 UTC (rev 955)
@@ -45,7 +45,7 @@
 
 EbmlSemantic KaxClusterSilentTracks_ContextList[1] =
 {
-	EbmlSemantic(true,  false, KaxClusterSilentTrackNumber::ClassInfos),
+	EbmlSemantic(false,  false, KaxClusterSilentTrackNumber::ClassInfos),
 };
 
 const EbmlSemanticContext KaxClusterTimecode_Context = EbmlSemanticContext(0, NULL, &KaxCluster_Context, *GetKaxGlobal_Context, &KaxClusterTimecode::ClassInfos);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.