diff options
Diffstat (limited to 'sub')
-rw-r--r-- | sub/osd.c | 184 | ||||
-rw-r--r-- | sub/osd.h | 119 | ||||
-rw-r--r-- | sub/osd_dummy.c | 2 | ||||
-rw-r--r-- | sub/osd_libass.c | 38 | ||||
-rw-r--r-- | sub/osd_state.h | 68 |
5 files changed, 285 insertions, 126 deletions
@@ -34,6 +34,7 @@ #include "common/global.h" #include "common/msg.h" #include "osd.h" +#include "osd_state.h" #include "dec_sub.h" #include "img_convert.h" #include "draw_bmp.h" @@ -87,15 +88,15 @@ struct osd_state *osd_create(struct mpv_global *global) .opts = global->opts, .global = global, .log = mp_log_new(osd, global->log, "osd"), - .osd_text = talloc_strdup(osd, ""), - .progbar_type = -1, }; + pthread_mutex_init(&osd->lock, NULL); for (int n = 0; n < MAX_OSD_PARTS; n++) { struct osd_object *obj = talloc(osd, struct osd_object); *obj = (struct osd_object) { .type = n, - .sub_text = talloc_strdup(obj, ""), + .text = talloc_strdup(obj, ""), + .progbar_state = {.type = -1}, }; for (int i = 0; i < OSD_CONV_CACHE_MAX; i++) obj->cache[i] = talloc_steal(obj, osd_conv_cache_new()); @@ -114,30 +115,102 @@ void osd_free(struct osd_state *osd) if (!osd) return; osd_destroy_backend(osd); + pthread_mutex_destroy(&osd->lock); talloc_free(osd); } -static bool set_text(void *talloc_ctx, char **var, const char *text) +static void osd_changed_unlocked(struct osd_state *osd, int obj) { + osd->objs[obj]->force_redraw = true; + osd->want_redraw = true; +} + +void osd_set_text(struct osd_state *osd, int obj, const char *text) +{ + pthread_mutex_lock(&osd->lock); + struct osd_object *osd_obj = osd->objs[obj]; if (!text) text = ""; - if (strcmp(*var, text) == 0) - return true; - talloc_free(*var); - *var = talloc_strdup(talloc_ctx, text); - return false; + if (strcmp(osd_obj->text, text) != 0) { + talloc_free(osd_obj->text); + osd_obj->text = talloc_strdup(osd_obj, text); + osd_changed_unlocked(osd, obj); + } + pthread_mutex_unlock(&osd->lock); +} + +void osd_set_sub(struct osd_state *osd, int obj, struct osd_sub_state *substate) +{ + pthread_mutex_lock(&osd->lock); + osd->objs[obj]->sub_state = substate ? *substate : (struct osd_sub_state){0}; + pthread_mutex_unlock(&osd->lock); +} + +void osd_get_sub(struct osd_state *osd, int obj, struct osd_sub_state *substate) +{ + pthread_mutex_lock(&osd->lock); + *substate = osd->objs[obj]->sub_state; + pthread_mutex_unlock(&osd->lock); } -void osd_set_text(struct osd_state *osd, const char *text) +bool osd_get_render_subs_in_filter(struct osd_state *osd) { - if (!set_text(osd, &osd->osd_text, text)) - osd_changed(osd, OSDTYPE_OSD); + pthread_mutex_lock(&osd->lock); + bool r = osd->render_subs_in_filter; + pthread_mutex_unlock(&osd->lock); + return r; +} + +void osd_set_render_subs_in_filter(struct osd_state *osd, bool s) +{ + pthread_mutex_lock(&osd->lock); + osd->render_subs_in_filter = s; + pthread_mutex_unlock(&osd->lock); +} + +void osd_set_progbar(struct osd_state *osd, struct osd_progbar_state *s) +{ + pthread_mutex_lock(&osd->lock); + struct osd_object *osd_obj = osd->objs[OSDTYPE_PROGBAR]; + osd_obj->progbar_state.type = s->type; + osd_obj->progbar_state.value = s->value; + osd_obj->progbar_state.num_stops = s->num_stops; + MP_TARRAY_GROW(osd_obj, osd_obj->progbar_state.stops, s->num_stops); + memcpy(osd_obj->progbar_state.stops, s->stops, + sizeof(osd_obj->progbar_state.stops[0]) * s->num_stops); + osd_changed_unlocked(osd, osd_obj->type); + pthread_mutex_unlock(&osd->lock); +} + +void osd_set_external(struct osd_state *osd, int res_x, int res_y, char *text) +{ + pthread_mutex_lock(&osd->lock); + struct osd_object *osd_obj = osd->objs[OSDTYPE_EXTERNAL]; + if (strcmp(osd_obj->text, text) != 0 || + osd_obj->external_res_x != res_x || + osd_obj->external_res_y != res_y) + { + talloc_free(osd_obj->text); + osd_obj->text = talloc_strdup(osd_obj, text); + osd_obj->external_res_x = res_x; + osd_obj->external_res_y = res_y; + osd_changed_unlocked(osd, osd_obj->type); + } + pthread_mutex_unlock(&osd->lock); } -void osd_set_sub(struct osd_state *osd, struct osd_object *obj, const char *text) +void osd_set_external2(struct osd_state *osd, struct sub_bitmaps *imgs) { - if (!set_text(obj, &obj->sub_text, text)) - osd_changed(osd, obj->type); + pthread_mutex_lock(&osd->lock); + osd->objs[OSDTYPE_EXTERNAL2]->external2 = imgs; + pthread_mutex_unlock(&osd->lock); +} + +void osd_set_nav_highlight(struct osd_state *osd, void *priv) +{ + pthread_mutex_lock(&osd->lock); + osd->objs[OSDTYPE_NAV_HIGHLIGHT]->highlight_priv = priv; + pthread_mutex_unlock(&osd->lock); } static void render_object(struct osd_state *osd, struct osd_object *obj, @@ -159,21 +232,23 @@ static void render_object(struct osd_state *osd, struct osd_object *obj, obj->vo_res = res; if (obj->type == OSDTYPE_SUB || obj->type == OSDTYPE_SUB2) { - if (obj->render_bitmap_subs && obj->dec_sub) { + struct osd_sub_state *sub = &obj->sub_state; + if (sub->render_bitmap_subs && sub->dec_sub) { double sub_pts = video_pts; if (sub_pts != MP_NOPTS_VALUE) - sub_pts -= obj->video_offset + opts->sub_delay; - sub_get_bitmaps(obj->dec_sub, obj->vo_res, sub_pts, out_imgs); + sub_pts -= sub->video_offset + opts->sub_delay; + sub_get_bitmaps(sub->dec_sub, obj->vo_res, sub_pts, out_imgs); } else { osd_object_get_bitmaps(osd, obj, out_imgs); } } else if (obj->type == OSDTYPE_EXTERNAL2) { - if (osd->external2.format) { - *out_imgs = osd->external2; - osd->external2.bitmap_id = osd->external2.bitmap_pos_id = 0; + if (obj->external2 && obj->external2->format) { + *out_imgs = *obj->external2; + obj->external2->bitmap_id = obj->external2->bitmap_pos_id = 0; } } else if (obj->type == OSDTYPE_NAV_HIGHLIGHT) { - mp_nav_get_highlight(osd, obj->vo_res, out_imgs); + if (obj->highlight_priv) + mp_nav_get_highlight(osd, obj->vo_res, out_imgs); } else { osd_object_get_bitmaps(osd, obj, out_imgs); } @@ -230,12 +305,11 @@ void osd_draw(struct osd_state *osd, struct mp_osd_res res, const bool formats[SUBBITMAP_COUNT], void (*cb)(void *ctx, struct sub_bitmaps *imgs), void *cb_ctx) { + pthread_mutex_lock(&osd->lock); + if (draw_flags & OSD_DRAW_SUB_FILTER) draw_flags |= OSD_DRAW_SUB_ONLY; - if (!(draw_flags & OSD_DRAW_SUB_ONLY)) - osd->last_vo_res = res; - for (int n = 0; n < MAX_OSD_PARTS; n++) { struct osd_object *obj = osd->objs[n]; @@ -246,8 +320,8 @@ void osd_draw(struct osd_state *osd, struct mp_osd_res res, if ((draw_flags & OSD_DRAW_SUB_ONLY) && !obj->is_sub) continue; - if (obj->dec_sub) - sub_lock(obj->dec_sub); + if (obj->sub_state.dec_sub) + sub_lock(obj->sub_state.dec_sub); struct sub_bitmaps imgs; render_object(osd, obj, res, video_pts, formats, &imgs); @@ -260,9 +334,11 @@ void osd_draw(struct osd_state *osd, struct mp_osd_res res, } } - if (obj->dec_sub) - sub_unlock(obj->dec_sub); + if (obj->sub_state.dec_sub) + sub_unlock(obj->sub_state.dec_sub); } + + pthread_mutex_unlock(&osd->lock); } struct draw_on_image_closure { @@ -311,11 +387,9 @@ void osd_draw_on_image_p(struct osd_state *osd, struct mp_osd_res res, void osd_changed(struct osd_state *osd, int new_value) { - for (int n = 0; n < MAX_OSD_PARTS; n++) { - if (osd->objs[n]->type == new_value) - osd->objs[n]->force_redraw = true; - } - osd->want_redraw = true; + pthread_mutex_lock(&osd->lock); + osd_changed_unlocked(osd, new_value); + pthread_mutex_unlock(&osd->lock); } void osd_changed_all(struct osd_state *osd) @@ -324,15 +398,41 @@ void osd_changed_all(struct osd_state *osd) osd_changed(osd, n); } +bool osd_query_and_reset_want_redraw(struct osd_state *osd) +{ + pthread_mutex_lock(&osd->lock); + bool r = osd->want_redraw; + osd->want_redraw = false; + pthread_mutex_unlock(&osd->lock); + return r; +} + +double osd_get_vo_pts(struct osd_state *osd) +{ + pthread_mutex_lock(&osd->lock); + double r = osd->vo_pts; + pthread_mutex_unlock(&osd->lock); + return r; +} + +void osd_set_vo_pts(struct osd_state *osd, double vo_pts) +{ + pthread_mutex_lock(&osd->lock); + osd->vo_pts = vo_pts; + pthread_mutex_unlock(&osd->lock); +} + // Scale factor to translate OSD coordinates to what the obj uses internally. // osd_coordinates * (sw, sh) = obj_coordinates -void osd_object_get_scale_factor(struct osd_state *osd, struct osd_object *obj, +void osd_object_get_scale_factor(struct osd_state *osd, int obj, double *sw, double *sh) { int nw, nh; osd_object_get_resolution(osd, obj, &nw, &nh); - *sw = nw / (double)obj->vo_res.w; - *sh = nh / (double)obj->vo_res.h; + pthread_mutex_lock(&osd->lock); + *sw = nw / (double)osd->objs[obj]->vo_res.w; + *sh = nh / (double)osd->objs[obj]->vo_res.h; + pthread_mutex_unlock(&osd->lock); } // Turn *x and *y, which are given in OSD coordinates, to video coordinates. @@ -342,6 +442,7 @@ void osd_object_get_scale_factor(struct osd_state *osd, struct osd_object *obj, void osd_coords_to_video(struct osd_state *osd, int frame_w, int frame_h, int *x, int *y) { + pthread_mutex_lock(&osd->lock); struct mp_osd_res res = osd->objs[OSDTYPE_OSD]->vo_res; int vidw = res.w - res.ml - res.mr; int vidh = res.h - res.mt - res.mb; @@ -350,6 +451,15 @@ void osd_coords_to_video(struct osd_state *osd, int frame_w, int frame_h, // The OSD size + margins make up the scaled rectangle of the video. *x = (*x - res.ml) / xscale; *y = (*y - res.mt) / yscale; + pthread_mutex_unlock(&osd->lock); +} + +struct mp_osd_res osd_get_vo_res(struct osd_state *osd, int obj) +{ + pthread_mutex_lock(&osd->lock); + struct mp_osd_res res = osd->objs[obj]->vo_res; + pthread_mutex_unlock(&osd->lock); + return res; } // Position the subbitmaps in imgs on the screen. Basically, this fits the @@ -97,70 +97,6 @@ enum mp_osdtype { MAX_OSD_PARTS }; -#define OSD_CONV_CACHE_MAX 4 - -struct osd_object { - int type; // OSDTYPE_* - bool is_sub; - - bool force_redraw; - - // OSDTYPE_SUB - struct dec_sub *dec_sub; - double video_offset; - bool render_bitmap_subs; - char *sub_text; - - // caches for OSD conversion (internal to render_object()) - struct osd_conv_cache *cache[OSD_CONV_CACHE_MAX]; - struct sub_bitmaps cached; - - // VO cache state - int vo_bitmap_id; - int vo_bitmap_pos_id; - struct mp_osd_res vo_res; - - // Internally used by osd_libass.c - struct sub_bitmap *parts_cache; - struct ass_track *osd_track; - struct ass_renderer *osd_render; - struct ass_library *osd_ass_library; -}; - -struct osd_state { - struct osd_object *objs[MAX_OSD_PARTS]; - - double vo_pts; - - bool render_subs_in_filter; - - struct mp_osd_res last_vo_res; - - bool want_redraw; - - // OSDTYPE_OSD - char *osd_text; - // OSDTYPE_PROGBAR - int progbar_type; // <0: disabled, 1-255: symbol, else: no symbol - float progbar_value; // range 0.0-1.0 - float *progbar_stops; // used for chapter indicators (0.0-1.0 each) - int progbar_num_stops; - // OSDTYPE_EXTERNAL - char *external; - int external_res_x, external_res_y; - // OSDTYPE_EXTERNAL2 - struct sub_bitmaps external2; - // OSDTYPE_NAV_HIGHLIGHT - void *highlight_priv; - - struct MPOpts *opts; - struct mpv_global *global; - struct mp_log *log; - - // Internal to sub.c - struct mp_draw_sub_cache *draw_cache; -}; - // Start of OSD symbols in osd_font.pfb #define OSD_CODEPOINTS 0xE000 @@ -204,13 +140,47 @@ struct osd_style_opts { extern const struct m_sub_options osd_style_conf; +struct osd_state; +struct osd_object; +struct mpv_global; + struct osd_state *osd_create(struct mpv_global *global); -void osd_set_text(struct osd_state *osd, const char *text); -void osd_set_sub(struct osd_state *osd, struct osd_object *obj, const char *text); void osd_changed(struct osd_state *osd, int new_value); void osd_changed_all(struct osd_state *osd); void osd_free(struct osd_state *osd); +bool osd_query_and_reset_want_redraw(struct osd_state *osd); + +double osd_get_vo_pts(struct osd_state *osd); +void osd_set_vo_pts(struct osd_state *osd, double vo_pts); + +void osd_set_text(struct osd_state *osd, int obj, const char *text); + +struct osd_sub_state { + struct dec_sub *dec_sub; + double video_offset; + bool render_bitmap_subs; +}; +void osd_set_sub(struct osd_state *osd, int obj, struct osd_sub_state *substate); +void osd_get_sub(struct osd_state *osd, int obj, struct osd_sub_state *substate); + +bool osd_get_render_subs_in_filter(struct osd_state *osd); +void osd_set_render_subs_in_filter(struct osd_state *osd, bool s); + +struct osd_progbar_state { + int type; // <0: disabled, 1-255: symbol, else: no symbol + float value; // range 0.0-1.0 + float *stops; // used for chapter indicators (0.0-1.0 each) + int num_stops; +}; +void osd_set_progbar(struct osd_state *osd, struct osd_progbar_state *s); + +void osd_set_external(struct osd_state *osd, int res_x, int res_y, char *text); + +void osd_set_external2(struct osd_state *osd, struct sub_bitmaps *imgs); + +void osd_set_nav_highlight(struct osd_state *osd, void *priv); + enum mp_osd_draw_flags { OSD_DRAW_SUB_FILTER = (1 << 0), OSD_DRAW_SUB_ONLY = (1 << 1), @@ -230,27 +200,34 @@ void osd_draw_on_image_p(struct osd_state *osd, struct mp_osd_res res, double video_pts, int draw_flags, struct mp_image_pool *pool, struct mp_image *dest); -void osd_object_get_scale_factor(struct osd_state *osd, struct osd_object *obj, +void osd_object_get_scale_factor(struct osd_state *osd, int obj, double *sw, double *sh); void osd_coords_to_video(struct osd_state *osd, int frame_w, int frame_h, int *x, int *y); +struct mp_osd_res osd_get_vo_res(struct osd_state *osd, int obj); + void osd_rescale_bitmaps(struct sub_bitmaps *imgs, int frame_w, int frame_h, struct mp_osd_res res, double compensate_par); // defined in osd_libass.c and osd_dummy.c +// internal use only void osd_object_get_bitmaps(struct osd_state *osd, struct osd_object *obj, struct sub_bitmaps *out_imgs); -void osd_object_get_resolution(struct osd_state *osd, struct osd_object *obj, - int *out_w, int *out_h); -void osd_get_function_sym(char *buffer, size_t buffer_size, int osd_function); void osd_init_backend(struct osd_state *osd); void osd_destroy_backend(struct osd_state *osd); +// doesn't need locking +void osd_get_function_sym(char *buffer, size_t buffer_size, int osd_function); + +// defined in backend, but locks if required +void osd_object_get_resolution(struct osd_state *osd, int obj, + int *out_w, int *out_h); + // defined in player -void mp_nav_get_highlight(struct osd_state *osd, struct mp_osd_res res, +void mp_nav_get_highlight(void *priv, struct mp_osd_res res, struct sub_bitmaps *out_imgs); #endif /* MPLAYER_SUB_H */ diff --git a/sub/osd_dummy.c b/sub/osd_dummy.c index cc2ba37377..6fc78ab368 100644 --- a/sub/osd_dummy.c +++ b/sub/osd_dummy.c @@ -24,7 +24,7 @@ void osd_object_get_bitmaps(struct osd_state *osd, struct osd_object *obj, *out_imgs = (struct sub_bitmaps) {0}; } -void osd_object_get_resolution(struct osd_state *osd, struct osd_object *obj, +void osd_object_get_resolution(struct osd_state *osd, int obj, int *out_w, int *out_h) { *out_w = 0; diff --git a/sub/osd_libass.c b/sub/osd_libass.c index fb50dce9cd..90807fa60a 100644 --- a/sub/osd_libass.c +++ b/sub/osd_libass.c @@ -29,6 +29,7 @@ #include "common/common.h" #include "common/msg.h" #include "osd.h" +#include "osd_state.h" static const char osd_font_pfb[] = #include "sub/osd_font.h" @@ -193,7 +194,7 @@ static void update_osd(struct osd_state *osd, struct osd_object *obj) create_ass_track(osd, obj, 0, 0); clear_obj(obj); - if (!osd->osd_text[0]) + if (!obj->text[0]) return; struct osd_style_opts font = *opts->osd_style; @@ -207,7 +208,7 @@ static void update_osd(struct osd_state *osd, struct osd_object *obj) ASS_Style *style = obj->osd_track->styles + obj->osd_track->default_style; mp_ass_set_style(style, playresy, &font); - add_osd_ass_event_escaped(obj->osd_track, osd->osd_text); + add_osd_ass_event_escaped(obj->osd_track, obj->text); } // align: -1 .. +1 @@ -322,7 +323,7 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj) clear_obj(obj); - if (osd->progbar_type < 0) + if (obj->progbar_state.type < 0) return; float sx = px - border * 2 - height / 4; // includes additional spacing @@ -330,13 +331,13 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj) bstr buf = bstr0(talloc_asprintf(NULL, "{\\an6\\pos(%f,%f)}", sx, sy)); - if (osd->progbar_type == 0 || osd->progbar_type >= 256) { + if (obj->progbar_state.type == 0 || obj->progbar_state.type >= 256) { // no sym - } else if (osd->progbar_type >= 32) { - mp_append_utf8_bstr(NULL, &buf, osd->progbar_type); + } else if (obj->progbar_state.type >= 32) { + mp_append_utf8_bstr(NULL, &buf, obj->progbar_state.type); } else { bstr_xappend(NULL, &buf, bstr0(ASS_USE_OSD_FONT)); - mp_append_utf8_bstr(NULL, &buf, OSD_CODEPOINTS + osd->progbar_type); + mp_append_utf8_bstr(NULL, &buf, OSD_CODEPOINTS + obj->progbar_state.type); bstr_xappend(NULL, &buf, bstr0("{\\r}")); } @@ -347,7 +348,7 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj) // filled area d->text = talloc_asprintf_append(d->text, "{\\bord0\\pos(%f,%f)}", px, py); ass_draw_start(d); - float pos = osd->progbar_value * width - border / 2; + float pos = obj->progbar_state.value * width - border / 2; ass_draw_rect_cw(d, 0, 0, pos, height); ass_draw_stop(d); add_osd_ass_event(obj->osd_track, d->text); @@ -373,8 +374,8 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj) ass_draw_rect_ccw(d, 0, 0, width, height); // chapter marks - for (int n = 0; n < osd->progbar_num_stops; n++) { - float s = osd->progbar_stops[n] * width; + for (int n = 0; n < obj->progbar_state.num_stops; n++) { + float s = obj->progbar_state.stops[n] * width; float dent = border * 1.3; if (s > dent && s < width - dent) { @@ -395,10 +396,10 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj) static void update_external(struct osd_state *osd, struct osd_object *obj) { - create_ass_track(osd, obj, osd->external_res_x, osd->external_res_y); + create_ass_track(osd, obj, obj->external_res_x, obj->external_res_y); clear_obj(obj); - bstr t = bstr0(osd->external); + bstr t = bstr0(obj->text); while (t.len) { bstr line; bstr_split_tok(t, "\n", &line, &t); @@ -416,7 +417,7 @@ static void update_sub(struct osd_state *osd, struct osd_object *obj) clear_obj(obj); - if (!obj->sub_text || !obj->sub_text[0] || obj->render_bitmap_subs) + if (!obj->text || !obj->text[0] || obj->sub_state.render_bitmap_subs) return; create_ass_renderer(osd, obj); @@ -435,7 +436,7 @@ static void update_sub(struct osd_state *osd, struct osd_object *obj) ass_set_line_position(obj->osd_render, 100 - opts->sub_pos); #endif - add_osd_ass_event_escaped(obj->osd_track, obj->sub_text); + add_osd_ass_event_escaped(obj->osd_track, obj->text); } static void update_object(struct osd_state *osd, struct osd_object *obj) @@ -474,9 +475,12 @@ void osd_object_get_bitmaps(struct osd_state *osd, struct osd_object *obj, talloc_steal(obj, obj->parts_cache); } -void osd_object_get_resolution(struct osd_state *osd, struct osd_object *obj, +void osd_object_get_resolution(struct osd_state *osd, int obj, int *out_w, int *out_h) { - *out_w = obj->osd_track ? obj->osd_track->PlayResX : 0; - *out_h = obj->osd_track ? obj->osd_track->PlayResY : 0; + pthread_mutex_lock(&osd->lock); + struct osd_object *osd_obj = osd->objs[obj]; + *out_w = osd_obj->osd_track ? osd_obj->osd_track->PlayResX : 0; + *out_h = osd_obj->osd_track ? osd_obj->osd_track->PlayResY : 0; + pthread_mutex_unlock(&osd->lock); } diff --git a/sub/osd_state.h b/sub/osd_state.h new file mode 100644 index 0000000000..55e484e3e0 --- /dev/null +++ b/sub/osd_state.h @@ -0,0 +1,68 @@ +#ifndef MP_OSD_STATE_H_ +#define MP_OSD_STATE_H_ + +#include <pthread.h> + +#include "osd.h" + +#define OSD_CONV_CACHE_MAX 4 + +struct osd_object { + int type; // OSDTYPE_* + bool is_sub; + + bool force_redraw; + + // OSDTYPE_SUB/OSDTYPE_SUB2/OSDTYPE_OSD/OSDTYPE_EXTERNAL + char *text; + + // OSDTYPE_PROGBAR + struct osd_progbar_state progbar_state; + + // OSDTYPE_SUB/OSDTYPE_SUB2 + struct osd_sub_state sub_state; + + // OSDTYPE_EXTERNAL + int external_res_x, external_res_y; + + // OSDTYPE_EXTERNAL2 + struct sub_bitmaps *external2; + + // OSDTYPE_NAV_HIGHLIGHT + void *highlight_priv; + + // caches for OSD conversion (internal to render_object()) + struct osd_conv_cache *cache[OSD_CONV_CACHE_MAX]; + struct sub_bitmaps cached; + + // VO cache state + int vo_bitmap_id; + int vo_bitmap_pos_id; + struct mp_osd_res vo_res; + + // Internally used by osd_libass.c + struct sub_bitmap *parts_cache; + struct ass_track *osd_track; + struct ass_renderer *osd_render; + struct ass_library *osd_ass_library; +}; + +struct osd_state { + pthread_mutex_t lock; + + struct osd_object *objs[MAX_OSD_PARTS]; + + double vo_pts; + + bool render_subs_in_filter; + + bool want_redraw; + + struct MPOpts *opts; + struct mpv_global *global; + struct mp_log *log; + + struct mp_draw_sub_cache *draw_cache; +}; + +#endif |