summaryrefslogtreecommitdiffstats
path: root/demux/demux.c
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/demux.c
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/demux.c')
-rw-r--r--demux/demux.c21
1 files changed, 20 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;
}
}