Chapters are re-timecoded correctly in both cases (with and without file linking). Updated documentation about chapters.

This commit is contained in:
Moritz Bunkus 2003-07-29 20:27:05 +00:00
parent b705914778
commit 5742bca3dc
7 changed files with 111 additions and 53 deletions

View File

@ -1,5 +1,7 @@
2003-07-29 Moritz Bunkus <moritz@bunkus.org>
* mkvextract: Support for extracting chapter information.
* mkvmerge: Added support for simple chapter files (CHAPTER01=...,
CHAPTER01NAME=Hello World etc).

View File

@ -32,6 +32,10 @@ Write to the file '\fIout\fR'.
.TP
\fB\-\-title\fR <\fItitle\fR>
Sets the general title for the output file, e.g. the movie name.
.TP
\fB\-\-chapters <\fIfile\fR>
Read chapter information from the \fIfile\fR. See the section about chapters
below for details.
.LP
General output control (still global, advanced options):
@ -407,6 +411,36 @@ in \fBmkvinfo\fR's output then please read the section about \fBDEFAULT
VALUES\fR.
.SH TRACK IDS
.LP
Some of the options for \fBmkvmerge\fR need a track ID to specify which track
they should be applied to. Those track IDs are printed by the readers when
demuxing the current input file, or if \fBmkvmerge\fR is called with the
\fB\-\-identify\fR option. Track IDs are assigned like this:
.TP
*
AVI files: The video track has the ID 0. All audio tracks get the ID 1, 2...
.TP
*
AAC, AC3, MP3, SRT and WAV files: The one 'track' in that file gets the ID 0.
.TP
*
Ogg/OGM files: The track's ID is its serial number as given in the Ogg stream
header page.
.TP
*
Matroska files: The track's ID is the track number as reported by \fBmkvinfo\fR
or \fBmkvmerge \-\-identify\fR. It is \fBnot\fR the track UID.
.LP
The special track ID '-1' is a wildcard and applies the given switch to all
tracks that are read from an input file. This was the bahviour of these
switches prior to version 0.4.4.
.LP
The options that use the track IDs are: \fB\-\-atracks\fR, \fB\-\-vtracks\fR,
\fB\-\-stracks\fR, \fB\-\-sync\fR, \fB\-\-default-track\fR, \fB\-\-cues\fR
and \fB\-\-language\fR.
.SH SUBTITLES
.LP
There are several text subtitle formats that can be embedded into Matroska.
@ -437,10 +471,10 @@ markup is not supported correctly.
Matroska supports file linking which simply says that a specific file is the
predecessor or successsor of the current file. To be precise, it's not really
the files that are linked but the Matroska segments. As most files will
probably only put one Matroska segment into a file I simply say 'file linking'
probably only contain one Matroska segment I simply say 'file linking'
although 'segment linking' would be more appropriate.
.LP
Each segment is identified by a unique 128 bit wide segmend UID. This UID
Each segment is identified by a unique 128 bit wide segment UID. This UID
is automatically generated by \fBmkvmerge\fR. The linking is done primarily
via putting the segment UIDs of the previous/next file into the segment
header information. \fBmkvinfo(1)\fR prints these UIDs if it finds them.
@ -470,36 +504,6 @@ with \'\fB\-\-link\-to\-next\fR\'. If splitting is not used then the one
output file will be linked to both of the two UIDs.
.SH TRACK IDS
.LP
Some of the options for \fBmkvmerge\fR need a track ID to specify which track
they should be applied to. Those track IDs are printed by the readers when
demuxing the current input file, or if \fBmkvmerge\fR is called with the
\fB\-\-identify\fR option. Track IDs are assigned like this:
.TP
*
AVI files: The video track has the ID 0. All audio tracks get the ID 1, 2...
.TP
*
AAC, AC3, MP3, SRT and WAV files: The one 'track' in that file gets the ID 0.
.TP
*
Ogg/OGM files: The track's ID is its serial number as given in the Ogg stream
header page.
.TP
*
Matroska files: The track's ID is the track number as reported by \fBmkvinfo\fR
or \fBmkvmerge \-\-identify\fR. It is \fBnot\fR the track UID.
.LP
The special track ID '-1' is a wildcard and applies the given switch to all
tracks that are read from an input file. This was the bahviour of these
switches prior to version 0.4.4.
.LP
The options that use the track IDs are: \fB\-\-atracks\fR, \fB\-\-vtracks\fR,
\fB\-\-stracks\fR, \fB\-\-sync\fR, \fB\-\-default-track\fR, \fB\-\-cues\fR
and \fB\-\-language\fR.
.SH DEFAULT VALUES
.LP
The Matroska specs say that some elements have a default value. Usually an
@ -532,6 +536,47 @@ $ \fBmkvmerge -o output.mkv -A video.avi sound.ogg \-\-attachment\-description
\-\-attach\-file really_cool_font.ttf
.SH CHAPTERS
.LP
The Matroska chapter system is more powerful than the old known system used
by OGMs. The full specs can be found at
.URL http://cvs.corecodec.org/cgi-bin/viewcvs.cgi/*checkout*/matroska/doc/website/technical/specs/chapters/index.html
.LP
\fBmkvmerge\fR's chapter support is still a bit limited, though. At the moment
it only supports reading chapter data in the same format that the OGM tools
expect. It looks basically like this:
.LP
CHAPTER01=00:00:00.000
.br
CHAPTER01NAME=Intro
.br
CHAPTER02=00:02:30.000
.br
CHAPTER02NAME=Baby prepares to rock
.br
CHAPTER03=00:02:42.300
.br
CHAPTER03NAME=Baby rocks the house
.LP
\fBmkvmerge\fR will transform every pair or lines (CHAPTERxx and CHAPTERxxNAME)
into one Matroska \fIChapterAtom\fR. It does not set any
\fIChapterTrackNumber\fR which means that the chapters all apply to all
tracks in the file.
.LP
When splitting files \fBmkvmerge\fR will correctly adjust the chapters as
well. This means that each file only includes the chapter entries that
apply to it, and that the timecodes will be offset to match the new timecodes
of each output file.
.LP
Another shortcoming is that \fBmkvmerge\fR will silently discards chapters
found in source files - e.g. when reading them from an OGM file or another
Matroska file. You can use \fBmkvextract\fR to export chapters from another
Matroska file and use the result with \fBmkvmerge\fR.
.LP
The upcoming version of \fBmkvmerge\fR will address most of the shortcomings
mentioned above.
.SH NOTES
.LP
What works:
@ -579,22 +624,19 @@ taken from other OGM files.
.TP
*
SSA/ASS subtitles from SSA/ASS files
.TP
*
Simple chapters.
.TP
*
Full tags support.
.LP
What not works:
.TP
*
Manual audio synchronization for PCM sound (who needs it anyway?)
.LP
Planned functionality:
.TP
*
support for other subtitle formats
.TP
*
chapter information
.TP
*
a lot of other stuff, like tags, user information etc.
.SH AUTHOR
.I mkvmerge
was written by Moritz Bunkus <moritz@bunkus.org>.

