summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/command.c11
-rw-r--r--core/mp_core.h2
-rw-r--r--core/mplayer.c74
3 files changed, 47 insertions, 40 deletions
diff --git a/core/command.c b/core/command.c
index d44521bf1c..aea8fb2017 100644
--- a/core/command.c
+++ b/core/command.c
@@ -350,14 +350,11 @@ static int mp_property_chapter(m_option_t *prop, int action, void *arg,
case M_PROPERTY_SET: ;
int step_all = *(int *)arg - chapter;
chapter += step_all;
- double next_pts = 0;
- queue_seek(mpctx, MPSEEK_NONE, 0, 0);
- chapter = seek_chapter(mpctx, chapter, &next_pts);
- if (chapter >= 0) {
- if (next_pts > -1.0)
- queue_seek(mpctx, MPSEEK_ABSOLUTE, next_pts, 0);
- } else if (step_all > 0)
+ if (chapter >= get_chapter_count(mpctx) && step_all > 0) {
mpctx->stop_play = PT_NEXT_ENTRY;
+ } else {
+ mp_seek_chapter(mpctx, chapter);
+ }
return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
diff --git a/core/mp_core.h b/core/mp_core.h
index 2590eefb96..941396c48a 100644
--- a/core/mp_core.h
+++ b/core/mp_core.h
@@ -303,7 +303,7 @@ void unpause_player(struct MPContext *mpctx);
void add_step_frame(struct MPContext *mpctx, int dir);
void queue_seek(struct MPContext *mpctx, enum seek_type type, double amount,
int exact);
-int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts);
+bool mp_seek_chapter(struct MPContext *mpctx, int chapter);
double get_time_length(struct MPContext *mpctx);
double get_start_time(struct MPContext *mpctx);
double get_current_time(struct MPContext *mpctx);
diff --git a/core/mplayer.c b/core/mplayer.c
index 7d657edb54..72871bd0f0 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -3113,6 +3113,14 @@ void queue_seek(struct MPContext *mpctx, enum seek_type type, double amount,
abort();
}
+static void execute_queued_seek(struct MPContext *mpctx)
+{
+ if (mpctx->seek.type) {
+ seek(mpctx, mpctx->seek, false);
+ mpctx->seek = (struct seek_params){0};
+ }
+}
+
double get_time_length(struct MPContext *mpctx)
{
struct demuxer *demuxer = mpctx->demuxer;
@@ -3262,33 +3270,42 @@ int get_chapter_count(struct MPContext *mpctx)
return 0;
}
-int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts)
+// Seek to a given chapter. Tries to queue the seek, but might seek immediately
+// in some cases. Returns success, no matter if seek is queued or immediate.
+bool mp_seek_chapter(struct MPContext *mpctx, int chapter)
{
+ int num = get_chapter_count(mpctx);
+ if (num == 0)
+ return false;
+ if (chapter < 0 || chapter >= num)
+ return false;
+
mpctx->last_chapter_seek = -2;
- if (mpctx->chapters) {
- if (chapter >= mpctx->num_chapters)
- return -1;
- if (chapter < 0)
- chapter = 0;
- *seek_pts = mpctx->chapters[chapter].start;
- mpctx->last_chapter_seek = chapter;
- mpctx->last_chapter_pts = *seek_pts;
- return chapter;
- }
- if (mpctx->master_demuxer) {
- int res = demuxer_seek_chapter(mpctx->master_demuxer, chapter, seek_pts);
+ double pts;
+ if (mpctx->chapters) {
+ pts = mpctx->chapters[chapter].start;
+ goto do_seek;
+ } else if (mpctx->master_demuxer) {
+ int res = demuxer_seek_chapter(mpctx->master_demuxer, chapter, &pts);
if (res >= 0) {
- if (*seek_pts == -1)
- seek_reset(mpctx, true, true); // for DVD
- else {
- mpctx->last_chapter_seek = res;
- mpctx->last_chapter_pts = *seek_pts;
+ if (pts == -1) {
+ // for DVD/BD - seek happened via stream layer
+ seek_reset(mpctx, true, true);
+ mpctx->seek = (struct seek_params){0};
+ return true;
}
+ chapter = res;
+ goto do_seek;
}
- return res;
}
- return -1;
+ return false;
+
+do_seek:
+ queue_seek(mpctx, MPSEEK_ABSOLUTE, pts, 0);
+ mpctx->last_chapter_seek = chapter;
+ mpctx->last_chapter_pts = pts;
+ return true;
}
static void update_avsync(struct MPContext *mpctx)
@@ -3772,10 +3789,7 @@ static void run_playloop(struct MPContext *mpctx)
}
}
- if (mpctx->seek.type) {
- seek(mpctx, mpctx->seek, false);
- mpctx->seek = (struct seek_params){ 0 };
- }
+ execute_queued_seek(mpctx);
}
@@ -4363,23 +4377,19 @@ goto_enable_cache: ;
mpctx->playing_msg_shown = false;
mpctx->paused = false;
mpctx->paused_for_cache = false;
+ mpctx->seek = (struct seek_params){ 0 };
// If there's a timeline force an absolute seek to initialize state
double startpos = rel_time_to_abs(mpctx, opts->play_start, -1);
if (startpos != -1 || mpctx->timeline) {
queue_seek(mpctx, MPSEEK_ABSOLUTE, startpos, 0);
- seek(mpctx, mpctx->seek, false);
+ execute_queued_seek(mpctx);
}
if (opts->chapterrange[0] > 0) {
- double pts;
- if (seek_chapter(mpctx, opts->chapterrange[0] - 1, &pts) >= 0
- && pts > -1.0) {
- queue_seek(mpctx, MPSEEK_ABSOLUTE, pts, 0);
- seek(mpctx, mpctx->seek, false);
- }
+ if (mp_seek_chapter(mpctx, opts->chapterrange[0] - 1))
+ execute_queued_seek(mpctx);
}
- mpctx->seek = (struct seek_params){ 0 };
get_relative_time(mpctx); // reset current delta
if (mpctx->opts.pause)