Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:X0F:HSF
mpv
mpv_PR12840.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File mpv_PR12840.patch of Package mpv
From e339f79154e2b9eda8a03c21da801590a7c85a43 Mon Sep 17 00:00:00 2001 From: Dudemanguy <random342@airmail.cc> Date: Mon, 6 Nov 2023 12:21:50 -0600 Subject: [PATCH] dec_sub: cache up to 10 packets 062104d16e34f348ffd9324ca4c997b6b0f487d4 started saving 2 packets in memory for the purposes of runtime updates of some options, but sometimes we need more. There are subs out there that will have overlapping durations so saving only 2 packets would only update those 2 subs at most and drop the rest. So with that in mind, let's just cache up to 10 (arbitrary but surely no one needs more) packets instead. We don't always want to hold onto that many since it's useless 99% of the time, so do some logic by checking the video pts and the durations. At least 2 must always be kept though so there's some extra conditions. --- sub/dec_sub.c | 50 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/sub/dec_sub.c b/sub/dec_sub.c index 18d826e8b591..8222d5ac6eca 100644 --- a/sub/dec_sub.c +++ b/sub/dec_sub.c @@ -32,6 +32,8 @@ #include "misc/dispatch.h" #include "osdep/threads.h" +#define PKT_CACHE 10 + extern const struct sd_functions sd_ass; extern const struct sd_functions sd_lavc; @@ -68,7 +70,7 @@ struct dec_sub { struct sd *sd; struct demux_packet *new_segment; - struct demux_packet *cached_pkts[2]; + struct demux_packet *cached_pkts[PKT_CACHE]; }; static void update_subtitle_speed(struct dec_sub *sub) @@ -193,6 +195,30 @@ struct dec_sub *sub_create(struct mpv_global *global, struct track *track, return NULL; } +// Called locked. +static void update_cached_packets(struct dec_sub *sub, struct demux_packet *pkt, + double video_pts) +{ + // Unconditionally cleared. + if (sub->cached_pkts[PKT_CACHE - 1]) + TA_FREEP(&sub->cached_pkts[PKT_CACHE - 1]); + + // Always save at least 2 packets but allow up to PKT_CACHE + // for subs with overlapping durations. + int i = PKT_CACHE; + while (--i) { + struct demux_packet *prev_pkt = sub->cached_pkts[i - 1]; + if (prev_pkt) { + double prev_pkt_end = prev_pkt->pts + prev_pkt->duration; + if (sub->cached_pkts[i] && prev_pkt_end < video_pts) + TA_FREEP(&sub->cached_pkts[i]); + sub->cached_pkts[i] = prev_pkt; + sub->cached_pkts[i - 1] = NULL; + } + } + sub->cached_pkts[0] = pkt; +} + // Called locked. static void update_segment(struct dec_sub *sub) { @@ -309,15 +335,7 @@ bool sub_read_packets(struct dec_sub *sub, double video_pts, bool force) if (sub->recorder_sink) mp_recorder_feed_packet(sub->recorder_sink, pkt); - - // Update cached packets - if (sub->cached_pkts[0]) { - if (sub->cached_pkts[1]) - talloc_free(sub->cached_pkts[1]); - sub->cached_pkts[1] = sub->cached_pkts[0]; - } - sub->cached_pkts[0] = pkt; - + update_cached_packets(sub, pkt, video_pts); sub->last_pkt_pts = pkt->pts; if (is_new_segment(sub, pkt)) { @@ -339,10 +357,10 @@ bool sub_read_packets(struct dec_sub *sub, double video_pts, bool force) void sub_redecode_cached_packets(struct dec_sub *sub) { mp_mutex_lock(&sub->lock); - if (sub->cached_pkts[0]) - sub->sd->driver->decode(sub->sd, sub->cached_pkts[0]); - if (sub->cached_pkts[1]) - sub->sd->driver->decode(sub->sd, sub->cached_pkts[1]); + for (int i = 0; i < PKT_CACHE; i++) { + if (sub->cached_pkts[i]) + sub->sd->driver->decode(sub->sd, sub->cached_pkts[i]); + } mp_mutex_unlock(&sub->lock); } @@ -417,8 +435,8 @@ void sub_reset(struct dec_sub *sub) sub->sd->driver->reset(sub->sd); sub->last_pkt_pts = MP_NOPTS_VALUE; sub->last_vo_pts = MP_NOPTS_VALUE; - TA_FREEP(&sub->cached_pkts[0]); - TA_FREEP(&sub->cached_pkts[1]); + for (int i = 0; i < PKT_CACHE; i++) + TA_FREEP(&sub->cached_pkts[i]); TA_FREEP(&sub->new_segment); mp_mutex_unlock(&sub->lock); }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor