mirror of https://github.com/mpv-player/mpv
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.
This commit is contained in:
parent
5098a27e66
commit
0a4b098c61
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue