From e928bd5fdb4e2a7cac3e55c4a2056c0cb4a76d9c Mon Sep 17 00:00:00 2001 From: Lypheo Date: Wed, 8 Mar 2023 19:05:59 +0100 Subject: [PATCH] sub: fix UPDATE_SUB_HARD for converted and external subtitles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upon an option update with an UPDATE_SUB_HARD flag, the ass_track that stores all the decoded subtitle packets/events is destroyed and recreated, which means the packets need to be read and decoded again to refill the ass_track. This caused issues (no subs displayed) in 2 cases: 1. external sub files Previously, external sub files were read and decoded only once when loaded. Since this meant all decoded events were lost forever when recreating the ass_track, we need to change this and trigger a new preload during sub reinits. 2. converted subs (non-ASS text subs like srt) For converted subs, we maintain a list of previously seen packets to avoid decoding and adding duplicate events to the ass_track. Previously this list wasn’t synchronized with the corresponding ass_track, so the sub decoder would reject any previously seen sub packets, usually meaning only subs sometime after the current pts would be displayed after sub reinits. Fix this by resetting the list upon ass_track recreation. --- sub/dec_sub.c | 10 +++++++++- sub/sd_ass.c | 4 ++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/sub/dec_sub.c b/sub/dec_sub.c index 958b92d48a..0fed1e668f 100644 --- a/sub/dec_sub.c +++ b/sub/dec_sub.c @@ -421,10 +421,18 @@ int sub_control(struct dec_sub *sub, enum sd_ctrl cmd, void *arg) if (r == CONTROL_OK) a[0] = pts_from_subtitle(sub, arg2[0]); break; - case SD_CTRL_UPDATE_OPTS: + } + case SD_CTRL_UPDATE_OPTS: { + int flags = (uintptr_t)arg; if (m_config_cache_update(sub->opts_cache)) update_subtitle_speed(sub); propagate = true; + if (flags & UPDATE_SUB_HARD) { + // forget about the previous preload because + // UPDATE_SUB_HARD will cause a sub reinit + // that clears all preloaded sub packets + sub->preload_attempted = false; + } break; } default: diff --git a/sub/sd_ass.c b/sub/sd_ass.c index 34dc567e54..bec989fee7 100644 --- a/sub/sd_ass.c +++ b/sub/sd_ass.c @@ -824,6 +824,10 @@ static int control(struct sd *sd, enum sd_ctrl cmd, void *arg) ctx->clear_once = true; // allow reloading on seeks } if (flags & UPDATE_SUB_HARD) { + // ass_track will be recreated, so clear duplicate cache + ctx->clear_once = true; + reset(sd); + assobjects_destroy(sd); assobjects_init(sd); }