summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-11-16 22:47:17 +0100
committerwm4 <wm4@nowhere>2015-11-16 22:47:17 +0100
commit70df1608d6f74f3eba9a5e593822984194f63951 (patch)
treee6f332aa72d8fd8020d4ba9a214a4826ed6e711f /demux
parente24e0ccd6828ff8a50fb290bed45a0f6d81eb00b (diff)
downloadmpv-70df1608d6f74f3eba9a5e593822984194f63951.tar.bz2
mpv-70df1608d6f74f3eba9a5e593822984194f63951.tar.xz
player: handle rebasing start time differently
Most of this is explained in the DOCS additions. This gives us slightly more sanity, because there is less interaction between the various parts. The goal is getting rid of the video_offset entirely. The simplification extends to the user API. In particular, we don't need to fix missing parts in the API, such as the lack for a seek command that seeks relatively to the start time. All these things are now transparent. (If someone really wants to know the real timestamps/start time, new properties would have to be added.)
Diffstat (limited to 'demux')
-rw-r--r--demux/demux.c21
-rw-r--r--demux/demux.h1
2 files changed, 21 insertions, 1 deletions
diff --git a/demux/demux.c b/demux/demux.c
index a00a3617cc..a3d1ecf7c2 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -124,6 +124,8 @@ struct demux_internal {
bool refresh_seeks_enabled;
bool start_refresh_seek;
+ double ts_offset; // timestamp offset to apply everything
+
// Cached state.
bool force_cache_update;
double time_length;
@@ -164,6 +166,8 @@ struct demux_stream {
#define MP_PTS_MIN(a, b) MPMIN(PTS_OR_DEF(a, b), PTS_OR_DEF(b, a))
#define MP_PTS_MAX(a, b) MPMAX(PTS_OR_DEF(a, b), PTS_OR_DEF(b, a))
+#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
+
static void demuxer_sort_chapters(demuxer_t *demuxer);
static void *demux_thread(void *pctx);
static void update_cache(struct demux_internal *in);
@@ -189,6 +193,14 @@ static void ds_flush(struct demux_stream *ds)
ds->last_pos = -1;
}
+void demux_set_ts_offset(struct demuxer *demuxer, double offset)
+{
+ struct demux_internal *in = demuxer->in;
+ pthread_mutex_lock(&in->lock);
+ in->ts_offset = offset;
+ pthread_mutex_unlock(&in->lock);
+}
+
struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type)
{
assert(demuxer == demuxer->in->d_thread);
@@ -603,6 +615,9 @@ static struct demux_packet *dequeue_packet(struct demux_stream *ds)
if (pkt->pos >= ds->in->d_user->filepos)
ds->in->d_user->filepos = pkt->pos;
+ pkt->pts = MP_ADD_PTS(pkt->pts, ds->in->ts_offset);
+ pkt->dts = MP_ADD_PTS(pkt->dts, ds->in->ts_offset);
+
return pkt;
}
@@ -664,7 +679,7 @@ double demux_get_next_pts(struct sh_stream *sh)
pthread_mutex_lock(&sh->ds->in->lock);
ds_get_packets(sh->ds);
if (sh->ds->head)
- res = sh->ds->head->pts;
+ res = MP_ADD_PTS(sh->ds->head->pts, sh->ds->in->ts_offset);
pthread_mutex_unlock(&sh->ds->in->lock);
}
return res;
@@ -1148,6 +1163,8 @@ int demux_seek(demuxer_t *demuxer, double rel_seek_secs, int flags)
in->seeking = true;
in->seek_flags = flags;
in->seek_pts = rel_seek_secs;
+ if (flags & SEEK_ABSOLUTE)
+ in->seek_pts = MP_ADD_PTS(in->seek_pts, -in->ts_offset);
if (!in->threading)
execute_seek(in);
@@ -1419,6 +1436,8 @@ static int cached_demux_control(struct demux_internal *in, int cmd, void *arg)
r->ts_duration = MPMAX(0, r->ts_range[1] - r->ts_range[0]);
if (!num_packets || in->seeking)
r->ts_duration = 0;
+ r->ts_range[0] = MP_ADD_PTS(r->ts_range[0], in->ts_offset);
+ r->ts_range[1] = MP_ADD_PTS(r->ts_range[1], in->ts_offset);
return DEMUXER_CTRL_OK;
}
}
diff --git a/demux/demux.h b/demux/demux.h
index 7823d50233..96717d5eeb 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -271,6 +271,7 @@ bool demux_cancel_test(struct demuxer *demuxer);
void demux_flush(struct demuxer *demuxer);
int demux_seek(struct demuxer *demuxer, double rel_seek_secs, int flags);
void demux_set_enable_refresh_seeks(struct demuxer *demuxer, bool enabled);
+void demux_set_ts_offset(struct demuxer *demuxer, double offset);
int demux_control(struct demuxer *demuxer, int cmd, void *arg);