From 14c21e6ae85a54d6e038ee428b47e1f3d4b0d004 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Mon, 11 Oct 2004 11:19:33 +0000 Subject: [PATCH] Defer the initialization of the XML mapping tables and link the entries to the libmatroska classes with their DebugName. This gets rid of the problems with different compilers/optimization settings causing the EbmlIds to be initialized too late. --- ChangeLog | 4 + src/common/commonebml.cpp | 25 ++++ src/common/commonebml.h | 2 + src/common/xml_element_mapping.cpp | 189 ++++++++++++----------------- src/common/xml_element_mapping.h | 3 +- 5 files changed, 111 insertions(+), 112 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8b99d115e..855215603 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2004-10-10 Moritz Bunkus + * mkvmerge/mkvinfo/mkvextract: bug fix: The chapter and tag + element tables were not always intialized correctly depending on + the compiler and the optimization flags used. + * mkvmerge: bug fix: The OGM reader was broken if at least one track was not to be copied from the file (happened between 0.9.5 and 0.9.6). diff --git a/src/common/commonebml.cpp b/src/common/commonebml.cpp index 9402ffb99..7170cfbf4 100644 --- a/src/common/commonebml.cpp +++ b/src/common/commonebml.cpp @@ -380,6 +380,31 @@ find_ebml_callbacks(const EbmlCallbacks &base, throw ""; } +const EbmlCallbacks & +find_ebml_callbacks(const EbmlCallbacks &base, + const char *debug_name) { + const EbmlSemanticContext &context = base.Context; + int i; + + if (!strcmp(debug_name, base.DebugName)) + return base; + + for (i = 0; i < context.Size; i++) + if (!strcmp(debug_name, context.MyTable[i].GetCallbacks.DebugName)) + return context.MyTable[i].GetCallbacks; + + for (i = 0; i < context.Size; i++) { + if (!(context != context.MyTable[i].GetCallbacks.Context)) + continue; + try { + return find_ebml_callbacks(context.MyTable[i].GetCallbacks, debug_name); + } catch (...) { + } + } + + throw ""; +} + const EbmlCallbacks & find_ebml_parent_callbacks(const EbmlCallbacks &base, const EbmlId &id) { diff --git a/src/common/commonebml.h b/src/common/commonebml.h index d183e9502..261022a8a 100644 --- a/src/common/commonebml.h +++ b/src/common/commonebml.h @@ -100,6 +100,8 @@ EbmlMaster *MTX_DLL_API sort_ebml_master(EbmlMaster *e); const EbmlCallbacks &MTX_DLL_API find_ebml_callbacks(const EbmlCallbacks &base, const EbmlId &id); const EbmlCallbacks &MTX_DLL_API +find_ebml_callbacks(const EbmlCallbacks &base, const char *debug_name); +const EbmlCallbacks &MTX_DLL_API find_ebml_parent_callbacks(const EbmlCallbacks &base, const EbmlId &id); const EbmlSemantic &MTX_DLL_API find_ebml_semantic(const EbmlCallbacks &base, const EbmlId &id); diff --git a/src/common/xml_element_mapping.cpp b/src/common/xml_element_mapping.cpp index fe947335a..91ee0c734 100644 --- a/src/common/xml_element_mapping.cpp +++ b/src/common/xml_element_mapping.cpp @@ -13,143 +13,110 @@ * Written by Moritz Bunkus . */ -#include "ebml/EbmlElement.h" -#include "matroska/KaxConfig.h" +#include +#include +#include +#include "common.h" +#include "commonebml.h" #include "xml_element_mapping.h" -namespace libmatroska { - extern EbmlId MATROSKA_DLL_API KaxChapters_TheId; - extern EbmlId MATROSKA_DLL_API KaxEditionEntry_TheId; - extern EbmlId MATROSKA_DLL_API KaxEditionUID_TheId; - extern EbmlId MATROSKA_DLL_API KaxEditionFlagHidden_TheId; - extern EbmlId MATROSKA_DLL_API KaxEditionFlagDefault_TheId; - extern EbmlId MATROSKA_DLL_API KaxEditionProcessed_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterAtom_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterUID_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterTimeStart_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterTimeEnd_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterFlagHidden_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterFlagEnabled_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterPhysicalEquiv_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterTrack_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterTrackNumber_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterDisplay_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterString_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterLanguage_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterCountry_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterProcessedPrivate_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterProcess_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterProcessTime_TheId; - extern EbmlId MATROSKA_DLL_API KaxChapterProcessCommand_TheId; - - extern EbmlId MATROSKA_DLL_API KaxTags_TheId; - extern EbmlId MATROSKA_DLL_API KaxTag_TheId; - extern EbmlId MATROSKA_DLL_API KaxTagTargets_TheId; - extern EbmlId MATROSKA_DLL_API KaxTagSimple_TheId; - extern EbmlId MATROSKA_DLL_API KaxTagName_TheId; - extern EbmlId MATROSKA_DLL_API KaxTagLangue_TheId; - extern EbmlId MATROSKA_DLL_API KaxTagDefault_TheId; - extern EbmlId MATROSKA_DLL_API KaxTagString_TheId; - extern EbmlId MATROSKA_DLL_API KaxTagBinary_TheId; - extern EbmlId MATROSKA_DLL_API KaxTagTrackUID_TheId; - extern EbmlId MATROSKA_DLL_API KaxTagEditionUID_TheId; - extern EbmlId MATROSKA_DLL_API KaxTagChapterUID_TheId; - extern EbmlId MATROSKA_DLL_API KaxTagAttachmentUID_TheId; - extern EbmlId MATROSKA_DLL_API KaxTagTargetType_TheId; - extern EbmlId MATROSKA_DLL_API KaxTagTargetTypeValue_TheId; -}; - using namespace libmatroska; +static EbmlId no_id((uint32_t)0, 0); + parser_element_t *chapter_elements = NULL; parser_element_t *tag_elements = NULL; -void xml_element_map_init() -{ - static parser_element_t _chapter_elements[] = { - {"Chapters", ebmlt_master, 0, 0, 0, KaxChapters_TheId, NULL, NULL}, +static void +init_mapping_table(parser_element_t *table) { + const char *debug_name; + int i; - {"EditionEntry", ebmlt_master, 1, 0, 0, KaxEditionEntry_TheId, NULL, NULL}, - {"EditionUID", ebmlt_uint, 2, 0, NO_MAX_VALUE, KaxEditionUID_TheId, NULL, + for (i = 0; table[i].name != NULL; i++) { + debug_name = table[i].debug_name != NULL ? table[i].debug_name : + table[i].name; + try { + table[i].id = + find_ebml_callbacks(KaxSegment::ClassInfos, debug_name).GlobalId; + } catch (...) { + mxerror("Error initializing the tables for the chapter and tag " + "elements: Could not find the element with the debug name " + "'%s'. %s\n", debug_name, BUGMSG); + } + } +} + +void +xml_element_map_init() { + static parser_element_t _chapter_elements[] = { + {"Chapters", ebmlt_master, 0, 0, 0, no_id, NULL, NULL, NULL}, + + {"EditionEntry", ebmlt_master, 1, 0, 0, no_id, NULL, NULL, NULL}, + {"EditionUID", ebmlt_uint, 2, 0, NO_MAX_VALUE, no_id, NULL, NULL, NULL}, + {"EditionFlagHidden", ebmlt_bool, 2, 0, 0, no_id, NULL, NULL, NULL}, + {"EditionProcessed", ebmlt_uint, 2, 0, NO_MAX_VALUE, no_id, NULL, NULL, NULL}, - {"EditionFlagHidden", ebmlt_bool, 2, 0, 0, KaxEditionFlagHidden_TheId, - NULL, NULL}, - {"EditionProcessed", ebmlt_uint, 2, 0, NO_MAX_VALUE, - KaxEditionProcessed_TheId, NULL, NULL}, - {"EditionFlagDefault", ebmlt_bool, 2, 0, 0, KaxEditionFlagDefault_TheId, - NULL, NULL}, + {"EditionFlagDefault", ebmlt_bool, 2, 0, 0, no_id, NULL, NULL, NULL}, - {"ChapterAtom", ebmlt_master, 2, 0, 0, KaxChapterAtom_TheId, NULL, + {"ChapterAtom", ebmlt_master, 2, 0, 0, no_id, NULL, NULL, NULL}, + {"ChapterUID", ebmlt_uint, 3, 0, NO_MAX_VALUE, no_id, NULL, NULL, NULL}, + {"ChapterTimeStart", ebmlt_time, 3, 0, 0, no_id, NULL, NULL, NULL}, + {"ChapterTimeEnd", ebmlt_time, 3, 0, 0, no_id, NULL, NULL, NULL}, + {"ChapterFlagHidden", ebmlt_bool, 3, 0, 0, no_id, NULL, NULL, NULL}, + {"ChapterFlagEnabled", ebmlt_bool, 3, 0, 0, no_id, NULL, NULL, NULL}, + {"ChapterProcessedPrivate", ebmlt_binary, 3, 0, 0, no_id, NULL, NULL, NULL}, - {"ChapterUID", ebmlt_uint, 3, 0, NO_MAX_VALUE, KaxChapterUID_TheId, NULL, + + {"ChapterProcess", ebmlt_master, 3, 0, 0, no_id, NULL, NULL, NULL}, + {"ChapterProcessTime", ebmlt_uint, 4, 0, 0, no_id, NULL, NULL, NULL}, + {"ChapterProcessCommand", ebmlt_binary, 4, 0, 0, no_id, NULL, NULL, NULL}, + + {"ChapterTrack", ebmlt_master, 3, 0, 0, no_id, NULL, NULL, NULL}, + {"ChapterTrackNumber", ebmlt_uint, 4, 0, NO_MAX_VALUE, no_id, NULL, NULL, NULL}, - {"ChapterTimeStart", ebmlt_time, 3, 0, 0, KaxChapterTimeStart_TheId, NULL, - NULL}, - {"ChapterTimeEnd", ebmlt_time, 3, 0, 0, KaxChapterTimeEnd_TheId, NULL, - NULL}, - {"ChapterFlagHidden", ebmlt_bool, 3, 0, 0, KaxChapterFlagHidden_TheId, - NULL, NULL}, - {"ChapterFlagEnabled", ebmlt_bool, 3, 0, 0, KaxChapterFlagEnabled_TheId, - NULL, NULL}, - {"ChapterProcessedPrivate", ebmlt_binary, 3, 0, 0, - KaxChapterProcessedPrivate_TheId, NULL, NULL}, - {"ChapterProcess", ebmlt_master, 3, 0, 0, KaxChapterProcess_TheId, - NULL, NULL}, - {"ChapterProcessTime", ebmlt_uint, 4, 0, 0, KaxChapterProcessTime_TheId, - NULL, NULL}, - {"ChapterProcessCommand", ebmlt_binary, 4, 0, 0, - KaxChapterProcessCommand_TheId, NULL, NULL}, + {"ChapterDisplay", ebmlt_master, 3, 0, 0, no_id, NULL, NULL, NULL}, + {"ChapterString", ebmlt_ustring, 4, 0, 0, no_id, NULL, NULL, NULL}, + {"ChapterLanguage", ebmlt_string, 4, 0, 0, no_id, NULL, NULL, NULL}, + {"ChapterCountry", ebmlt_string, 4, 0, 0, no_id, NULL, NULL, NULL}, - {"ChapterTrack", ebmlt_master, 3, 0, 0, KaxChapterTrack_TheId, - NULL, NULL}, - {"ChapterTrackNumber", ebmlt_uint, 4, 0, NO_MAX_VALUE, - KaxChapterTrackNumber_TheId, NULL, NULL}, - - {"ChapterDisplay", ebmlt_master, 3, 0, 0, KaxChapterDisplay_TheId, - NULL, NULL}, - {"ChapterString", ebmlt_ustring, 4, 0, 0, KaxChapterString_TheId, - NULL, NULL}, - {"ChapterLanguage", ebmlt_string, 4, 0, 0, KaxChapterLanguage_TheId, - NULL, NULL}, - {"ChapterCountry", ebmlt_string, 4, 0, 0, KaxChapterCountry_TheId, - NULL, NULL}, - - {NULL, ebmlt_master, 0, 0, 0, EbmlId((uint32_t)0, 0), NULL, NULL} + {NULL, ebmlt_master, 0, 0, 0, EbmlId((uint32_t)0, 0), NULL, NULL, NULL} }; static parser_element_t _tag_elements[] = { - {"Tags", ebmlt_master, 0, 0, 0, KaxTags_TheId, NULL, NULL}, + {"Tags", ebmlt_master, 0, 0, 0, no_id, NULL, NULL, NULL}, - {"Tag", ebmlt_master, 1, 0, 0, KaxTag_TheId, NULL, NULL}, + {"Tag", ebmlt_master, 1, 0, 0, no_id, NULL, NULL, NULL}, - {"Targets", ebmlt_master, 2, 0, 0, KaxTagTargets_TheId, NULL, NULL}, - {"TrackUID", ebmlt_uint, 3, 0, NO_MAX_VALUE, KaxTagTrackUID_TheId, - NULL, NULL}, - {"EditionUID", ebmlt_uint, 3, 0, NO_MAX_VALUE, KaxTagEditionUID_TheId, - NULL, NULL}, - {"ChapterUID", ebmlt_uint, 3, 0, NO_MAX_VALUE, KaxTagChapterUID_TheId, - NULL, NULL}, - {"AttachmentUID", ebmlt_uint, 3, 0, NO_MAX_VALUE, - KaxTagAttachmentUID_TheId, NULL, NULL}, - {"TargetType", ebmlt_string, 3, 0, 0, KaxTagTargetType_TheId, NULL, NULL}, - {"TargetTypeValue", ebmlt_uint, 3, 0, NO_MAX_VALUE, - KaxTagTargetTypeValue_TheId, NULL, NULL}, + {"Targets", ebmlt_master, 2, 0, 0, no_id, NULL, NULL, "TagTargets"}, + {"TrackUID", ebmlt_uint, 3, 0, NO_MAX_VALUE, no_id, NULL, NULL, + "TagTrackUID"}, + {"EditionUID", ebmlt_uint, 3, 0, NO_MAX_VALUE, no_id, NULL, NULL, + "TagEditionUID"}, + {"ChapterUID", ebmlt_uint, 3, 0, NO_MAX_VALUE, no_id, NULL, NULL, + "TagChapterUID"}, + {"AttachmentUID", ebmlt_uint, 3, 0, NO_MAX_VALUE, no_id, NULL, NULL, + "TagAttachmentUID"}, + {"TargetType", ebmlt_string, 3, 0, 0, no_id, NULL, NULL, "TagTargetType"}, + {"TargetTypeValue", ebmlt_uint, 3, 0, NO_MAX_VALUE, no_id, NULL, NULL, + "TagTargetTypeValue"}, - {"Simple", ebmlt_master, 2, 0, 0, KaxTagSimple_TheId, NULL, NULL}, - {"Name", ebmlt_ustring, 3, 0, 0, KaxTagName_TheId, NULL, NULL}, - {"String", ebmlt_ustring, 3, 0, 0, KaxTagString_TheId, NULL, NULL}, - {"Binary", ebmlt_binary, 3, 0, 0, KaxTagBinary_TheId, NULL, NULL}, - {"TagLanguage", ebmlt_string, 3, 0, 0, KaxTagLangue_TheId, NULL, NULL}, - {"DefaultLanguage", ebmlt_bool, 3, 0, 1, KaxTagDefault_TheId, NULL, NULL}, + {"Simple", ebmlt_master, 2, 0, 0, no_id, NULL, NULL, "TagSimple"}, + {"Name", ebmlt_ustring, 3, 0, 0, no_id, NULL, NULL, "TagName"}, + {"String", ebmlt_ustring, 3, 0, 0, no_id, NULL, NULL, "TagString"}, + {"Binary", ebmlt_binary, 3, 0, 0, no_id, NULL, NULL, "TagBinary"}, + {"TagLanguage", ebmlt_string, 3, 0, 0, no_id, NULL, NULL, "TagLanguage"}, + {"DefaultLanguage", ebmlt_bool, 3, 0, 1, no_id, NULL, NULL, "TagDefault"}, - {NULL, ebmlt_master, 0, 0, 0, EbmlId((uint32_t)0, 0), NULL, NULL} + {NULL, ebmlt_master, 0, 0, 0, EbmlId((uint32_t)0, 0), NULL, NULL, NULL} }; chapter_elements = _chapter_elements; tag_elements = _tag_elements; -}; + init_mapping_table(chapter_elements); + init_mapping_table(tag_elements); +} int xml_element_map_index(const parser_element_t *element_map, diff --git a/src/common/xml_element_mapping.h b/src/common/xml_element_mapping.h index 4e2f46c78..2b500bde6 100644 --- a/src/common/xml_element_mapping.h +++ b/src/common/xml_element_mapping.h @@ -36,9 +36,10 @@ typedef struct { int level; int64_t min_value; int64_t max_value; - const EbmlId id; + EbmlId id; parser_element_callback_t start_hook; parser_element_callback_t end_hook; + const char *debug_name; } parser_element_t; extern parser_element_t MTX_DLL_API *chapter_elements;