summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-01-18 01:19:20 +0100
committerwm4 <wm4@nowhere>2014-01-18 01:27:43 +0100
commit7f4a09bb8534dfafd83099d773adf2e33c64e267 (patch)
tree5b75791151f92e164fbd9badee47590d1164683d /player
parent92a9f11a0b4fda60c8880014be5920dcf3e95253 (diff)
downloadmpv-7f4a09bb8534dfafd83099d773adf2e33c64e267.tar.bz2
mpv-7f4a09bb8534dfafd83099d773adf2e33c64e267.tar.xz
sub: uglify OSD code path with locking
Do two things: 1. add locking to struct osd_state 2. make struct osd_state opaque While 1. is somewhat simple, 2. is quite horrible. Lots of code accesses lots of osd_state (and osd_object) members. To make sure everything is accessed synchronously, I prefer making osd_state opaque, even if it means adding pretty dumb accessors. All of this is meant to allow running VO in their own threads. Eventually, VOs will request OSD on their own, which means osd_state will be accessed from foreign threads.
Diffstat (limited to 'player')
-rw-r--r--player/command.c58
-rw-r--r--player/core.h2
-rw-r--r--player/dvdnav.c39
-rw-r--r--player/loadfile.c3
-rw-r--r--player/lua.c31
-rw-r--r--player/osd.c36
-rw-r--r--player/playloop.c9
-rw-r--r--player/screenshot.c6
-rw-r--r--player/sub.c38
-rw-r--r--player/video.c4
10 files changed, 119 insertions, 107 deletions
diff --git a/player/command.c b/player/command.c
index 2334e844b4..bb0e9789cf 100644
--- a/player/command.c
+++ b/player/command.c
@@ -87,6 +87,7 @@ struct command_ctx {
#define OVERLAY_MAX_ID 64
void *overlay_map[OVERLAY_MAX_ID];
+ struct sub_bitmaps external2;
};
static int edit_filters(struct MPContext *mpctx, enum stream_type mediatype,
@@ -1573,20 +1574,22 @@ static int mp_property_window_scale(m_option_t *prop, int action, void *arg,
static int mp_property_osd_w(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- return m_property_int_ro(prop, action, arg, mpctx->osd->last_vo_res.w);
+ struct mp_osd_res vo_res = osd_get_vo_res(mpctx->osd, OSDTYPE_OSD);
+ return m_property_int_ro(prop, action, arg, vo_res.w);
}
static int mp_property_osd_h(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- return m_property_int_ro(prop, action, arg, mpctx->osd->last_vo_res.w);
+ struct mp_osd_res vo_res = osd_get_vo_res(mpctx->osd, OSDTYPE_OSD);
+ return m_property_int_ro(prop, action, arg, vo_res.w);
}
static int mp_property_osd_par(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- return m_property_double_ro(prop, action, arg,
- mpctx->osd->last_vo_res.display_par);
+ struct mp_osd_res vo_res = osd_get_vo_res(mpctx->osd, OSDTYPE_OSD);
+ return m_property_double_ro(prop, action, arg, vo_res.display_par);
}
/// Video fps (RO)
@@ -2348,7 +2351,7 @@ static int edit_filters_osd(struct MPContext *mpctx, enum stream_type mediatype,
static int ext2_sub_find(struct MPContext *mpctx, int id)
{
struct command_ctx *cmd = mpctx->command_ctx;
- struct sub_bitmaps *sub = &mpctx->osd->external2;
+ struct sub_bitmaps *sub = &cmd->external2;
void *p = NULL;
if (id >= 0 && id < OVERLAY_MAX_ID)
p = cmd->overlay_map[id];
@@ -2363,10 +2366,10 @@ static int ext2_sub_find(struct MPContext *mpctx, int id)
static int ext2_sub_alloc(struct MPContext *mpctx)
{
- struct osd_state *osd = mpctx->osd;
- struct sub_bitmaps *sub = &osd->external2;
+ struct command_ctx *cmd = mpctx->command_ctx;
+ struct sub_bitmaps *sub = &cmd->external2;
struct sub_bitmap b = {0};
- MP_TARRAY_APPEND(osd, sub->parts, sub->num_parts, b);
+ MP_TARRAY_APPEND(cmd, sub->parts, sub->num_parts, b);
return sub->num_parts - 1;
}
@@ -2375,14 +2378,16 @@ static int overlay_add(struct MPContext *mpctx, int id, int x, int y,
int stride)
{
struct command_ctx *cmd = mpctx->command_ctx;
- struct osd_state *osd = mpctx->osd;
+ int r = -1;
+ // Temporarily unmap them to avoid race condition with concurrent access.
+ osd_set_external2(mpctx->osd, NULL);
if (strcmp(fmt, "bgra") != 0) {
MP_ERR(mpctx, "overlay_add: unsupported OSD format '%s'\n", fmt);
- return -1;
+ goto error;
}
if (id < 0 || id >= OVERLAY_MAX_ID) {
MP_ERR(mpctx, "overlay_add: invalid id %d\n", id);
- return -1;
+ goto error;
}
int fd = -1;
bool close_fd = true;
@@ -2400,48 +2405,52 @@ static int overlay_add(struct MPContext *mpctx, int id, int x, int y,
close(fd);
if (!p) {
MP_ERR(mpctx, "overlay_add: could not open or map '%s'\n", file);
- return -1;
+ goto error;
}
int index = ext2_sub_find(mpctx, id);
if (index < 0)
index = ext2_sub_alloc(mpctx);
if (index < 0) {
munmap(p, h * stride);
- return -1;
+ goto error;
}
cmd->overlay_map[id] = p;
- osd->external2.parts[index] = (struct sub_bitmap) {
+ cmd->external2.parts[index] = (struct sub_bitmap) {
.bitmap = p,
.stride = stride,
.x = x, .y = y,
.w = w, .h = h,
.dw = w, .dh = h,
};
- osd->external2.bitmap_id = osd->external2.bitmap_pos_id = 1;
- osd->external2.format = SUBBITMAP_RGBA;
- osd->want_redraw = true;
- return 0;
+ cmd->external2.bitmap_id = cmd->external2.bitmap_pos_id = 1;
+ cmd->external2.format = SUBBITMAP_RGBA;
+ r = 0;
+error:
+ osd_set_external2(mpctx->osd, &cmd->external2);
+ return r;
}
static void overlay_remove(struct MPContext *mpctx, int id)
{
struct command_ctx *cmd = mpctx->command_ctx;
- struct osd_state *osd = mpctx->osd;
+ osd_set_external2(mpctx->osd, NULL);
int index = ext2_sub_find(mpctx, id);
if (index >= 0) {
- struct sub_bitmaps *sub = &osd->external2;
+ struct sub_bitmaps *sub = &cmd->external2;
struct sub_bitmap *part = &sub->parts[index];
munmap(part->bitmap, part->h * part->stride);
MP_TARRAY_REMOVE_AT(sub->parts, sub->num_parts, index);
cmd->overlay_map[id] = NULL;
sub->bitmap_id = sub->bitmap_pos_id = 1;
}
+ osd_set_external2(mpctx->osd, &cmd->external2);
}
static void overlay_uninit(struct MPContext *mpctx)
{
for (int id = 0; id < OVERLAY_MAX_ID; id++)
overlay_remove(mpctx, id);
+ osd_set_external2(mpctx->osd, NULL);
}
#else
@@ -2739,12 +2748,13 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
case MP_CMD_SUB_STEP:
case MP_CMD_SUB_SEEK: {
- struct osd_object *obj = mpctx->osd->objs[OSDTYPE_SUB];
- if (obj->dec_sub) {
+ struct osd_sub_state state;
+ osd_get_sub(mpctx->osd, OSDTYPE_SUB, &state);
+ if (state.dec_sub) {
double a[2];
- a[0] = mpctx->video_pts - obj->video_offset - opts->sub_delay;
+ a[0] = mpctx->video_pts - state.video_offset - opts->sub_delay;
a[1] = cmd->args[0].v.i;
- if (sub_control(obj->dec_sub, SD_CTRL_SUB_STEP, a) > 0) {
+ if (sub_control(state.dec_sub, SD_CTRL_SUB_STEP, a) > 0) {
if (cmd->id == MP_CMD_SUB_STEP) {
opts->sub_delay -= a[0];
osd_changed_all(mpctx->osd);
diff --git a/player/core.h b/player/core.h
index edfdaec2e1..1018ea9df3 100644
--- a/player/core.h
+++ b/player/core.h
@@ -23,6 +23,7 @@
#include "common/common.h"
#include "options/options.h"
+#include "sub/osd.h"
// definitions used internally by the core player code
@@ -158,6 +159,7 @@ typedef struct MPContext {
int osd_function;
double osd_function_visible;
double osd_last_update;
+ struct osd_progbar_state osd_progbar;
struct playlist *playlist;
char *filename; // currently playing file
diff --git a/player/dvdnav.c b/player/dvdnav.c
index 7e28c1922b..fd370599c6 100644
--- a/player/dvdnav.c
+++ b/player/dvdnav.c
@@ -39,8 +39,11 @@ struct mp_nav_state {
bool nav_eof;
bool nav_menu;
bool nav_draining;
+
+ // Accessed by OSD (possibly separate thread)
int hi_visible;
int highlight[4]; // x0 y0 x1 y1
+ int vidsize[2];
int subsize[2];
struct sub_bitmap *hi_elem;
};
@@ -78,6 +81,7 @@ void mp_nav_reset(struct MPContext *mpctx)
return;
struct mp_nav_cmd inp = {MP_NAV_CMD_RESUME};
stream_control(mpctx->stream, STREAM_CTRL_NAV_CMD, &inp);
+ osd_set_nav_highlight(mpctx->osd, NULL);
nav->hi_visible = 0;
nav->nav_menu = false;
nav->nav_draining = false;
@@ -90,6 +94,7 @@ void mp_nav_reset(struct MPContext *mpctx)
void mp_nav_destroy(struct MPContext *mpctx)
{
+ osd_set_nav_highlight(mpctx->osd, NULL);
if (!mpctx->nav_state)
return;
mp_input_disable_section(mpctx->input, "dvdnav");
@@ -164,19 +169,32 @@ void mp_handle_nav(struct MPContext *mpctx)
mp_input_disable_section(mpctx->input, "dvdnav-menu");
}
break;
- case MP_NAV_EVENT_HIGHLIGHT:
+ case MP_NAV_EVENT_HIGHLIGHT: {
MP_VERBOSE(nav, "highlight: %d %d %d - %d %d\n",
ev->u.highlight.display,
ev->u.highlight.sx, ev->u.highlight.sy,
ev->u.highlight.ex, ev->u.highlight.ey);
+ osd_set_nav_highlight(mpctx->osd, NULL);
nav->highlight[0] = ev->u.highlight.sx;
nav->highlight[1] = ev->u.highlight.sy;
nav->highlight[2] = ev->u.highlight.ex;
nav->highlight[3] = ev->u.highlight.ey;
nav->hi_visible = ev->u.highlight.display;
- mpctx->osd->highlight_priv = mpctx;
- osd_changed(mpctx->osd, OSDTYPE_NAV_HIGHLIGHT);
+ int sizes[2] = {0};
+ if (mpctx->d_sub[0])
+ sub_control(mpctx->d_sub[0], SD_CTRL_GET_RESOLUTION, sizes);
+ if (sizes[0] < 1 || sizes[1] < 1) {
+ struct mp_image_params vid = {0};
+ if (mpctx->d_video)
+ vid = mpctx->d_video->decoder_output;
+ sizes[0] = vid.w;
+ sizes[1] = vid.h;
+ }
+ for (int n = 0; n < 2; n++)
+ nav->vidsize[n] = sizes[n];
+ osd_set_nav_highlight(mpctx->osd, mpctx);
break;
+ }
default: ; // ignore
}
talloc_free(ev);
@@ -209,10 +227,10 @@ void mp_handle_nav(struct MPContext *mpctx)
// Note: a proper solution would introduce something like
// SD_CTRL_APPLY_DVDNAV, which would crop the vobsub frame,
// and apply the current CLUT.
-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)
{
- struct MPContext *mpctx = osd->highlight_priv;
+ struct MPContext *mpctx = priv;
struct mp_nav_state *nav = mpctx ? mpctx->nav_state : NULL;
if (!nav)
return;
@@ -221,16 +239,7 @@ void mp_nav_get_highlight(struct osd_state *osd, struct mp_osd_res res,
sub = talloc_zero(nav, struct sub_bitmap);
nav->hi_elem = sub;
- int sizes[2] = {0};
- if (mpctx->d_sub[0])
- sub_control(mpctx->d_sub[0], SD_CTRL_GET_RESOLUTION, sizes);
- if (sizes[0] < 1 || sizes[1] < 1) {
- struct mp_image_params vid = {0};
- if (mpctx->d_video)
- vid = mpctx->d_video->decoder_output;
- sizes[0] = vid.w;
- sizes[1] = vid.h;
- }
+ int sizes[2] = {nav->vidsize[0], nav->vidsize[1]};
if (sizes[0] < 1 || sizes[1] < 1)
return;
if (sizes[0] != nav->subsize[0] || sizes[1] != nav->subsize[1]) {
diff --git a/player/loadfile.c b/player/loadfile.c
index 6262042709..b81da983f8 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -67,7 +67,8 @@ static void uninit_sub(struct MPContext *mpctx, int order)
if (mpctx->d_sub[order])
sub_reset(mpctx->d_sub[order]);
mpctx->d_sub[order] = NULL; // Note: not free'd.
- mpctx->osd->objs[order ? OSDTYPE_SUB2 : OSDTYPE_SUB]->dec_sub = NULL;
+ int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB;
+ osd_set_sub(mpctx->osd, obj, NULL);
reset_subtitles(mpctx, order);
reselect_demux_streams(mpctx);
}
diff --git a/player/lua.c b/player/lua.c
index f77f9d1a7e..ca92aa009d 100644
--- a/player/lua.c
+++ b/player/lua.c
@@ -479,17 +479,7 @@ static int script_set_osd_ass(lua_State *L)
int res_x = luaL_checkinteger(L, 1);
int res_y = luaL_checkinteger(L, 2);
const char *text = luaL_checkstring(L, 3);
- if (!mpctx->osd->external ||
- strcmp(mpctx->osd->external, text) != 0 ||
- mpctx->osd->external_res_x != res_x ||
- mpctx->osd->external_res_y != res_y)
- {
- talloc_free(mpctx->osd->external);
- mpctx->osd->external = talloc_strdup(mpctx->osd, text);
- mpctx->osd->external_res_x = res_x;
- mpctx->osd->external_res_y = res_y;
- osd_changed(mpctx->osd, OSDTYPE_EXTERNAL);
- }
+ osd_set_external(mpctx->osd, res_x, res_y, (char *)text);
return 0;
}
@@ -497,8 +487,7 @@ static int script_get_osd_resolution(lua_State *L)
{
struct MPContext *mpctx = get_mpctx(L);
int w, h;
- osd_object_get_resolution(mpctx->osd, mpctx->osd->objs[OSDTYPE_EXTERNAL],
- &w, &h);
+ osd_object_get_resolution(mpctx->osd, OSDTYPE_EXTERNAL, &w, &h);
lua_pushnumber(L, w);
lua_pushnumber(L, h);
return 2;
@@ -507,11 +496,11 @@ static int script_get_osd_resolution(lua_State *L)
static int script_get_screen_size(lua_State *L)
{
struct MPContext *mpctx = get_mpctx(L);
- struct osd_object *obj = mpctx->osd->objs[OSDTYPE_EXTERNAL];
- double aspect = 1.0 * obj->vo_res.w / MPMAX(obj->vo_res.h, 1) /
- obj->vo_res.display_par;
- lua_pushnumber(L, obj->vo_res.w);
- lua_pushnumber(L, obj->vo_res.h);
+ struct mp_osd_res vo_res = osd_get_vo_res(mpctx->osd, OSDTYPE_EXTERNAL);
+ double aspect = 1.0 * vo_res.w / MPMAX(vo_res.h, 1) /
+ vo_res.display_par;
+ lua_pushnumber(L, vo_res.w);
+ lua_pushnumber(L, vo_res.h);
lua_pushnumber(L, aspect);
return 3;
}
@@ -522,8 +511,7 @@ static int script_get_mouse_pos(lua_State *L)
int px, py;
mp_input_get_mouse_pos(mpctx->input, &px, &py);
double sw, sh;
- osd_object_get_scale_factor(mpctx->osd, mpctx->osd->objs[OSDTYPE_EXTERNAL],
- &sw, &sh);
+ osd_object_get_scale_factor(mpctx->osd, OSDTYPE_EXTERNAL, &sw, &sh);
lua_pushnumber(L, px * sw);
lua_pushnumber(L, py * sh);
return 2;
@@ -652,8 +640,7 @@ static int script_input_set_section_mouse_area(lua_State *L)
struct MPContext *mpctx = get_mpctx(L);
double sw, sh;
- struct osd_object *obj = mpctx->osd->objs[OSDTYPE_EXTERNAL];
- osd_object_get_scale_factor(mpctx->osd, obj, &sw, &sh);
+ osd_object_get_scale_factor(mpctx->osd, OSDTYPE_EXTERNAL, &sw, &sh);
char *section = (char *)luaL_checkstring(L, 1);
int x0 = luaL_checkinteger(L, 2) / sw;
diff --git a/player/osd.c b/player/osd.c
index 8401f75b36..1f15e3ddc7 100644
--- a/player/osd.c
+++ b/player/osd.c
@@ -292,8 +292,8 @@ static mp_osd_msg_t *get_osd_msg(struct MPContext *mpctx)
if (mpctx->osd_visible && now >= mpctx->osd_visible) {
mpctx->osd_visible = 0;
- mpctx->osd->progbar_type = -1; // disable
- osd_changed(mpctx->osd, OSDTYPE_PROGBAR);
+ mpctx->osd_progbar.type = -1; // disable
+ osd_set_progbar(mpctx->osd, &mpctx->osd_progbar);
}
if (mpctx->osd_function_visible && now >= mpctx->osd_function_visible) {
mpctx->osd_function_visible = 0;
@@ -335,10 +335,10 @@ void set_osd_bar(struct MPContext *mpctx, int type, const char *name,
if (mpctx->video_out && opts->term_osd != 1) {
mpctx->osd_visible = mp_time_sec() + opts->osd_duration / 1000.0;
- mpctx->osd->progbar_type = type;
- mpctx->osd->progbar_value = (val - min) / (max - min);
- mpctx->osd->progbar_num_stops = 0;
- osd_changed(mpctx->osd, OSDTYPE_PROGBAR);
+ mpctx->osd_progbar.type = type;
+ mpctx->osd_progbar.value = (val - min) / (max - min);
+ mpctx->osd_progbar.num_stops = 0;
+ osd_set_progbar(mpctx->osd, &mpctx->osd_progbar);
return;
}
@@ -351,20 +351,19 @@ void set_osd_bar(struct MPContext *mpctx, int type, const char *name,
static void update_osd_bar(struct MPContext *mpctx, int type,
double min, double max, double val)
{
- if (mpctx->osd->progbar_type == type) {
+ if (mpctx->osd_progbar.type == type) {
float new_value = (val - min) / (max - min);
- if (new_value != mpctx->osd->progbar_value) {
- mpctx->osd->progbar_value = new_value;
- osd_changed(mpctx->osd, OSDTYPE_PROGBAR);
+ if (new_value != mpctx->osd_progbar.value) {
+ mpctx->osd_progbar.value = new_value;
+ osd_set_progbar(mpctx->osd, &mpctx->osd_progbar);
}
}
}
static void set_osd_bar_chapters(struct MPContext *mpctx, int type)
{
- struct osd_state *osd = mpctx->osd;
- osd->progbar_num_stops = 0;
- if (osd->progbar_type == type) {
+ mpctx->osd_progbar.num_stops = 0;
+ if (mpctx->osd_progbar.type == type) {
double len = get_time_length(mpctx);
if (len > 0) {
int num = get_chapter_count(mpctx);
@@ -372,12 +371,13 @@ static void set_osd_bar_chapters(struct MPContext *mpctx, int type)
double time = chapter_start_time(mpctx, n);
if (time >= 0) {
float pos = time / len;
- MP_TARRAY_APPEND(osd, osd->progbar_stops,
- osd->progbar_num_stops, pos);
+ MP_TARRAY_APPEND(mpctx, mpctx->osd_progbar.stops,
+ mpctx->osd_progbar.num_stops, pos);
}
}
}
}
+ osd_set_progbar(mpctx->osd, &mpctx->osd_progbar);
}
// osd_function is the symbol appearing in the video status, such as OSD_PLAY
@@ -394,7 +394,7 @@ void set_osd_function(struct MPContext *mpctx, int osd_function)
*/
void set_osd_subtitle(struct MPContext *mpctx, const char *text)
{
- osd_set_sub(mpctx->osd, mpctx->osd->objs[OSDTYPE_SUB], text);
+ osd_set_text(mpctx->osd, OSDTYPE_SUB, text);
term_osd_set_subs(mpctx, text);
}
@@ -495,7 +495,7 @@ void update_osd_msg(struct MPContext *mpctx)
// Look if we have a msg
mp_osd_msg_t *msg = get_osd_msg(mpctx);
if (msg && !msg->show_position) {
- osd_set_text(osd, msg->msg);
+ osd_set_text(osd, OSDTYPE_OSD, msg->msg);
term_osd_set_text(mpctx, msg->msg);
return;
}
@@ -510,7 +510,7 @@ void update_osd_msg(struct MPContext *mpctx)
if (osd_level >= 2)
sadd_osd_status(&text, mpctx, osd_level == 3);
- osd_set_text(osd, text);
+ osd_set_text(osd, OSDTYPE_OSD, text);
talloc_free(text);
// always clear (term-osd has separate status line)
diff --git a/player/playloop.c b/player/playloop.c
index 95e9a9c5a4..167a0722a2 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -136,7 +136,7 @@ static void draw_osd(struct MPContext *mpctx)
{
struct vo *vo = mpctx->video_out;
- mpctx->osd->vo_pts = mpctx->video_pts;
+ osd_set_vo_pts(mpctx->osd, mpctx->video_pts);
vo_draw_osd(vo, mpctx->osd);
}
@@ -646,10 +646,9 @@ static bool handle_osd_redraw(struct MPContext *mpctx)
{
if (!mpctx->video_out || !mpctx->video_out->config_ok)
return false;
- bool want_redraw = vo_get_want_redraw(mpctx->video_out);
- if (mpctx->video_out->driver->draw_osd)
- want_redraw |= mpctx->osd->want_redraw;
- mpctx->osd->want_redraw = false;
+ bool want_redraw = vo_get_want_redraw(mpctx->video_out) |
+ (osd_query_and_reset_want_redraw(mpctx->osd) &&
+ mpctx->video_out->driver->draw_osd);
if (want_redraw) {
if (redraw_osd(mpctx))
return true;
diff --git a/player/screenshot.c b/player/screenshot.c
index d5a6b1b3d0..9b8922c39a 100644
--- a/player/screenshot.c
+++ b/player/screenshot.c
@@ -307,7 +307,7 @@ static void add_subs(struct MPContext *mpctx, struct mp_image *image)
.display_par = sar / dar,
};
- osd_draw_on_image(mpctx->osd, res, mpctx->osd->vo_pts,
+ osd_draw_on_image(mpctx->osd, res, osd_get_vo_pts(mpctx->osd),
OSD_DRAW_SUB_ONLY, image);
}
@@ -330,7 +330,7 @@ static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode)
{
struct mp_image *image = NULL;
if (mpctx->video_out && mpctx->video_out->config_ok) {
- if (mode == MODE_SUBTITLES && mpctx->osd->render_subs_in_filter)
+ if (mode == MODE_SUBTITLES && osd_get_render_subs_in_filter(mpctx->osd))
mode = 0;
struct voctrl_screenshot_args args =
@@ -386,7 +386,7 @@ void screenshot_request(struct MPContext *mpctx, int mode, bool each_frame,
{
screenshot_ctx *ctx = mpctx->screenshot_ctx;
- if (mode == MODE_SUBTITLES && mpctx->osd->render_subs_in_filter)
+ if (mode == MODE_SUBTITLES && osd_get_render_subs_in_filter(mpctx->osd))
mode = 0;
if (each_frame) {
diff --git a/player/sub.c b/player/sub.c
index 6d39ef2299..00b2260c67 100644
--- a/player/sub.c
+++ b/player/sub.c
@@ -68,12 +68,11 @@ static bool is_interleaved(struct MPContext *mpctx, struct track *track)
void reset_subtitles(struct MPContext *mpctx, int order)
{
- struct osd_object *osd_obj =
- mpctx->osd->objs[order ? OSDTYPE_SUB2 : OSDTYPE_SUB];
+ int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB;
if (mpctx->d_sub[order])
sub_reset(mpctx->d_sub[order]);
set_osd_subtitle(mpctx, NULL);
- osd_set_sub(mpctx->osd, osd_obj, NULL);
+ osd_set_text(mpctx->osd, obj, NULL);
}
static void update_subtitle(struct MPContext *mpctx, int order)
@@ -90,8 +89,7 @@ static void update_subtitle(struct MPContext *mpctx, int order)
struct track *track = mpctx->current_track[order][STREAM_SUB];
struct dec_sub *dec_sub = mpctx->d_sub[order];
assert(track && dec_sub);
- struct osd_object *osd_obj
- = mpctx->osd->objs[order ? OSDTYPE_SUB2 : OSDTYPE_SUB];
+ int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB;
if (mpctx->d_video) {
struct mp_image_params params = mpctx->d_video->vf_input;
@@ -99,9 +97,14 @@ static void update_subtitle(struct MPContext *mpctx, int order)
sub_control(dec_sub, SD_CTRL_SET_VIDEO_PARAMS, &params);
}
- osd_obj->video_offset = track->under_timeline ? mpctx->video_offset : 0;
+ struct osd_sub_state state;
+ osd_get_sub(mpctx->osd, obj, &state);
- double refpts_s = mpctx->playback_pts - osd_obj->video_offset;
+ state.video_offset = track->under_timeline ? mpctx->video_offset : 0;
+
+ osd_set_sub(mpctx->osd, obj, &state);
+
+ double refpts_s = mpctx->playback_pts - state.video_offset;
double curpts_s = refpts_s - opts->sub_delay;
if (!track->preloaded && track->stream) {
@@ -136,14 +139,14 @@ static void update_subtitle(struct MPContext *mpctx, int order)
// Handle displaying subtitles on terminal; never done for secondary subs
if (order == 0) {
- if (!osd_obj->render_bitmap_subs || !mpctx->video_out) {
+ if (!state.render_bitmap_subs || !mpctx->video_out) {
sub_lock(dec_sub);
set_osd_subtitle(mpctx, sub_get_text(dec_sub, curpts_s));
sub_unlock(dec_sub);
}
} else if (order == 1) {
sub_lock(dec_sub);
- osd_set_sub(mpctx->osd, osd_obj, sub_get_text(dec_sub, curpts_s));
+ osd_set_text(mpctx->osd, obj, sub_get_text(dec_sub, curpts_s));
sub_unlock(dec_sub);
}
}
@@ -225,8 +228,7 @@ void reinit_subs(struct MPContext *mpctx, int order)
{
struct MPOpts *opts = mpctx->opts;
struct track *track = mpctx->current_track[order][STREAM_SUB];
- struct osd_object *osd_obj =
- mpctx->osd->objs[order ? OSDTYPE_SUB2 : OSDTYPE_SUB];
+ int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB;
int init_flag = order ? INITIALIZED_SUB2 : INITIALIZED_SUB;
assert(!(mpctx->initialized_flags & init_flag));
@@ -256,16 +258,18 @@ void reinit_subs(struct MPContext *mpctx, int order)
reinit_subdec(mpctx, track, dec_sub);
- osd_obj->dec_sub = dec_sub;
-
- // Decides whether to use OSD path or normal subtitle rendering path.
- osd_obj->render_bitmap_subs =
- opts->ass_enabled || !sub_has_get_text(dec_sub);
+ struct osd_sub_state state = {
+ .dec_sub = dec_sub,
+ // Decides whether to use OSD path or normal subtitle rendering path.
+ .render_bitmap_subs = opts->ass_enabled || !sub_has_get_text(dec_sub),
+ };
// Secondary subs are rendered with the "text" renderer to transform them
// to toptitles.
if (order == 1 && sub_has_get_text(dec_sub))
- osd_obj->render_bitmap_subs = false;
+ state.render_bitmap_subs = false;
reset_subtitles(mpctx, order);
+
+ osd_set_sub(mpctx->osd, obj, &state);
}
diff --git a/player/video.c b/player/video.c
index 17eaab619e..6f634270d2 100644
--- a/player/video.c
+++ b/player/video.c
@@ -126,8 +126,8 @@ static void recreate_video_filters(struct MPContext *mpctx)
// for vf_sub
vf_control_any(d_video->vfilter, VFCTRL_SET_OSD_OBJ, mpctx->osd);
- mpctx->osd->render_subs_in_filter
- = vf_control_any(d_video->vfilter, VFCTRL_INIT_OSD, NULL) == CONTROL_OK;
+ osd_set_render_subs_in_filter(mpctx->osd,
+ vf_control_any(d_video->vfilter, VFCTRL_INIT_OSD, NULL) == CONTROL_OK);
set_allowed_vo_formats(d_video->vfilter, mpctx->video_out);
}