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

ayana at matroska.org ayana at matroska.org
Thu Jul 13 17:47:52 CEST 2006


Author: ayana
Date: 2006-07-13 19:47:42 +0400 (Thu, 13 Jul 2006)
New Revision: 1255

Added:
   trunk/foo_input_matroska/container_matroska.h
   trunk/foo_input_matroska/container_matroska_impl.cpp
   trunk/foo_input_matroska/container_matroska_impl.h
Modified:
   trunk/foo_input_matroska/Foobar2000ReaderIOCallback.h
   trunk/foo_input_matroska/foo_input_matroska.cpp
   trunk/foo_input_matroska/foo_input_matroska.rc
   trunk/foo_input_matroska/matroska_parser.cpp
   trunk/foo_input_matroska/matroska_parser.h
   trunk/foo_input_matroska/resource.h
Log:
0.9.1.0
add: offers service of container_matroska (see "container_matroska.h")
add: support - DataAdditional Block (for WavPack hybrid mode)
add: support - nested ChapterAtom
add: output pregap (techinfo)

Modified: trunk/foo_input_matroska/Foobar2000ReaderIOCallback.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/foo_input_matroska/Foobar2000ReaderIOCallback.h	2006-06-02 14:3=
2:52 UTC (rev 1254)
+++ trunk/foo_input_matroska/Foobar2000ReaderIOCallback.h	2006-07-13 15:4=
7:42 UTC (rev 1255)
@@ -23,17 +23,15 @@
=20
 class Foobar2000ReaderIOCallback : public IOCallback {
 public:
-	Foobar2000ReaderIOCallback(service_ptr_t<file> source, abort_callback &=
 p_abort)
+	Foobar2000ReaderIOCallback(service_ptr_t<file> & source, abort_callback=
 & p_abort)
 		: m_abort(p_abort)
 	{
-		m_NoSeekReader =3D NULL;
 		m_Reader =3D source;
-		//m_Reader->service_add_ref();
 		if (!m_Reader->can_seek()) {
 			m_NoSeekReader =3D source;
-			//m_Reader =3D new service_impl_p2_t<reader_seekback_wrap,service_ptr=
_t<file>,unsigned>(source, 1024*1024);
 		}
 	};
+
 	virtual ~Foobar2000ReaderIOCallback() {
 		close();
 	};
@@ -49,10 +47,10 @@
 				m_Reader->seek(Offset, m_abort);
 				break;
 			case seek_current:
-				m_Reader->seek_ex(Offset, file::t_seek_mode::seek_from_current, m_ab=
ort);
+				m_Reader->seek_ex(Offset, file::seek_from_current, m_abort);
 				break;
 			case seek_end:
-				m_Reader->seek_ex(Offset, file::t_seek_mode::seek_from_eof, m_abort)=
;
+				m_Reader->seek_ex(Offset, file::seek_from_eof, m_abort);
 				break;
 			default:
 				//throw "Invalid Seek Mode!!!";
@@ -70,14 +68,6 @@
 	};
=20
 	virtual void close() {
-		if (m_Reader !=3D NULL) {
-			//m_Reader->service_release();
-			//m_Reader =3D NULL;
-		}
-		if (m_NoSeekReader !=3D NULL) {
-			//m_NoSeekReader->service_release();
-			//m_NoSeekReader =3D NULL;
-		}
 	}
