mirror of
https://github.com/mpv-player/mpv
synced 2025-03-20 02:09:52 +00:00
player: use demuxer ts offset to simplify timeline ts handling
Use the demux_set_ts_offset() added in the previous commit to base each timeline segment to use timestamps according to its relative position within the overall timeline. As a consequence we don't need to care about these timestamps anymore, and everything becomes simpler. (Another minor but delicious nugget of sanity.)
This commit is contained in:
parent
70df1608d6
commit
85450d06a1
@ -384,8 +384,7 @@ double written_audio_pts(struct MPContext *mpctx)
|
||||
// to get the length in original units without speedup or slowdown
|
||||
a_pts -= buffered_output * mpctx->audio_speed;
|
||||
|
||||
return a_pts +
|
||||
get_track_video_offset(mpctx, mpctx->current_track[0][STREAM_AUDIO]);
|
||||
return a_pts;
|
||||
}
|
||||
|
||||
// Return pts value corresponding to currently playing audio.
|
||||
|
@ -4477,7 +4477,7 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re
|
||||
double refpts = get_current_time(mpctx);
|
||||
if (state.dec_sub && refpts != MP_NOPTS_VALUE) {
|
||||
double a[2];
|
||||
a[0] = refpts - state.video_offset - opts->sub_delay;
|
||||
a[0] = refpts - opts->sub_delay;
|
||||
a[1] = cmd->args[0].v.i;
|
||||
if (sub_control(state.dec_sub, SD_CTRL_SUB_STEP, a) > 0) {
|
||||
if (cmd->id == MP_CMD_SUB_STEP) {
|
||||
|
@ -226,7 +226,6 @@ typedef struct MPContext {
|
||||
int timeline_part;
|
||||
struct demux_chapter *chapters;
|
||||
int num_chapters;
|
||||
double video_offset;
|
||||
|
||||
struct demuxer *demuxer; // can change with timeline
|
||||
struct mp_tags *filtered_tags;
|
||||
@ -431,7 +430,8 @@ void mp_switch_track_n(struct MPContext *mpctx, int order,
|
||||
void mp_deselect_track(struct MPContext *mpctx, struct track *track);
|
||||
struct track *mp_track_by_tid(struct MPContext *mpctx, enum stream_type type,
|
||||
int tid);
|
||||
double timeline_set_from_time(struct MPContext *mpctx, double pts, bool *need_reset);
|
||||
void timeline_set_part(struct MPContext *mpctx, int i, bool initial);
|
||||
int timeline_get_for_time(struct MPContext *mpctx, double pts);
|
||||
void add_demuxer_tracks(struct MPContext *mpctx, struct demuxer *demuxer);
|
||||
bool mp_remove_track(struct MPContext *mpctx, struct track *track);
|
||||
struct playlist_entry *mp_next_file(struct MPContext *mpctx, int direction,
|
||||
@ -455,7 +455,6 @@ void wakeup_playloop(void *ctx);
|
||||
|
||||
// misc.c
|
||||
double get_main_demux_pts(struct MPContext *mpctx);
|
||||
double get_track_video_offset(struct MPContext *mpctx, struct track *track);
|
||||
double rel_time_to_abs(struct MPContext *mpctx, struct m_rel_time t);
|
||||
double get_play_end_pts(struct MPContext *mpctx);
|
||||
double get_relative_time(struct MPContext *mpctx);
|
||||
|
@ -96,8 +96,6 @@ static void uninit_demuxer(struct MPContext *mpctx)
|
||||
talloc_free(mpctx->sources);
|
||||
mpctx->sources = NULL;
|
||||
mpctx->num_sources = 0;
|
||||
|
||||
mpctx->video_offset = 0;
|
||||
}
|
||||
|
||||
static void uninit_stream(struct MPContext *mpctx)
|
||||
@ -288,14 +286,10 @@ static void enable_demux_thread(struct MPContext *mpctx)
|
||||
}
|
||||
}
|
||||
|
||||
static bool timeline_set_part(struct MPContext *mpctx, int i, bool initial)
|
||||
void timeline_set_part(struct MPContext *mpctx, int i, bool initial)
|
||||
{
|
||||
struct timeline_part *p = mpctx->timeline + mpctx->timeline_part;
|
||||
struct timeline_part *n = mpctx->timeline + i;
|
||||
mpctx->timeline_part = i;
|
||||
mpctx->video_offset = n->start - n->source_start;
|
||||
if (n->source == p->source && !initial)
|
||||
return false;
|
||||
|
||||
uninit_audio_chain(mpctx);
|
||||
uninit_video_chain(mpctx);
|
||||
@ -311,6 +305,7 @@ static bool timeline_set_part(struct MPContext *mpctx, int i, bool initial)
|
||||
}
|
||||
|
||||
mpctx->demuxer = n->source;
|
||||
demux_set_ts_offset(mpctx->demuxer, n->start - n->source_start);
|
||||
|
||||
// While another timeline was active, the selection of active tracks might
|
||||
// have been changed - possibly we need to update this source.
|
||||
@ -334,27 +329,20 @@ static bool timeline_set_part(struct MPContext *mpctx, int i, bool initial)
|
||||
reselect_demux_streams(mpctx);
|
||||
enable_demux_thread(mpctx);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Given pts, switch playback to the corresponding part.
|
||||
// Return offset within that part.
|
||||
double timeline_set_from_time(struct MPContext *mpctx, double pts, bool *need_reset)
|
||||
// Given pts, return the segment number of the corresponding part.
|
||||
int timeline_get_for_time(struct MPContext *mpctx, double pts)
|
||||
{
|
||||
if (pts < 0)
|
||||
pts = 0;
|
||||
|
||||
int new = mpctx->num_timeline_parts - 1;
|
||||
for (int i = 0; i < mpctx->num_timeline_parts; i++) {
|
||||
if (pts < mpctx->timeline[i + 1].start) {
|
||||
new = i;
|
||||
break;
|
||||
}
|
||||
if (pts < mpctx->timeline[i + 1].start)
|
||||
return i;
|
||||
}
|
||||
|
||||
*need_reset = timeline_set_part(mpctx, new, false);
|
||||
return pts - mpctx->timeline[new].start + mpctx->timeline[new].source_start;
|
||||
return mpctx->num_timeline_parts - 1;
|
||||
}
|
||||
|
||||
static int find_new_tid(struct MPContext *mpctx, enum stream_type t)
|
||||
|
@ -115,14 +115,6 @@ double get_main_demux_pts(struct MPContext *mpctx)
|
||||
return main_new_pos;
|
||||
}
|
||||
|
||||
// Get the offset from the given track to the video.
|
||||
double get_track_video_offset(struct MPContext *mpctx, struct track *track)
|
||||
{
|
||||
if (track && track->under_timeline)
|
||||
return mpctx->video_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
float mp_get_cache_percent(struct MPContext *mpctx)
|
||||
{
|
||||
if (mpctx->demuxer) {
|
||||
|
@ -229,10 +229,9 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
|
||||
|
||||
double demuxer_amount = seek.amount;
|
||||
if (mpctx->timeline) {
|
||||
bool need_reset = false;
|
||||
demuxer_amount = timeline_set_from_time(mpctx, seek.amount,
|
||||
&need_reset);
|
||||
if (need_reset) {
|
||||
int segment = timeline_get_for_time(mpctx, seek.amount);
|
||||
if (segment != mpctx->timeline_part) {
|
||||
timeline_set_part(mpctx, segment, false);
|
||||
reinit_video_chain(mpctx);
|
||||
reinit_audio_chain(mpctx);
|
||||
reinit_subs(mpctx, 0);
|
||||
@ -268,7 +267,6 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
|
||||
double main_new_pos = seek.amount;
|
||||
if (seek.type != MPSEEK_ABSOLUTE)
|
||||
main_new_pos = get_main_demux_pts(mpctx);
|
||||
main_new_pos -= get_track_video_offset(mpctx, track);
|
||||
demux_seek(track->demuxer, main_new_pos, SEEK_ABSOLUTE | SEEK_BACKWARD);
|
||||
}
|
||||
}
|
||||
|
@ -195,7 +195,6 @@ void update_osd_sub_state(struct MPContext *mpctx, int order,
|
||||
struct osd_sub_state *out_state)
|
||||
{
|
||||
struct MPOpts *opts = mpctx->opts;
|
||||
struct track *track = mpctx->current_track[order][STREAM_SUB];
|
||||
struct dec_sub *dec_sub = mpctx->d_sub[order];
|
||||
int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB;
|
||||
bool textsub = dec_sub && sub_has_get_text(dec_sub);
|
||||
@ -204,7 +203,6 @@ void update_osd_sub_state(struct MPContext *mpctx, int order,
|
||||
.dec_sub = dec_sub,
|
||||
// Decides whether to use OSD path or normal subtitle rendering path.
|
||||
.render_bitmap_subs = opts->ass_enabled || !textsub,
|
||||
.video_offset = get_track_video_offset(mpctx, track),
|
||||
};
|
||||
|
||||
// Secondary subs are rendered with the "text" renderer to transform them
|
||||
@ -240,7 +238,7 @@ static void update_subtitle(struct MPContext *mpctx, int order)
|
||||
struct osd_sub_state state;
|
||||
update_osd_sub_state(mpctx, order, &state);
|
||||
|
||||
double refpts_s = mpctx->playback_pts - state.video_offset;
|
||||
double refpts_s = mpctx->playback_pts;
|
||||
double curpts_s = refpts_s - opts->sub_delay;
|
||||
|
||||
if (!track->preloaded && track->stream) {
|
||||
|
@ -390,10 +390,6 @@ static int decode_image(struct MPContext *mpctx)
|
||||
struct demux_packet *pkt;
|
||||
if (demux_read_packet_async(d_video->header, &pkt) == 0)
|
||||
return VD_WAIT;
|
||||
if (pkt && pkt->pts != MP_NOPTS_VALUE)
|
||||
pkt->pts += mpctx->video_offset;
|
||||
if (pkt && pkt->dts != MP_NOPTS_VALUE)
|
||||
pkt->dts += mpctx->video_offset;
|
||||
if ((pkt && pkt->pts >= mpctx->hrseek_pts - .005) ||
|
||||
d_video->has_broken_packet_pts ||
|
||||
!mpctx->opts->hr_seek_framedrop)
|
||||
|
@ -247,7 +247,7 @@ static void render_object(struct osd_state *osd, struct osd_object *obj,
|
||||
if (sub->render_bitmap_subs && sub->dec_sub) {
|
||||
double sub_pts = video_pts;
|
||||
if (sub_pts != MP_NOPTS_VALUE)
|
||||
sub_pts -= sub->video_offset + opts->sub_delay;
|
||||
sub_pts -= opts->sub_delay;
|
||||
sub_get_bitmaps(sub->dec_sub, obj->vo_res, sub_pts, out_imgs);
|
||||
} else {
|
||||
osd_object_get_bitmaps(osd, obj, out_imgs);
|
||||
|
Loading…
Reference in New Issue
Block a user