1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-27 09:32:40 +00:00

core: ordered chapters: add heuristic for merging inaccurate chapters

Some Matroska files have inaccurate ordered chapter endpoints, and so
parts where one chapter should end and the next begin at the same
timestamp were not merged. This resulted in an unnecessary seek over a
minimal distance. Add a heuristic to merge parts with a minimal gap or
overlap between them.

Based on patch by Hector Martin <hector@marcansoft.com>.
This commit is contained in:
Uoti Urpala 2010-11-26 16:56:05 +02:00
parent 90d8bbb225
commit 7001c2d994
5 changed files with 32 additions and 6 deletions

View File

@ -798,6 +798,17 @@ With this option MPlayer will also ignore frame duration when playing
only video (you can think of that as infinite fps).
.
.TP
.B \-chapter\-merge\-threshold <number>
Threshold for merging almost consecutive ordered chapter parts
in milliseconds (default: 100).
Some Matroska files with ordered chapters have inaccurate chapter
end timestamps, causing a small gap between the end of one chapter and
the start of the next one when they should match.
If the end of one playback part is less than the given threshold away
from the start of the next one then keep playing video normally over the
chapter change instead of doing a seek.
.
.TP
.B \-colorkey <number>
Changes the colorkey to an RGB value of your choice.
0x000000 is black and 0xffffff is white.

View File

@ -305,6 +305,7 @@ const m_option_t mplayer_opts[]={
{"playlist", NULL, CONF_TYPE_STRING, 0, 0, 0, NULL},
OPT_MAKE_FLAGS("ordered-chapters", ordered_chapters, 0),
OPT_INTRANGE("chapter-merge-threshold", chapter_merge_threshold, 0, 0, 10000),
// a-v sync stuff:
OPT_MAKE_FLAGS("correct-pts", user_correct_pts, 0),

View File

@ -23,6 +23,7 @@ void set_default_mplayer_options(struct MPOpts *opts)
.stream_dump_name = "stream.dump",
.loop_times = -1,
.ordered_chapters = 1,
.chapter_merge_threshold = 100,
.stream_cache_min_percent = 20.0,
.stream_cache_seek_min_percent = 50.0,
.chapterrange = {-1, -1},

View File

@ -3100,7 +3100,9 @@ static int find_ordered_chapter_sources(struct MPContext *mpctx,
static void build_ordered_chapter_timeline(struct MPContext *mpctx)
{
if (!mpctx->opts.ordered_chapters) {
struct MPOpts *opts = &mpctx->opts;
if (!opts->ordered_chapters) {
mp_msg(MSGT_CPLAYER, MSGL_INFO, "File uses ordered chapters, but "
"you have disabled support for them. Ignoring.\n");
return;
@ -3162,21 +3164,31 @@ static void build_ordered_chapter_timeline(struct MPContext *mpctx)
missing_time += c->end - c->start;
continue;
found2:;
chapters[num_chapters].start = starttime / 1000.;
chapters[num_chapters].name = talloc_strdup(chapters, c->name);
/* Only add a separate part if the time or file actually changes.
* Matroska files have chapter divisions that are redundant from
* timeline point of view because the same chapter structure is used
* both to specify the timeline and for normal chapter information.
* Removing a missing inserted external chapter can also cause this. */
if (part_count == 0 || c->start != starttime + prev_part_offset
* Removing a missing inserted external chapter can also cause this.
* We allow for a configurable fudge factor because of files which
* specify chapter end times that are one frame too early;
* we don't want to try seeking over a one frame gap. */
int64_t join_diff = c->start - starttime - prev_part_offset;
if (part_count == 0 || FFABS(join_diff) > opts->chapter_merge_threshold
|| sources + j != timeline[part_count - 1].source) {
timeline[part_count].source = sources + j;
timeline[part_count].start = chapters[num_chapters].start;
timeline[part_count].start = starttime / 1000.;
timeline[part_count].source_start = c->start / 1000.;
prev_part_offset = c->start - starttime;
part_count++;
} else if (part_count > 0 && join_diff) {
/* Chapter was merged at an inexact boundary;
* adjust timestamps to match. */
mp_msg(MSGT_CPLAYER, MSGL_V, "Merging timeline part %d with "
"offset %d ms.\n", i, (int) join_diff);
starttime += join_diff;
}
chapters[num_chapters].start = starttime / 1000.;
chapters[num_chapters].name = talloc_strdup(chapters, c->name);
starttime += c->end - c->start;
num_chapters++;
}

View File

@ -37,6 +37,7 @@ typedef struct MPOpts {
int capture_dump;
int loop_times;
int ordered_chapters;
int chapter_merge_threshold;
int quiet;
float stream_cache_min_percent;
float stream_cache_seek_min_percent;