summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
Diffstat (limited to 'demux')
-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
8 files changed, 40 insertions, 102 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)