[Matroska-cvs] [matroska] r1252 - trunk/foo_input_matroska

ayana at matroska.org ayana at matroska.org
Wed May 10 19:02:06 CEST 2006


Author: ayana
Date: 2006-05-10 21:01:56 +0400 (Wed, 10 May 2006)
New Revision: 1252

Modified:
   trunk/foo_input_matroska/Foobar2000ReaderIOCallback.h
   trunk/foo_input_matroska/foo_input_matroska.cpp
   trunk/foo_input_matroska/foo_input_matroska.vcproj
   trunk/foo_input_matroska/matroska_parser.cpp
   trunk/foo_input_matroska/matroska_parser.h
Log:
0.9.0.8 release
fix: memory leak
change: update interval of VBR
add: support - packet_decoder::analyse_first_frame()

Modified: trunk/foo_input_matroska/Foobar2000ReaderIOCallback.h
===================================================================
--- trunk/foo_input_matroska/Foobar2000ReaderIOCallback.h	2006-04-30 14:23:26 UTC (rev 1251)
+++ trunk/foo_input_matroska/Foobar2000ReaderIOCallback.h	2006-05-10 17:01:56 UTC (rev 1252)
@@ -28,7 +28,6 @@
 	{
 		m_NoSeekReader = NULL;
 		m_Reader = source;
-		m_abort = p_abort;
 		//m_Reader->service_add_ref();
 		if (!m_Reader->can_seek()) {
 			m_NoSeekReader = source;
@@ -73,11 +72,11 @@
 	virtual void close() {
 		if (m_Reader != NULL) {
 			//m_Reader->service_release();
-			m_Reader = NULL;
+			//m_Reader = NULL;
 		}
 		if (m_NoSeekReader != NULL) {
 			//m_NoSeekReader->service_release();
-			m_NoSeekReader = NULL;
+			//m_NoSeekReader = NULL;
 		}
 	}
 

Modified: trunk/foo_input_matroska/foo_input_matroska.cpp
===================================================================
--- trunk/foo_input_matroska/foo_input_matroska.cpp	2006-04-30 14:23:26 UTC (rev 1251)
+++ trunk/foo_input_matroska/foo_input_matroska.cpp	2006-05-10 17:01:56 UTC (rev 1252)
@@ -56,6 +56,7 @@
 #include <commctrl.h>
 #include <Shlwapi.h>
 #include <time.h>
+//#include "contextmenu_item_matroska.h"
 #include "matroska_parser.h"
 #include "resource.h"
 #include "DbgOut.h"
@@ -112,7 +113,7 @@
 		m_vbr_update_bytes = 0;
 		m_vbr_update_time = 0;
 		m_vbr_update_enabled = true;
-		m_vbr_update_interval = 32;
+		m_vbr_update_interval = 0;
 		m_position = 0;
 		m_length = 0;
 
@@ -143,14 +144,17 @@
 
 		m_parser = new MatroskaAudioParser(m_file, p_abort);
 
-		if (m_parser->Parse(!(p_reason & input_open_decode))) {
+		//if (m_parser->Parse(!(p_reason & input_open_decode))) {
+		if (m_parser->Parse()) {
 			console::error("Matroska: Invalid Matroska file.");
+			cleanup();
 			throw exception_io_unsupported_format();
 		}
 
 		m_TrackNo = m_parser->GetFirstAudioTrack();
 		if (m_TrackNo == -1) {
 			console::error("Matroska: no decodable streams found.");
+			cleanup();
 			throw exception_io_unsupported_format();
 		}
 	}
@@ -208,7 +212,9 @@
 		//hprintf(L"Matroska: m_parser->GetDuration(): %f\n", (double)(int64)m_parser->GetDuration() / 1000000000.0);
 		p_info.set_length((double)(int64)m_parser->GetDuration() / 1000000000.0);
 
-		p_info.info_set_bitrate(m_parser->GetAvgBitrate());
+		if (p_info.info_get_bitrate() == 0) {
+			p_info.info_set_bitrate(m_parser->GetAvgBitrate());
+		}
 	}
 
 	t_filestats get_file_stats(abort_callback & p_abort) {
@@ -229,7 +235,9 @@
 		m_skip_frames = 0;
 		m_frame_remaining = 0;
 		m_frame = 0;
-		decode_seek(0, p_abort);
+		if (decode_can_seek()) {
+			decode_seek(0, p_abort);
+		}
 	}
 
 	bool decode_run(audio_chunk & p_chunk, abort_callback & p_abort) {
@@ -281,17 +289,15 @@
 			}
 			
 			m_tempchunk.reset();
-			m_decoder->decode(m_buffer.get_ptr(), buffer_size, m_tempchunk, p_abort);
-			if (m_tempchunk.is_empty())
-			{
-				/*
+			try {
+				m_decoder->decode(m_buffer.get_ptr(), buffer_size, m_tempchunk, p_abort);
+			} catch (...) {
 				MatroskaTrackInfo &currentTrack = m_parser->GetTrack(m_TrackNo);
 				console::error(uStringPrintf("Matroska: '%s' decode error.", (const char*)currentTrack.codecID.c_str()));
-				console::error(uStringPrintf("buffer_size = %d, m_frame_remaining = %d", buffer_size, m_frame_remaining));
-				console::error(uStringPrintf("buffer 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", m_buffer[0], m_buffer[1], m_buffer[2], m_buffer[3], m_buffer[4], m_buffer[5], m_buffer[6], m_buffer[7]));				
+				//console::error(uStringPrintf("buffer_size = %d, m_frame_remaining = %d", buffer_size, m_frame_remaining));
+				//console::error(uStringPrintf("buffer 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", m_buffer[0], m_buffer[1], m_buffer[2], m_buffer[3], m_buffer[4], m_buffer[5], m_buffer[6], m_buffer[7]));				
 				cleanup();
 				return false;
-				*/
 			}
 			if (m_tempchunk.is_valid())
 			{
@@ -397,6 +403,7 @@
 		if (m_decoder == NULL)
 		{
 			console::error("Matroska: attempting to seek while not open.");
+			cleanup();
 			throw exception_io_object_not_seekable();
 		}
 
@@ -414,7 +421,7 @@
 		m_position = (uint64)(m_expected_sample_rate * p_seconds + 0.5);
 
 		double time_to_skip = 0;
-		if (!m_parser->Seek(p_seconds-max_frame_dependency_time,frames_to_skip,time_to_skip,m_expected_sample_rate)) throw exception_io_object_not_seekable();
+		if (!m_parser->Seek(p_seconds-max_frame_dependency_time,frames_to_skip,time_to_skip,m_expected_sample_rate)) return;
 		
 		m_skip_frames = frames_to_skip;
 
@@ -434,7 +441,7 @@
 		bool ret = false;
 		if (m_vbr_update_enabled)
 		{
-			if (m_vbr_update_time > 0 && m_vbr_update_frames >= m_vbr_update_interval)
+			if (m_vbr_update_time > 0.5 && m_vbr_update_frames >= m_vbr_update_interval)
 			{
 				int val = (int) ( ((double)m_vbr_update_bytes * 8.0 / m_vbr_update_time + 500.0) / 1000.0 );
 				if (val != p_out.info_get_bitrate_vbr())
@@ -581,11 +588,38 @@
 		m_expected_channels = currentTrack.channels;
 		m_expected_sample_rate = (unsigned)(currentTrack.samplesOutputPerSec == 0 ? currentTrack.samplesPerSec : currentTrack.samplesOutputPerSec);
 		m_expected_bitspersample = currentTrack.bitsPerSample;
+		//*
+		if ((p_decode == false) && m_decoder->analyze_first_frame_supported()) {
+			if (m_frame != NULL) {
+				delete m_frame;
+				m_frame = NULL;
+			}
+			m_decoder->reset_after_seek();
+			// The timecode scale in Matroska is in milliseconds, but foobar deals in seconds
+			m_timescale = m_parser->GetTimecodeScale() * 1000;
+			m_length = duration_to_samples(m_parser->GetDuration());
+			m_position = 0;
+			m_skip_samples = 0;
+			m_skip_frames = 0;
+			m_frame_remaining = 0;
+			m_frame = 0;
+			if (decode_can_seek()) {
+				decode_seek(0, p_abort);
+			}
+			m_frame = m_parser->ReadSingleFrame();
+			if (m_frame != NULL) {
+				unsigned int buffer_size = m_frame->dataBuffer.at(0).size();
+				m_buffer.set_size(buffer_size);
+				m_buffer.set_data_fromptr(&m_frame->dataBuffer.at(0)[0], buffer_size);
+				m_decoder->analyze_first_frame(m_buffer.get_ptr(), buffer_size, p_abort);
+			}
+		}
+		//*/
 	}
 };
 
 static input_factory_t<input_matroska> g_input_matroska_factory;
 
-DECLARE_COMPONENT_VERSION("Matroska Plugin" ,"0.9.0.7","ported to 0.9 by Haru Ayana <ayana at reharmonize.net>\nCopyright (C) 2003-2004 Jory Stone (jcsston at toughguy.net)\nCopyright (C) 2003-2004 Peter Pawlowski");
+DECLARE_COMPONENT_VERSION("Matroska Plugin" ,"0.9.0.8","ported to 0.9 by Haru Ayana <ayana at reharmonize.net>\nCopyright (C) 2003-2004 Jory Stone (jcsston at toughguy.net)\nCopyright (C) 2003-2004 Peter Pawlowski");
 
 DECLARE_FILE_TYPE("Matroska Audio files","*.MKA");

Modified: trunk/foo_input_matroska/foo_input_matroska.vcproj
===================================================================
--- trunk/foo_input_matroska/foo_input_matroska.vcproj	2006-04-30 14:23:26 UTC (rev 1251)
+++ trunk/foo_input_matroska/foo_input_matroska.vcproj	2006-05-10 17:01:56 UTC (rev 1252)
@@ -16,7 +16,7 @@
 	<Configurations>
 		<Configuration
 			Name="Debug|Win32"
-			OutputDirectory=".\../Debug"
+			OutputDirectory=".\Debug"
 			IntermediateDirectory=".\Debug"
 			ConfigurationType="2"
 			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -77,15 +77,15 @@
 				Name="VCLinkerTool"
 				AdditionalDependencies="shared.lib libebmld.lib libmatroskad.lib"
 				ShowProgress="0"
-				OutputFile=".\../foobar2000/components/foo_matroska.dll"
+				OutputFile="../foobar2000/components/foo_matroska.dll"
 				LinkIncremental="2"
 				SuppressStartupBanner="true"
 				AdditionalLibraryDirectories="../shared"
 				IgnoreAllDefaultLibraries="false"
 				IgnoreDefaultLibraryNames=""
 				GenerateDebugInformation="true"
-				ProgramDatabaseFile=".\../Debug/foo_matroska.pdb"
-				ImportLibrary=".\../Debug/foo_matroska.lib"
+				ProgramDatabaseFile=".\Debug/foo_matroska.pdb"
+				ImportLibrary=".\Debug/foo_matroska.lib"
 				TargetMachine="1"
 			/>
 			<Tool
@@ -117,7 +117,7 @@
 		</Configuration>
 		<Configuration
 			Name="Release|Win32"
-			OutputDirectory=".\../Release"
+			OutputDirectory=".\Release"
 			IntermediateDirectory=".\Release"
 			ConfigurationType="2"
 			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -176,15 +176,15 @@
 			<Tool
 				Name="VCLinkerTool"
 				AdditionalDependencies="shared.lib libebml.lib libmatroska.lib"
-				OutputFile=".\../Release/foo_input_matroska.dll"
+				OutputFile=".\Release/foo_input_matroska.dll"
 				Version=""
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
 				AdditionalLibraryDirectories="../shared"
 				IgnoreAllDefaultLibraries="false"
 				IgnoreDefaultLibraryNames=""
-				ProgramDatabaseFile=".\../Release/foo_matroska.pdb"
-				ImportLibrary=".\../Release/foo_matroska.lib"
+				ProgramDatabaseFile=".\Release/foo_matroska.pdb"
+				ImportLibrary=".\Release/foo_matroska.lib"
 				TargetMachine="1"
 			/>
 			<Tool

Modified: trunk/foo_input_matroska/matroska_parser.cpp
===================================================================
--- trunk/foo_input_matroska/matroska_parser.cpp	2006-04-30 14:23:26 UTC (rev 1251)
+++ trunk/foo_input_matroska/matroska_parser.cpp	2006-05-10 17:01:56 UTC (rev 1252)
@@ -202,7 +202,7 @@
 	m_FileDate = 0;
 	m_Duration = 0;
 	m_CurrentTimecode = 0;
-	m_ElementLevel0 = NULL;
+	//m_ElementLevel0 = NULL;
 	//UpperElementLevel = 0;
 	m_CurrentEdition = 0;
 	m_CurrentChapter = 0;
@@ -214,12 +214,14 @@
 };
 
 MatroskaAudioParser::~MatroskaAudioParser() {
-	if (m_ElementLevel0 != NULL)
-		delete m_ElementLevel0;
+	//if (m_ElementLevel0 != NULL)
+	//	_DELETE(m_ElementLevel0);
+		//delete m_ElementLevel0;
 	
 	while (!m_Queue.empty()) {
 		MatroskaAudioFrame *currentPacket = m_Queue.front();
-		delete currentPacket;
+		//delete currentPacket;
+		_DELETE(currentPacket);
 		m_Queue.pop();
 	}
 };
@@ -230,39 +232,42 @@
 		int UpperElementLevel = 0;
 		bool bAllowDummy = false;
 		// Elements for different levels
-		EbmlElement *ElementLevel1 = NULL;
-		EbmlElement *ElementLevel2 = NULL;
-		EbmlElement *ElementLevel3 = NULL;
-		EbmlElement *ElementLevel4 = NULL;
-		EbmlElement *ElementLevel5 = NULL;		
+		ElementPtr ElementLevel1;
+		ElementPtr ElementLevel2;
+		ElementPtr ElementLevel3;
+		ElementPtr ElementLevel4;
+		ElementPtr ElementLevel5;
+		ElementPtr NullElement;
 
 		// Be sure we are at the beginning of the file
 		m_IOCallback.setFilePointer(0);
 		// Find the EbmlHead element. Must be the first one.
-		m_ElementLevel0 = m_InputStream.FindNextID(EbmlHead::ClassInfos, 0xFFFFFFFFFFFFFFFFL);
-		if (m_ElementLevel0 == NULL) {
+		m_ElementLevel0 = ElementPtr(m_InputStream.FindNextID(EbmlHead::ClassInfos, 0xFFFFFFFFFFFFFFFFL));
+		if (m_ElementLevel0 == NullElement) {
 			return 1;
 		}
 		//We must have found the EBML head :)
 		m_ElementLevel0->SkipData(m_InputStream, m_ElementLevel0->Generic().Context);
-		delete m_ElementLevel0;
+		//delete m_ElementLevel0;
+		//_DELETE(m_ElementLevel0);
 
 		// Next element must be a segment
-		m_ElementLevel0 = m_InputStream.FindNextID(KaxSegment::ClassInfos, 0xFFFFFFFFFFFFFFFFL);
-		if (m_ElementLevel0 == NULL) {
+		m_ElementLevel0 = ElementPtr(m_InputStream.FindNextID(KaxSegment::ClassInfos, 0xFFFFFFFFFFFFFFFFL));
+		if (m_ElementLevel0 == NullElement) {
 			//No segment/level 0 element found.
 			return 1;
 		}
 		if (!(EbmlId(*m_ElementLevel0) == KaxSegment::ClassInfos.GlobalId)) {
-			delete m_ElementLevel0;
-			m_ElementLevel0 = NULL;
+			//delete m_ElementLevel0;
+			//m_ElementLevel0 = NULL;
+			//_DELETE(m_ElementLevel0);
 			return 1;
 		}
 
 		UpperElementLevel = 0;
 		// We've got our segment, so let's find the tracks
-		ElementLevel1 = m_InputStream.FindNextElement(m_ElementLevel0->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1);
-		while (ElementLevel1 != NULL) {
+		ElementLevel1 = ElementPtr(m_InputStream.FindNextElement(m_ElementLevel0->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1));
+		while (ElementLevel1 != NullElement) {
 			if (UpperElementLevel > 0) {
 				break;
 			}
@@ -294,17 +299,15 @@
 									m_IOCallback.setFilePointer(s_pos+pos+3);
 									uint64 startPos = m_IOCallback.getFilePointer();
 									m_IOCallback.setFilePointer(-4, seek_current);
-									EbmlElement *levelUnknown = m_InputStream.FindNextID(KaxTags::ClassInfos, 0xFFFFFFFFFFFFFFFFL);
-									if ((levelUnknown != NULL) 
+									ElementPtr levelUnknown = ElementPtr(m_InputStream.FindNextID(KaxTags::ClassInfos, 0xFFFFFFFFFFFFFFFFL));
+									if ((levelUnknown != NullElement) 
 										&& (m_FileSize >= startPos + levelUnknown->GetSize()) 
 										&& (EbmlId(*levelUnknown) == KaxTags::ClassInfos.GlobalId))
 									{
-										Parse_Tags(static_cast<KaxTags *>(levelUnknown));
+										Parse_Tags(static_cast<KaxTags *>(levelUnknown.get()));
 										_TIMER("MatroskaAudioParser::Parse(BM)");
 										break;
 									}
-									delete levelUnknown;
-									levelUnknown = NULL;
 									m_IOCallback.setFilePointer(s_pos);
 									pos = search.Match(pos+1);
 								} while (pos != -1);
@@ -323,19 +326,17 @@
 										//seek back 3 bytes, so libmatroska can find the Tags element Ebml ID
 										m_IOCallback.setFilePointer(-4, seek_current);
 
-										EbmlElement *levelUnknown = m_InputStream.FindNextID(KaxTags::ClassInfos, 0xFFFFFFFFFFFFFFFFL);
-										if ((levelUnknown != NULL) 
+										ElementPtr levelUnknown = ElementPtr(m_InputStream.FindNextID(KaxTags::ClassInfos, 0xFFFFFFFFFFFFFFFFL));
+										if ((levelUnknown != NullElement) 
 											&& (m_FileSize >= startPos + levelUnknown->GetSize()) 
 											&& (EbmlId(*levelUnknown) == KaxTags::ClassInfos.GlobalId))
 										{
 											_TIMER("MatroskaAudioParser::Parse()");
-											Parse_Tags(static_cast<KaxTags *>(levelUnknown));
-											delete levelUnknown;
-											levelUnknown = NULL;
+											Parse_Tags(static_cast<KaxTags *>(levelUnknown.get()));
+											//_DELETE(levelUnknown);
 											break;
 										}
-										delete levelUnknown;
-										levelUnknown = NULL;
+										//_DELETE(levelUnknown);
 
 										//Restore the file pos
 										m_IOCallback.setFilePointer(startPos);
@@ -351,8 +352,8 @@
 				}
 			}else if (EbmlId(*ElementLevel1) == KaxInfo::ClassInfos.GlobalId) {
 				// General info about this Matroska file
-				ElementLevel2 = m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, bAllowDummy);
-				while (ElementLevel2 != NULL) {
+				ElementLevel2 = ElementPtr(m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, bAllowDummy));
+				while (ElementLevel2 != NullElement) {
 					if (UpperElementLevel > 0) {
 						break;
 					}
@@ -361,13 +362,13 @@
 					}
 
 					if (EbmlId(*ElementLevel2) == KaxTimecodeScale::ClassInfos.GlobalId) {
-						KaxTimecodeScale &TimeScale = *static_cast<KaxTimecodeScale *>(ElementLevel2);
+						KaxTimecodeScale &TimeScale = *static_cast<KaxTimecodeScale *>(ElementLevel2.get());
 						TimeScale.ReadData(m_InputStream.I_O());
 
 						//matroskaGlobalTrack->SetTimecodeScale(uint64(TimeScale));
 						m_TimecodeScale = uint64(TimeScale);
 					} else if (EbmlId(*ElementLevel2) == KaxDuration::ClassInfos.GlobalId) {
-						KaxDuration &duration = *static_cast<KaxDuration *>(ElementLevel2);
+						KaxDuration &duration = *static_cast<KaxDuration *>(ElementLevel2.get());
 						duration.ReadData(m_InputStream.I_O());
 
 						// it's in milliseconds?
@@ -375,58 +376,60 @@
 						//matroskaGlobalTrack->SetDuration(float(duration) * int64(m_TimecodeScale) / 1000000000.0);
 
 					} else if (EbmlId(*ElementLevel2) == KaxDateUTC::ClassInfos.GlobalId) {
-						KaxDateUTC & DateUTC = *static_cast<KaxDateUTC *>(ElementLevel2);
+						KaxDateUTC & DateUTC = *static_cast<KaxDateUTC *>(ElementLevel2.get());
 						DateUTC.ReadData(m_InputStream.I_O());
 						
 						m_FileDate = DateUTC.GetEpochDate();
 
 					} else if (EbmlId(*ElementLevel2) == KaxSegmentFilename::ClassInfos.GlobalId) {
-						KaxSegmentFilename &tag_SegmentFilename = *static_cast<KaxSegmentFilename *>(ElementLevel2);
+						KaxSegmentFilename &tag_SegmentFilename = *static_cast<KaxSegmentFilename *>(ElementLevel2.get());
 						tag_SegmentFilename.ReadData(m_InputStream.I_O());
 
 						m_SegmentFilename = *static_cast<EbmlUnicodeString *>(&tag_SegmentFilename);
 
 					} else if (EbmlId(*ElementLevel2) == KaxMuxingApp::ClassInfos.GlobalId)	{
-						KaxMuxingApp &tag_MuxingApp = *static_cast<KaxMuxingApp *>(ElementLevel2);
+						KaxMuxingApp &tag_MuxingApp = *static_cast<KaxMuxingApp *>(ElementLevel2.get());
 						tag_MuxingApp.ReadData(m_InputStream.I_O());
 
 						m_MuxingApp = *static_cast<EbmlUnicodeString *>(&tag_MuxingApp);
 
 					} else if (EbmlId(*ElementLevel2) == KaxWritingApp::ClassInfos.GlobalId) {
-						KaxWritingApp &tag_WritingApp = *static_cast<KaxWritingApp *>(ElementLevel2);
+						KaxWritingApp &tag_WritingApp = *static_cast<KaxWritingApp *>(ElementLevel2.get());
 						tag_WritingApp.ReadData(m_InputStream.I_O());
 						
 						m_WritingApp = *static_cast<EbmlUnicodeString *>(&tag_WritingApp);
 
 					} else if (EbmlId(*ElementLevel2) == KaxTitle::ClassInfos.GlobalId) {
-						KaxTitle &Title = *static_cast<KaxTitle*>(ElementLevel2);
+						KaxTitle &Title = *static_cast<KaxTitle*>(ElementLevel2.get());
 						Title.ReadData(m_InputStream.I_O());
 						m_FileTitle = UTFstring(Title).c_str();
 					}
 
 					if (UpperElementLevel > 0) {	// we're coming from ElementLevel3
 						UpperElementLevel--;
-						delete ElementLevel2;
+						//delete ElementLevel2;
 						ElementLevel2 = ElementLevel3;
 						if (UpperElementLevel > 0)
 							break;
 					} else {
 						ElementLevel2->SkipData(m_InputStream, ElementLevel2->Generic().Context);
-						delete ElementLevel2;
-						ElementLevel2 = m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, bAllowDummy);
+						//delete ElementLevel2;
+						//_DELETE(ElementLevel2);
+						ElementLevel2 = ElementPtr(m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, bAllowDummy));
 					}
-				}							
+				}
 			}else if (EbmlId(*ElementLevel1) == KaxChapters::ClassInfos.GlobalId) {
-				Parse_Chapters(static_cast<KaxChapters *>(ElementLevel1));
+				Parse_Chapters(static_cast<KaxChapters *>(ElementLevel1.get()));
 
 			}else if (EbmlId(*ElementLevel1) == KaxTags::ClassInfos.GlobalId) {
-				Parse_Tags(static_cast<KaxTags *>(ElementLevel1));
+				Parse_Tags(static_cast<KaxTags *>(ElementLevel1.get()));
 
 			} else if (EbmlId(*ElementLevel1) == KaxTracks::ClassInfos.GlobalId) {
 				// Yep, we've found our KaxTracks element. Now find all tracks
 				// contained in this segment. 
-				KaxTracks *Tracks = static_cast<KaxTracks *>(ElementLevel1);
-				Tracks->Read(m_InputStream, KaxTracks::ClassInfos.Context, UpperElementLevel, ElementLevel2, bAllowDummy);
+				KaxTracks *Tracks = static_cast<KaxTracks *>(ElementLevel1.get());
+				EbmlElement* tmpElement = ElementLevel2.get();
+				Tracks->Read(m_InputStream, KaxTracks::ClassInfos.Context, UpperElementLevel, tmpElement, bAllowDummy);
 
 				unsigned int Index0;
 				for (Index0 = 0; Index0 < Tracks->ListSize(); Index0++) {
@@ -538,8 +541,9 @@
 				
 				if (bBreakAtClusters) {
 					m_IOCallback.setFilePointer(ElementLevel1->GetElementPosition());
-					delete ElementLevel1;
-					ElementLevel1 = NULL;
+					//delete ElementLevel1;
+					//ElementLevel1 = NULL;
+					//_DELETE(ElementLevel1);
 					break;
 				}
 
@@ -599,13 +603,15 @@
 
 							if (UpperElementLevel > 0) {	// we're coming from ElementLevel4
 								UpperElementLevel--;
-								delete ElementLevel3;
-								ElementLevel3 = ElementLevel4;
+								//delete ElementLevel3;
+								_DELETE(ElementLevel3);
+								ElementLevel3 = ElementLevel4->Clone();
 								if (UpperElementLevel > 0)
 									break;
 							} else {
 								ElementLevel3->SkipData(m_InputStream, ElementLevel3->Generic().Context);
-								delete ElementLevel3;
+								//delete ElementLevel3;
+								_DELETE(ElementLevel3);
 								ElementLevel3 = m_InputStream.FindNextElement(ElementLevel2->Generic().Context, UpperElementLevel, 0xFFFFFFFFL, true, 1);
 							}					
 						} // while (ElementLevel3 != NULL)
@@ -614,35 +620,40 @@
 
 					if (UpperElementLevel > 0) {	// we're coming from ElementLevel3
 						UpperElementLevel--;
-						delete ElementLevel2;
-						ElementLevel2 = ElementLevel3;
+						//delete ElementLevel2;
+						_DELETE(ElementLevel2);
+						ElementLevel2 = ElementLevel3->Clone();
 						if (UpperElementLevel > 0)
 							break;
 					} else {
 						ElementLevel2->SkipData(m_InputStream, ElementLevel2->Generic().Context);
-						delete ElementLevel2;
+						//delete ElementLevel2;
+						_DELETE(ElementLevel2);
 						ElementLevel2 = m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, 0xFFFFFFFFL, true, 1);
 					}
 				} // while (ElementLevel2 != NULL)							
 #endif
 			}
