mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-23 19:31:44 +00:00
Added an option for setting the track name. Track names and the segment title are kept when reading a Matroska file.
This commit is contained in:
parent
5bffe14d93
commit
e48c6bc73a
@ -1,5 +1,7 @@
|
||||
2003-09-12 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvmerge: Support for setting the track names.
|
||||
|
||||
* mkvmerge: For Matroska source files: If the source contains
|
||||
chapters then these are kept unless the user specified chapters
|
||||
with --chapters.
|
||||
|
@ -222,6 +222,10 @@ prefer the track that has his 'default' flag set. Only one track of each kind
|
||||
This option can be used multiple times for an input file applying to several
|
||||
tracks by selecting different track IDs each time.
|
||||
.TP
|
||||
\fB\-\-track\-name\fR <\fITID\fR:\fIname\fR>
|
||||
Sets the track name for the given track (see section \fBTRACK IDS\fR) to
|
||||
\fIname\fR.
|
||||
.TP
|
||||
\fB\-\-language\fR <\fITID\fR:\fIlanguage\fR>
|
||||
Sets the language for the given track (see section \fBTRACK IDS\fR). Only
|
||||
ISO639-2 codes are allowed. All languages including their ISO639-2 codes can be
|
||||
|
@ -168,7 +168,7 @@ char *chapter_file_name = NULL;
|
||||
char *chapter_language = NULL;
|
||||
char *chapter_charset = NULL;
|
||||
|
||||
string title;
|
||||
string segment_title;
|
||||
|
||||
int64_t tags_size = 0;
|
||||
bool accept_tags = true;
|
||||
@ -283,6 +283,7 @@ static void usage() {
|
||||
" omitted. Both o and p can be floating point\n"
|
||||
" numbers.\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"
|
||||
" Create cue (index) entries for this track:\n"
|
||||
" None at all, only for I frames, for all.\n"
|
||||
@ -691,24 +692,24 @@ static void parse_compression(char *s, cue_creation_t &compression) {
|
||||
orig.c_str());
|
||||
}
|
||||
|
||||
static void parse_language(char *s, language_t &lang) {
|
||||
static void parse_language(char *s, language_t &lang, const char *opt,
|
||||
const char *topic, bool check) {
|
||||
char *colon;
|
||||
string orig = s;
|
||||
|
||||
// Extract the track number.
|
||||
if ((colon = strchr(s, ':')) == NULL)
|
||||
mxerror("Invalid language option. No track ID specified in "
|
||||
"'--language %s'.\n", orig.c_str());
|
||||
mxerror("No track ID specified in '--%s' %s'.\n", opt, orig.c_str());
|
||||
|
||||
*colon = 0;
|
||||
if (!parse_int(s, lang.id))
|
||||
mxerror("Invalid track ID specified in '--language %s'.\n", orig.c_str());
|
||||
mxerror("Invalid track ID specified in '--%s %s'.\n", opt, orig.c_str());
|
||||
|
||||
s = &colon[1];
|
||||
if (*s == 0)
|
||||
mxerror("Invalid language specified in '--language %s'.\n", orig.c_str());
|
||||
mxerror("Invalid %s specified in '--%s %s'.\n", topic, opt, orig.c_str());
|
||||
|
||||
if (!is_valid_iso639_2_code(s))
|
||||
if (check && !is_valid_iso639_2_code(s))
|
||||
mxerror("'%s' is not a valid ISO639-2 code. See "
|
||||
"'mkvmerge --list-languages'.\n", s);
|
||||
|
||||
@ -791,9 +792,9 @@ static void render_headers(mm_io_c *out, bool last_file, bool first_file) {
|
||||
cstr_to_UTFstring(VERSIONINFO);
|
||||
GetChild<KaxDateUTC>(*kax_infos).SetEpochDate(time(NULL));
|
||||
|
||||
if (title.length() > 0)
|
||||
if (segment_title.length() > 0)
|
||||
*((EbmlUnicodeString *)&GetChild<KaxTitle>(*kax_infos)) =
|
||||
cstr_to_UTFstring(title.c_str());
|
||||
cstrutf8_to_UTFstring(segment_title.c_str());
|
||||
|
||||
// Generate the segment UIDs.
|
||||
if (first_file) {
|
||||
@ -1007,6 +1008,7 @@ static void identify(const char *filename) {
|
||||
ti.stracks = new vector<int64_t>;
|
||||
ti.aac_is_sbr = new vector<int64_t>;
|
||||
ti.compression_list = new vector<cue_creation_t>;
|
||||
ti.track_names = new vector<language_t>;
|
||||
|
||||
file = (filelist_t *)safemalloc(sizeof(filelist_t));
|
||||
|
||||
@ -1064,6 +1066,7 @@ static void parse_args(int argc, char **argv) {
|
||||
ti.vtracks = new vector<int64_t>;
|
||||
ti.stracks = new vector<int64_t>;
|
||||
ti.compression_list = new vector<cue_creation_t>;
|
||||
ti.track_names = new vector<language_t>;
|
||||
attachment = (attachment_t *)safemalloc(sizeof(attachment_t));
|
||||
memset(attachment, 0, sizeof(attachment_t));
|
||||
memset(&tags, 0, sizeof(tags_t));
|
||||
@ -1147,10 +1150,13 @@ static void parse_args(int argc, char **argv) {
|
||||
verbose = 2;
|
||||
|
||||
else if (!strcmp(this_arg, "--title")) {
|
||||
char *tmp;
|
||||
if ((next_arg == NULL) || (next_arg[0] == 0))
|
||||
mxerror("'--title' lacks the title.\n");
|
||||
|
||||
title = next_arg;
|
||||
tmp = to_utf8(cc_local_utf8, next_arg);
|
||||
segment_title = tmp;
|
||||
safefree(tmp);
|
||||
i++;
|
||||
|
||||
} else if (!strcmp(this_arg, "--split")) {
|
||||
@ -1452,7 +1458,7 @@ static void parse_args(int argc, char **argv) {
|
||||
if (next_arg == NULL)
|
||||
mxerror("'--language' lacks its argument.\n");
|
||||
|
||||
parse_language(next_arg, lang);
|
||||
parse_language(next_arg, lang, "language", "language", true);
|
||||
ti.languages->push_back(lang);
|
||||
i++;
|
||||
|
||||
@ -1491,6 +1497,15 @@ static void parse_args(int argc, char **argv) {
|
||||
ti.compression_list->push_back(cues);
|
||||
i++;
|
||||
|
||||
} else if (!strcmp(this_arg, "--track-name")) {
|
||||
if (next_arg == NULL)
|
||||
mxerror("'--track-name' lacks its argument.\n");
|
||||
|
||||
parse_language(next_arg, lang, "track-name", "track name", false);
|
||||
lang.language = to_utf8(cc_local_utf8, lang.language);
|
||||
ti.track_names->push_back(lang);
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
// The argument is an input file.
|
||||
@ -1537,6 +1552,9 @@ static void parse_args(int argc, char **argv) {
|
||||
delete ti.all_tags;
|
||||
delete ti.aac_is_sbr;
|
||||
delete ti.compression_list;
|
||||
for (j = 0; j < ti.track_names->size(); j++)
|
||||
safefree((*ti.track_names)[j].language);
|
||||
delete ti.track_names;
|
||||
memset(&ti, 0, sizeof(track_info_t));
|
||||
ti.audio_syncs = new vector<audio_sync_t>;
|
||||
ti.cue_creations = new vector<cue_creation_t>;
|
||||
@ -1550,6 +1568,7 @@ static void parse_args(int argc, char **argv) {
|
||||
ti.vtracks = new vector<int64_t>;
|
||||
ti.stracks = new vector<int64_t>;
|
||||
ti.compression_list = new vector<cue_creation_t>;
|
||||
ti.track_names = new vector<language_t>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1584,6 +1603,9 @@ static void parse_args(int argc, char **argv) {
|
||||
delete ti.vtracks;
|
||||
delete ti.stracks;
|
||||
delete ti.compression_list;
|
||||
for (j = 0; j < ti.track_names->size(); j++)
|
||||
safefree((*ti.track_names)[j].language);
|
||||
delete ti.track_names;
|
||||
safefree(attachment);
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ extern KaxSeekHead *kax_sh_main, *kax_sh_cues;
|
||||
extern KaxChapters *kax_chapters;
|
||||
extern int track_number;
|
||||
extern int64_t tags_size;
|
||||
extern string segment_title;
|
||||
|
||||
extern float video_fps;
|
||||
|
||||
|
@ -125,6 +125,16 @@ generic_packetizer_c::generic_packetizer_c(generic_reader_c *nreader,
|
||||
}
|
||||
}
|
||||
|
||||
// Let's see if the user has specified a name for this track.
|
||||
for (i = 0; i < ti->track_names->size(); i++) {
|
||||
lang = &(*ti->track_names)[i];
|
||||
if ((lang->id == ti->id) || (lang->id == -1)) { // -1 == all tracks
|
||||
safefree(ti->track_name);
|
||||
ti->track_name = safestrdup(lang->language);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Set default header values to 'unset'.
|
||||
hserialno = track_number++;
|
||||
huid = 0;
|
||||
@ -246,6 +256,11 @@ int generic_packetizer_c::get_track_num() {
|
||||
return hserialno;
|
||||
}
|
||||
|
||||
void generic_packetizer_c::set_track_name(const char *name) {
|
||||
safefree(ti->track_name);
|
||||
ti->track_name = safestrdup(name);
|
||||
}
|
||||
|
||||
void generic_packetizer_c::set_codec_id(const char *id) {
|
||||
safefree(hcodec_id);
|
||||
if (id == NULL) {
|
||||
@ -426,11 +441,15 @@ void generic_packetizer_c::set_headers() {
|
||||
*(static_cast<EbmlUInteger *>
|
||||
(&GetChild<KaxTrackFlagDefault>(*track_entry))) = 0;
|
||||
|
||||
if (ti->language != NULL) {
|
||||
if (ti->language != NULL)
|
||||
*(static_cast<EbmlString *>
|
||||
(&GetChild<KaxTrackLanguage>(*track_entry))) = ti->language;
|
||||
}
|
||||
|
||||
if (ti->track_name != NULL)
|
||||
*(static_cast<EbmlUnicodeString *>
|
||||
(&GetChild<KaxTrackName>(*track_entry))) =
|
||||
cstrutf8_to_UTFstring(ti->track_name);
|
||||
|
||||
if (htrack_type == track_video) {
|
||||
KaxTrackVideo &video =
|
||||
GetChild<KaxTrackVideo>(*track_entry);
|
||||
@ -662,19 +681,24 @@ track_info_t *duplicate_track_info(track_info_t *src) {
|
||||
dst->languages = new vector<language_t>(*src->languages);
|
||||
for (i = 0; i < src->languages->size(); i++)
|
||||
(*dst->languages)[i].language = safestrdup((*src->languages)[i].language);
|
||||
dst->language = safestrdup(src->language);
|
||||
dst->sub_charsets = new vector<language_t>(*src->sub_charsets);
|
||||
for (i = 0; i < src->sub_charsets->size(); i++)
|
||||
(*dst->sub_charsets)[i].language =
|
||||
safestrdup((*src->sub_charsets)[i].language);
|
||||
dst->sub_charset = safestrdup(src->sub_charset);
|
||||
dst->all_tags = new vector<tags_t>(*src->all_tags);
|
||||
for (i = 0; i < src->all_tags->size(); i++)
|
||||
(*dst->all_tags)[i].file_name = safestrdup((*src->all_tags)[i].file_name);
|
||||
dst->aac_is_sbr = new vector<int64_t>(*src->aac_is_sbr);
|
||||
dst->private_data = (unsigned char *)safememdup(src->private_data,
|
||||
src->private_size);
|
||||
dst->language = safestrdup(src->language);
|
||||
dst->sub_charset = safestrdup(src->sub_charset);
|
||||
dst->compression_list = new vector<cue_creation_t>(*src->compression_list);
|
||||
dst->track_names = new vector<language_t>(*src->track_names);
|
||||
for (i = 0; i < src->track_names->size(); i++)
|
||||
(*dst->track_names)[i].language =
|
||||
safestrdup((*src->track_names)[i].language);
|
||||
dst->track_name = safestrdup(src->track_name);
|
||||
dst->tags = NULL;
|
||||
|
||||
return dst;
|
||||
@ -696,17 +720,21 @@ void free_track_info(track_info_t *ti) {
|
||||
for (i = 0; i < ti->languages->size(); i++)
|
||||
safefree((*ti->languages)[i].language);
|
||||
delete ti->languages;
|
||||
safefree(ti->language);
|
||||
for (i = 0; i < ti->sub_charsets->size(); i++)
|
||||
safefree((*ti->sub_charsets)[i].language);
|
||||
delete ti->sub_charsets;
|
||||
safefree(ti->sub_charset);
|
||||
for (i = 0; i < ti->all_tags->size(); i++)
|
||||
safefree((*ti->all_tags)[i].file_name);
|
||||
delete ti->all_tags;
|
||||
delete ti->aac_is_sbr;
|
||||
delete ti->compression_list;
|
||||
safefree(ti->language);
|
||||
for (i = 0; i < ti->track_names->size(); i++)
|
||||
safefree((*ti->track_names)[i].language);
|
||||
delete ti->track_names;
|
||||
safefree(ti->track_name);
|
||||
safefree(ti->private_data);
|
||||
safefree(ti->sub_charset);
|
||||
if (ti->tags != NULL)
|
||||
delete ti->tags;
|
||||
safefree(ti);
|
||||
|
@ -115,6 +115,9 @@ typedef struct {
|
||||
vector<cue_creation_t> *compression_list; // As given on the command line
|
||||
int compression; // For this very track
|
||||
|
||||
vector<language_t> *track_names; // As given on the command line
|
||||
char *track_name; // For this very track
|
||||
|
||||
bool no_chapters;
|
||||
} track_info_t;
|
||||
|
||||
@ -213,6 +216,8 @@ public:
|
||||
|
||||
virtual void set_tag_track_uid();
|
||||
|
||||
virtual void set_track_name(const char *name);
|
||||
|
||||
protected:
|
||||
virtual void dump_packet(const void *buffer, int size);
|
||||
};
|
||||
|
@ -136,6 +136,8 @@ kax_reader_c::~kax_reader_c() {
|
||||
delete tracks[i]->packetizer;
|
||||
safefree(tracks[i]->private_data);
|
||||
safefree(tracks[i]->codec_id);
|
||||
safefree(tracks[i]->language);
|
||||
safefree(tracks[i]->track_name);
|
||||
safefree(tracks[i]);
|
||||
}
|
||||
|
||||
@ -664,6 +666,7 @@ int kax_reader_c::read_headers() {
|
||||
if (EbmlId(*l1) == KaxInfo::ClassInfos.GlobalId) {
|
||||
KaxTimecodeScale *ktc_scale;
|
||||
KaxDuration *kduration;
|
||||
KaxTitle *ktitle;
|
||||
|
||||
// General info about this Matroska file
|
||||
if (verbose > 1)
|
||||
@ -687,6 +690,20 @@ int kax_reader_c::read_headers() {
|
||||
mxinfo(PFX "| + duration: %.3fs\n", segment_duration);
|
||||
}
|
||||
|
||||
ktitle = FINDFIRST(l1, KaxTitle);
|
||||
if (ktitle != NULL) {
|
||||
char *tmp;
|
||||
tmp = UTFstring_to_cstr(UTFstring(*ktitle));
|
||||
if (verbose > 1)
|
||||
mxinfo(PFX "| + title: %s\n", tmp);
|
||||
safefree(tmp);
|
||||
if (segment_title.length() == 0) {
|
||||
tmp = UTFstring_to_cstrutf8(UTFstring(*ktitle));
|
||||
segment_title = tmp;
|
||||
safefree(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (EbmlId(*l1) == KaxTracks::ClassInfos.GlobalId) {
|
||||
KaxTrackEntry *ktentry;
|
||||
|
||||
@ -712,6 +729,7 @@ int kax_reader_c::read_headers() {
|
||||
KaxTrackFlagDefault *ktfdefault;
|
||||
KaxTrackLanguage *ktlanguage;
|
||||
KaxTrackMinCache *ktmincache;
|
||||
KaxTrackName *ktname;
|
||||
|
||||
if (verbose > 1)
|
||||
mxinfo(PFX "| + a track...\n");
|
||||
@ -909,6 +927,18 @@ int kax_reader_c::read_headers() {
|
||||
track->language = safestrdup(string(*ktlanguage).c_str());
|
||||
}
|
||||
|
||||
ktname = FINDFIRST(ktentry, KaxTrackName);
|
||||
if (ktname != NULL) {
|
||||
char *tmp;
|
||||
safefree(track->track_name);
|
||||
track->track_name =
|
||||
UTFstring_to_cstrutf8(UTFstring(*ktname));
|
||||
tmp = UTFstring_to_cstr(UTFstring(*ktname));
|
||||
if (verbose > 1)
|
||||
mxinfo(PFX "| + Name: %s\n", tmp);
|
||||
safefree(tmp);
|
||||
}
|
||||
|
||||
ktentry = FINDNEXT(l1, KaxTrackEntry, ktentry);
|
||||
} // while (ktentry != NULL)
|
||||
|
||||
@ -1029,8 +1059,10 @@ void kax_reader_c::create_packetizers() {
|
||||
memcpy(nti.fourcc, t->v_fourcc, 5);
|
||||
if (nti.default_track == 0)
|
||||
nti.default_track = t->default_track;
|
||||
if (nti.language == 0)
|
||||
if (nti.language == NULL)
|
||||
nti.language = t->language;
|
||||
if (nti.track_name == NULL)
|
||||
nti.track_name = t->track_name;
|
||||
|
||||
if (t->ok && demuxing_requested(t->type, t->tnum)) {
|
||||
nti.id = t->tnum; // ID for this track.
|
||||
|
@ -73,6 +73,8 @@ typedef struct {
|
||||
|
||||
int64_t units_processed;
|
||||
|
||||
char *track_name;
|
||||
|
||||
int ok;
|
||||
|
||||
generic_packetizer_c *packetizer;
|
||||
|
Loading…
Reference in New Issue
Block a user