diff --git a/src/mkvmerge.cpp b/src/mkvmerge.cpp index 5f70697ea..714b49d55 100644 --- a/src/mkvmerge.cpp +++ b/src/mkvmerge.cpp @@ -249,6 +249,7 @@ static void usage(void) { " None at all, only for I frames, for all.\n" " --language Sets the language for the track (ISO639-2\n" " code, see --list-languages).\n" + " -t, --tags Read tags for the track from a XML file.\n" "\n Options that only apply to video tracks:\n" " -f, --fourcc Forces the FourCC to the specified value.\n" " Works only for video tracks.\n" @@ -646,6 +647,29 @@ static void parse_sub_charset(char *s, language_t &sub_charset) { sub_charset.language = s; } +static void parse_tags(char *s, tags_t &tags) { + char *colon; + + // Extract the track number. + if ((colon = strchr(s, ':')) == NULL) { + mxprint(stderr, "Error: Invalid tags option. No track ID specified " + "(%s).\n", s); + exit(1); + } + *colon = 0; + if (!parse_int(s, tags.id)) { + mxprint(stderr, "Error: Invalid track ID specified.\n"); + exit(1); + } + s = &colon[1]; + if (*s == 0) { + mxprint(stderr, "Error: Invalid tags file name specified.\n"); + exit(1); + } + + tags.file_name = s; +} + static void render_headers(mm_io_c *out, bool last_file, bool first_file) { EbmlHead head; int i; @@ -917,6 +941,7 @@ static void identify(const char *filename) { ti.default_track_flags = new vector; ti.languages = new vector; ti.sub_charsets = new vector; + ti.all_tags = new vector; ti.aspect_ratio = 1.0; ti.atracks = new vector; ti.vtracks = new vector; @@ -960,6 +985,7 @@ static void parse_args(int argc, char **argv) { int64_t id; language_t lang; attachment_t *attachment; + tags_t tags; mm_io_c *io; memset(&ti, 0, sizeof(track_info_t)); @@ -968,12 +994,14 @@ static void parse_args(int argc, char **argv) { ti.default_track_flags = new vector; ti.languages = new vector; ti.sub_charsets = new vector; + ti.all_tags = new vector; ti.aspect_ratio = 1.0; ti.atracks = new vector; ti.vtracks = new vector; ti.stracks = new vector; attachment = (attachment_t *)safemalloc(sizeof(attachment_t)); memset(attachment, 0, sizeof(attachment_t)); + memset(&tags, 0, sizeof(tags_t)); // Check if only information about the file is wanted. In this mode only // two parameters are allowed: the --identify switch and the file. @@ -1305,6 +1333,15 @@ static void parse_args(int argc, char **argv) { parse_sub_charset(argv[i + 1], lang); ti.sub_charsets->push_back(lang); i++; + + } else if (!strcmp(argv[i], "-t") || !strcmp(argv[i], "--tags")) { + if ((i + 1) >= argc) { + mxprint(stderr, "Error: %s lacks its argument.\n", argv[i]); + exit(1); + } + parse_tags(argv[i + 1], tags); + ti.all_tags->push_back(tags); + i++; } // The argument is an input file. @@ -1353,12 +1390,14 @@ static void parse_args(int argc, char **argv) { delete ti.default_track_flags; delete ti.languages; delete ti.sub_charsets; + delete ti.all_tags; memset(&ti, 0, sizeof(track_info_t)); ti.audio_syncs = new vector; ti.cue_creations = new vector; ti.default_track_flags = new vector; ti.languages = new vector; ti.sub_charsets = new vector; + ti.all_tags = new vector; ti.aspect_ratio = 1.0; ti.atracks = new vector; ti.vtracks = new vector; diff --git a/src/pr_generic.cpp b/src/pr_generic.cpp index f8ef3ab50..6b1354106 100644 --- a/src/pr_generic.cpp +++ b/src/pr_generic.cpp @@ -26,6 +26,7 @@ #include "common.h" #include "mkvmerge.h" #include "pr_generic.h" +#include "tagparser.h" generic_packetizer_c::generic_packetizer_c(generic_reader_c *nreader, track_info_t *nti) throw(error_c) { @@ -34,6 +35,7 @@ generic_packetizer_c::generic_packetizer_c(generic_reader_c *nreader, cue_creation_t *cc; int64_t id; language_t *lang; + tags_t *tags; bool found; #ifdef DEBUG @@ -101,6 +103,17 @@ generic_packetizer_c::generic_packetizer_c(generic_reader_c *nreader, } } + // Let's see if the user has specified a sub charset for this track. + for (i = 0; i < ti->all_tags->size(); i++) { + tags = &(*ti->all_tags)[i]; + if ((tags->id == ti->id) || (tags->id == -1)) { // -1 == all tracks + ti->tags_ptr = tags; + ti->tags = new KaxTags; + parse_xml_tags(ti->tags_ptr->file_name, ti->tags); + break; + } + } + // Set default header values to 'unset'. hserialno = track_number++; huid = 0; @@ -538,6 +551,7 @@ track_info_t *duplicate_track_info(track_info_t *src) { for (i = 0; i < src->sub_charsets->size(); i++) (*dst->sub_charsets)[i].language = safestrdup((*src->sub_charsets)[i].language); + dst->all_tags = new vector(*src->all_tags); dst->private_data = (unsigned char *)safememdup(src->private_data, src->private_size); dst->sub_charset = safestrdup(src->sub_charset); @@ -564,6 +578,7 @@ void free_track_info(track_info_t *ti) { for (i = 0; i < ti->sub_charsets->size(); i++) safefree((*ti->sub_charsets)[i].language); delete ti->sub_charsets; + delete ti->all_tags; safefree(ti->language); safefree(ti->private_data); safefree(ti->sub_charset); diff --git a/src/pr_generic.h b/src/pr_generic.h index 66ebf4f10..997607370 100644 --- a/src/pr_generic.h +++ b/src/pr_generic.h @@ -29,6 +29,7 @@ #include #include #include +#include #include "error.h" @@ -67,6 +68,11 @@ typedef struct { int64_t id; } language_t; +typedef struct { + const char *file_name; + int64_t id; +} tags_t; + typedef struct { // The track ID. int64_t id; @@ -97,6 +103,10 @@ typedef struct { vector *sub_charsets; // As given on the command line char *sub_charset; // For this very track + + vector *all_tags; // As given on the command line + tags_t *tags_ptr; // For this very track + KaxTags *tags; // For this very track } track_info_t; class generic_reader_c;