summaryrefslogtreecommitdiffstats
path: root/sub/sd_lavc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sub/sd_lavc.c')
-rw-r--r--sub/sd_lavc.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c
index 88c45856b4..1e6180b074 100644
--- a/sub/sd_lavc.c
+++ b/sub/sd_lavc.c
@@ -53,6 +53,7 @@ struct sd_lavc_priv {
int64_t displayed_id;
int64_t new_id;
struct mp_image_params video_params;
+ double current_pts;
};
static bool supports_format(const char *format)
@@ -116,6 +117,7 @@ static int init(struct sd *sd)
priv->avctx = ctx;
sd->priv = priv;
priv->displayed_id = -1;
+ priv->current_pts = MP_NOPTS_VALUE;
return 0;
error:
@@ -138,8 +140,10 @@ static void clear_sub(struct sub *sub)
static void alloc_sub(struct sd_lavc_priv *priv)
{
clear_sub(&priv->subs[MAX_QUEUE - 1]);
+ struct sub tmp = priv->subs[MAX_QUEUE - 1];
for (int n = MAX_QUEUE - 1; n > 0; n--)
priv->subs[n] = priv->subs[n - 1];
+ priv->subs[0] = tmp;
// clear only some fields; the memory allocs can be reused
priv->subs[0].valid = false;
priv->subs[0].count = 0;
@@ -239,8 +243,10 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res d, double pts,
struct sd_lavc_priv *priv = sd->priv;
struct MPOpts *opts = sd->opts;
+ priv->current_pts = pts;
+
struct sub *current = NULL;
- for (int n = 0; n < MAX_QUEUE; n++) {
+ for (int n = MAX_QUEUE - 1; n >= 0; n--) {
struct sub *sub = &priv->subs[n];
if (!sub->valid)
continue;
@@ -297,6 +303,28 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res d, double pts,
osd_rescale_bitmaps(res, insize[0], insize[1], d, video_par);
}
+static bool accepts_packet(struct sd *sd)
+{
+ struct sd_lavc_priv *priv = sd->priv;
+
+ double pts = priv->current_pts;
+ int last_needed = -1;
+ for (int n = 0; n < MAX_QUEUE; n++) {
+ struct sub *sub = &priv->subs[n];
+ if (!sub->valid)
+ continue;
+ if (pts == MP_NOPTS_VALUE ||
+ ((sub->pts == MP_NOPTS_VALUE || sub->pts >= pts) ||
+ (sub->endpts == MP_NOPTS_VALUE || pts < sub->endpts)))
+ {
+ last_needed = n;
+ }
+ }
+ // We can accept a packet if it wouldn't overflow the fixed subtitle queue.
+ // We assume that get_bitmaps() never decreases the PTS.
+ return last_needed + 1 < MAX_QUEUE;
+}
+
static void reset(struct sd *sd)
{
struct sd_lavc_priv *priv = sd->priv;
@@ -305,6 +333,8 @@ static void reset(struct sd *sd)
clear_sub(&priv->subs[n]);
// lavc might not do this right for all codecs; may need close+reopen
avcodec_flush_buffers(priv->avctx);
+
+ priv->current_pts = MP_NOPTS_VALUE;
}
static void uninit(struct sd *sd)
@@ -340,6 +370,7 @@ const struct sd_functions sd_lavc = {
.init = init,
.decode = decode,
.get_bitmaps = get_bitmaps,
+ .accepts_packet = accepts_packet,
.control = control,
.reset = reset,
.uninit = uninit,