-
 			
 			if (UpperElementLevel > 0) {		// we're coming from ElementLevel2
 				UpperElementLevel--;
-				delete ElementLevel1;
+				//delete ElementLevel1;
+				//_DELETE(ElementLevel1);
 				ElementLevel1 = ElementLevel2;
 				if (UpperElementLevel > 0)
 					break;
 			} else {
 				ElementLevel1->SkipData(m_InputStream, ElementLevel1->Generic().Context);
-				delete ElementLevel1;
-				ElementLevel1 = NULL;
+				//delete ElementLevel1;
+				//ElementLevel1 = NULL;
+				//_DELETE(ElementLevel1);
 
-				ElementLevel1 = m_InputStream.FindNextElement(m_ElementLevel0->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1);
+				ElementLevel1 = ElementPtr(m_InputStream.FindNextElement(m_ElementLevel0->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1));
 			}
-		} // while (ElementLevel1 != NULL)		
-	
+		} // while (ElementLevel1 != NULL)
+		//_DELETE(ElementLevel3);
+		//_DELETE(ElementLevel2);
+		//_DELETE(ElementLevel1);
 	} catch (std::exception &) {
 		return 1;
 
@@ -657,7 +668,7 @@
 //int MatroskaAudioParser::WriteTags(const file_info & info)
 int MatroskaAudioParser::WriteTags()
 {
-	KaxTags & MyKaxTags = GetChild<KaxTags>(*static_cast<EbmlMaster *>(m_ElementLevel0));
+	KaxTags & MyKaxTags = GetChild<KaxTags>(*static_cast<EbmlMaster *>(m_ElementLevel0.get()));
 
 	// On to writing :)
 	if (m_TagPos == 0) {
@@ -737,7 +748,7 @@
 
 		m_IOCallback.setFilePointer(m_TagPos);
 		// Now we write the tags to the file
-		EbmlVoid & Dummy = GetChild<EbmlVoid>(*static_cast<EbmlMaster *>(m_ElementLevel0));
+		EbmlVoid & Dummy = GetChild<EbmlVoid>(*static_cast<EbmlMaster *>(m_ElementLevel0.get()));
 		uint64 size_of_tags = m_TagSize;
 		MyKaxTags.UpdateSize(true);
 		if (size_of_tags < MyKaxTags.GetSize())
@@ -759,7 +770,7 @@
 		
 		//l0->UpdateSize(false, true);
 		std::auto_ptr<KaxSegment> new_segment(new KaxSegment);
-		KaxSegment * segment = (KaxSegment *)m_ElementLevel0;
+		KaxSegment * segment = (KaxSegment *)m_ElementLevel0.get();
 
 		m_IOCallback.setFilePointer(segment->GetElementPosition());
 		new_segment->WriteHead(m_IOCallback, segment->HeadSize() - 4);
@@ -1536,7 +1547,8 @@
 			}
 			last_time = packet_time;
 			done += (last_laced = currentPacket->dataBuffer.size());
-			delete currentPacket;
+			//delete currentPacket;
+			_DELETE(currentPacket);
 			m_Queue.pop();
 		}
 		if (FillQueue()!=0)
@@ -1549,7 +1561,8 @@
 {
 	while (!m_Queue.empty()) {
 		MatroskaAudioFrame *currentPacket = m_Queue.front();
-		delete currentPacket;
+		//delete currentPacket;
+		_DELETE(currentPacket);
 		m_Queue.pop();
 	}
 }
@@ -1566,7 +1579,7 @@
 
 bool MatroskaAudioParser::Seek(double seconds,unsigned & frames_to_skip,double & time_to_skip,unsigned samplerate_hint)
 {
-	int64 ret = 0;	
+	int64 ret = 0;
 
 	if (m_CurrentChapter != NULL) {
 		seconds += (double)(int64)m_CurrentChapter->timeStart / 1000000000; // ns -> seconds
@@ -1601,20 +1614,22 @@
 	}
 };
 
+typedef boost::shared_ptr<EbmlId> EbmlIdPtr;
 
-void MatroskaAudioParser::Parse_MetaSeek(EbmlElement *metaSeekElement, bool bInfoOnly) 
+void MatroskaAudioParser::Parse_MetaSeek(ElementPtr metaSeekElement, bool bInfoOnly) 
 {
 	uint64 lastSeekPos = 0;
 	uint64 endSeekPos = 0;
-	EbmlElement *l2 = NULL;
-	EbmlElement *l3 = NULL;
+	ElementPtr l2;
+	ElementPtr l3;
+	ElementPtr NullElement;
 	int UpperElementLevel = 0;
 
-	if (metaSeekElement == NULL)
+	if (metaSeekElement == NullElement)
 		return;
 
-	l2 = m_InputStream.FindNextElement(metaSeekElement->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1);
-	while (l2 != NULL) {
+	l2 = ElementPtr(m_InputStream.FindNextElement(metaSeekElement->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1));
+	while (l2 != NullElement) {
 		if (UpperElementLevel > 0) {
 			break;
 		}
@@ -1624,10 +1639,11 @@
 
 		if (EbmlId(*l2) == KaxSeek::ClassInfos.GlobalId) {
 			//Wow we found the SeekEntries, time to speed up reading ;)
-			l3 = m_InputStream.FindNextElement(l2->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1);
+			l3 = ElementPtr(m_InputStream.FindNextElement(l2->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1));
 
-			EbmlId *id = NULL;
-			while (l3 != NULL) {
+			//EbmlId *id = NULL;
+			EbmlIdPtr id;
+			while (l3 != NullElement) {
 				if (UpperElementLevel > 0) {
 					break;
 				}
@@ -1642,9 +1658,10 @@
 					seek_id.ReadData(m_InputStream.I_O(), SCOPE_ALL_DATA);
 					b = seek_id.GetBuffer();
 					s = (uint16)seek_id.GetSize();
-					delete id;
-					id = NULL;
-					id = new EbmlId(b, s);
+					//delete id;
+					//id = NULL;
+					//_DELETE(id);
+					id = EbmlIdPtr(new EbmlId(b, s));
 
 				} else if (EbmlId(*l3) == KaxSeekPosition::ClassInfos.GlobalId) {
 					KaxSeekPosition &seek_pos = static_cast<KaxSeekPosition &>(*l3);
@@ -1658,16 +1675,17 @@
 						//uint64 orig_pos = inputFile.getFilePointer();									
 						MatroskaMetaSeekClusterEntry newCluster;
 						newCluster.timecode = MAX_UINT64;
-						newCluster.filePos = static_cast<KaxSegment *>(m_ElementLevel0)->GetGlobalPosition(lastSeekPos);
+						newCluster.filePos = static_cast<KaxSegment *>(m_ElementLevel0.get())->GetGlobalPosition(lastSeekPos);
 						m_ClusterIndex.push_back(newCluster);
 
 					} else if ((*id == KaxSeekHead::ClassInfos.GlobalId) && !bInfoOnly) {
 						NOTE1("Found MetaSeek Seek Entry Postion: %u", (unsigned long)lastSeekPos);
 						uint64 orig_pos = m_IOCallback.getFilePointer();									
-						m_IOCallback.setFilePointer(static_cast<KaxSegment *>(m_ElementLevel0)->GetGlobalPosition(lastSeekPos));
+						m_IOCallback.setFilePointer(static_cast<KaxSegment *>(m_ElementLevel0.get())->GetGlobalPosition(lastSeekPos));
 						
-						EbmlElement *levelUnknown = m_InputStream.FindNextID(KaxSeekHead::ClassInfos, 0xFFFFFFFFFFFFFFFFL);										
+						ElementPtr levelUnknown = ElementPtr(m_InputStream.FindNextID(KaxSeekHead::ClassInfos, 0xFFFFFFFFFFFFFFFFL));										
 						Parse_MetaSeek(levelUnknown, false);
+						//_DELETE(levelUnknown);
 
 						m_IOCallback.setFilePointer(orig_pos);
 					}
@@ -1676,30 +1694,36 @@
 
 				}
 				l3->SkipData(m_InputStream, l3->Generic().Context);
-				delete l3;
-				l3 = NULL;
-				l3 = m_InputStream.FindNextElement(l2->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1);
+				//delete l3;
+				//l3 = NULL;
+				//_DELETE(l3);
+				l3 = ElementPtr(m_InputStream.FindNextElement(l2->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1));
 			} // while (l3 != NULL)
-			delete id;
-			id = NULL;
+			//delete id;
+			//id = NULL;
+			//_DELETE(id);
 		} else {
 
 		}
 
 		if (UpperElementLevel > 0) {    // we're coming from l3
 			UpperElementLevel--;
-			delete l2;
+			//delete l2;
+			//_DELETE(l2);
 			l2 = l3;
 			if (UpperElementLevel > 0)
 				break;
 
 		} else {
 			l2->SkipData(m_InputStream, l2->Generic().Context);
-			delete l2;
-			l2 = NULL;
-			l2 = m_InputStream.FindNextElement(metaSeekElement->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1);
+			//delete l2;
+			//l2 = NULL;
+			//_DELETE(l2);
+			l2 = ElementPtr(m_InputStream.FindNextElement(metaSeekElement->Generic().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1));
 		}
 	} // while (l2 != NULL)
+	//_DELETE(l3);
+	//_DELETE(l2);
 }
 
 #define IS_ELEMENT_ID(__x__) (Element->Generic().GlobalId == __x__::ClassInfos.GlobalId)
@@ -1946,11 +1970,12 @@
 	int UpperElementLevel = 0;
 	bool bAllowDummy = false;
 	// Elements for different levels
-	EbmlElement *ElementLevel1 = NULL;
-	EbmlElement *ElementLevel2 = NULL;
-	EbmlElement *ElementLevel3 = NULL;
-	EbmlElement *ElementLevel4 = NULL;
-	m_framebuffer.set_size(0);
+	ElementPtr ElementLevel1;
+	ElementPtr ElementLevel2;
+	ElementPtr ElementLevel3;
+	ElementPtr ElementLevel4;
+	ElementPtr NullElement;
+	//m_framebuffer.set_size(0);
 
 	if (m_IOCallback.seekable()) {
 		MatroskaMetaSeekClusterEntry *currentCluster = FindCluster(m_CurrentTimecode);
@@ -1962,18 +1987,18 @@
 
 		m_IOCallback.setFilePointer(clusterFilePos);
 		// Find the element data
-		ElementLevel1 = m_InputStream.FindNextID(KaxCluster::ClassInfos, 0xFFFFFFFFFFFFFFFFL);
-		if (ElementLevel1 == NULL)
+		ElementLevel1 = ElementPtr(m_InputStream.FindNextID(KaxCluster::ClassInfos, 0xFFFFFFFFFFFFFFFFL));
+		if (ElementLevel1 == NullElement)
 			return 1;
 
 		if (EbmlId(*ElementLevel1) == KaxCluster::ClassInfos.GlobalId) {
-			KaxCluster *SegmentCluster = static_cast<KaxCluster *>(ElementLevel1);
+			KaxCluster *SegmentCluster = static_cast<KaxCluster *>(ElementLevel1.get());
 			uint32 ClusterTimecode = 0;
 			MatroskaAudioFrame *prevFrame = NULL;
 
 			// read blocks and discard the ones we don't care about
-			ElementLevel2 = m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, ElementLevel1->ElementSize(), bAllowDummy);
-			while (ElementLevel2 != NULL) {
+			ElementLevel2 = ElementPtr(m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, ElementLevel1->ElementSize(), bAllowDummy));
+			while (ElementLevel2 != NullElement) {
 				if (UpperElementLevel > 0) {
 					break;
 				}
@@ -1981,7 +2006,7 @@
 					UpperElementLevel = 0;
 				}
 				if (EbmlId(*ElementLevel2) == KaxClusterTimecode::ClassInfos.GlobalId) {						
-					KaxClusterTimecode & ClusterTime = *static_cast<KaxClusterTimecode*>(ElementLevel2);
+					KaxClusterTimecode & ClusterTime = *static_cast<KaxClusterTimecode*>(ElementLevel2.get());
 					ClusterTime.ReadData(m_InputStream.I_O());
 					ClusterTimecode = uint32(ClusterTime);
 					currentCluster->timecode = ClusterTimecode * m_TimecodeScale;
@@ -1992,8 +2017,8 @@
 					// Create a new frame
 					MatroskaAudioFrame *newFrame = new MatroskaAudioFrame;
 
-					ElementLevel3 = m_InputStream.FindNextElement(ElementLevel2->Generic().Context, UpperElementLevel, ElementLevel2->ElementSize(), bAllowDummy);
-					while (ElementLevel3 != NULL) {
+					ElementLevel3 = ElementPtr(m_InputStream.FindNextElement(ElementLevel2->Generic().Context, UpperElementLevel, ElementLevel2->ElementSize(), bAllowDummy));
+					while (ElementLevel3 != NullElement) {
 						if (UpperElementLevel > 0) {
 							break;
 						}
@@ -2001,7 +2026,7 @@
 							UpperElementLevel = 0;
 						}
 						if (EbmlId(*ElementLevel3) == KaxBlock::ClassInfos.GlobalId) {								
-							KaxBlock & DataBlock = *static_cast<KaxBlock*>(ElementLevel3);														
+							KaxBlock & DataBlock = *static_cast<KaxBlock*>(ElementLevel3.get());														
 							DataBlock.ReadData(m_InputStream.I_O());		
 							DataBlock.SetParent(*SegmentCluster);
 
@@ -2039,22 +2064,24 @@
 							//wxLogDebug("  Reference frame at scaled (%d) timecode %ld\n", int32(RefTime), int32(int64(RefTime) * TimecodeScale));
 							*/
 						} else if (EbmlId(*ElementLevel3) == KaxBlockDuration::ClassInfos.GlobalId) {
-							KaxBlockDuration & BlockDuration = *static_cast<KaxBlockDuration*>(ElementLevel3);
+							KaxBlockDuration & BlockDuration = *static_cast<KaxBlockDuration*>(ElementLevel3.get());
 							BlockDuration.ReadData(m_InputStream.I_O());
 							newFrame->duration = uint32(BlockDuration);
 						}
 						if (UpperElementLevel > 0) {
 							UpperElementLevel--;
-							delete ElementLevel3;
+							//delete ElementLevel3;
+							//_DELETE(ElementLevel3);
 							ElementLevel3 = ElementLevel4;
 							if (UpperElementLevel > 0)
 								break;
 						} else {
 							ElementLevel3->SkipData(m_InputStream, ElementLevel3->Generic().Context);
-							delete ElementLevel3;
-							ElementLevel3 = NULL;
+							//delete ElementLevel3;
+							//ElementLevel3 = NULL;
+							//_DELETE(ElementLevel3);
 
-							ElementLevel3 = m_InputStream.FindNextElement(ElementLevel2->Generic().Context, UpperElementLevel, ElementLevel2->ElementSize(), bAllowDummy);
+							ElementLevel3 = ElementPtr(m_InputStream.FindNextElement(ElementLevel2->Generic().Context, UpperElementLevel, ElementLevel2->ElementSize(), bAllowDummy));
 						}							
 						//newFrame = new MatroskaReadFrame();
 					}
@@ -2080,21 +2107,26 @@
 
 				if (UpperElementLevel > 0) {
 					UpperElementLevel--;
-					delete ElementLevel2;
+					//delete ElementLevel2;
+					//_DELETE(ElementLevel2);
 					ElementLevel2 = ElementLevel3;
 					if (UpperElementLevel > 0)
 						break;
 				} else {
 					ElementLevel2->SkipData(m_InputStream, ElementLevel2->Generic().Context);
 					//if (ElementLevel2 != pChecksum)
-						delete ElementLevel2;								
-					ElementLevel2 = NULL;
+					//	delete ElementLevel2;								
+					//ElementLevel2 = NULL;
+					//_DELETE(ElementLevel2);
 
-					ElementLevel2 = m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, ElementLevel1->ElementSize(), bAllowDummy);
+					ElementLevel2 = ElementPtr(m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, ElementLevel1->ElementSize(), bAllowDummy));
 				}
 			}
 		}
-		delete ElementLevel1;
+		//_DELETE(ElementLevel3);
+		//_DELETE(ElementLevel2);
+		//_DELETE(ElementLevel1);
+		//delete ElementLevel1;
 		
 		if (currentCluster->clusterNo < m_ClusterIndex.size()-1) {
 			if (m_ClusterIndex[currentCluster->clusterNo+1].timecode == MAX_UINT64)
@@ -2111,17 +2143,17 @@
 		
 	} else {
 		// Find the element data
-		ElementLevel1 = m_InputStream.FindNextID(KaxCluster::ClassInfos, 0xFFFFFFFFFFFFFFFFL);
-		if (ElementLevel1 == NULL)
+		ElementLevel1 = ElementPtr(m_InputStream.FindNextID(KaxCluster::ClassInfos, 0xFFFFFFFFFFFFFFFFL));
+		if (ElementLevel1 == NullElement)
 			return 1;
 
 		if (EbmlId(*ElementLevel1) == KaxCluster::ClassInfos.GlobalId) {
-			KaxCluster *SegmentCluster = static_cast<KaxCluster *>(ElementLevel1);
+			KaxCluster *SegmentCluster = static_cast<KaxCluster *>(ElementLevel1.get());
 			uint32 ClusterTimecode = 0;
 
 			// read blocks and discard the ones we don't care about
-			ElementLevel2 = m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, ElementLevel1->ElementSize(), bAllowDummy);
-			while (ElementLevel2 != NULL) {
+			ElementLevel2 = ElementPtr(m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, ElementLevel1->ElementSize(), bAllowDummy));
+			while (ElementLevel2 != NullElement) {
 				if (UpperElementLevel > 0) {
 					break;
 				}
@@ -2129,7 +2161,7 @@
 					UpperElementLevel = 0;
 				}
 				if (EbmlId(*ElementLevel2) == KaxClusterTimecode::ClassInfos.GlobalId) {						
-					KaxClusterTimecode & ClusterTime = *static_cast<KaxClusterTimecode*>(ElementLevel2);
+					KaxClusterTimecode & ClusterTime = *static_cast<KaxClusterTimecode*>(ElementLevel2.get());
 					ClusterTime.ReadData(m_InputStream.I_O());
 					ClusterTimecode = uint32(ClusterTime);
 					SegmentCluster->InitTimecode(ClusterTimecode, m_TimecodeScale);
@@ -2139,8 +2171,8 @@
 					// Create a new frame
 					MatroskaAudioFrame *newFrame = new MatroskaAudioFrame;				
 
-					ElementLevel3 = m_InputStream.FindNextElement(ElementLevel2->Generic().Context, UpperElementLevel, ElementLevel2->ElementSize(), bAllowDummy);
-					while (ElementLevel3 != NULL) {
+					ElementLevel3 = ElementPtr(m_InputStream.FindNextElement(ElementLevel2->Generic().Context, UpperElementLevel, ElementLevel2->ElementSize(), bAllowDummy));
+					while (ElementLevel3 != NullElement) {
 						if (UpperElementLevel > 0) {
 							break;
 						}
@@ -2148,7 +2180,7 @@
 							UpperElementLevel = 0;
 						}
 						if (EbmlId(*ElementLevel3) == KaxBlock::ClassInfos.GlobalId) {								
-							KaxBlock & DataBlock = *static_cast<KaxBlock*>(ElementLevel3);														
+							KaxBlock & DataBlock = *static_cast<KaxBlock*>(ElementLevel3.get());														
 							DataBlock.ReadData(m_InputStream.I_O());		
 							DataBlock.SetParent(*SegmentCluster);
 
@@ -2186,22 +2218,24 @@
 							//wxLogDebug("  Reference frame at scaled (%d) timecode %ld\n", int32(RefTime), int32(int64(RefTime) * TimecodeScale));
 							*/
 						} else if (EbmlId(*ElementLevel3) == KaxBlockDuration::ClassInfos.GlobalId) {
-							KaxBlockDuration & BlockDuration = *static_cast<KaxBlockDuration*>(ElementLevel3);
+							KaxBlockDuration & BlockDuration = *static_cast<KaxBlockDuration*>(ElementLevel3.get());
 							BlockDuration.ReadData(m_InputStream.I_O());
 							newFrame->duration = uint32(BlockDuration);
 						}
 						if (UpperElementLevel > 0) {
 							UpperElementLevel--;
-							delete ElementLevel3;
+							//delete ElementLevel3;
+							//_DELETE(ElementLevel3);
 							ElementLevel3 = ElementLevel4;
 							if (UpperElementLevel > 0)
 								break;
 						} else {
 							ElementLevel3->SkipData(m_InputStream, ElementLevel3->Generic().Context);
-							delete ElementLevel3;
-							ElementLevel3 = NULL;
+							//delete ElementLevel3;
+							//ElementLevel3 = NULL;
+							//_DELETE(ElementLevel3);
 
-							ElementLevel3 = m_InputStream.FindNextElement(ElementLevel2->Generic().Context, UpperElementLevel, ElementLevel2->ElementSize(), bAllowDummy);
+							ElementLevel3 = ElementPtr(m_InputStream.FindNextElement(ElementLevel2->Generic().Context, UpperElementLevel, ElementLevel2->ElementSize(), bAllowDummy));
 						}							
 						//newFrame = new MatroskaReadFrame();
 					}
@@ -2211,22 +2245,27 @@
 
 				if (UpperElementLevel > 0) {
 					UpperElementLevel--;
-					delete ElementLevel2;
+					//delete ElementLevel2;
+					//_DELETE(ElementLevel2);
 					ElementLevel2 = ElementLevel3;
 					if (UpperElementLevel > 0)
 						break;
 				} else {
 					ElementLevel2->SkipData(m_InputStream, ElementLevel2->Generic().Context);
 					//if (ElementLevel2 != pChecksum)
-						delete ElementLevel2;								
-					ElementLevel2 = NULL;
+					//	delete ElementLevel2;								
+					//ElementLevel2 = NULL;
+					//_DELETE(ElementLevel2);
 
-					ElementLevel2 = m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, ElementLevel1->ElementSize(), bAllowDummy);
+					ElementLevel2 = ElementPtr(m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, ElementLevel1->ElementSize(), bAllowDummy));
 				}
 			}
 		}
 		ElementLevel1->SkipData(m_InputStream, ElementLevel1->Generic().Context);
-		delete ElementLevel1;
+		//_DELETE(ElementLevel3);
+		//_DELETE(ElementLevel2);
+		//_DELETE(ElementLevel1);
+		//delete ElementLevel1;
 	}
 	//NOTE1("MatroskaAudioParser::FillQueue() - Queue now has %u frames", m_Queue.size());
 	return 0;
@@ -2238,14 +2277,15 @@
 
 		int UpperElementLevel = 0;
 		// Elements for different levels
-		EbmlElement *ElementLevel1 = NULL;
-		EbmlElement *ElementLevel2 = NULL;		
-		EbmlElement *ElementLevel3 = NULL;		
+		ElementPtr ElementLevel1;
+		ElementPtr ElementLevel2;		
+		ElementPtr ElementLevel3;
+		ElementPtr NullElement;
 
 		m_IOCallback.setFilePointer(filePos);
 		// Find the element data
-		ElementLevel1 = m_InputStream.FindNextID(KaxCluster::ClassInfos, 0xFFFFFFFFFFFFFFFFL);
-		if (ElementLevel1 == NULL)
+		ElementLevel1 = ElementPtr(m_InputStream.FindNextID(KaxCluster::ClassInfos, 0xFFFFFFFFFFFFFFFFL));
+		if (ElementLevel1 == NullElement)
 			return MAX_UINT64;
 
 		if (EbmlId(*ElementLevel1) == KaxCluster::ClassInfos.GlobalId) {
@@ -2253,8 +2293,8 @@
 			//uint32 ClusterTimecode = 0;
 
 			// read blocks and discard the ones we don't care about
-			ElementLevel2 = m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, ElementLevel1->ElementSize(), false);
-			while (ElementLevel2 != NULL) {
+			ElementLevel2 = ElementPtr(m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, ElementLevel1->ElementSize(), false));
+			while (ElementLevel2 != NullElement) {
 				if (UpperElementLevel > 0) {
 					break;
 				}
@@ -2262,7 +2302,7 @@
 					UpperElementLevel = 0;
 				}
 				if (EbmlId(*ElementLevel2) == KaxClusterTimecode::ClassInfos.GlobalId) {						
-					KaxClusterTimecode & ClusterTime = *static_cast<KaxClusterTimecode*>(ElementLevel2);
+					KaxClusterTimecode & ClusterTime = *static_cast<KaxClusterTimecode*>(ElementLevel2.get());
 					ClusterTime.ReadData(m_InputStream.I_O());
 					ret = uint64(ClusterTime) * m_TimecodeScale;
 					
@@ -2270,21 +2310,27 @@
 
 				if (UpperElementLevel > 0) {
 					UpperElementLevel--;
-					delete ElementLevel2;
+					//delete ElementLevel2;
+					//_DELETE(ElementLevel2);
 					ElementLevel2 = ElementLevel3;
 					if (UpperElementLevel > 0)
 						break;
 				} else {
 					ElementLevel2->SkipData(m_InputStream, ElementLevel2->Generic().Context);
 					//if (ElementLevel2 != pChecksum)
-					delete ElementLevel2;								
-					ElementLevel2 = NULL;
+					//delete ElementLevel2;								
+					//ElementLevel2 = NULL;
+					//_DELETE(ElementLevel2);
+					ElementLevel2 = NullElement;
 					if (ret == -1)
-						ElementLevel2 = m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, ElementLevel1->ElementSize(), false);
+						ElementLevel2 = ElementPtr(m_InputStream.FindNextElement(ElementLevel1->Generic().Context, UpperElementLevel, ElementLevel1->ElementSize(), false));
 				}
 			}
 		}
-		delete ElementLevel1;
+		//_DELETE(ElementLevel3);
+		//_DELETE(ElementLevel2);
+		//_DELETE(ElementLevel1);
+		//delete ElementLevel1;
 
 		return ret;
 	} catch (...) {

Modified: trunk/foo_input_matroska/matroska_parser.h
===================================================================
--- trunk/foo_input_matroska/matroska_parser.h	2006-04-30 14:23:26 UTC (rev 1251)
+++ trunk/foo_input_matroska/matroska_parser.h	2006-05-10 17:01:56 UTC (rev 1252)
@@ -31,6 +31,7 @@
 #include "DbgOut.h"
 #include <queue>
 #include <deque>
+#include <boost/shared_ptr.hpp>
 
 // libebml includes
 #include "ebml/StdIOCallback.h"
@@ -69,6 +70,7 @@
 
 #define TIMECODE_SCALE  1000000
 #define MAX_UINT64 0xFFFFFFFFFFFFFFFF
+#define _DELETE(__x) if (__x) { delete __x; __x = NULL; }
 
 //Memory Leak Debuging define
 #ifdef _DEBUG
@@ -94,6 +96,7 @@
 using namespace LIBMATROSKA_NAMESPACE;
 
 typedef std::vector<uint8> ByteArray;
+typedef boost::shared_ptr<EbmlElement> ElementPtr;
 
 class MatroskaAudioFrame {
 public:
@@ -271,7 +274,7 @@
 	MatroskaAudioFrame * ReadSingleFrame();
 
 protected:
-	void Parse_MetaSeek(EbmlElement *metaSeekElement, bool bInfoOnly);
+	void Parse_MetaSeek(ElementPtr metaSeekElement, bool bInfoOnly);
 	void Parse_Chapters(KaxChapters *chaptersElement);
 	void Parse_Chapter_Atom(KaxChapterAtom *ChapterAtom);
 	void Parse_Tags(KaxTags *tagsElement);
@@ -306,7 +309,7 @@
 	Foobar2000ReaderIOCallback m_IOCallback;
 	EbmlStream m_InputStream;
 	/// The main/base/master element, should be the segment
-	EbmlElement *m_ElementLevel0;
+	ElementPtr m_ElementLevel0;
 
 	MatroskaEditionInfo *m_CurrentEdition;
 	MatroskaChapterInfo *m_CurrentChapter;
@@ -336,7 +339,7 @@
 	uint32 m_TagSize;
 	uint32 m_TagScanRange;
 
-	pfc::alloc_fast<BYTE> m_framebuffer;
+	//pfc::alloc_fast<BYTE> m_framebuffer;
 	//mem_block_factalloc<BYTE> m_framebuffer;
 	//int UpperElementLevel;
 private:



More information about the Matroska-cvs mailing list