mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 11:54:01 +00:00
Meta seek element is split into two elements. The first's located at the start of the file containing only a small number of level 1 elements. The clusters are referenced in a second meta seek element located at the end of the file. Removed the options "--meta-seek-size" and "--no-meta-seek". Added the option to disable that second meta seek entry, "--no-clusters-in-meta-seek".
This commit is contained in:
parent
98697f1958
commit
c50de21f63
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
||||
2003-08-24 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvmerge: Meta seek element is split into two elements. The
|
||||
first's located at the start of the file containing only a small
|
||||
number of level 1 elements. The clusters are referenced in a
|
||||
second meta seek element located at the end of the file. Removed
|
||||
the options "--meta-seek-size" and "--no-meta-seek". Added the
|
||||
option to disable that second meta seek entry,
|
||||
"--no-clusters-in-meta-seek".
|
||||
|
||||
2003-08-22 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvextract: Backwards compatibility: Accepts S_SSA and S_ASS as
|
||||
|
@ -59,19 +59,9 @@ data, but seeking will probably be imprecise and slower. Use this only if
|
||||
you're really desperate for space or for testing purposes. See also option
|
||||
\fB\-\-cues\fR which can be specified for each input file.
|
||||
.TP
|
||||
\fB\-\-no\-meta\-seek\fR
|
||||
The meta seek information is stored along with the headers at the beginning
|
||||
of the file and points to the cue entries (the index). This allows a player
|
||||
to quickly find the index and uses very little space. It should be left on
|
||||
and only disabled for testing purposes. At the moment \fB\-\-no\-cues\fR
|
||||
implies \fB\-\-no\-meta\-seek\fR.
|
||||
.TP
|
||||
\fB\-\-meta\-seek\-size\fR \fId\fR
|
||||
Reserve \fRd\fR bytes for the meta seek information (see
|
||||
\fB\-\-no\-meta\-seek). Default value is 100 bytes which should be enough.
|
||||
\fBmkvmerge\fR will abort with an appropriate warning message if the space
|
||||
is not enough and also provide the optimal size to use with this option.
|
||||
This option is normally not needed.
|
||||
\fB\-\-no\-clusters\-in\-meta\-seek\fR
|
||||
Tells \fBmkvmerge\fR not to create a meta seek element at the end of the file
|
||||
containing all clusters. See also the section about \fBMATROSKA FILE LAYOUT\fR.
|
||||
.TP
|
||||
\fB\-\-no\-lacing\fR
|
||||
Disable lacing for all tracks. This will increase the file's size, especially
|
||||
@ -716,6 +706,36 @@ the seconds (two digits long, range 00 - 59). \fI+TZTZ\fR is the time zone,
|
||||
e.g. +0100 or -0200. An example would be 2003-07-30T19:10:16+0200.
|
||||
|
||||
|
||||
|
||||
.SH MATROSKA FILE LAYOUT
|
||||
.LP
|
||||
The Matroska file layout is quite flexible. \fBmkvmerge\fR will render a file
|
||||
in a predefined way. The resulting file looks like this:
|
||||
.LP
|
||||
[EBML head] [segment {meta seek #1} {attachments} {chapters}
|
||||
[segment information] [track information] [cluster 1] {cluster 2} ...
|
||||
{cluster n} {meta seek #2} {tags}]
|
||||
.LP
|
||||
The elements in curly braces optional and depend on the contents and options
|
||||
used. Some notes:
|
||||
.TP
|
||||
*
|
||||
meta seek #1 includes only a small number of level 1 element, and only if
|
||||
they exist: attachments, chapters, tags, meta seek #2. Older versions of
|
||||
\fBmkvmerge\fR used to put the clusters into this meta seek element as well.
|
||||
Therefore some imprecise guessing was necessary to reserve enough space. It
|
||||
often failed. Now only the clusters are stored in meta seek #2, and meta
|
||||
seek #1 refers to the meta seek element #2.
|
||||
.TP
|
||||
*
|
||||
Attachment, chapter and tag elements are only present if they were added.
|
||||
.LP
|
||||
The shortest possible Matroska file would look like this:
|
||||
.LP
|
||||
[EBML head] [segment [segment information] [track information] [cluster 1]]
|
||||
.LP
|
||||
This might be the case for audio-only files.
|
||||
|
||||
.SH NOTES
|
||||
.LP
|
||||
What works:
|
||||
|
@ -488,8 +488,8 @@ int cluster_helper_c::render() {
|
||||
|
||||
cluster->Render(*out, *kax_cues);
|
||||
|
||||
if (kax_seekhead != NULL)
|
||||
kax_seekhead->IndexThis(*cluster, *kax_segment);
|
||||
if (kax_sh_cues != NULL)
|
||||
kax_sh_cues->IndexThis(*cluster, *kax_segment);
|
||||
|
||||
last_cluster_tc = cluster->GlobalTimecode();
|
||||
} else
|
||||
|
138
src/mkvmerge.cpp
138
src/mkvmerge.cpp
@ -136,8 +136,7 @@ int max_blocks_per_cluster = 65535;
|
||||
int max_ms_per_cluster = 2000;
|
||||
bool write_cues = true, cue_writing_requested = false;
|
||||
bool video_track_present = false;
|
||||
bool write_meta_seek = true;
|
||||
int64_t meta_seek_size = 0;
|
||||
bool write_meta_seek_for_clusters = true;
|
||||
bool no_lacing = false, no_linking = false;
|
||||
int64_t split_after = -1;
|
||||
bool split_by_time = false;
|
||||
@ -156,9 +155,9 @@ KaxInfo *kax_infos;
|
||||
KaxTracks *kax_tracks;
|
||||
KaxTrackEntry *kax_last_entry;
|
||||
KaxCues *kax_cues;
|
||||
EbmlVoid *kax_seekhead_void = NULL;
|
||||
EbmlVoid *kax_sh_void = NULL;
|
||||
KaxDuration *kax_duration;
|
||||
KaxSeekHead *kax_seekhead = NULL;
|
||||
KaxSeekHead *kax_sh_main = NULL, *kax_sh_cues = NULL;
|
||||
KaxTags *kax_tags = NULL;
|
||||
KaxAttachments *kax_as = NULL;
|
||||
KaxChapters *kax_chapters = NULL;
|
||||
@ -234,8 +233,8 @@ static void usage() {
|
||||
" put at most n milliseconds of data into each\n"
|
||||
" cluster.\n"
|
||||
" --no-cues Do not write the cue data (the index).\n"
|
||||
" --no-meta-seek Do not write any meta seek information.\n"
|
||||
" --meta-seek-size <d> Reserve d bytes for the meta seek entries.\n"
|
||||
" --no-clusters-in-meta-seek\n"
|
||||
" Do not write meta seek data for clusters.\n"
|
||||
" --no-lacing Do not use lacing.\n"
|
||||
"\n File splitting and linking (still global):\n"
|
||||
" --split <d[K,M,G]|HH:MM:SS|ns>\n"
|
||||
@ -770,19 +769,12 @@ static void render_headers(mm_io_c *out, bool last_file, bool first_file) {
|
||||
kax_segment->WriteHead(*out, 5);
|
||||
|
||||
// Reserve some space for the meta seek stuff.
|
||||
if (write_meta_seek) {
|
||||
kax_seekhead = new KaxSeekHead();
|
||||
kax_seekhead_void = new EbmlVoid();
|
||||
if (meta_seek_size == 0)
|
||||
if (video_track_present)
|
||||
meta_seek_size =
|
||||
(int64_t)((float)file_sizes * 1.8 / 10240.0);
|
||||
else
|
||||
meta_seek_size =
|
||||
(int64_t)((float)file_sizes * 5 / 4096.0);
|
||||
kax_seekhead_void->SetSize(meta_seek_size);
|
||||
kax_seekhead_void->Render(*out);
|
||||
}
|
||||
kax_sh_main = new KaxSeekHead();
|
||||
kax_sh_void = new EbmlVoid();
|
||||
kax_sh_void->SetSize(100);
|
||||
kax_sh_void->Render(*out);
|
||||
if (write_meta_seek_for_clusters)
|
||||
kax_sh_cues = new KaxSeekHead();
|
||||
|
||||
kax_infos->Render(*out);
|
||||
|
||||
@ -1153,20 +1145,11 @@ static void parse_args(int argc, char **argv) {
|
||||
|
||||
i++;
|
||||
|
||||
} else if (!strcmp(argv[i], "--meta-seek-size")) {
|
||||
if ((i + 1) >= argc)
|
||||
mxerror("--meta-seek-size lacks the size argument.\n");
|
||||
|
||||
if (!parse_int(argv[i + 1], meta_seek_size) || (meta_seek_size < 1))
|
||||
mxerror("Invalid size given for --meta-seek-size.\n");
|
||||
|
||||
i++;
|
||||
|
||||
} else if (!strcmp(argv[i], "--no-cues"))
|
||||
write_cues = false;
|
||||
|
||||
else if (!strcmp(argv[i], "--no-meta-seek"))
|
||||
write_meta_seek = false;
|
||||
else if (!strcmp(argv[i], "--no-clusters-in-meta-seek"))
|
||||
write_meta_seek_for_clusters = false;
|
||||
|
||||
else if (!strcmp(argv[i], "--no-lacing"))
|
||||
no_lacing = true;
|
||||
@ -1243,6 +1226,12 @@ static void parse_args(int argc, char **argv) {
|
||||
dump_packets = safestrdup(argv[i + 1]);
|
||||
i++;
|
||||
|
||||
} else if (!strcmp(argv[i], "--meta-seek-size")) {
|
||||
mxwarn("The option '--meta-seek-size' is no longer supported. Please "
|
||||
"read mkvmerge's documentation, especially the section about "
|
||||
"the MATROSKA FILE LAYOUT.");
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
// Options that apply to the next input file only.
|
||||
@ -1526,8 +1515,9 @@ static void setup() {
|
||||
static void init_globals() {
|
||||
track_number = 1;
|
||||
cluster_helper = NULL;
|
||||
kax_seekhead = NULL;
|
||||
kax_seekhead_void = NULL;
|
||||
kax_sh_main = NULL;
|
||||
kax_sh_cues = NULL;
|
||||
kax_sh_void = NULL;
|
||||
video_fps = -1.0;
|
||||
default_tracks[0] = 0;
|
||||
default_tracks[1] = 0;
|
||||
@ -1578,7 +1568,7 @@ static void cleanup() {
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ output file creation and finishing
|
||||
// {{{ FUNCTIONs create_output_name()/file(), finish_file()
|
||||
|
||||
// Transform the output filename and insert the current file number.
|
||||
// Rules and search order:
|
||||
@ -1720,7 +1710,6 @@ void finish_file() {
|
||||
int i;
|
||||
KaxChapters *chapters_here;
|
||||
int64_t start, end, offset;
|
||||
KaxSeekHead *emerg_seek_head = NULL;
|
||||
|
||||
// Render the cues.
|
||||
if (write_cues && cue_writing_requested) {
|
||||
@ -1756,6 +1745,13 @@ void finish_file() {
|
||||
} else
|
||||
chapters_here = NULL;
|
||||
|
||||
// Render the meta seek information with the cues
|
||||
if (write_meta_seek_for_clusters && (kax_sh_cues->ListSize() > 0)) {
|
||||
kax_sh_cues->UpdateSize();
|
||||
kax_sh_cues->Render(*out);
|
||||
kax_sh_main->IndexThis(*kax_sh_cues, *kax_segment);
|
||||
}
|
||||
|
||||
// Render the tags if we have some.
|
||||
if (kax_tags != NULL) {
|
||||
kax_tags->UpdateSize();
|
||||
@ -1763,53 +1759,31 @@ void finish_file() {
|
||||
}
|
||||
|
||||
// Write meta seek information if it is not disabled.
|
||||
if (write_meta_seek) {
|
||||
emerg_seek_head = new KaxSeekHead();
|
||||
if (cue_writing_requested)
|
||||
kax_sh_main->IndexThis(*kax_cues, *kax_segment);
|
||||
|
||||
if (write_cues && cue_writing_requested) {
|
||||
kax_seekhead->IndexThis(*kax_cues, *kax_segment);
|
||||
emerg_seek_head->IndexThis(*kax_cues, *kax_segment);
|
||||
}
|
||||
if (kax_tags != NULL)
|
||||
kax_sh_main->IndexThis(*kax_tags, *kax_segment);
|
||||
|
||||
if (kax_tags != NULL) {
|
||||
kax_seekhead->IndexThis(*kax_tags, *kax_segment);
|
||||
emerg_seek_head->IndexThis(*kax_tags, *kax_segment);
|
||||
}
|
||||
if (chapters_here != NULL) {
|
||||
kax_sh_main->IndexThis(*chapters_here, *kax_segment);
|
||||
delete chapters_here;
|
||||
} else if ((pass == 0) && (kax_chapters != NULL))
|
||||
kax_sh_main->IndexThis(*kax_chapters, *kax_segment);
|
||||
|
||||
if (chapters_here != NULL) {
|
||||
kax_seekhead->IndexThis(*chapters_here, *kax_segment);
|
||||
emerg_seek_head->IndexThis(*chapters_here, *kax_segment);
|
||||
delete chapters_here;
|
||||
} else if ((pass == 0) && (kax_chapters != NULL)) {
|
||||
kax_seekhead->IndexThis(*kax_chapters, *kax_segment);
|
||||
emerg_seek_head->IndexThis(*kax_chapters, *kax_segment);
|
||||
}
|
||||
if (kax_as != NULL) {
|
||||
kax_sh_main->IndexThis(*kax_as, *kax_segment);
|
||||
delete kax_as;
|
||||
kax_as = NULL;
|
||||
}
|
||||
|
||||
if (kax_as != NULL) {
|
||||
kax_seekhead->IndexThis(*kax_as, *kax_segment);
|
||||
emerg_seek_head->IndexThis(*kax_as, *kax_segment);
|
||||
delete kax_as;
|
||||
kax_as = NULL;
|
||||
}
|
||||
|
||||
if (kax_seekhead->ListSize() > 0)
|
||||
kax_seekhead->UpdateSize();
|
||||
if (kax_seekhead_void->ReplaceWith(*kax_seekhead, *out, true) == 0) {
|
||||
mxwarn("Could not update the meta seek information "
|
||||
"with all cluster entries as the space reserved for them was "
|
||||
"too small. This is NOT fatal! The resulting file will be "
|
||||
"fine. All important elements (attachments, chapters, cues, "
|
||||
"tags) are still indexed in the meta seek. If you really want "
|
||||
"to have all clusters indexed in the meta seek, then re-run "
|
||||
"mkvmerge with the additional parameters '--meta-seek-size "
|
||||
"%lld'.\n", kax_seekhead->ElementSize() + 100);
|
||||
|
||||
if (write_cues && cue_writing_requested)
|
||||
if (emerg_seek_head->ListSize() > 0) {
|
||||
emerg_seek_head->UpdateSize();
|
||||
kax_seekhead_void->ReplaceWith(*emerg_seek_head, *out, true);
|
||||
}
|
||||
}
|
||||
if (kax_sh_main->ListSize() > 0) {
|
||||
kax_sh_main->UpdateSize();
|
||||
if (kax_sh_void->ReplaceWith(*kax_sh_main, *out, true) == 0)
|
||||
mxwarn("This should REALLY not have happened. The space reserved for "
|
||||
"the first meta seek element was too small. Size needed: %lld. "
|
||||
"Please contact Moritz Bunkus at moritz@bunkus.org.\n",
|
||||
kax_sh_main->ElementSize());
|
||||
}
|
||||
|
||||
// Set the correct size for the segment.
|
||||
@ -1821,12 +1795,10 @@ void finish_file() {
|
||||
delete out;
|
||||
delete kax_segment;
|
||||
delete kax_cues;
|
||||
if (write_meta_seek) {
|
||||
delete kax_seekhead_void;
|
||||
delete kax_seekhead;
|
||||
}
|
||||
if (emerg_seek_head != NULL)
|
||||
delete emerg_seek_head;
|
||||
delete kax_sh_void;
|
||||
delete kax_sh_main;
|
||||
if (kax_sh_cues != NULL)
|
||||
delete kax_sh_cues;
|
||||
|
||||
for (i = 0; i < packetizers.size(); i++)
|
||||
packetizers[i]->packetizer->reset();;
|
||||
|
@ -41,7 +41,7 @@ extern KaxSegment *kax_segment;
|
||||
extern KaxTracks *kax_tracks;
|
||||
extern KaxTrackEntry *kax_last_entry;
|
||||
extern KaxCues *kax_cues;
|
||||
extern KaxSeekHead *kax_seekhead;
|
||||
extern KaxSeekHead *kax_sh_main, *kax_sh_cues;
|
||||
extern int track_number;
|
||||
extern int64_t tags_size;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user