summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmpcodecs/vf_vo.c16
-rw-r--r--libvo/eosd_packer.c13
-rw-r--r--libvo/eosd_packer.h2
-rw-r--r--libvo/vo_vdpau.c9
-rw-r--r--sub/dec_sub.c19
-rw-r--r--sub/dec_sub.h2
-rw-r--r--sub/sd_ass.c7
-rw-r--r--sub/sub.h3
8 files changed, 39 insertions, 32 deletions
diff --git a/libmpcodecs/vf_vo.c b/libmpcodecs/vf_vo.c
index 076850c8c2..3aec40cd15 100644
--- a/libmpcodecs/vf_vo.c
+++ b/libmpcodecs/vf_vo.c
@@ -34,7 +34,6 @@
struct vf_priv_s {
struct vo *vo;
- bool prev_visibility;
double scale_ratio;
};
#define video_out (vf->priv->vo)
@@ -77,9 +76,6 @@ static int config(struct vf_instance *vf,
vf->priv->scale_ratio = (double) d_width / d_height * height / width;
- // force EOSD change detection reset
- vf->priv->prev_visibility = false;
-
return 1;
}
@@ -121,27 +117,17 @@ static int control(struct vf_instance *vf, int request, void *data)
};
return vo_control(video_out, VOCTRL_GET_EQUALIZER, &param) == VO_TRUE;
}
- case VFCTRL_INIT_EOSD: {
- vf->priv->prev_visibility = false;
- return CONTROL_TRUE;
- }
-
case VFCTRL_DRAW_EOSD: {
struct osd_state *osd = data;
osd->dim = (struct mp_eosd_res){0};
if (!video_out->config_ok ||
- vo_control(video_out, VOCTRL_GET_EOSD_RES, &osd->dim) != true) {
- vf->priv->prev_visibility = false;
+ vo_control(video_out, VOCTRL_GET_EOSD_RES, &osd->dim) != true)
return CONTROL_FALSE;
- }
osd->normal_scale = 1;
osd->vsfilter_scale = vf->priv->scale_ratio;
osd->unscaled = vf->default_caps & VFCAP_EOSD_UNSCALED;
struct sub_bitmaps images;
sub_get_bitmaps(osd, &images);
- if (!vf->priv->prev_visibility)
- images.changed = 2;
- vf->priv->prev_visibility = true;
return vo_control(video_out, VOCTRL_DRAW_EOSD, &images) == VO_TRUE;
}
}
diff --git a/libvo/eosd_packer.c b/libvo/eosd_packer.c
index 103648b7c4..8f831d512e 100644
--- a/libvo/eosd_packer.c
+++ b/libvo/eosd_packer.c
@@ -147,17 +147,18 @@ void eosd_packer_generate(struct eosd_packer *state, mp_eosd_images_t *imgs,
ASS_Image *p;
struct eosd_surface *sfc = &state->surface;
- *out_need_reposition = false;
- *out_need_upload = false;
+ *out_need_reposition = imgs->bitmap_pos_id != state->last_bitmap_pos_id;
+ *out_need_upload = imgs->bitmap_id != state->last_bitmap_id;
*out_need_reallocate = false;
- int change_state = imgs->changed;
+ state->last_bitmap_pos_id = imgs->bitmap_pos_id;
+ state->last_bitmap_id = imgs->bitmap_id;
// eosd_reinit() was probably called, force full reupload.
if (state->targets_count == 0 && img)
- change_state = 2;
+ *out_need_upload = true;
- if (change_state == 0)
+ if (!(*out_need_reposition) && !(*out_need_upload))
return; // Nothing changed, no need to redraw
state->targets_count = 0;
@@ -167,7 +168,7 @@ void eosd_packer_generate(struct eosd_packer *state, mp_eosd_images_t *imgs,
if (!img)
return; // There's nothing to render!
- if (change_state == 1)
+ if (!(*out_need_upload))
goto eosd_skip_upload;
*out_need_upload = true;
diff --git a/libvo/eosd_packer.h b/libvo/eosd_packer.h
index eaacd0223f..228057d3c4 100644
--- a/libvo/eosd_packer.h
+++ b/libvo/eosd_packer.h
@@ -58,6 +58,8 @@ struct eosd_packer {
uint32_t max_surface_height;
int *scratch;
+ int last_bitmap_id;
+ int last_bitmap_pos_id;
};
struct eosd_packer *eosd_packer_create(void *talloc_ctx);
diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c
index d9b59c7dbe..922ec24201 100644
--- a/libvo/vo_vdpau.c
+++ b/libvo/vo_vdpau.c
@@ -186,6 +186,8 @@ struct vdpctx {
} *eosd_targets, osd_targets[MAX_OLD_OSD_BITMAPS][2];
int eosd_targets_size;
int eosd_render_count;
+ int bitmap_id;
+ int bitmap_pos_id;
// Video equalizer
struct mp_csp_equalizer video_eq;
@@ -812,6 +814,7 @@ static void mark_vdpau_objects_uninitialized(struct vo *vo)
vc->vdp_device = VDP_INVALID_HANDLE;
talloc_free(vc->osd_surface.packer);
talloc_free(vc->eosd_surface.packer);
+ vc->bitmap_id = vc->bitmap_pos_id = 0;
vc->osd_surface = vc->eosd_surface = (struct eosd_bitmap_surface){
.surface = VDP_INVALID_HANDLE,
};
@@ -999,7 +1002,7 @@ static void generate_eosd(struct vo *vo, mp_eosd_images_t *imgs)
struct eosd_bitmap_surface *sfc = &vc->eosd_surface;
bool need_upload = false;
- if (imgs->changed == 0 && sfc->packer)
+ if (imgs->bitmap_pos_id == vc->bitmap_pos_id)
return; // Nothing changed and we still have the old data
vc->eosd_render_count = 0;
@@ -1007,7 +1010,7 @@ static void generate_eosd(struct vo *vo, mp_eosd_images_t *imgs)
if (!imgs->imgs)
return; // There's nothing to render!
- if (imgs->changed == 1)
+ if (imgs->bitmap_id == vc->bitmap_id)
goto eosd_skip_upload;
need_upload = true;
@@ -1069,6 +1072,8 @@ eosd_skip_upload:
target->dest.y1 = p->h + p->dst_y;
vc->eosd_render_count++;
}
+ vc->bitmap_id = imgs->bitmap_id;
+ vc->bitmap_pos_id = imgs->bitmap_pos_id;
}
static void record_osd(void *ctx, int x0, int y0, int w, int h,
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index c710ff575a..3278c10d85 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -45,7 +45,7 @@ void sub_init(struct sh_sub *sh, struct osd_state *osd)
if (sh->sd_driver->init(sh, osd) < 0)
return;
osd->sh_sub = sh;
- osd->changed_outside_sd = true;
+ osd->bitmap_id = ++osd->bitmap_pos_id;
sh->initialized = true;
sh->active = true;
}
@@ -62,16 +62,23 @@ void sub_get_bitmaps(struct osd_state *osd, struct sub_bitmaps *res)
{
struct MPOpts *opts = osd->opts;
- *res = (struct sub_bitmaps){.imgs = NULL, .changed = 2};
+ *res = (struct sub_bitmaps){ .bitmap_id = osd->bitmap_id,
+ .bitmap_pos_id = osd->bitmap_pos_id };
if (!opts->sub_visibility || !osd->sh_sub || !osd->sh_sub->active) {
- osd->changed_outside_sd = true;
+ /* Change ID in case we just switched from visible subtitles
+ * to current state. Hopefully, unnecessarily claiming that
+ * things may have changed is harmless for empty contents.
+ * Increase osd-> values ahead so that _next_ returned id
+ * is also guaranteed to differ from this one.
+ */
+ res->bitmap_id = ++res->bitmap_pos_id;
+ osd->bitmap_id = osd->bitmap_pos_id += 2;
return;
}
if (osd->sh_sub->sd_driver->get_bitmaps)
osd->sh_sub->sd_driver->get_bitmaps(osd->sh_sub, osd, res);
- if (osd->changed_outside_sd)
- res->changed = 2;
- osd->changed_outside_sd = false;
+ osd->bitmap_id = res->bitmap_id;
+ osd->bitmap_pos_id = res->bitmap_pos_id;
}
void sub_reset(struct sh_sub *sh, struct osd_state *osd)
diff --git a/sub/dec_sub.h b/sub/dec_sub.h
index f09b555685..ae39f15f31 100644
--- a/sub/dec_sub.h
+++ b/sub/dec_sub.h
@@ -12,7 +12,7 @@ typedef struct mp_eosd_res {
typedef struct sub_bitmaps {
struct ass_image *imgs;
- int changed;
+ int bitmap_id, bitmap_pos_id;
} mp_eosd_images_t;
static inline bool is_text_sub(int type)
diff --git a/sub/sd_ass.c b/sub/sd_ass.c
index 72dee06018..67bbd4665e 100644
--- a/sub/sd_ass.c
+++ b/sub/sd_ass.c
@@ -140,8 +140,13 @@ static void get_bitmaps(struct sh_sub *sh, struct osd_state *osd,
ASS_Renderer *renderer = osd->ass_renderer;
mp_ass_configure(renderer, opts, &osd->dim, osd->unscaled);
ass_set_aspect_ratio(renderer, scale, 1);
+ int changed;
res->imgs = ass_render_frame(renderer, ctx->ass_track,
- osd->sub_pts * 1000 + .5, &res->changed);
+ osd->sub_pts * 1000 + .5, &changed);
+ if (changed == 2)
+ res->bitmap_id = ++res->bitmap_pos_id;
+ else if (changed)
+ res->bitmap_pos_id++;
}
static void reset(struct sh_sub *sh, struct osd_state *osd)
diff --git a/sub/sub.h b/sub/sub.h
index 8a8a2ab941..05c89af565 100644
--- a/sub/sub.h
+++ b/sub/sub.h
@@ -63,7 +63,8 @@ struct osd_state {
struct ass_library *ass_library;
struct ass_renderer *ass_renderer;
struct sh_sub *sh_sub;
- bool changed_outside_sd;
+ int bitmap_id;
+ int bitmap_pos_id;
double sub_pts;
double sub_offset;
struct mp_eosd_res dim;