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:
parent
90d8bbb225
commit
7001c2d994
@ -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.
|
||||
|
@ -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),
|
||||
|
@ -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},
|
||||
|
24
mplayer.c
24
mplayer.c
@ -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++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user