summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/mplayer.c38
-rw-r--r--demux/demux.c4
-rw-r--r--demux/demux_lavf.c12
3 files changed, 41 insertions, 13 deletions
diff --git a/core/mplayer.c b/core/mplayer.c
index 4eb4ff0e23..81302f284f 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -439,6 +439,23 @@ static void print_file_properties(struct MPContext *mpctx, const char *filename)
/// step size of mixer changes
int volstep = 3;
+// Time used to seek external tracks to.
+static double get_main_demux_pts(struct MPContext *mpctx)
+{
+ double main_new_pos = MP_NOPTS_VALUE;
+ if (mpctx->demuxer) {
+ for (int type = 0; type < STREAM_TYPE_COUNT; type++) {
+ struct demux_stream *ds = mpctx->demuxer->ds[type];
+ if (ds->sh && main_new_pos == MP_NOPTS_VALUE) {
+ demux_fill_buffer(mpctx->demuxer, ds);
+ if (ds->first)
+ main_new_pos = ds->first->pts;
+ }
+ }
+ }
+ return main_new_pos;
+}
+
static void set_demux_field(struct MPContext *mpctx, enum stream_type type,
struct sh_stream *s)
{
@@ -456,8 +473,13 @@ static void init_demux_stream(struct MPContext *mpctx, enum stream_type type)
struct track *track = mpctx->current_track[type];
set_demux_field(mpctx, type, track ? track->stream : NULL);
struct sh_stream *stream = mpctx->sh[type];
- if (stream)
+ if (stream) {
demuxer_switch_track(stream->demuxer, type, stream);
+ if (track->is_external) {
+ double pts = get_main_demux_pts(mpctx);
+ demux_seek(stream->demuxer, pts, audio_delay, SEEK_ABSOLUTE);
+ }
+ }
}
static void cleanup_demux_stream(struct MPContext *mpctx, enum stream_type type)
@@ -2863,18 +2885,12 @@ static int seek(MPContext *mpctx, struct seek_params seek,
have_external_tracks |= track && track->is_external && track->demuxer;
}
if (have_external_tracks) {
- double main_new_pos = MP_NOPTS_VALUE;
- if (seek.type == MPSEEK_ABSOLUTE)
+ double main_new_pos;
+ if (seek.type == MPSEEK_ABSOLUTE) {
main_new_pos = seek.amount - mpctx->video_offset;
- for (int type = 0; type < STREAM_TYPE_COUNT; type++) {
- struct demux_stream *ds = mpctx->demuxer->ds[type];
- if (ds->sh && main_new_pos == MP_NOPTS_VALUE) {
- demux_fill_buffer(mpctx->demuxer, ds);
- if (ds->first)
- main_new_pos = ds->first->pts;
- }
+ } else {
+ main_new_pos = get_main_demux_pts(mpctx);
}
- assert(main_new_pos != MP_NOPTS_VALUE);
for (int type = 0; type < STREAM_TYPE_COUNT; type++) {
struct track *track = mpctx->current_track[type];
if (track && track->is_external && track->demuxer)
diff --git a/demux/demux.c b/demux/demux.c
index 82159057d8..f765b2ae87 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -1077,6 +1077,10 @@ int demux_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_delay,
mp_tmsg(MSGT_SEEK, MSGL_WARN, "Cannot seek in this file.\n");
return 0;
}
+
+ if (rel_seek_secs == MP_NOPTS_VALUE && (flags & SEEK_ABSOLUTE))
+ return 0;
+
// clear demux buffers:
demux_flush(demuxer);
demuxer->video->eof = 0;
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index c1c15f345a..42b687dc20 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -886,9 +886,17 @@ static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs,
priv->last_pts += rel_seek_secs * priv->avfc->duration;
} else
priv->last_pts += rel_seek_secs * AV_TIME_BASE;
- if (av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags) < 0) {
- avsflags ^= AVSEEK_FLAG_BACKWARD;
+
+ if (!priv->avfc->iformat->read_seek2) {
+ // Normal seeking.
av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags);
+ } else {
+ // av_seek_frame() won't work. Use "new" seeking API. We don't use this
+ // API by default, because there are some major issues.
+ // Set max_ts==ts, so that demuxing starts from an earlier position in
+ // the worst case.
+ avformat_seek_file(priv->avfc, -1, INT64_MIN,
+ priv->last_pts, priv->last_pts, avsflags);
}
}