sd_lavc: fix subtitle presentation time

Packet duration is not necessarily related to the display time of the
subtitle. Use start/end_display_time fields as source of the timing.

Fixes subtitles with infinite duration that should be on screen until
next sub is displayed.
This commit is contained in:
Kacper Michajłow 2023-09-09 04:16:32 +02:00 committed by Dudemanguy
parent f5690e3c97
commit 8536aaac3c
1 changed files with 1 additions and 13 deletions

View File

@ -300,17 +300,8 @@ static void decode(struct sd *sd, struct demux_packet *packet)
AVCodecContext *ctx = priv->avctx;
double pts = packet->pts;
double endpts = MP_NOPTS_VALUE;
double duration = packet->duration;
AVSubtitle sub;
// libavformat sets duration==0, even if the duration is unknown. Some files
// also have actually subtitle packets with duration explicitly set to 0
// (yes, at least some of such mkv files were muxed by libavformat).
// Assume there are no bitmap subs that actually use duration==0 for
// hidden subtitle events.
if (duration == 0)
duration = -1;
if (pts == MP_NOPTS_VALUE)
MP_WARN(sd, "Subtitle with unknown start time.\n");
@ -334,13 +325,10 @@ static void decode(struct sd *sd, struct demux_packet *packet)
if (sub.end_display_time > sub.start_display_time &&
sub.end_display_time != UINT32_MAX)
{
duration = (sub.end_display_time - sub.start_display_time) / 1000.0;
endpts = pts + sub.end_display_time / 1000.0;
}
pts += sub.start_display_time / 1000.0;
if (duration >= 0)
endpts = pts + duration;
// set end time of previous sub
struct sub *prev = &priv->subs[0];
if (prev->valid) {