summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDudemanguy <random342@airmail.cc>2024-01-22 12:55:50 -0600
committerDudemanguy <random342@airmail.cc>2024-02-15 16:43:11 +0000
commit0a4b098c616bf1b6700bc88878b028bf1f446868 (patch)
tree9d53a4c433917954ed327f750365bba02071c63b
parent5098a27e662ba4a4779baad0408b5e6dcb85c384 (diff)
downloadmpv-0a4b098c616bf1b6700bc88878b028bf1f446868.tar.bz2
mpv-0a4b098c616bf1b6700bc88878b028bf1f446868.tar.xz
dec_sub: expand sub packet caching
Previously, mpv only saved a strict limit of two packets while decoding subtitles, but it is a bit incomplete. Firstly, it's certainly possible for there to be more than two subtitles visible at once. And also, it did not take into account preloading. Rework this mechanism so that it is a growable array that can store as many packets as we want. Note that in this commit, the packets are only ever discarded on reset or destroy, so in theory it could grow forever. Some discarding logic will be added in the next commit since it is inherently tied to other things.
-rw-r--r--sub/dec_sub.c39
1 files changed, 21 insertions, 18 deletions
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index c993b047a1..5221a65fde 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -70,7 +70,8 @@ struct dec_sub {
struct sd *sd;
struct demux_packet *new_segment;
- struct demux_packet *cached_pkts[2];
+ struct demux_packet **cached_pkts;
+ int num_cached_pkts;
};
static void update_subtitle_speed(struct dec_sub *sub)
@@ -119,6 +120,16 @@ static void wakeup_demux(void *ctx)
mp_dispatch_interrupt(q);
}
+static void sub_destroy_cached_pkts(struct dec_sub *sub)
+{
+ int index = 0;
+ while (index < sub->num_cached_pkts) {
+ TA_FREEP(&sub->cached_pkts[index]);
+ ++index;
+ }
+ sub->num_cached_pkts = 0;
+}
+
void sub_destroy(struct dec_sub *sub)
{
if (!sub)
@@ -258,7 +269,7 @@ void sub_preload(struct dec_sub *sub)
if (!pkt)
break;
sub->sd->driver->decode(sub->sd, pkt);
- talloc_free(pkt);
+ MP_TARRAY_APPEND(sub, sub->cached_pkts, sub->num_cached_pkts, pkt);
}
demux_set_stream_wakeup_cb(sub->sh, NULL, NULL);
@@ -317,16 +328,8 @@ 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;
-
sub->last_pkt_pts = pkt->pts;
+ MP_TARRAY_APPEND(sub, sub->cached_pkts, sub->num_cached_pkts, pkt);
if (is_new_segment(sub, pkt)) {
sub->new_segment = demux_copy_packet(pkt);
@@ -342,15 +345,16 @@ bool sub_read_packets(struct dec_sub *sub, double video_pts, bool force)
return r;
}
-// Redecode both cached packets if needed.
+// Redecode all cached packets if needed.
// Used with UPDATE_SUB_HARD and UPDATE_SUB_FILT.
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]);
+ int index = 0;
+ while (index < sub->num_cached_pkts) {
+ sub->sd->driver->decode(sub->sd, sub->cached_pkts[index]);
+ ++index;
+ }
mp_mutex_unlock(&sub->lock);
}
@@ -425,8 +429,7 @@ 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]);
+ sub_destroy_cached_pkts(sub);
TA_FREEP(&sub->new_segment);
mp_mutex_unlock(&sub->lock);
}