=20
 	bool seekable() {

Added: trunk/foo_input_matroska/container_matroska.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/foo_input_matroska/container_matroska.h	2006-06-02 14:32:52 UTC=
 (rev 1254)
+++ trunk/foo_input_matroska/container_matroska.h	2006-07-13 15:47:42 UTC=
 (rev 1255)
@@ -0,0 +1,54 @@
+#ifndef _CONTAINER_MATROSKA_H_
+#define _CONTAINER_MATROSKA_H_
+
+namespace foobar2000_io {
+
+    namespace matroska {
+        class NOVTABLE attachment {
+        public:
+            virtual ~attachment() {};
+            virtual void get_name(pfc::string_base & p_out)=3D0;
+            virtual void get_mime_type(pfc::string_base & p_out)=3D0;
+            virtual void get_description(pfc::string_base & p_out)=3D0;
+            virtual t_size get_size()=3D0;
+            virtual t_sfilesize get_position()=3D0;
+            virtual void get(void * p_buffer, t_size p_size =3D 0)=3D0;
+            virtual void get(void * p_buffer, t_sfilesize p_position, t_=
size p_size)=3D0;
+        };
+
+        typedef pfc::ptr_list_t<attachment> attachment_list_t;
+    };
+
+    class NOVTABLE container_matroska : public service_base {
+    public:
+        virtual void open(service_ptr_t<container_matroska> & p_out, ser=
vice_ptr_t<file> & p_file, bool p_info_only, abort_callback & p_abort)=3D=
0;
+        virtual matroska::attachment_list_t & get_attachment_list()=3D0;
+    public:
+        static void g_open(service_ptr_t<container_matroska> & p_out, se=
rvice_ptr_t<file> & p_file, bool p_info_only, abort_callback & p_abort) {
+            service_enum_t<container_matroska> e;
+            service_ptr_t<container_matroska> ptr;
+            if (e.first(ptr)) {
+                do {
+                    p_file->reopen(p_abort);
+		            try {
+			            ptr->open(p_out, p_file, p_info_only, p_abort);
+			            return;
+		            } catch(exception_io_data const &) {}
+	            } while(e.next(ptr));
+            }
+	        throw exception_io_data();
+        }
+
+        FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(container_matroska);
+    };
+
+};
+
+template<typename T>
+class container_matroska_factory_t : public service_factory_t<T> {};
+
+// {32491C6C-F941-42cf-8519-EBF5061BB088}
+FOOGUIDDECL const GUID container_matroska::class_guid =3D=20
+{ 0x32491c6c, 0xf941, 0x42cf, { 0x85, 0x19, 0xeb, 0xf5, 0x6, 0x1b, 0xb0,=
 0x88 } };
+
+#endif // _CONTAINER_MATROSKA_H_
\ No newline at end of file

Added: trunk/foo_input_matroska/container_matroska_impl.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/foo_input_matroska/container_matroska_impl.cpp	2006-06-02 14:32=
:52 UTC (rev 1254)
+++ trunk/foo_input_matroska/container_matroska_impl.cpp	2006-07-13 15:47=
:42 UTC (rev 1255)
@@ -0,0 +1,64 @@
+#include "container_matroska_impl.h"
+
+/**
+ * matroska::attachment
+ */
+
+matroska::attachment_impl::attachment_impl(service_ptr_t<file> & p_file,=
 const MatroskaAttachment p_attachment, abort_callback & p_abort)
+: m_file(p_file)
+{
+    m_abort =3D &p_abort;
+    m_attachment =3D p_attachment;
+    console::info("construct");
+}
+
+void matroska::attachment_impl::get_name(pfc::string_base & p_out) {
+    p_out =3D m_attachment.FileName.GetUTF8().c_str();
+}
+
+void matroska::attachment_impl::get_mime_type(pfc::string_base & p_out) =
{
+    p_out =3D m_attachment.MimeType.c_str();
+}
+
+void matroska::attachment_impl::get_description(pfc::string_base & p_out=
) {
+    p_out =3D m_attachment.Description.GetUTF8().c_str();
+}
+
+t_size matroska::attachment_impl::get_size() {
+    return static_cast<t_size>(m_attachment.SourceDataLength);
+}
+
+t_sfilesize matroska::attachment_impl::get_position() {
+    return static_cast<t_sfilesize>(m_attachment.SourceStartPos);
+}
+
+void matroska::attachment_impl::get(void * p_buffer, t_size p_size) {
+    if (!p_size) {
+        p_size =3D get_size();
+    }
+    get(p_buffer, get_position(), p_size);
+}
+
+void matroska::attachment_impl::get(void * p_buffer, t_sfilesize p_posit=
ion, t_size p_size) {
+    m_file->seek_ex(p_position, file::seek_from_beginning, *m_abort);
+    m_file->read(p_buffer, p_size, *m_abort);
+}
+
+/**
+ * container_matroska
+ */
+
+void container_matroska_impl::open(service_ptr_t<container_matroska> & p=
_out, service_ptr_t<file> & p_file, bool p_info_only, foobar2000_io::abor=
t_callback &p_abort) {
+    m_attachment_list.delete_all();
+    matroska_parser_ptr_t parser =3D matroska_parser_ptr_t(new MatroskaA=
udioParser(p_file, p_abort));
+    parser->Parse(p_info_only);
+    for (t_size i =3D 0; i !=3D parser->GetAttachmentList().get_count();=
 ++i) {
+        matroska::attachment * attachment =3D new matroska::attachment_i=
mpl(p_file, parser->GetAttachmentList().get_item(i), p_abort);
+        m_attachment_list.add_item(attachment);
+    }
+    p_out =3D this;
+}
+
+matroska::attachment_list_t & container_matroska_impl::get_attachment_li=
st() {
+    return m_attachment_list;
+}
\ No newline at end of file

Added: trunk/foo_input_matroska/container_matroska_impl.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/foo_input_matroska/container_matroska_impl.h	2006-06-02 14:32:5=
2 UTC (rev 1254)
+++ trunk/foo_input_matroska/container_matroska_impl.h	2006-07-13 15:47:4=
2 UTC (rev 1255)
@@ -0,0 +1,51 @@
+#ifndef _CONTAINER_MATROSKA_IMPL_H_
+#define _CONTAINER_MATROSKA_IMPL_H_
+
+#include "matroska_parser.h"
+#include "container_matroska.h"
+
+namespace foobar2000_io {
+    namespace matroska {
+        class attachment_impl : public attachment
+        {
+        private:
+            service_ptr_t<file> m_file;
+            abort_callback * m_abort;
+            MatroskaAttachment m_attachment;
+        public:
+            attachment_impl(service_ptr_t<file> & p_file, const Matroska=
Attachment p_attachment, abort_callback & p_abort);
+            virtual ~attachment_impl() {
+                console::info("destruct");
+            };
+            virtual void get_name(pfc::string_base & p_out);
+            virtual void get_mime_type(pfc::string_base & p_out);
+            virtual void get_description(pfc::string_base & p_out);
+            virtual t_size get_size();
+            virtual t_sfilesize get_position();
+            virtual void get(void * p_buffer, t_size p_size =3D 0);
+            virtual void get(void * p_buffer, t_sfilesize p_position, t_=
size p_size);
+        };
+
+        typedef pfc::ptr_list_t<matroska::attachment_impl> attachment_im=
pl_list_t;
+    };
+};
+
+typedef boost::shared_ptr<MatroskaAudioParser> matroska_parser_ptr_t;
+
+class container_matroska_impl : public container_matroska
+{
+private:
+    matroska::attachment_list_t m_attachment_list;
+protected:
+    container_matroska_impl() {};
+    ~container_matroska_impl() {
+        m_attachment_list.delete_all();
+    };
+public:
+    virtual void open(service_ptr_t<container_matroska> & p_out, service=
_ptr_t<file> & p_file, bool p_info_only, abort_callback & p_abort);
+    virtual matroska::attachment_list_t & get_attachment_list();
+};
+
+static container_matroska_factory_t<container_matroska_impl> g_container=
_matroska_impl_factory;
+
+#endif // _CONTAINER_MATROSKA_IMPL_H_
\ No newline at end of file

Modified: trunk/foo_input_matroska/foo_input_matroska.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/foo_input_matroska/foo_input_matroska.cpp	2006-06-02 14:32:52 U=
TC (rev 1254)
+++ trunk/foo_input_matroska/foo_input_matroska.cpp	2006-07-13 15:47:42 U=
TC (rev 1255)
@@ -56,7 +56,6 @@
 #include <commctrl.h>
 #include <Shlwapi.h>
 #include <time.h>
-//#include "contextmenu_item_matroska.h"
 #include "matroska_parser.h"
 #include "resource.h"
 #include "DbgOut.h"
@@ -291,6 +290,9 @@
 			m_tempchunk.reset();
 			try {
 				m_decoder->decode(m_buffer.get_ptr(), buffer_size, m_tempchunk, p_ab=
ort);
+                if (m_tempchunk.is_empty() && m_frame->add_id > 0) {
+                    m_decoder->decode(&m_frame->additional_data_buffer.a=
t(0), m_frame->additional_data_buffer.size(), m_tempchunk, p_abort);
+                }
 			} catch (...) {
 				MatroskaTrackInfo &currentTrack =3D m_parser->GetTrack(m_TrackNo);
 				console::error(uStringPrintf("Matroska: '%s' decode error.", (const =
char*)currentTrack.codecID.c_str()));
@@ -589,7 +591,7 @@
 		m_expected_sample_rate =3D (unsigned)(currentTrack.samplesOutputPerSec=
 =3D=3D 0 ? currentTrack.samplesPerSec : currentTrack.samplesOutputPerSec=
);
 		m_expected_bitspersample =3D currentTrack.bitsPerSample;
 		//*
-		if ((p_decode =3D=3D false) && m_decoder->analyze_first_frame_supporte=
d()) {
+		if (!p_decode && m_decoder->analyze_first_frame_supported()) {
 			if (m_frame !=3D NULL) {
 				delete m_frame;
 				m_frame =3D NULL;
@@ -620,6 +622,21 @@
=20
 static input_factory_t<input_matroska> g_input_matroska_factory;
=20
-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");
+#ifdef ARCH_SSE
+#define INPUT_MATROSKA_NAME "Matroska Plugin (/arch:SSE)"
+#else
+#ifdef _DEBUG
+#define INPUT_MATROSKA_NAME "Matroska Plugin (debug)"
+#else
+#define INPUT_MATROSKA_NAME "Matroska Plugin"
+#endif
+#endif
+DECLARE_COMPONENT_VERSION(
+    INPUT_MATROSKA_NAME,
+    "0.9.1.0",
+    "ported to 0.9 by Haru Ayana <ayana at matroska.org>\n"
+    "Copyright (C) 2003-2004 Jory Stone (jcsston at toughguy.net)\n"
+    "Copyright (C) 2003-2004 Peter Pawlowski"
+);
=20
 DECLARE_FILE_TYPE("Matroska Audio files","*.MKA");

Modified: trunk/foo_input_matroska/foo_input_matroska.rc
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/foo_input_matroska/foo_input_matroska.rc	2006-06-02 14:32:52 UT=
C (rev 1254)
+++ trunk/foo_input_matroska/foo_input_matroska.rc	2006-07-13 15:47:42 UT=
C (rev 1255)
@@ -1,63 +1,113 @@
-//Microsoft Developer Studio generated resource script.
-//
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-////////////////////////////////////////////////////////////////////////=
/////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "afxres.h"
-
-////////////////////////////////////////////////////////////////////////=
/////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-////////////////////////////////////////////////////////////////////////=
/////
-// English (U.K.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
-#pragma code_page(1252)
-#endif //_WIN32
-
-#ifdef APSTUDIO_INVOKED
-////////////////////////////////////////////////////////////////////////=
/////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE MOVEABLE PURE=20
-BEGIN
-    "resource.h\0"
-END
-
-2 TEXTINCLUDE MOVEABLE PURE=20
-BEGIN
-    "#include ""afxres.h""\r\n"
-    "\0"
-END
-
-3 TEXTINCLUDE MOVEABLE PURE=20
-BEGIN
-    "\r\n"
-    "\0"
-END
-
-#endif    // APSTUDIO_INVOKED
-
-#endif    // English (U.K.) resources
-////////////////////////////////////////////////////////////////////////=
/////
-
-
-
-#ifndef APSTUDIO_INVOKED
-////////////////////////////////////////////////////////////////////////=
/////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-////////////////////////////////////////////////////////////////////////=
/////
-#endif    // not APSTUDIO_INVOKED
-
+=FF=FE/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file

Modified: trunk/foo_input_matroska/matroska_parser.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/foo_input_matroska/matroska_parser.cpp	2006-06-02 14:32:52 UTC =
(rev 1254)
+++ trunk/foo_input_matroska/matroska_parser.cpp	2006-07-13 15:47:42 UTC =
(rev 1255)
@@ -51,19 +51,20 @@
=20
 static const char * chapter_tag_mapping[][2] =3D
 {=09
-	{ "PART_NUMBER", "TRACKNUMBER" }
+	{ "PART_NUMBER", "TRACKNUMBER" },
+	{ "DATE_RELEASED", "DATE" }
 };
=20
 static const char * edition_tag_mapping[][2] =3D
 {
 	{ "TITLE", "ALBUM" },
-	{ "SUBTITLE", "SUBALBUM"}
+	{ "SUBTITLE", "SUBALBUM" },
+	{ "CATALOG_NUMBER", "CATALOG" },
 };
=20
 static const char * hidden_edition_field[] =3D
 {
-	"CATALOG_NUMBER",
-	"TOTAL_PARTS"
+	"___DUMMY___",
 };
=20
 static const char * hidden_chapter_field[] =3D
@@ -90,12 +91,24 @@
 {
 	timecode =3D 0;
 	duration =3D 0;
+    add_id =3D 0;
 };
=20
+MatroskaAttachment::MatroskaAttachment()
+{
+	FileName =3D L"";
+	MimeType =3D "";
+	Description =3D L"";
+	SourceFilename =3D L"";
+	SourceStartPos =3D 0;
+	SourceDataLength =3D 0;
+}
+
 void MatroskaAudioFrame::Reset()
 {
 	timecode =3D 0;
 	duration =3D 0;
+    add_id =3D 0;
 };
=20
 MatroskaSimpleTag::MatroskaSimpleTag()
@@ -282,7 +295,6 @@
 						// Search for them at the end of the file
 						if (m_TagScanRange > 0)
 						{
-							TIMER;
 							m_IOCallback.setFilePointer(m_FileSize - m_TagScanRange);
 							uint64 init_pos =3D m_IOCallback.getFilePointer();
 							/*
@@ -305,7 +317,6 @@
 										&& (EbmlId(*levelUnknown) =3D=3D KaxTags::ClassInfos.GlobalId)=
)
 									{
 										Parse_Tags(static_cast<KaxTags *>(levelUnknown.get()));
-										_TIMER("MatroskaAudioParser::Parse(BM)");
 										break;
 									}
 									m_IOCallback.setFilePointer(s_pos);
@@ -331,7 +342,6 @@
 											&& (m_FileSize >=3D startPos + levelUnknown->GetSize())=20
 											&& (EbmlId(*levelUnknown) =3D=3D KaxTags::ClassInfos.GlobalId=
))
 										{
-											_TIMER("MatroskaAudioParser::Parse()");
 											Parse_Tags(static_cast<KaxTags *>(levelUnknown.get()));
 											//_DELETE(levelUnknown);
 											break;
@@ -420,10 +430,8 @@
 				}
 			}else if (EbmlId(*ElementLevel1) =3D=3D KaxChapters::ClassInfos.Globa=
lId) {
 				Parse_Chapters(static_cast<KaxChapters *>(ElementLevel1.get()));
-
 			}else if (EbmlId(*ElementLevel1) =3D=3D KaxTags::ClassInfos.GlobalId)=
 {
 				Parse_Tags(static_cast<KaxTags *>(ElementLevel1.get()));
-
 			} else if (EbmlId(*ElementLevel1) =3D=3D KaxTracks::ClassInfos.Global=
Id) {
 				// Yep, we've found our KaxTracks element. Now find all tracks
 				// contained in this segment.=20
@@ -538,7 +546,6 @@
 					}
 				}
 			} else if (EbmlId(*ElementLevel1) =3D=3D KaxCluster::ClassInfos.Globa=
lId) {
-			=09
 				if (bBreakAtClusters) {
 					m_IOCallback.setFilePointer(ElementLevel1->GetElementPosition());
 					//delete ElementLevel1;
@@ -546,13 +553,12 @@
 					//_DELETE(ElementLevel1);
 					break;
 				}
-
 			} else if (EbmlId(*ElementLevel1) =3D=3D KaxAttachments::ClassInfos.G=
lobalId) {
 				// Yep, we've found our KaxAttachment element. Now find all attached=
 files
-				// contained in this segment. 			=09
-#if 0
-				ElementLevel2 =3D m_InputStream.FindNextElement(ElementLevel1->Gener=
ic().Context, UpperElementLevel, 0xFFFFFFFFL, true, 1);
-				while (ElementLevel2 !=3D NULL) {
+				// contained in this segment.
+#if 1
+				ElementLevel2 =3D ElementPtr(m_InputStream.FindNextElement(ElementLe=
vel1->Generic().Context, UpperElementLevel, 0xFFFFFFFFL, true, 1));
+				while (ElementLevel2 !=3D NullElement) {
 					if (UpperElementLevel > 0) {
 						break;
 					}
@@ -561,10 +567,10 @@
 					}
 					if (EbmlId(*ElementLevel2) =3D=3D KaxAttached::ClassInfos.GlobalId)=
 {
 						// We actually found a attached file entry :D
-						MatroskaAttachment *newAttachment =3D new MatroskaAttachment();
+						MatroskaAttachment newAttachment;
=20
-						ElementLevel3 =3D m_InputStream.FindNextElement(ElementLevel2->Gen=
eric().Context, UpperElementLevel, 0xFFFFFFFFL, true, 1);
-						while (ElementLevel3 !=3D NULL) {
+						ElementLevel3 =3D ElementPtr(m_InputStream.FindNextElement(Element=
Level2->Generic().Context, UpperElementLevel, 0xFFFFFFFFL, true, 1));
+						while (ElementLevel3 !=3D NullElement) {
 							if (UpperElementLevel > 0) {
 								break;
 							}
@@ -574,64 +580,56 @@
=20
 							// Now evaluate the data belonging to this track
 							if (EbmlId(*ElementLevel3) =3D=3D KaxFileName::ClassInfos.GlobalI=
d) {
-								KaxFileName &attached_filename =3D *static_cast<KaxFileName *>(E=
lementLevel3);
+								KaxFileName &attached_filename =3D *static_cast<KaxFileName *>(E=
lementLevel3.get());
 								attached_filename.ReadData(m_InputStream.I_O());
-								newAttachment->FileName =3D UTFstring(attached_filename).c_str()=
;
+								newAttachment.FileName =3D UTFstring(attached_filename);
=20
 							} else if (EbmlId(*ElementLevel3) =3D=3D KaxMimeType::ClassInfos.=
GlobalId) {
-								KaxMimeType &attached_mime_type =3D *static_cast<KaxMimeType *>(=
ElementLevel3);
+								KaxMimeType &attached_mime_type =3D *static_cast<KaxMimeType *>(=
ElementLevel3.get());
 								attached_mime_type.ReadData(m_InputStream.I_O());
-								newAttachment->MimeType =3D wxString(std::string(attached_mime_t=
ype).c_str(), wxConvUTF8);
+								newAttachment.MimeType =3D std::string(attached_mime_type);
=20
 							} else if (EbmlId(*ElementLevel3) =3D=3D KaxFileDescription::Clas=
sInfos.GlobalId) {
-								KaxFileDescription &attached_description =3D *static_cast<KaxFil=
eDescription *>(ElementLevel3);
+								KaxFileDescription &attached_description =3D *static_cast<KaxFil=
eDescription *>(ElementLevel3.get());
 								attached_description.ReadData(m_InputStream.I_O());
-								newAttachment->Description =3D UTFstring(attached_description).c=
_str();
+								newAttachment.Description =3D UTFstring(attached_description);
=20
 							} else if (EbmlId(*ElementLevel3) =3D=3D KaxFileData::ClassInfos.=
GlobalId) {
-								KaxFileData &attached_data =3D *static_cast<KaxFileData *>(Eleme=
ntLevel3);
+								KaxFileData &attached_data =3D *static_cast<KaxFileData *>(Eleme=
ntLevel3.get());
=20
 								//We don't what to read the data into memory because it could be=
 very large
 								//attached_data.ReadData(m_InputStream.I_O());
=20
 								//Instead we store the Matroska filename, the start of the data =
and the length, so we can read it
 								//later at the users request. IMHO This will save a lot of memor=
y
-								newAttachment->SourceFilename =3D MatroskaFilename;
-								newAttachment->SourceStartPos =3D attached_data.GetElementPositi=
on() + attached_data.HeadSize();
-								newAttachment->SourceDataLength =3D attached_data.GetSize();
+								newAttachment.SourceStartPos =3D attached_data.GetElementPositio=
n() + attached_data.HeadSize();
+								newAttachment.SourceDataLength =3D attached_data.GetSize();
 							}
=20
 							if (UpperElementLevel > 0) {	// we're coming from ElementLevel4
 								UpperElementLevel--;
-								//delete ElementLevel3;
-								_DELETE(ElementLevel3);
-								ElementLevel3 =3D ElementLevel4->Clone();
+								ElementLevel3 =3D ElementLevel4;
 								if (UpperElementLevel > 0)
 									break;
 							} else {
 								ElementLevel3->SkipData(m_InputStream, ElementLevel3->Generic().=
Context);
-								//delete ElementLevel3;
-								_DELETE(ElementLevel3);
-								ElementLevel3 =3D m_InputStream.FindNextElement(ElementLevel2->G=
eneric().Context, UpperElementLevel, 0xFFFFFFFFL, true, 1);
+								ElementLevel3 =3D ElementPtr(m_InputStream.FindNextElement(Eleme=
ntLevel2->Generic().Context, UpperElementLevel, 0xFFFFFFFFL, true, 1));
 							}				=09
 						} // while (ElementLevel3 !=3D NULL)
-						m_AttachmentList.push_back(newAttachment);
+						//m_AttachmentList.push_back(newAttachment);
+                        m_AttachmentList.add_item(newAttachment);
 					}
=20
 					if (UpperElementLevel > 0) {	// we're coming from ElementLevel3
 						UpperElementLevel--;
-						//delete ElementLevel2;
-						_DELETE(ElementLevel2);
-						ElementLevel2 =3D ElementLevel3->Clone();
+						ElementLevel2 =3D ElementLevel3;
 						if (UpperElementLevel > 0)
 							break;
 					} else {
 						ElementLevel2->SkipData(m_InputStream, ElementLevel2->Generic().Co=
ntext);
-						//delete ElementLevel2;
-						_DELETE(ElementLevel2);
-						ElementLevel2 =3D m_InputStream.FindNextElement(ElementLevel1->Gen=
eric().Context, UpperElementLevel, 0xFFFFFFFFL, true, 1);
+						ElementLevel2 =3D ElementPtr(m_InputStream.FindNextElement(Element=
Level1->Generic().Context, UpperElementLevel, 0xFFFFFFFFL, true, 1));
 					}
-				} // while (ElementLevel2 !=3D NULL)						=09
+				} // while (ElementLevel2 !=3D NULL)
 #endif
 			}
 		=09
@@ -834,6 +832,18 @@
 	return rv;
 }
=20
+bool isEditionTag(const char * name) {
+	if (starts_with(name, "ALBUM") ||
+		starts_with(name, "SUBALBUM") ||
+		starts_with(name, "DISCID") ||
+		starts_with(name, "CATALOG"))
+	{
+		return true;
+	} else {
+		return false;
+	}
+}
+
 void MatroskaAudioParser::SetTags(const file_info &info)
 {
 	int i, idx;
@@ -914,9 +924,7 @@
 				value =3D info.meta_enum_value(i, j);
 				//idx =3D meta_get_num(info, name, i);
 				idx =3D j;
-				if (starts_with(name, "ALBUM") ||
-					starts_with(name, "SUBALBUM") ||
-					starts_with(name, "DISCID"))
+				if (isEditionTag(name))
 				{
 					name =3D foobar2k_to_matroska_edition_tag(name);
 				} else {
@@ -976,9 +984,7 @@
 				value =3D info.meta_enum_value(i, j);
 				//idx =3D meta_get_num(info, name, i);
 				idx =3D j;
-				if (starts_with(name, "ALBUM") ||
-					starts_with(name, "SUBALBUM") ||
-					starts_with(name, "DISCID"))
+				if (isEditionTag(name))
 				{
 					name =3D NULL;
 				} else {
@@ -1342,12 +1348,11 @@
 			} else {
 				info.meta_add("SUBALBUM", simpleTag.value.GetUTF8().c_str());
 			}
-		}
-		else if(IsTagNamed(simpleTag,"DISCID"))
+		} else if (IsTagNamed(simpleTag, "DISCID") ||
+				   IsTagNamed(simpleTag, "CATALOG_NUMBER"))
 		{
-			info.meta_add("DISCID", simpleTag.value.GetUTF8().c_str());
-		}
-		else if(IsTagNamed(simpleTag,"COMMENTS"))
+			info.meta_add(matroska_to_foobar2k_edition_tag(simpleTag.name.GetUTF8=
().c_str()), simpleTag.value.GetUTF8().c_str());
+		} else if (IsTagNamed(simpleTag,"COMMENTS"))
 		{
 			info.meta_add("ALBUM COMMENT", simpleTag.value.GetUTF8().c_str());
 		}
@@ -1357,7 +1362,7 @@
 			// Prefix tag with "ALBUM "
 			char newTagName[255] =3D "ALBUM ";
 			strncat(newTagName, matroska_to_foobar2k_edition_tag(simpleTag.name.G=
etUTF8().c_str()),255);
-			info.meta_add(newTagName, simpleTag.value.GetUTF8().c_str());				=09
+			info.meta_add(newTagName, simpleTag.value.GetUTF8().c_str());
 		}
 		else=20
 		{
@@ -1420,12 +1425,21 @@
 	if (m_FileTitle.length() > 0)
 		info.info_set("TITLE", m_FileTitle.GetUTF8().c_str());
=20
+	// pregap
+	try {
+		if (m_Chapters.at(p_subsong).subChapters.size() > 1) {
+			double pregap =3D TimecodeToSeconds(m_Chapters.at(p_subsong).subChapt=
ers.at(1).timeStart - m_Chapters.at(p_subsong).subChapters.at(0).timeStar=
t);
+			info.info_set("pregap", cuesheet_format_index_time(pregap));
+		}
+	} catch (std::out_of_range & e) {
+	}
+
 	MatroskaTagInfo *TrackTags =3D FindTagWithTrackUID(m_Tracks.at(m_Curren=
tTrackNo).trackUID);
 	MatroskaTagInfo *ChapterTags =3D NULL;
 	if(m_CurrentChapter !=3D NULL)
 	{
 		ChapterTags =3D FindTagWithChapterUID(m_CurrentChapter->chapterUID,
-			m_Tracks.at(m_CurrentTrackNo).trackUID);	=09
+			m_Tracks.at(m_CurrentTrackNo).trackUID);
 	}
 	/*
 	MatroskaTagInfo *EditionTags =3D NULL;
@@ -1618,6 +1632,7 @@
=20
 void MatroskaAudioParser::Parse_MetaSeek(ElementPtr metaSeekElement, boo=
l bInfoOnly)=20
 {
+    TIMER;
 	uint64 lastSeekPos =3D 0;
 	uint64 endSeekPos =3D 0;
 	ElementPtr l2;
@@ -1641,7 +1656,6 @@
 			//Wow we found the SeekEntries, time to speed up reading ;)
 			l3 =3D ElementPtr(m_InputStream.FindNextElement(l2->Generic().Context=
, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1));
=20
-			//EbmlId *id =3D NULL;
 			EbmlIdPtr id;
 			while (l3 !=3D NullElement) {
 				if (UpperElementLevel > 0) {
@@ -1658,9 +1672,7 @@
 					seek_id.ReadData(m_InputStream.I_O(), SCOPE_ALL_DATA);
 					b =3D seek_id.GetBuffer();
 					s =3D (uint16)seek_id.GetSize();
-					//delete id;
-					//id =3D NULL;
-					//_DELETE(id);
+                    id.reset();
 					id =3D EbmlIdPtr(new EbmlId(b, s));
=20
 				} else if (EbmlId(*l3) =3D=3D KaxSeekPosition::ClassInfos.GlobalId) =
{
@@ -1672,20 +1684,20 @@
=20
 					if ((*id =3D=3D KaxCluster::ClassInfos.GlobalId) && !bInfoOnly) {
 						//NOTE1("Found Cluster Seek Entry Postion: %u", (unsigned long)las=
tSeekPos);
-						//uint64 orig_pos =3D inputFile.getFilePointer();								=09
-						MatroskaMetaSeekClusterEntry newCluster;
-						newCluster.timecode =3D MAX_UINT64;
-						newCluster.filePos =3D static_cast<KaxSegment *>(m_ElementLevel0.g=
et())->GetGlobalPosition(lastSeekPos);
+						//uint64 orig_pos =3D inputFile.getFilePointer();
+						//MatroskaMetaSeekClusterEntry newCluster;
+                        cluster_entry_ptr_t newCluster(new MatroskaMetaS=
eekClusterEntry());
+						newCluster->timecode =3D MAX_UINT64;
+						newCluster->filePos =3D static_cast<KaxSegment *>(m_ElementLevel0.=
get())->GetGlobalPosition(lastSeekPos);
 						m_ClusterIndex.push_back(newCluster);
=20
 					} else if ((*id =3D=3D KaxSeekHead::ClassInfos.GlobalId) && !bInfoO=
nly) {
 						NOTE1("Found MetaSeek Seek Entry Postion: %u", (unsigned long)last=
SeekPos);
-						uint64 orig_pos =3D m_IOCallback.getFilePointer();								=09
+						uint64 orig_pos =3D m_IOCallback.getFilePointer();
 						m_IOCallback.setFilePointer(static_cast<KaxSegment *>(m_ElementLev=
el0.get())->GetGlobalPosition(lastSeekPos));
 					=09
 						ElementPtr levelUnknown =3D ElementPtr(m_InputStream.FindNextID(Ka=
xSeekHead::ClassInfos, 0xFFFFFFFFFFFFFFFFL));									=09
 						Parse_MetaSeek(levelUnknown, false);
-						//_DELETE(levelUnknown);
=20
 						m_IOCallback.setFilePointer(orig_pos);
 					}
@@ -1694,42 +1706,35 @@
=20
 				}
 				l3->SkipData(m_InputStream, l3->Generic().Context);
-				//delete l3;
-				//l3 =3D NULL;
-				//_DELETE(l3);
 				l3 =3D ElementPtr(m_InputStream.FindNextElement(l2->Generic().Contex=
t, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1));
-			} // while (l3 !=3D NULL)
-			//delete id;
-			//id =3D NULL;
-			//_DELETE(id);
+			}
 		} else {
=20
 		}
=20
 		if (UpperElementLevel > 0) {    // we're coming from l3
 			UpperElementLevel--;
-			//delete l2;
-			//_DELETE(l2);
 			l2 =3D l3;
 			if (UpperElementLevel > 0)
 				break;
=20
 		} else {
 			l2->SkipData(m_InputStream, l2->Generic().Context);
-			//delete l2;
-			//l2 =3D NULL;
-			//_DELETE(l2);
 			l2 =3D ElementPtr(m_InputStream.FindNextElement(metaSeekElement->Gene=
ric().Context, UpperElementLevel, 0xFFFFFFFFFFFFFFFFL, true, 1));
 		}
-	} // while (l2 !=3D NULL)
-	//_DELETE(l3);
-	//_DELETE(l2);
+	}
+    _TIMER("Parse_MetaSeek");
 }
=20
 #define IS_ELEMENT_ID(__x__) (Element->Generic().GlobalId =3D=3D __x__::=
ClassInfos.GlobalId)
=20
 void MatroskaAudioParser::Parse_Chapter_Atom(KaxChapterAtom *ChapterAtom=
)
 {
+	Parse_Chapter_Atom(ChapterAtom, m_Chapters);
+}
+
+void MatroskaAudioParser::Parse_Chapter_Atom(KaxChapterAtom *ChapterAtom=
, std::vector<MatroskaChapterInfo> &p_chapters)
+{
 	int i, j;
 	EbmlElement *Element =3D NULL;
 	MatroskaChapterInfo newChapter;
@@ -1801,14 +1806,17 @@
 				newChapter.display.push_back(newChapterDisplay);
 		}
 		else if(IS_ELEMENT_ID(KaxChapterAtom))
-		{						=09
+		{
+			/*
 			// Ignore sub-chapter
 			NOTE("ignore sub-chapter");
 			//Parse_Chapter_Atom((KaxChapterAtom *)Element);
+			*/
+			Parse_Chapter_Atom((KaxChapterAtom *)Element, newChapter.subChapters)=
;
 		}
 	}
 	if ((newChapter.chapterUID !=3D 0) && !FindChapterUID(newChapter.chapte=
rUID))
-		m_Chapters.push_back(newChapter);
+		p_chapters.push_back(newChapter);
 }
=20
 void MatroskaAudioParser::Parse_Chapters(KaxChapters *chaptersElement)
@@ -1974,12 +1982,13 @@
 	ElementPtr ElementLevel2;
 	ElementPtr ElementLevel3;
 	ElementPtr ElementLevel4;
+    ElementPtr ElementLevel5;
 	ElementPtr NullElement;
 	//m_framebuffer.set_size(0);
=20
 	if (m_IOCallback.seekable()) {
-		MatroskaMetaSeekClusterEntry *currentCluster =3D FindCluster(m_Current=
Timecode);
-		if (currentCluster =3D=3D NULL)
+		cluster_entry_ptr_t currentCluster =3D FindCluster(m_CurrentTimecode);
+		if (currentCluster.get() =3D=3D NULL)
 			return 2;
 		int64 clusterFilePos =3D currentCluster->filePos;
=20
@@ -2027,12 +2036,12 @@
 						}
 						if (EbmlId(*ElementLevel3) =3D=3D KaxBlock::ClassInfos.GlobalId) {=
							=09
 							KaxBlock & DataBlock =3D *static_cast<KaxBlock*>(ElementLevel3.ge=
t());													=09
-							DataBlock.ReadData(m_InputStream.I_O());	=09
+							DataBlock.ReadData(m_InputStream.I_O());
 							DataBlock.SetParent(*SegmentCluster);
=20
 							//NOTE4("Track # %u / %u frame%s / Timecode %I64d", DataBlock.Tra=
ckNum(), DataBlock.NumberFrames(), (DataBlock.NumberFrames() > 1)?"s":"",=
 DataBlock.GlobalTimecode()/m_TimecodeScale);
 							if (DataBlock.TrackNum() =3D=3D m_Tracks.at(m_CurrentTrackNo).tra=
ckNumber) {										=09
-								newFrame->timecode =3D DataBlock.GlobalTimecode();						=09
+								newFrame->timecode =3D DataBlock.GlobalTimecode();
=20
 								if (DataBlock.NumberFrames() > 1) {=09
 									// The evil lacing has been used
@@ -2067,19 +2076,59 @@
 							KaxBlockDuration & BlockDuration =3D *static_cast<KaxBlockDuratio=
n*>(ElementLevel3.get());
 							BlockDuration.ReadData(m_InputStream.I_O());
 							newFrame->duration =3D uint32(BlockDuration);
-						}
+                        } else if (EbmlId(*ElementLevel3) =3D=3D KaxBloc=
kAdditions::ClassInfos.GlobalId) {
+                            ElementLevel4 =3D ElementPtr(m_InputStream.F=
indNextElement(ElementLevel3->Generic().Context, UpperElementLevel, 0xFFF=
FFFFFL, bAllowDummy));
+                            while (ElementLevel4 !=3D NullElement) {
+                                if (UpperElementLevel > 0) {
+							        break;
+						        }
+						        if (UpperElementLevel < 0) {
+							        UpperElementLevel =3D 0;
+						        }
+                                if (EbmlId(*ElementLevel4) =3D=3D KaxBlo=
ckMore::ClassInfos.GlobalId) {
+                                    ElementLevel5 =3D ElementPtr(m_Input=
Stream.FindNextElement(ElementLevel4->Generic().Context, UpperElementLeve=
l, 0xFFFFFFFFL, bAllowDummy));
+                                    while (ElementLevel5 !=3D NullElemen=
t) {
+                                        if (UpperElementLevel > 0) {
+							                break;
+						                }
+						                if (UpperElementLevel < 0) {
+							                UpperElementLevel =3D 0;
+						                }
+                                        if (EbmlId(*ElementLevel5) =3D=3D=
 KaxBlockAddID::ClassInfos.GlobalId) {
+                                            KaxBlockAddID & AddId =3D *s=
tatic_cast<KaxBlockAddID*>(ElementLevel5.get());
+                                            AddId.ReadData(m_InputStream=
.I_O());
+                                            newFrame->add_id =3D uint64(=
AddId);
+                                        } else if (EbmlId(*ElementLevel5=
) =3D=3D KaxBlockAdditional::ClassInfos.GlobalId) {
+                                            KaxBlockAdditional & DataBlo=
ckAdditional =3D *static_cast<KaxBlockAdditional*>(ElementLevel5.get());	=
												=09
+							                DataBlockAdditional.ReadData(m_InputStream.I_O())=
;	=09
+                                            newFrame->additional_data_bu=
ffer.resize(DataBlockAdditional.GetSize());
+                                            if (!newFrame->add_id) {
+                                                newFrame->add_id =3D 1;
+                                            }
+                                            memcpy(&newFrame->additional=
_data_buffer.at(0), DataBlockAdditional.GetBuffer(), DataBlockAdditional.=
GetSize());
+                                        }
+                                        ElementLevel5->SkipData(m_InputS=
tream, ElementLevel5->Generic().Context);
+							            ElementLevel5 =3D ElementPtr(m_InputStream.FindNextEl=
ement(ElementLevel4->Generic().Context, UpperElementLevel, ElementLevel4-=
>ElementSize(), bAllowDummy));
+                                    }
+                                }
+                                if (UpperElementLevel > 0) {
+							        UpperElementLevel--;
+							        ElementLevel4 =3D ElementLevel5;
+							        if (UpperElementLevel > 0)
+								        break;
+						        } else {
+							        ElementLevel4->SkipData(m_InputStream, ElementLevel4->Gen=
eric().Context);
+							        ElementLevel4 =3D ElementPtr(m_InputStream.FindNextElemen=
t(ElementLevel3->Generic().Context, UpperElementLevel, ElementLevel3->Ele=
mentSize(), bAllowDummy));
+						        }
+                            }
+                        }
 						if (UpperElementLevel > 0) {
 							UpperElementLevel--;
-							//delete ElementLevel3;
-							//_DELETE(ElementLevel3);
 							ElementLevel3 =3D ElementLevel4;
 							if (UpperElementLevel > 0)
 								break;
 						} else {
 							ElementLevel3->SkipData(m_InputStream, ElementLevel3->Generic().C=
ontext);
-							//delete ElementLevel3;
-							//ElementLevel3 =3D NULL;
-							//_DELETE(ElementLevel3);
=20
 							ElementLevel3 =3D ElementPtr(m_InputStream.FindNextElement(Elemen=
tLevel2->Generic().Context, UpperElementLevel, ElementLevel2->ElementSize=
(), bAllowDummy));
 						}						=09
@@ -2129,9 +2178,9 @@
 		//delete ElementLevel1;
 	=09
 		if (currentCluster->clusterNo < m_ClusterIndex.size()-1) {
-			if (m_ClusterIndex[currentCluster->clusterNo+1].timecode =3D=3D MAX_U=
INT64)
-				m_ClusterIndex[currentCluster->clusterNo+1].timecode =3D GetClusterT=
imecode(m_ClusterIndex[currentCluster->clusterNo+1].filePos);
-			m_CurrentTimecode =3D m_ClusterIndex[currentCluster->clusterNo+1].tim=
ecode;
+			if (m_ClusterIndex[currentCluster->clusterNo+1]->timecode =3D=3D MAX_=
UINT64)
+				m_ClusterIndex[currentCluster->clusterNo+1]->timecode =3D GetCluster=
Timecode(m_ClusterIndex[currentCluster->clusterNo+1]->filePos);
+			m_CurrentTimecode =3D m_ClusterIndex[currentCluster->clusterNo+1]->ti=
mecode;
 			if(m_CurrentTimecode =3D=3D 0)
 			{
 				console::error(uStringPrintf("clusterNo : %d, m_ClusterIndex.size() =
: %d", currentCluster->clusterNo, m_ClusterIndex.size()));
@@ -2338,7 +2387,7 @@
 	}=09
 };
=20
-MatroskaMetaSeekClusterEntry *MatroskaAudioParser::FindCluster(uint64 ti=
mecode)
+cluster_entry_ptr_t MatroskaAudioParser::FindCluster(uint64 timecode)
 {
 	try {
 		#ifdef _DEBUG_NO_SEEKING
@@ -2350,24 +2399,24 @@
=20
 		if (timecode =3D=3D 0)
 			// Special case
-			return &m_ClusterIndex.at(0);
+			return m_ClusterIndex.at(0);
 	=09
-		MatroskaMetaSeekClusterEntry *correctEntry =3D NULL;
+		cluster_entry_ptr_t correctEntry;
 		double clusterDuration =3D (double)(int64)m_ClusterIndex.size() / (dou=
ble)(int64)m_Duration;
 		size_t clusterIndex =3D clusterDuration * (double)(int64)timecode;
 		//int lookCount =3D 0;
 		if (clusterIndex > m_ClusterIndex.size())
 			clusterIndex =3D m_ClusterIndex.size()-1;
=20
-		MatroskaMetaSeekClusterEntry *clusterEntry =3D NULL;
-		MatroskaMetaSeekClusterEntry *prevClusterEntry =3D NULL;
-		MatroskaMetaSeekClusterEntry *nextClusterEntry =3D NULL;
+		cluster_entry_ptr_t clusterEntry;
+		cluster_entry_ptr_t prevClusterEntry;
+		cluster_entry_ptr_t nextClusterEntry;
 		while (correctEntry =3D=3D NULL) {
-			clusterEntry =3D &m_ClusterIndex.at(clusterIndex);	=09
+			clusterEntry =3D m_ClusterIndex.at(clusterIndex);	=09
 			if (clusterIndex > 0)
-				prevClusterEntry =3D &m_ClusterIndex.at(clusterIndex-1);
+				prevClusterEntry =3D m_ClusterIndex.at(clusterIndex-1);
 			if (clusterIndex+1 < m_ClusterIndex.size())
-				nextClusterEntry =3D &m_ClusterIndex.at(clusterIndex+1);		=09
+				nextClusterEntry =3D m_ClusterIndex.at(clusterIndex+1);		=09
 		=09
 			// We need timecodes to do good seeking
 			if (clusterEntry->timecode =3D=3D MAX_UINT64) {			=09
@@ -2438,15 +2487,16 @@
=20
 		return correctEntry;
 	} catch (...) {
-		return NULL;
+        cluster_entry_ptr_t null_ptr;
+		return null_ptr;
 	}
 }
=20
 void MatroskaAudioParser::CountClusters()=20
 {
 	for (uint32 c =3D 0; c < m_ClusterIndex.size(); c++) {
-		MatroskaMetaSeekClusterEntry &clusterEntry =3D m_ClusterIndex.at(c);	=09
-		clusterEntry.clusterNo =3D c;
+		cluster_entry_ptr_t clusterEntry =3D m_ClusterIndex.at(c);	=09
+		clusterEntry->clusterNo =3D c;
 	}
 }
=20

Modified: trunk/foo_input_matroska/matroska_parser.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/foo_input_matroska/matroska_parser.h	2006-06-02 14:32:52 UTC (r=
ev 1254)
+++ trunk/foo_input_matroska/matroska_parser.h	2006-07-13 15:47:42 UTC (r=
ev 1255)
@@ -26,6 +26,7 @@
 #define MULTITRACK 1
=20
 #include "../SDK/foobar2000.h"
+#include "../helpers/helpers.h"
 #include "../../pfc/pfc.h"
 #include "Foobar2000ReaderIOCallback.h"
 #include "DbgOut.h"
@@ -98,6 +99,24 @@
 typedef std::vector<uint8> ByteArray;
 typedef boost::shared_ptr<EbmlElement> ElementPtr;
=20
+class MatroskaVersion {
+public:
+    static const char * lib_ebml() { return EbmlCodeVersion.c_str(); };
+    static const char * lib_matroska() { return KaxCodeVersion.c_str(); =
};
+};
+
+class MatroskaAttachment {
+public:
+	MatroskaAttachment();
+
+	UTFstring FileName;
+	std::string MimeType;
+	UTFstring Description;
+	UTFstring SourceFilename;
+	uint64 SourceStartPos;
+	uint64 SourceDataLength;
+};
+
 class MatroskaAudioFrame {
 public:
 	MatroskaAudioFrame();
@@ -107,6 +126,8 @@
 	uint32 duration;
 	std::vector<ByteArray> dataBuffer;
 	/// Linked-list for laced frames
+    uint64 add_id;
+    ByteArray additional_data_buffer;
 };
=20
=20
@@ -166,6 +187,7 @@
 	std::vector<uint64> tracks;
 	/// Vector of strings we can display for chapter
 	std::vector<MatroskaChapterDisplayInfo> display;
+	std::vector<MatroskaChapterInfo> subChapters;
 };
=20
 class MatroskaEditionInfo {
@@ -207,6 +229,8 @@
 		float defaultDuration;
 };
=20
+typedef boost::shared_ptr<MatroskaMetaSeekClusterEntry> cluster_entry_pt=
r_t;
+
 class MatroskaAudioParser {
 public:
 	MatroskaAudioParser(service_ptr_t<file> input, abort_callback & p_abort=
);
@@ -231,7 +255,7 @@
 	/// Returns the track index of the first decodable track
 	int32 GetFirstAudioTrack();
=20
-	double TimecodeToSeconds(uint64 code,unsigned samplerate_hint);
+	double TimecodeToSeconds(uint64 code,unsigned samplerate_hint =3D 44100=
);
 	uint64 SecondsToTimecode(double seconds);
=20
 	/// Set the fb2k info from the matroska file
@@ -273,14 +297,19 @@
 	/// \return 2 End of track (EOT)
 	MatroskaAudioFrame * ReadSingleFrame();
=20
+	UTFstring GetSegmentFileName() { return m_SegmentFilename; }
+    typedef pfc::list_t<MatroskaAttachment> attachment_list_t;
+	attachment_list_t &GetAttachmentList() { return m_AttachmentList; }
+
 protected:
 	void Parse_MetaSeek(ElementPtr metaSeekElement, bool bInfoOnly);
 	void Parse_Chapters(KaxChapters *chaptersElement);
 	void Parse_Chapter_Atom(KaxChapterAtom *ChapterAtom);
+	void Parse_Chapter_Atom(KaxChapterAtom *ChapterAtom, std::vector<Matros=
kaChapterInfo> &p_chapters);
 	void Parse_Tags(KaxTags *tagsElement);
 	int FillQueue();
 	uint64 GetClusterTimecode(uint64 filePos);
-	MatroskaMetaSeekClusterEntry *FindCluster(uint64 timecode);
+	cluster_entry_ptr_t FindCluster(uint64 timecode);
 	void CountClusters();
 	void FixChapterEndTimes();
 	// See if the edition uid is already in our vector
@@ -323,8 +352,11 @@
 	std::queue<MatroskaAudioFrame *> m_Queue;
=20
 	/// This is the index of clusters in the file, it's used to seek in the=
 file
-	std::vector<MatroskaMetaSeekClusterEntry> m_ClusterIndex;
+	// std::vector<MatroskaMetaSeekClusterEntry> m_ClusterIndex;
+    std::vector<cluster_entry_ptr_t> m_ClusterIndex;
=20
+    attachment_list_t m_AttachmentList;
+
 	uint64 m_CurrentTimecode;
 	uint64 m_Duration;
 	uint64 m_TimecodeScale;

Modified: trunk/foo_input_matroska/resource.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/foo_input_matroska/resource.h	2006-06-02 14:32:52 UTC (rev 1254=
)
+++ trunk/foo_input_matroska/resource.h	2006-07-13 15:47:42 UTC (rev 1255=
)
@@ -1,6 +1,6 @@
 //{{NO_DEPENDENCIES}}
 // Microsoft Visual C++ generated include file.
-// Used by foo_matroska.rc
+// Used by foo_input_matroska.rc
 //
 #define IDC_BUFSIZE                     1000
 #define IDC_PREBUF_START                1001
@@ -15,7 +15,7 @@
 //=20
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        102
+#define _APS_NEXT_RESOURCE_VALUE        103
 #define _APS_NEXT_COMMAND_VALUE         40001
 #define _APS_NEXT_CONTROL_VALUE         1008
 #define _APS_NEXT_SYMED_VALUE           101



More information about the Matroska-cvs mailing list