Enable RTTI on the MSVC build. Initialize the XML mapping tables later because MSVC initializes them before the EbmlIDs in libmatroska are initialized resulting in invalid tables. Added a --delay option. General patch by Steve Lhomme with changes by Moritz Bunkus.

This commit is contained in:
Moritz Bunkus 2004-09-27 20:53:39 +00:00
parent 370070224a
commit d6bf885dbd
9 changed files with 175 additions and 71 deletions

View File

@ -261,6 +261,13 @@ Defaults: no manual sync correction (which is the same as \fId\fR = 0 and
This option can be used multiple times for an input file applying to several
tracks by selecting different track IDs each time.
.TP
\fB\-\-delay\fR <\fITID\fR:\fIx\fR>
The delay to apply to the packets of the track by simply adjusting the
timecodes.
The argument \fIx\fR must be postfixed with \fBs\fR, \fBms\fR, \fBus\fR or
\fBns\fR to specify seconds, milliseconds, microseconds and nanoseconds
respectively.
.TP
\fB\-\-cues\fR <\fITID\fR:\fInone\fR|\fIiframes\fR|\fIall\fR>
Controls for which tracks cue (index) entries are created for the given track
(see section \fBTRACK IDS\fR). \fInone\fR inhibits the creation of cue entries.

View File

@ -24,6 +24,7 @@
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
@ -73,6 +74,7 @@
AdditionalIncludeDirectories="&quot;.\avilib-0.6.10&quot;;.\librmff;src\common;src\input;src\output;.;.\src;..\..\work\libebml;..\..\work\libmatroska;..\..\..\zlib;..\..\..\libogg\include;..\..\..\libvorbis\include;..\..\..\expat\lib;..\..\..\flac\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;FLAC__NO_DLL"
RuntimeLibrary="2"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
@ -552,6 +554,12 @@
<File
RelativePath=".\src\common\xml_element_mapping.h">
</File>
<File
RelativePath=".\src\common\xml_element_parser.cpp">
</File>
<File
RelativePath=".\src\common\xml_element_parser.h">
</File>
</Filter>
</Files>
<Globals>

View File

@ -62,84 +62,93 @@ namespace libmatroska {
using namespace libmatroska;
parser_element_t chapter_elements[] = {
{"Chapters", ebmlt_master, 0, 0, 0, KaxChapters_TheId, NULL, NULL},
parser_element_t *chapter_elements = NULL;
parser_element_t *tag_elements = NULL;
{"EditionEntry", ebmlt_master, 1, 0, 0, KaxEditionEntry_TheId, NULL, NULL},
{"EditionUID", ebmlt_uint, 2, 0, NO_MAX_VALUE, KaxEditionUID_TheId, 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},
void xml_element_map_init()
{
static parser_element_t _chapter_elements[] = {
{"Chapters", ebmlt_master, 0, 0, 0, KaxChapters_TheId, NULL, NULL},
{"ChapterAtom", ebmlt_master, 2, 0, 0, KaxChapterAtom_TheId, NULL,
NULL},
{"ChapterUID", ebmlt_uint, 3, 0, NO_MAX_VALUE, KaxChapterUID_TheId, 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},
{"EditionEntry", ebmlt_master, 1, 0, 0, KaxEditionEntry_TheId, NULL, NULL},
{"EditionUID", ebmlt_uint, 2, 0, NO_MAX_VALUE, KaxEditionUID_TheId, 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},
{"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},
{"ChapterAtom", ebmlt_master, 2, 0, 0, KaxChapterAtom_TheId, NULL,
NULL},
{"ChapterUID", ebmlt_uint, 3, 0, NO_MAX_VALUE, KaxChapterUID_TheId, 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},
{"ChapterTrack", ebmlt_master, 3, 0, 0, KaxChapterTrack_TheId,
NULL, NULL},
{"ChapterTrackNumber", ebmlt_uint, 4, 0, NO_MAX_VALUE,
KaxChapterTrackNumber_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, 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},
{"ChapterTrack", ebmlt_master, 3, 0, 0, KaxChapterTrack_TheId,
NULL, NULL},
{"ChapterTrackNumber", ebmlt_uint, 4, 0, NO_MAX_VALUE,
KaxChapterTrackNumber_TheId, NULL, NULL},
{NULL, ebmlt_master, 0, 0, 0, EbmlId((uint32_t)0, 0), 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},
parser_element_t tag_elements[] = {
{"Tags", ebmlt_master, 0, 0, 0, KaxTags_TheId, NULL, NULL},
{NULL, ebmlt_master, 0, 0, 0, EbmlId((uint32_t)0, 0), NULL, NULL}
};
{"Tag", ebmlt_master, 1, 0, 0, KaxTag_TheId, NULL, NULL},
static parser_element_t _tag_elements[] = {
{"Tags", ebmlt_master, 0, 0, 0, KaxTags_TheId, 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},
{"Tag", ebmlt_master, 1, 0, 0, KaxTag_TheId, NULL, NULL},
{"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},
{"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},
{NULL, ebmlt_master, 0, 0, 0, EbmlId((uint32_t)0, 0), NULL, NULL}
{"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},
{NULL, ebmlt_master, 0, 0, 0, EbmlId((uint32_t)0, 0), NULL, NULL}
};
chapter_elements = _chapter_elements;
tag_elements = _tag_elements;
};
int

View File

@ -41,8 +41,8 @@ typedef struct {
parser_element_callback_t end_hook;
} parser_element_t;
extern parser_element_t MTX_DLL_API chapter_elements[];
extern parser_element_t MTX_DLL_API tag_elements[];
extern parser_element_t MTX_DLL_API *chapter_elements;
extern parser_element_t MTX_DLL_API *tag_elements;
#define chapter_element_map_index(name) \
xml_element_map_index(chapter_elements, name)
@ -51,5 +51,6 @@ extern parser_element_t MTX_DLL_API tag_elements[];
int MTX_DLL_API xml_element_map_index(const parser_element_t *element_map,
const char *name);
void MTX_DLL_API xml_element_map_init();
#endif

View File

@ -63,6 +63,7 @@
#include "mkvextract.h"
#include "mm_io.h"
#include "tagwriter.h"
#include "xml_element_mapping.h"
using namespace libmatroska;
using namespace std;
@ -406,6 +407,8 @@ main(int argc,
utf8_init(NULL);
conv_utf8 = utf8_init("UTF-8");
xml_element_map_init();
parse_args(argc, argv, input_file, mode);
if (mode == MODE_TRACKS) {
extract_tracks(input_file);

View File

@ -1925,6 +1925,8 @@ setup() {
#endif
cc_local_utf8 = utf8_init(NULL);
xml_element_map_init();
}
void

View File

@ -88,6 +88,7 @@
#include "r_vobsub.h"
#include "r_wav.h"
#include "tagparser.h"
#include "xml_element_mapping.h"
using namespace libmatroska;
using namespace std;
@ -296,7 +297,7 @@ usage() {
" appended to another track of another file.\n"
" --timecode-scale <n> Force the timecode scale factor to n.\n"
"\n File splitting and linking (more global options):\n"
" --split <d[K,M,G]|HH:MM:SS|ns>\n"
" --split <d[K,M,G]|HH:MM:SS|s>\n"
" Create a new file after d bytes (KB, MB, GB)\n"
" or after a specific time.\n"
" --split-max-files <n> Create at most n files.\n"
@ -335,6 +336,8 @@ usage() {
" linear drifts. p defaults to 1000 if\n"
" omitted. Both o and p can be floating point\n"
" numbers.\n"
" --delay <Xs|ms|us|ns> Delay to apply to the packets of the track\n"
" by simply adjusting the timecodes.\n"
" --default-track <TID> Sets the 'default' flag for this track.\n"
" --track-name <TID:name> Sets the name for a track.\n"
" --cues <TID:none|iframes|all>\n"
@ -1007,6 +1010,49 @@ parse_split(const char *arg) {
split_by_time = false;
}
/** \brief Parse the \c --delay argument
*
* time based: A number that must be postfixed with <tt>s</tt>,
* <tt>ms</tt>, <tt>us</tt> or <tt>ns</tt> to specify seconds,
* milliseconds, microseconds and nanoseconds respectively.
*/
static void
parse_delay(const char *arg,
audio_sync_t &async) {
char *colon, *unit;
string orig = arg;
int64_t mult;
// Extract the track number.
if ((colon = strchr(arg, ':')) == NULL)
mxerror(_("Invalid delay option. No track ID specified in "
"'--delay %s'.\n"), arg);
*colon = 0;
if (!parse_int(arg, async.id))
mxerror(_("Invalid track ID specified in '--delay %s'.\n"), orig.c_str());
colon++;
for (unit = colon; isdigit(*unit); unit++)
;
if (unit == colon)
mxerror(_("Missing delay given in '--delay %s'.\n"), orig.c_str());
mult = 1;
if (!strcasecmp(unit, "s"))
mult = 1000000000;
else if (!strcasecmp(unit, "ms"))
mult = 1000000;
else if (!strcasecmp(unit, "us"))
mult = 1000;
else if (strcasecmp(unit, "ns"))
mxerror(_("Invalid unit given in '--delay %s'.\n"), orig.c_str());
*unit = 0;
if (!parse_int(colon, async.displacement))
mxerror(_("Invalid delay given in '--delay %s'.\n"), orig.c_str());
async.displacement *= mult;
}
/** \brief Parse the \c --cues argument
*
* The argument must have the form \c TID:cuestyle, e.g. \c 0:none.
@ -2282,6 +2328,14 @@ parse_args(int argc,
ti->cue_creations->push_back(cues);
i++;
} else if (!strcmp(this_arg, "--delay")) {
if (next_arg == NULL)
mxerror(_("'--delay' lacks the delay to apply.\n"));
parse_delay(next_arg, async);
ti->packet_delays->push_back(async);
i++;
} else if (!strcmp(this_arg, "--default-track")) {
if (next_arg == NULL)
mxerror(_("'--default-track' lacks the track ID.\n"));
@ -2598,6 +2652,8 @@ setup() {
cc_local_utf8 = utf8_init(NULL);
cluster_helper = new cluster_helper_c();
xml_element_map_init();
}
/** \brief Initialize global variables

View File

@ -80,6 +80,16 @@ generic_packetizer_c::generic_packetizer_c(generic_reader_c *nreader,
initial_displacement = ti->async.displacement;
ti->async.displacement = 0;
// Let's see if the user has specified a delay for this track.
ti->packet_delay = 0;
for (i = 0; i < ti->packet_delays->size(); i++) {
as = &(*ti->packet_delays)[i];
if ((as->id == ti->id) || (as->id == -1)) { // -1 == all tracks
ti->packet_delay = as->displacement;
break;
}
}
// Let's see if the user has specified which cues he wants for this track.
ti->cues = CUES_UNSPECIFIED;
for (i = 0; i < ti->cue_creations->size(); i++) {
@ -850,7 +860,7 @@ generic_packetizer_c::add_packet(memory_c &mem,
pack->duration = duration;
pack->duration_mandatory = duration_mandatory;
pack->source = this;
pack->assigned_timecode = get_next_timecode(timecode);
pack->assigned_timecode = get_next_timecode(timecode) + ti->packet_delay;
if (reader->max_timecode_seen < (pack->assigned_timecode + pack->duration))
reader->max_timecode_seen = pack->assigned_timecode + pack->duration;
@ -1327,6 +1337,7 @@ track_info_c::track_info_c():
sub_charset(NULL),
tags_ptr(NULL),
tags(NULL),
packet_delay(0),
compression(COMPRESSION_NONE),
track_name(NULL),
ext_timecodes(NULL),
@ -1349,6 +1360,7 @@ track_info_c::track_info_c():
sub_charsets = new vector<language_t>;
all_tags = new vector<tags_t>;
aac_is_sbr = new vector<int64_t>;
packet_delays = new vector<audio_sync_t>;
compression_list = new vector<cue_creation_t>;
track_names = new vector<language_t>;
all_ext_timecodes = new vector<language_t>;
@ -1464,6 +1476,9 @@ track_info_c::operator =(const track_info_c &src) {
aac_is_sbr = new vector<int64_t>(*src.aac_is_sbr);
packet_delay = src.packet_delay;
packet_delays = new vector<audio_sync_t>(*src.packet_delays);
compression_list = new vector<cue_creation_t>(*src.compression_list);
compression = src.compression;

View File

@ -198,6 +198,9 @@ public:
vector<int64_t> *aac_is_sbr; // For AAC+/HE-AAC/SBR
vector<audio_sync_t> *packet_delays; // As given on the command line
int64_t packet_delay; // For this very track
vector<cue_creation_t> *compression_list; // As given on the command line
int compression; // For this very track