summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-02-28 19:14:23 +0100
committerwm4 <wm4@nowhere>2016-02-28 19:28:34 +0100
commit92ba63079617f6579c276dd3ec54197b56378913 (patch)
treefff93c447a045a03cbc51ac4a0bac3a360220054
parentb638a413c37e8c892fcf40ca4ae29693f4942d0c (diff)
downloadmpv-92ba63079617f6579c276dd3ec54197b56378913.tar.bz2
mpv-92ba63079617f6579c276dd3ec54197b56378913.tar.xz
demux: remove relative seeking
Ever since a change in mplayer2 or so, relative seeks were translated to absolute seeks before sending them to the demuxer in most cases. The only exception in current mpv is DVD seeking. Remove the SEEK_ABSOLUTE flag; it's not the implied default. SEEK_FACTOR is kept, because it's sometimes slightly useful for seeking in things like transport streams. (And maybe mkv files without duration set?) DVD seeking is terrible because DVD and libdvdnav are terrible, but mostly because libdvdnav is terrible. libdvdnav does not expose seeking with seek tables. (Although I know xbmc/kodi use an undocumented API that is not declared in the headers by dladdr()ing it - I think the function is dvdnav_jump_to_sector_by_time().) With the current mpv policy if not giving a shit about DVD, just revert our half-working seek hacks and always use dvdnav_time_search(). Relative seeking might get stuck sometimes; in this case --hr-seek=always is recommended.
-rw-r--r--demux/demux.c28
-rw-r--r--demux/demux.h4
-rw-r--r--demux/demux_disc.c24
-rw-r--r--demux/demux_lavf.c34
-rw-r--r--demux/demux_mf.c9
-rw-r--r--demux/demux_mkv.c17
-rw-r--r--demux/demux_raw.c8
-rw-r--r--demux/demux_timeline.c18
-rw-r--r--player/loadfile.c2
-rw-r--r--player/playloop.c15
-rw-r--r--player/sub.c2
-rw-r--r--stream/stream_dvdnav.c37
12 files changed, 49 insertions, 149 deletions
diff --git a/demux/demux.c b/demux/demux.c
index fe72d3ef4c..05a8551608 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -580,8 +580,7 @@ static void start_refreshing(struct demux_internal *in)
pthread_mutex_unlock(&in->lock);
// Seek back to player's current position, with a small offset added.
- in->d_thread->desc->seek(in->d_thread, start_ts - 1.0,
- SEEK_ABSOLUTE | SEEK_BACKWARD | SEEK_HR);
+ in->d_thread->desc->seek(in->d_thread, start_ts - 1.0, SEEK_BACKWARD | SEEK_HR);
pthread_mutex_lock(&in->lock);
}
@@ -947,7 +946,6 @@ static void demux_copy(struct demuxer *dst, struct demuxer *src)
dst->partially_seekable = src->partially_seekable;
dst->filetype = src->filetype;
dst->ts_resets_possible = src->ts_resets_possible;
- dst->rel_seeks = src->rel_seeks;
dst->allow_refresh_seeks = src->allow_refresh_seeks;
dst->fully_read = src->fully_read;
dst->start_time = src->start_time;
@@ -1240,7 +1238,7 @@ void demux_flush(demuxer_t *demuxer)
pthread_mutex_unlock(&demuxer->in->lock);
}
-int demux_seek(demuxer_t *demuxer, double rel_seek_secs, int flags)
+int demux_seek(demuxer_t *demuxer, double seek_pts, int flags)
{
struct demux_internal *in = demuxer->in;
assert(demuxer == in->d_user);
@@ -1250,32 +1248,22 @@ int demux_seek(demuxer_t *demuxer, double rel_seek_secs, int flags)
return 0;
}
- if ((flags & SEEK_FACTOR) && !(flags & SEEK_ABSOLUTE)) {
- MP_WARN(demuxer, "Invalid seek flags.\n");
- return 0;
- }
-
- if (rel_seek_secs == MP_NOPTS_VALUE && (flags & SEEK_ABSOLUTE))
+ if (seek_pts == MP_NOPTS_VALUE)
return 0;
- if (!(flags & (SEEK_BACKWARD | SEEK_FORWARD))) {
- if (flags & SEEK_ABSOLUTE || rel_seek_secs < 0) {
- flags |= SEEK_BACKWARD;
- } else {
- flags |= SEEK_FORWARD;
- }
- }
+ if (!(flags & SEEK_FORWARD))
+ flags |= SEEK_BACKWARD;
pthread_mutex_lock(&in->lock);
- MP_VERBOSE(in, "queuing seek to %f%s\n", rel_seek_secs,
+ MP_VERBOSE(in, "queuing seek to %f%s\n", seek_pts,
in->seeking ? " (cascade)" : "");
flush_locked(demuxer);
in->seeking = true;
in->seek_flags = flags;
- in->seek_pts = rel_seek_secs;
- if ((flags & SEEK_ABSOLUTE) && !(flags & SEEK_FACTOR))
+ in->seek_pts = seek_pts;
+ if (!(flags & SEEK_FACTOR))
in->seek_pts = MP_ADD_PTS(in->seek_pts, -in->ts_offset);
if (!in->threading)
diff --git a/demux/demux.h b/demux/demux.h
index 05e645f728..e882e90da8 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -57,7 +57,6 @@ struct demux_ctrl_stream_ctrl {
int res;
};
-#define SEEK_ABSOLUTE (1 << 0) // argument is a timestamp
#define SEEK_FACTOR (1 << 1) // argument is in range [0,1]
#define SEEK_FORWARD (1 << 2) // prefer later time if not exact
#define SEEK_BACKWARD (1 << 3) // prefer earlier time if not exact
@@ -179,9 +178,6 @@ typedef struct demuxer {
double start_time;
// File format allows PTS resets (even if the current file is without)
bool ts_resets_possible;
- // Send relative seek requests, instead of SEEK_ABSOLUTE or SEEK_FACTOR.
- // This is only done if the user explicitly uses a relative seek.
- bool rel_seeks;
// Enable fast track switching hacks. This requires from the demuxer:
// - seeking is somewhat reliable; packet contents must not change
// - packet position (demux_packet.pos) is set, not negative, unique, and
diff --git a/demux/demux_disc.c b/demux/demux_disc.c
index 7feec6ca72..91b87a4631 100644
--- a/demux/demux_disc.c
+++ b/demux/demux_disc.c
@@ -42,7 +42,6 @@ struct priv {
double base_time; // playback display start time of current segment
double base_dts; // packet DTS that maps to base_time
double last_dts; // DTS of previously demuxed packet
- double seek_pts;
bool seek_reinit; // needs reinit after seek
};
@@ -159,35 +158,27 @@ static void add_streams(demuxer_t *demuxer)
reselect_streams(demuxer);
}
-static void d_seek(demuxer_t *demuxer, double rel_seek_secs, int flags)
+static void d_seek(demuxer_t *demuxer, double seek_pts, int flags)
{
struct priv *p = demuxer->priv;
if (demuxer->stream->uncached_type == STREAMTYPE_CDDA) {
- demux_seek(p->slave, rel_seek_secs, flags);
+ demux_seek(p->slave, seek_pts, flags);
return;
}
- double pts = p->seek_pts;
- if (flags & SEEK_ABSOLUTE)
- pts = 0.0f;
- double base_pts = pts; // to what pts is relative
-
if (flags & SEEK_FACTOR) {
double tmp = 0;
stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH, &tmp);
- pts += tmp * rel_seek_secs;
- } else {
- pts += rel_seek_secs;
+ seek_pts *= tmp;
}
- MP_VERBOSE(demuxer, "seek to: %f\n", pts);
+ MP_VERBOSE(demuxer, "seek to: %f\n", seek_pts);
- double seek_arg[] = {pts, base_pts, flags};
+ double seek_arg[] = {seek_pts, flags};
stream_control(demuxer->stream, STREAM_CTRL_SEEK_TO_TIME, seek_arg);
demux_control(p->slave, DEMUXER_CTRL_RESYNC, NULL);
- p->seek_pts = pts;
p->seek_reinit = true;
}
@@ -268,9 +259,6 @@ static int d_fill_buffer(demuxer_t *demuxer)
MP_TRACE(demuxer, "opts: %d %f %f\n", sh->type, pkt->pts, pkt->dts);
- if (pkt->pts != MP_NOPTS_VALUE)
- p->seek_pts = pkt->pts;
-
demux_add_packet(sh, pkt);
return 1;
}
@@ -328,8 +316,6 @@ static int d_open(demuxer_t *demuxer, enum demux_check check)
// Can be seekable even if the stream isn't.
demuxer->seekable = true;
-
- demuxer->rel_seeks = true;
}
add_dvd_streams(demuxer);
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 518dd0f8dd..8a92a2886f 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -164,7 +164,6 @@ typedef struct lavf_priv {
int avif_flags;
AVFormatContext *avfc;
AVIOContext *pb;
- int64_t last_pts;
struct sh_stream **streams; // NULL for unknown streams
int num_streams;
int cur_program;
@@ -920,11 +919,6 @@ static int demux_lavf_fill_buffer(demuxer_t *demux)
#endif
dp->pos = pkt->pos;
dp->keyframe = pkt->flags & AV_PKT_FLAG_KEY;
- if (dp->pts != MP_NOPTS_VALUE) {
- priv->last_pts = dp->pts * AV_TIME_BASE;
- } else if (dp->dts != MP_NOPTS_VALUE) {
- priv->last_pts = dp->dts * AV_TIME_BASE;
- }
av_packet_unref(pkt);
if (priv->format_hack.clear_filepos)
@@ -934,19 +928,13 @@ static int demux_lavf_fill_buffer(demuxer_t *demux)
return 1;
}
-static void demux_seek_lavf(demuxer_t *demuxer, double rel_seek_secs, int flags)
+static void demux_seek_lavf(demuxer_t *demuxer, double seek_pts, int flags)
{
lavf_priv_t *priv = demuxer->priv;
int avsflags = 0;
+ int64_t seek_pts_av = 0;
- if (flags & SEEK_ABSOLUTE)
- priv->last_pts = 0;
- else if (rel_seek_secs < 0)
- avsflags = AVSEEK_FLAG_BACKWARD;
-
- if (flags & SEEK_FORWARD)
- avsflags = 0;
- else if (flags & SEEK_BACKWARD)
+ if (flags & SEEK_BACKWARD)
avsflags = AVSEEK_FLAG_BACKWARD;
if (flags & SEEK_FACTOR) {
@@ -956,28 +944,28 @@ static void demux_seek_lavf(demuxer_t *demuxer, double rel_seek_secs, int flags)
!(priv->avif_flags & AVFMT_NO_BYTE_SEEK))
{
avsflags |= AVSEEK_FLAG_BYTE;
- priv->last_pts = end * rel_seek_secs;
+ seek_pts_av = end * seek_pts;
} else if (priv->avfc->duration != 0 &&
priv->avfc->duration != AV_NOPTS_VALUE)
{
- priv->last_pts = rel_seek_secs * priv->avfc->duration;
+ seek_pts_av = seek_pts * priv->avfc->duration;
}
} else {
if (flags & SEEK_BACKWARD)
- rel_seek_secs -= priv->seek_delay;
- priv->last_pts += rel_seek_secs * AV_TIME_BASE;
+ seek_pts -= priv->seek_delay;
+ seek_pts_av = seek_pts * AV_TIME_BASE;
}
int r;
if (!priv->avfc->iformat->read_seek2) {
// Normal seeking.
- r = av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags);
+ r = av_seek_frame(priv->avfc, -1, seek_pts_av, avsflags);
if (r < 0 && (avsflags & AVSEEK_FLAG_BACKWARD)) {
// When seeking before the beginning of the file, and seeking fails,
// try again without the backwards flag to make it seek to the
// beginning.
avsflags &= ~AVSEEK_FLAG_BACKWARD;
- r = av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags);
+ r = av_seek_frame(priv->avfc, -1, seek_pts_av, avsflags);
}
} else {
// av_seek_frame() won't work. Use "new" seeking API. We don't use this
@@ -985,11 +973,11 @@ static void demux_seek_lavf(demuxer_t *demuxer, double rel_seek_secs, int flags)
// Set max_ts==ts, so that demuxing starts from an earlier position in
// the worst case.
r = avformat_seek_file(priv->avfc, -1, INT64_MIN,
- priv->last_pts, priv->last_pts, avsflags);
+ seek_pts_av, seek_pts_av, avsflags);
// Similar issue as in the normal seeking codepath.
if (r < 0) {
r = avformat_seek_file(priv->avfc, -1, INT64_MIN,
- priv->last_pts, INT64_MAX, avsflags);
+ seek_pts_av, INT64_MAX, avsflags);
}
}
if (r < 0) {
diff --git a/demux/demux_mf.c b/demux/demux_mf.c
index c60f5c6307..c0b159e4ea 100644
--- a/demux/demux_mf.c
+++ b/demux/demux_mf.c
@@ -159,15 +159,12 @@ static mf_t *open_mf_single(void *talloc_ctx, struct mp_log *log, char *filename
return mf;
}
-static void demux_seek_mf(demuxer_t *demuxer, double rel_seek_secs, int flags)
+static void demux_seek_mf(demuxer_t *demuxer, double seek_pts, int flags)
{
mf_t *mf = demuxer->priv;
- int newpos = (flags & SEEK_ABSOLUTE) ? 0 : mf->curr_frame - 1;
-
+ int newpos = seek_pts * mf->sh->codec->fps;
if (flags & SEEK_FACTOR)
- newpos += rel_seek_secs * (mf->nr_of_files - 1);
- else
- newpos += rel_seek_secs * mf->sh->codec->fps;
+ newpos = seek_pts * (mf->nr_of_files - 1);
if (newpos < 0)
newpos = 0;
if (newpos >= mf->nr_of_files)
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 7b5efd8219..c932b45f39 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -163,7 +163,7 @@ struct block_info {
typedef struct mkv_demuxer {
int64_t segment_start, segment_end;
- double duration, last_pts;
+ double duration;
mkv_track_t **tracks;
int num_tracks;
@@ -2441,7 +2441,6 @@ static int handle_block(demuxer_t *demuxer, struct block_info *block_info)
if (use_this_block) {
uint64_t filepos = block_info->filepos;
- mkv_d->last_pts = current_pts;
for (int i = 0; i < laces; i++) {
bstr block = bstr_splice(data, 0, lace_size[i]);
@@ -2459,7 +2458,7 @@ static int handle_block(demuxer_t *demuxer, struct block_info *block_info)
* values being the same). Also, don't use it for extra
* packets resulting from parsing. */
if (i == 0 || track->default_duration)
- dp->pts = mkv_d->last_pts + i * track->default_duration;
+ dp->pts = current_pts + i * track->default_duration;
if (stream->codec->avi_dts)
MPSWAP(double, dp->pts, dp->dts);
if (i == 0)
@@ -2784,7 +2783,7 @@ static struct mkv_index *seek_with_cues(struct demuxer *demuxer, int seek_id,
return index;
}
-static void demux_mkv_seek(demuxer_t *demuxer, double rel_seek_secs, int flags)
+static void demux_mkv_seek(demuxer_t *demuxer, double seek_pts, int flags)
{
mkv_demuxer_t *mkv_d = demuxer->priv;
int64_t old_pos = stream_tell(demuxer->stream);
@@ -2814,15 +2813,13 @@ static void demux_mkv_seek(demuxer_t *demuxer, double rel_seek_secs, int flags)
// Adjust the target a little bit to catch cases where the target position
// specifies a keyframe with high, but not perfect, precision.
- rel_seek_secs += flags & SEEK_FORWARD ? -0.005 : 0.005;
+ seek_pts += flags & SEEK_FORWARD ? -0.005 : 0.005;
if (!(flags & SEEK_FACTOR)) { /* time in secs */
mkv_index_t *index = NULL;
- if (!(flags & SEEK_ABSOLUTE)) /* relative seek */
- rel_seek_secs += mkv_d->last_pts;
- rel_seek_secs = FFMAX(rel_seek_secs, 0);
- int64_t target_timecode = rel_seek_secs * 1e9 + 0.5;
+ seek_pts = FFMAX(seek_pts, 0);
+ int64_t target_timecode = seek_pts * 1e9 + 0.5;
if (create_index_until(demuxer, target_timecode) >= 0) {
int seek_id = st_active[STREAM_VIDEO] ? v_tnum : a_tnum;
@@ -2846,7 +2843,7 @@ static void demux_mkv_seek(demuxer_t *demuxer, double rel_seek_secs, int flags)
read_deferred_cues(demuxer);
int64_t size = stream_get_size(s);
- int64_t target_filepos = size * MPCLAMP(rel_seek_secs, 0, 1);
+ int64_t target_filepos = size * MPCLAMP(seek_pts, 0, 1);
mkv_index_t *index = NULL;
if (mkv_d->index_complete) {
diff --git a/demux/demux_raw.c b/demux/demux_raw.c
index 7fd9fdefa2..0d7517c3f0 100644
--- a/demux/demux_raw.c
+++ b/demux/demux_raw.c
@@ -263,17 +263,15 @@ static int raw_fill_buffer(demuxer_t *demuxer)
return 1;
}
-static void raw_seek(demuxer_t *demuxer, double rel_seek_secs, int flags)
+static void raw_seek(demuxer_t *demuxer, double seek_pts, int flags)
{
struct priv *p = demuxer->priv;
stream_t *s = demuxer->stream;
int64_t end = 0;
stream_control(s, STREAM_CTRL_GET_SIZE, &end);
- int64_t pos = (flags & SEEK_ABSOLUTE) ? 0 : stream_tell(s);
+ int64_t pos = seek_pts * p->frame_rate * p->frame_size;
if (flags & SEEK_FACTOR)
- pos += end * rel_seek_secs;
- else
- pos += rel_seek_secs * p->frame_rate * p->frame_size;
+ pos = end * seek_pts;
if (pos < 0)
pos = 0;
if (end && pos > end)
diff --git a/demux/demux_timeline.c b/demux/demux_timeline.c
index 9fba3d5abb..0c6c3986cc 100644
--- a/demux/demux_timeline.c
+++ b/demux/demux_timeline.c
@@ -63,8 +63,6 @@ struct priv {
// Total number of packets received past end of segment. Used
// to be clever about determining when to switch segments.
int eos_packets;
-
- double seek_pts;
};
static void reselect_streams(struct demuxer *demuxer)
@@ -107,7 +105,7 @@ static void switch_segment(struct demuxer *demuxer, struct segment *new,
p->current = new;
reselect_streams(demuxer);
demux_set_ts_offset(new->d, new->start - new->d_start);
- demux_seek(new->d, start_pts, flags | SEEK_ABSOLUTE);
+ demux_seek(new->d, start_pts, flags);
for (int n = 0; n < p->num_streams; n++) {
struct virtual_stream *vs = &p->streams[n];
@@ -118,19 +116,11 @@ static void switch_segment(struct demuxer *demuxer, struct segment *new,
p->eos_packets = 0;
}
-static void d_seek(struct demuxer *demuxer, double rel_seek_secs, int flags)
+static void d_seek(struct demuxer *demuxer, double seek_pts, int flags)
{
struct priv *p = demuxer->priv;
- double pts = p->seek_pts;
- if (flags & SEEK_ABSOLUTE)
- pts = 0.0f;
-
- if (flags & SEEK_FACTOR) {
- pts += p->duration * rel_seek_secs;
- } else {
- pts += rel_seek_secs;
- }
+ double pts = seek_pts * ((flags & SEEK_FACTOR) ? p->duration : 1);
flags &= SEEK_FORWARD | SEEK_BACKWARD | SEEK_HR;
@@ -144,8 +134,6 @@ static void d_seek(struct demuxer *demuxer, double rel_seek_secs, int flags)
p->current = NULL; // force seek
switch_segment(demuxer, new, pts, flags);
-
- p->seek_pts = pts;
}
static int d_fill_buffer(struct demuxer *demuxer)
diff --git a/player/loadfile.c b/player/loadfile.c
index 9ab930dfa7..b1e9cd2057 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -209,7 +209,7 @@ void reselect_demux_stream(struct MPContext *mpctx, struct track *track)
double pts = get_current_time(mpctx);
if (pts == MP_NOPTS_VALUE)
pts = 0;
- demux_seek(track->demuxer, pts, SEEK_ABSOLUTE);
+ demux_seek(track->demuxer, pts, 0);
}
}
}
diff --git a/player/playloop.c b/player/playloop.c
index 3e68ee9027..07a21e462c 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -242,8 +242,7 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek)
// Prefer doing absolute seeks, unless not possible.
if ((seek.type == MPSEEK_FACTOR && !mpctx->demuxer->ts_resets_possible &&
- target_time != MP_NOPTS_VALUE) ||
- (seek.type == MPSEEK_RELATIVE && (!mpctx->demuxer->rel_seeks || hr_seek)))
+ target_time != MP_NOPTS_VALUE) || seek.type == MPSEEK_RELATIVE)
{
seek.type = MPSEEK_ABSOLUTE;
seek.amount = target_time;
@@ -253,15 +252,7 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek)
double demuxer_amount = seek.amount;
- int demuxer_style = 0;
- switch (seek.type) {
- case MPSEEK_FACTOR:
- demuxer_style |= SEEK_ABSOLUTE | SEEK_FACTOR;
- break;
- case MPSEEK_ABSOLUTE:
- demuxer_style |= SEEK_ABSOLUTE;
- break;
- }
+ int demuxer_style = seek.type == MPSEEK_FACTOR ? SEEK_FACTOR : 0;
if (hr_seek || direction < 0) {
demuxer_style |= SEEK_BACKWARD;
} else if (direction > 0) {
@@ -281,7 +272,7 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek)
double main_new_pos = demuxer_amount;
if (seek.type != MPSEEK_ABSOLUTE)
main_new_pos = target_time;
- demux_seek(track->demuxer, main_new_pos, SEEK_ABSOLUTE | SEEK_BACKWARD);
+ demux_seek(track->demuxer, main_new_pos, 0);
}
}
diff --git a/player/sub.c b/player/sub.c
index 6b2a3664dc..6892ac935b 100644
--- a/player/sub.c
+++ b/player/sub.c
@@ -103,7 +103,7 @@ static bool update_subtitle(struct MPContext *mpctx, double video_pts,
{
// Assume fully_read implies no interleaved audio/video streams.
// (Reading packets will change the demuxer position.)
- demux_seek(track->demuxer, 0, SEEK_ABSOLUTE);
+ demux_seek(track->demuxer, 0, 0);
track->preloaded = sub_read_all_packets(track->d_sub);
}
diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c
index e2562dbcbc..d61ca5c937 100644
--- a/stream/stream_dvdnav.c
+++ b/stream/stream_dvdnav.c
@@ -332,8 +332,7 @@ static int control(stream_t *stream, int cmd, void *arg)
case STREAM_CTRL_SEEK_TO_TIME: {
double *args = arg;
double d = args[0]; // absolute target timestamp
- double r = args[1]; // if not SEEK_ABSOLUTE, the base time for d
- int flags = args[2]; // from SEEK_* flags (demux.h)
+ int flags = args[1]; // from SEEK_* flags (demux.h)
if (flags & SEEK_HR)
d -= 10; // fudge offset; it's a hack, because fuck libdvd*
int64_t tm = (int64_t)(d * 90000);
@@ -344,37 +343,9 @@ static int control(stream_t *stream, int cmd, void *arg)
uint32_t pos, len;
if (dvdnav_get_position(dvdnav, &pos, &len) != DVDNAV_STATUS_OK)
break;
- // The following is convoluted, because we have to translate between
- // dvdnav's block/CBR-based seeking bullshit, and the player's
- // timestamp-based high-level machinery.
- if (!(flags & SEEK_ABSOLUTE) && !(flags & SEEK_HR) && priv->duration > 0)
- {
- int dir = (flags & SEEK_BACKWARD) ? -1 : 1;
- // The user is making a relative seek (translated to absolute),
- // and we try not to get the user stuck on "boundaries". So try
- // to do block based seeks, which should workaround libdvdnav's
- // terrible CBR-based seeking.
- d -= r; // relative seek amount in seconds
- d = d / (priv->duration / 1000.0) * len; // d is now in blocks
- d += pos; // absolute target in blocks
- if (dir > 0)
- d = MPMAX(d, pos + 1.0);
- if (dir < 0)
- d = MPMIN(d, pos - 1.0);
- d += 0.5; // round
- uint32_t target = MPCLAMP(d, 0, len);
- MP_VERBOSE(stream, "seek from block %lu to %lu, dir=%d\n",
- (unsigned long)pos, (unsigned long)target, dir);
- if (dvdnav_sector_search(dvdnav, target, SEEK_SET) != DVDNAV_STATUS_OK)
- break;
- } else {
- // "old" method, should be good enough for large seeks. Used for
- // hr-seeks (with fudge offset), because I fear that block-based
- // seeking might be off too far for large jumps.
- MP_VERBOSE(stream, "seek to PTS %f (%"PRId64")\n", d, tm);
- if (dvdnav_time_search(dvdnav, tm) != DVDNAV_STATUS_OK)
- break;
- }
+ MP_VERBOSE(stream, "seek to PTS %f (%"PRId64")\n", d, tm);
+ if (dvdnav_time_search(dvdnav, tm) != DVDNAV_STATUS_OK)
+ break;
stream_drop_buffers(stream);
d = dvdnav_get_current_time(dvdnav) / 90000.0f;
MP_VERBOSE(stream, "landed at: %f\n", d);