diff options
author | wm4 <wm4@nowhere> | 2020-02-27 02:23:58 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2020-02-27 02:23:58 +0100 |
commit | cf2b7a4997299ff9e0ff91d4273cd294686b001f (patch) | |
tree | 21c3f4a5c83407d5e1df92ba35d5847c6eba6097 /sub | |
parent | b873f1f8e5a0d34defe4c7b975ec584377c731ac (diff) | |
download | mpv-cf2b7a4997299ff9e0ff91d4273cd294686b001f.tar.bz2 mpv-cf2b7a4997299ff9e0ff91d4273cd294686b001f.tar.xz |
sub, demux: improve behavior with negative subtitle delay/muxed subs
A negative subtitle delay means that subtitles from the future should be
shown earlier. With muxed subtitles, subtitle packets are demuxed along
with audio and video packets. But since they are demuxed "lazily",
nothing guarantees that subtitle packets from the future are available
in time.
Typically, the user-observed effect is that subtitles do not appear at
all (or too late) with large negative --sub-delay values, but that using
--cache might fix this.
Make this behave better. Automatically extend read-ahead to as much as
needed by the subtitles. It seems it's the easiest to pass the subtitle
render timestamp to the demuxer in order to guarantee that everything is
read. This timestamp based approach might be fragile, so disable it if
no negative sub-delay is used.
As far as the player frontend part is concerned, this makes use of the
code path for external subtitles, which are not lazily demuxed, and may
already trigger waiting.
Fixes: #7484
Diffstat (limited to 'sub')
-rw-r--r-- | sub/dec_sub.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/sub/dec_sub.c b/sub/dec_sub.c index f98a478be4..ad46eaea73 100644 --- a/sub/dec_sub.c +++ b/sub/dec_sub.c @@ -299,13 +299,16 @@ bool sub_read_packets(struct dec_sub *sub, double video_pts) if (sub->new_segment) break; + // (Use this mechanism only if sub_delay matters to avoid corner cases.) + double min_pts = sub->opts->sub_delay < 0 ? video_pts : MP_NOPTS_VALUE; + struct demux_packet *pkt; - int st = demux_read_packet_async(sub->sh, &pkt); + int st = demux_read_packet_async_until(sub->sh, min_pts, &pkt); // Note: "wait" (st==0) happens with non-interleaved streams only, and // then we should stop the playloop until a new enough packet has been - // seen (or the subtitle decoder's queue is full). This does not happen - // for interleaved subtitle streams, which never return "wait" when - // reading. + // seen (or the subtitle decoder's queue is full). This usually does not + // happen for interleaved subtitle streams, which never return "wait" + // when reading, unless min_pts is set. if (st <= 0) { r = st < 0 || (sub->last_pkt_pts != MP_NOPTS_VALUE && sub->last_pkt_pts > video_pts); |