mirror of
https://github.com/mpv-player/mpv
synced 2025-04-24 12:24:21 +00:00
core: track current chapter for relative chapter seeks
Due to inexact seeks, chapter seek commands may result in a playback position that's inside the previous chapter. This causes problems when the user does repeated next-chapter/previous-chapter seeks, because the code will use the wrong base for calculating 'next' or 'previous'. Improve the behavior by adding a heuristic that keeps track of what chapter the user last wanted to seek to and adjusts the "current chapter" value based on that.
This commit is contained in:
parent
823b989f0f
commit
d2e25a90c4
@ -154,6 +154,12 @@ typedef struct MPContext {
|
|||||||
double rel_seek_secs;
|
double rel_seek_secs;
|
||||||
int abs_seek_pos;
|
int abs_seek_pos;
|
||||||
|
|
||||||
|
/* Heuristic for relative chapter seeks: keep track which chapter
|
||||||
|
* the user wanted to go to, even if we aren't exactly within the
|
||||||
|
* boundaries of that chapter due to an inaccurate seek. */
|
||||||
|
int last_chapter_seek;
|
||||||
|
double last_chapter_pts;
|
||||||
|
|
||||||
float begin_skip; ///< start time of the current skip while on edlout mode
|
float begin_skip; ///< start time of the current skip while on edlout mode
|
||||||
// audio is muted if either EDL or user activates mute
|
// audio is muted if either EDL or user activates mute
|
||||||
short edl_muted; ///< Stores whether EDL is currently in muted mode.
|
short edl_muted; ///< Stores whether EDL is currently in muted mode.
|
||||||
|
23
mplayer.c
23
mplayer.c
@ -2750,6 +2750,10 @@ static int seek(MPContext *mpctx, double amount, int style)
|
|||||||
current_module = "seek";
|
current_module = "seek";
|
||||||
if (mpctx->stop_play == AT_END_OF_FILE)
|
if (mpctx->stop_play == AT_END_OF_FILE)
|
||||||
mpctx->stop_play = KEEP_PLAYING;
|
mpctx->stop_play = KEEP_PLAYING;
|
||||||
|
if (style & SEEK_FACTOR
|
||||||
|
|| style & SEEK_ABSOLUTE && amount < mpctx->last_chapter_pts
|
||||||
|
|| amount < 0)
|
||||||
|
mpctx->last_chapter_seek = -1;
|
||||||
if (mpctx->timeline && style & SEEK_FACTOR) {
|
if (mpctx->timeline && style & SEEK_FACTOR) {
|
||||||
amount *= mpctx->timeline[mpctx->num_timeline_parts].start;
|
amount *= mpctx->timeline[mpctx->num_timeline_parts].start;
|
||||||
style &= ~SEEK_FACTOR;
|
style &= ~SEEK_FACTOR;
|
||||||
@ -2795,14 +2799,15 @@ static int seek(MPContext *mpctx, double amount, int style)
|
|||||||
int get_current_chapter(struct MPContext *mpctx)
|
int get_current_chapter(struct MPContext *mpctx)
|
||||||
{
|
{
|
||||||
if (!mpctx->chapters || !mpctx->sh_video)
|
if (!mpctx->chapters || !mpctx->sh_video)
|
||||||
return demuxer_get_current_chapter(mpctx->demuxer);
|
return FFMAX(mpctx->last_chapter_seek,
|
||||||
|
demuxer_get_current_chapter(mpctx->demuxer));
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
double current_pts = mpctx->sh_video->pts;
|
double current_pts = mpctx->sh_video->pts;
|
||||||
for (i = 1; i < mpctx->num_chapters; i++)
|
for (i = 1; i < mpctx->num_chapters; i++)
|
||||||
if (current_pts < mpctx->chapters[i].start)
|
if (current_pts < mpctx->chapters[i].start)
|
||||||
break;
|
break;
|
||||||
return i - 1;
|
return FFMAX(mpctx->last_chapter_seek, i - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// currently returns a string allocated with malloc, not talloc
|
// currently returns a string allocated with malloc, not talloc
|
||||||
@ -2816,11 +2821,18 @@ char *chapter_display_name(struct MPContext *mpctx, int chapter)
|
|||||||
int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts,
|
int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts,
|
||||||
char **chapter_name)
|
char **chapter_name)
|
||||||
{
|
{
|
||||||
|
mpctx->last_chapter_seek = -1;
|
||||||
if (!mpctx->chapters || !mpctx->sh_video) {
|
if (!mpctx->chapters || !mpctx->sh_video) {
|
||||||
int res = demuxer_seek_chapter(mpctx->demuxer, chapter, seek_pts,
|
int res = demuxer_seek_chapter(mpctx->demuxer, chapter, seek_pts,
|
||||||
chapter_name);
|
chapter_name);
|
||||||
if (res >= 0 && *seek_pts == -1)
|
if (res >= 0) {
|
||||||
seek_reset(mpctx);
|
if (*seek_pts == -1)
|
||||||
|
seek_reset(mpctx);
|
||||||
|
else {
|
||||||
|
mpctx->last_chapter_seek = res;
|
||||||
|
mpctx->last_chapter_pts = *seek_pts;
|
||||||
|
}
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2829,6 +2841,8 @@ int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts,
|
|||||||
if (chapter < 0)
|
if (chapter < 0)
|
||||||
chapter = 0;
|
chapter = 0;
|
||||||
*seek_pts = mpctx->chapters[chapter].start;
|
*seek_pts = mpctx->chapters[chapter].start;
|
||||||
|
mpctx->last_chapter_seek = chapter;
|
||||||
|
mpctx->last_chapter_pts = *seek_pts;
|
||||||
if (chapter_name)
|
if (chapter_name)
|
||||||
*chapter_name = talloc_strdup(NULL, mpctx->chapters[chapter].name);
|
*chapter_name = talloc_strdup(NULL, mpctx->chapters[chapter].name);
|
||||||
return chapter;
|
return chapter;
|
||||||
@ -4085,6 +4099,7 @@ if (mpctx->stream->type == STREAMTYPE_DVDNAV) {
|
|||||||
mpctx->drop_message_shown = 0;
|
mpctx->drop_message_shown = 0;
|
||||||
mpctx->update_video_immediately = true;
|
mpctx->update_video_immediately = true;
|
||||||
mpctx->total_avsync_change = 0;
|
mpctx->total_avsync_change = 0;
|
||||||
|
mpctx->last_chapter_seek = -1;
|
||||||
// Make sure VO knows current pause state
|
// Make sure VO knows current pause state
|
||||||
if (mpctx->sh_video)
|
if (mpctx->sh_video)
|
||||||
vo_control(mpctx->video_out, mpctx->paused ? VOCTRL_PAUSE : VOCTRL_RESUME,
|
vo_control(mpctx->video_out, mpctx->paused ? VOCTRL_PAUSE : VOCTRL_RESUME,
|
||||||
|
Loading…
Reference in New Issue
Block a user