summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
Diffstat (limited to 'sub')
-rw-r--r--sub/osd.c184
-rw-r--r--sub/osd.h119
-rw-r--r--sub/osd_dummy.c2
-rw-r--r--sub/osd_libass.c38
-rw-r--r--sub/osd_state.h68
5 files changed, 285 insertions, 126 deletions
diff --git a/sub/osd.c b/sub/osd.c
index 56d845b97f..69ba554890 100644
--- a/sub/osd.c
+++ b/sub/osd.c
@@ -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
diff --git a/sub/osd.h b/sub/osd.h
index 17e8a02c08..239286c5e6 100644
--- a/sub/osd.h
+++ b/sub/osd.h
@@ -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