View File

@ -103,7 +103,7 @@ static bool probe_simple_chapters(mm_text_io_c *in) {
// CHAPTER01NAME=Hallo Welt
static KaxChapters *parse_simple_chapters(mm_text_io_c *in, int64_t min_tc,
int64_t max_tc) {
int64_t max_tc, int64_t offset) {
KaxChapters *chaps;
KaxEditionEntry *edition;
KaxChapterAtom *atom;
@ -119,6 +119,8 @@ static KaxChapters *parse_simple_chapters(mm_text_io_c *in, int64_t min_tc,
atom = NULL;
edition = NULL;
printf("off: %lld\n", offset);
while (in->getline2(line)) {
strip(line);
if (line.length() == 0)
@ -158,7 +160,7 @@ static KaxChapters *parse_simple_chapters(mm_text_io_c *in, int64_t min_tc,
*static_cast<EbmlUInteger *>(&GetChild<KaxChapterUID>(*atom)) =
create_unique_uint32();
*static_cast<EbmlUInteger *>(&GetChild<KaxChapterTimeStart>(*atom)) =
(start - min_tc) * 1000000;
(start - offset) * 1000000;
display = &GetChild<KaxChapterDisplay>(*atom);
*static_cast<EbmlUnicodeString *>
(&GetChild<KaxChapterString>(*display)) =
@ -178,12 +180,13 @@ static bool probe_xml_chapters(mm_text_io_c *) {
return false;
}
static KaxChapters *parse_xml_chapters(mm_text_io_c *, int64_t, int64_t) {
static KaxChapters *parse_xml_chapters(mm_text_io_c *, int64_t, int64_t,
int64_t) {
return NULL;
}
KaxChapters *parse_chapters(const char *file_name, int64_t min_tc,
int64_t max_tc) {
int64_t max_tc, int64_t offset) {
mm_text_io_c *in;
try {
@ -194,10 +197,10 @@ KaxChapters *parse_chapters(const char *file_name, int64_t min_tc,
}
if (probe_simple_chapters(in))
return parse_simple_chapters(in, min_tc, max_tc);
return parse_simple_chapters(in, min_tc, max_tc, offset);
if (probe_xml_chapters(in))
return parse_xml_chapters(in, min_tc, max_tc);
return parse_xml_chapters(in, min_tc, max_tc, offset);
mxprint(stderr, "Error: Unknown file format for '%s'. It does not contain "
"a supported chapter format.\n", file_name);

View File

@ -28,7 +28,7 @@
using namespace libmatroska;
KaxChapters *parse_chapters(const char *file_name, int64_t min_tc = 0,
int64_t max_tc = -1);
int64_t max_tc = -1, int64_t offset = 0);
void write_chapters_xml(KaxChapters *chapters, FILE *out);

View File

@ -666,3 +666,7 @@ int64_t cluster_helper_c::get_max_timecode() {
int64_t cluster_helper_c::get_first_timecode() {
return first_timecode;
}
int64_t cluster_helper_c::get_timecode_offset() {
return timecode_offset;
}

View File

@ -72,6 +72,7 @@ public:
int get_cluster_content_size();
int64_t get_max_timecode();
int64_t get_first_timecode();
int64_t get_timecode_offset();
void find_next_splitpoint();
int get_next_splitpoint();

View File

@ -1799,6 +1799,7 @@ void create_next_output_file(bool last_file, bool first_file) {
void finish_file() {
int i;
KaxChapters *chapters_here;
int64_t start, end, offset;
// Render the cues.
if (write_cues && cue_writing_requested) {
@ -1819,9 +1820,14 @@ void finish_file() {
out->restore_pos();
if ((kax_chapters != NULL) && (pass > 0)) {
chapters_here = parse_chapters(chapter_file_name,
cluster_helper->get_first_timecode(),
cluster_helper->get_max_timecode());
if (no_linking)
offset = cluster_helper->get_timecode_offset();
else
offset = 0;
start = cluster_helper->get_first_timecode() + offset;
end = cluster_helper->get_max_timecode() + offset;
chapters_here = parse_chapters(chapter_file_name, start, end, offset);
kax_chapters_void->ReplaceWith(*chapters_here, *out, true);
delete kax_chapters_void;
kax_chapters_void = NULL;