From 716285782d5e4b264e18e253e9d58980183c76c6 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 15 Jun 2014 20:46:57 +0200 Subject: [PATCH] video/out: change aspects of OSD handling Let the VOs draw the OSD on their own, instead of making OSD drawing a separate VO driver call. Further, let it be the VOs responsibility to request subtitles with the correct PTS. We also basically allow the VO to request OSD/subtitles at any time. OSX changes untested. --- player/main.c | 1 + player/playloop.c | 41 +++++++++------------------------------ player/screenshot.c | 2 +- player/video.c | 1 + sub/osd.c | 15 -------------- sub/osd.h | 3 --- sub/osd_state.h | 2 -- video/out/gl_osd.c | 19 ++++++++++++------ video/out/gl_osd.h | 7 ++++--- video/out/gl_video.c | 13 +++++++++---- video/out/gl_video.h | 4 ++-- video/out/vo.c | 30 ++++++++++++---------------- video/out/vo.h | 15 +++++++------- video/out/vo_corevideo.c | 18 ++++++----------- video/out/vo_direct3d.c | 12 +++++++----- video/out/vo_image.c | 8 +------- video/out/vo_lavc.c | 24 +++++++---------------- video/out/vo_opengl.c | 17 +++------------- video/out/vo_opengl_old.c | 12 ++++++++---- video/out/vo_sdl.c | 9 ++++++--- video/out/vo_vaapi.c | 13 ++++++++++--- video/out/vo_vdpau.c | 15 ++++++++------ video/out/vo_wayland.c | 10 +++++++--- video/out/vo_x11.c | 12 ++---------- video/out/vo_xv.c | 14 +++---------- 25 files changed, 129 insertions(+), 188 deletions(-) diff --git a/player/main.c b/player/main.c index b7e683ad05..ee78fccbaf 100644 --- a/player/main.c +++ b/player/main.c @@ -435,6 +435,7 @@ int mp_initialize(struct MPContext *mpctx) if (opts->force_vo) { opts->fixed_vo = 1; mpctx->video_out = init_best_video_out(mpctx->global, mpctx->input, + mpctx->osd, mpctx->encode_lavc_ctx); if (!mpctx->video_out) { MP_FATAL(mpctx, "Error opening/initializing " diff --git a/player/playloop.c b/player/playloop.c index c06c40bd73..96326da57c 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -132,26 +132,6 @@ end: mp_notify(mpctx, mpctx->opts->pause ? MPV_EVENT_PAUSE : MPV_EVENT_UNPAUSE, 0); } -static void draw_osd(struct MPContext *mpctx) -{ - struct vo *vo = mpctx->video_out; - - osd_set_vo_pts(mpctx->osd, mpctx->video_pts); - vo_draw_osd(vo, mpctx->osd); -} - -static bool redraw_osd(struct MPContext *mpctx) -{ - struct vo *vo = mpctx->video_out; - if (vo_redraw_frame(vo) < 0) - return false; - - draw_osd(mpctx); - - vo_flip_page(vo, 0, -1); - return true; -} - void add_step_frame(struct MPContext *mpctx, int dir) { if (!mpctx->d_video) @@ -630,13 +610,11 @@ 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) | - (osd_query_and_reset_want_redraw(mpctx->osd) && - mpctx->video_out->driver->draw_osd); - if (want_redraw) { - if (redraw_osd(mpctx)) - return true; - } - return false; + osd_query_and_reset_want_redraw(mpctx->osd); + if (!want_redraw) + return false; + vo_redraw(mpctx->video_out); + return true; } static void handle_metadata_update(struct MPContext *mpctx) @@ -890,7 +868,7 @@ void handle_force_window(struct MPContext *mpctx, bool reconfig) .d_w = w, .d_h = h, }; vo_reconfig(vo, &p, 0); - redraw_osd(mpctx); + vo_redraw(vo); mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL); } } @@ -1103,9 +1081,7 @@ void run_playloop(struct MPContext *mpctx) //=================== FLIP PAGE (VIDEO BLT): ====================== - MP_STATS(mpctx, "vo draw frame"); - vo_new_frame_imminent(vo); mpctx->video_pts = mpctx->video_next_pts; mpctx->last_vo_pts = mpctx->video_pts; mpctx->playback_pts = mpctx->video_pts; @@ -1113,8 +1089,9 @@ void run_playloop(struct MPContext *mpctx) update_subtitles(mpctx); update_osd_msg(mpctx); - MP_STATS(mpctx, "draw OSD"); - draw_osd(mpctx); + MP_STATS(mpctx, "vo draw frame"); + + vo_new_frame_imminent(vo); MP_STATS(mpctx, "vo sleep"); diff --git a/player/screenshot.c b/player/screenshot.c index 1c3177cff7..30eceedafc 100644 --- a/player/screenshot.c +++ b/player/screenshot.c @@ -304,7 +304,7 @@ static void add_subs(struct MPContext *mpctx, struct mp_image *image) .display_par = sar / dar, }; - osd_draw_on_image(mpctx->osd, res, osd_get_vo_pts(mpctx->osd), + osd_draw_on_image(mpctx->osd, res, mpctx->video_pts, OSD_DRAW_SUB_ONLY, image); } diff --git a/player/video.c b/player/video.c index 50f0956f1e..e0aeaadf9e 100644 --- a/player/video.c +++ b/player/video.c @@ -187,6 +187,7 @@ int reinit_video_chain(struct MPContext *mpctx) //================== Init VIDEO (codec & libvo) ========================== if (!opts->fixed_vo || !(mpctx->initialized_flags & INITIALIZED_VO)) { mpctx->video_out = init_best_video_out(mpctx->global, mpctx->input, + mpctx->osd, mpctx->encode_lavc_ctx); if (!mpctx->video_out) { MP_FATAL(mpctx, "Error opening/initializing " diff --git a/sub/osd.c b/sub/osd.c index 8b19428e5d..28a98892ce 100644 --- a/sub/osd.c +++ b/sub/osd.c @@ -423,21 +423,6 @@ bool osd_query_and_reset_want_redraw(struct osd_state *osd) 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, int obj, diff --git a/sub/osd.h b/sub/osd.h index d79f55ae3d..2a5bf71b05 100644 --- a/sub/osd.h +++ b/sub/osd.h @@ -149,9 +149,6 @@ 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 { diff --git a/sub/osd_state.h b/sub/osd_state.h index 55e484e3e0..01546d7c6f 100644 --- a/sub/osd_state.h +++ b/sub/osd_state.h @@ -52,8 +52,6 @@ struct osd_state { struct osd_object *objs[MAX_OSD_PARTS]; - double vo_pts; - bool render_subs_in_filter; bool want_redraw; diff --git a/video/out/gl_osd.c b/video/out/gl_osd.c index 393619e554..2458a61cce 100644 --- a/video/out/gl_osd.c +++ b/video/out/gl_osd.c @@ -47,7 +47,7 @@ static const struct osd_fmt_entry osd_to_gl_legacy_formats[SUBBITMAP_COUNT] = { [SUBBITMAP_RGBA] = {GL_RGBA, GL_BGRA, GL_UNSIGNED_BYTE}, }; -struct mpgl_osd *mpgl_osd_init(GL *gl, struct mp_log *log, bool legacy) +struct mpgl_osd *mpgl_osd_init(GL *gl, struct mp_log *log, struct osd_state *osd) { GLint max_texture_size; gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); @@ -55,8 +55,9 @@ struct mpgl_osd *mpgl_osd_init(GL *gl, struct mp_log *log, bool legacy) struct mpgl_osd *ctx = talloc_ptrtype(NULL, ctx); *ctx = (struct mpgl_osd) { .log = log, + .osd = osd, .gl = gl, - .fmt_table = legacy ? osd_to_gl_legacy_formats : osd_to_gl3_formats, + .fmt_table = osd_to_gl3_formats, .scratch = talloc_zero_size(ctx, 1), }; @@ -79,6 +80,9 @@ struct mpgl_osd *mpgl_osd_init(GL *gl, struct mp_log *log, bool legacy) void mpgl_osd_destroy(struct mpgl_osd *ctx) { + if (!ctx) + return; + GL *gl = ctx->gl; for (int n = 0; n < MAX_OSD_PARTS; n++) { @@ -274,7 +278,7 @@ static void draw_cb(void *pctx, struct sub_bitmaps *imgs) } void mpgl_osd_draw_cb(struct mpgl_osd *ctx, - struct osd_state *osd, + double pts, struct mp_osd_res res, void (*cb)(void *ctx, struct mpgl_osd_part *part, struct sub_bitmaps *imgs), @@ -282,7 +286,7 @@ void mpgl_osd_draw_cb(struct mpgl_osd *ctx, { struct draw_cb_closure c = {ctx, cb, cb_ctx}; reset(ctx); - osd_draw(osd, res, osd_get_vo_pts(osd), 0, ctx->formats, draw_cb, &c); + osd_draw(ctx->osd, res, pts, 0, ctx->formats, draw_cb, &c); } void mpgl_osd_redraw_cb(struct mpgl_osd *ctx, @@ -373,8 +377,11 @@ static void draw_legacy_cb(void *pctx, struct sub_bitmaps *imgs) gl->DisableClientState(GL_COLOR_ARRAY); } -void mpgl_osd_draw_legacy(struct mpgl_osd *ctx, struct osd_state *osd, +void mpgl_osd_draw_legacy(struct mpgl_osd *ctx, double pts, struct mp_osd_res res) { - osd_draw(osd, res, osd_get_vo_pts(osd), 0, ctx->formats, draw_legacy_cb, ctx); + ctx->fmt_table = osd_to_gl_legacy_formats; + for (int n = 0; n < SUBBITMAP_COUNT; n++) + ctx->formats[n] = ctx->fmt_table[n].type != 0; + osd_draw(ctx->osd, res, pts, 0, ctx->formats, draw_legacy_cb, ctx); } diff --git a/video/out/gl_osd.h b/video/out/gl_osd.h index 445766d19a..e4c4502a2a 100644 --- a/video/out/gl_osd.h +++ b/video/out/gl_osd.h @@ -21,6 +21,7 @@ struct mpgl_osd_part { struct mpgl_osd { struct mp_log *log; + struct osd_state *osd; GL *gl; bool use_pbo; bool scaled; @@ -30,16 +31,16 @@ struct mpgl_osd { void *scratch; }; -struct mpgl_osd *mpgl_osd_init(GL *gl, struct mp_log *log, bool legacy); +struct mpgl_osd *mpgl_osd_init(GL *gl, struct mp_log *log, struct osd_state *osd); void mpgl_osd_destroy(struct mpgl_osd *ctx); void mpgl_osd_set_gl_state(struct mpgl_osd *ctx, struct mpgl_osd_part *p); void mpgl_osd_unset_gl_state(struct mpgl_osd *ctx, struct mpgl_osd_part *p); -void mpgl_osd_draw_legacy(struct mpgl_osd *ctx, struct osd_state *osd, +void mpgl_osd_draw_legacy(struct mpgl_osd *ctx, double pts, struct mp_osd_res res); void mpgl_osd_draw_cb(struct mpgl_osd *ctx, - struct osd_state *osd, + double pts, struct mp_osd_res res, void (*cb)(void *ctx, struct mpgl_osd_part *part, struct sub_bitmaps *imgs), diff --git a/video/out/gl_video.c b/video/out/gl_video.c index 26c49d5737..b6975ced1f 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -153,7 +153,9 @@ struct gl_video { GLuint osd_programs[SUBBITMAP_COUNT]; GLuint indirect_program, scale_sep_program, final_program; + struct osd_state *osd_state; struct mpgl_osd *osd; + double osd_pts; GLuint lut_3d_texture; bool use_lut_3d; @@ -1157,7 +1159,7 @@ static void recreate_osd(struct gl_video *p) { if (p->osd) mpgl_osd_destroy(p->osd); - p->osd = mpgl_osd_init(p->gl, p->log, false); + p->osd = mpgl_osd_init(p->gl, p->log, p->osd_state); p->osd->use_pbo = p->opts.pbo; } @@ -1710,6 +1712,8 @@ void gl_video_upload_image(struct gl_video *p, struct mp_image *mpi) struct video_image *vimg = &p->image; + p->osd_pts = mpi->pts; + if (p->hwdec_active) { mp_image_setrefp(&vimg->hwimage, mpi); p->have_image = true; @@ -1833,12 +1837,12 @@ static void draw_osd_cb(void *ctx, struct mpgl_osd_part *osd, debug_check_gl(p, "after drawing osd"); } -void gl_video_draw_osd(struct gl_video *p, struct osd_state *osd) +void gl_video_draw_osd(struct gl_video *p) { GL *gl = p->gl; assert(p->osd); - mpgl_osd_draw_cb(p->osd, osd, p->osd_rect, draw_osd_cb, p); + mpgl_osd_draw_cb(p->osd, p->osd_pts, p->osd_rect, draw_osd_cb, p); // The playloop calls this last before waiting some time until it decides // to call flip_page(). Tell OpenGL to start execution of the GPU commands @@ -2201,12 +2205,13 @@ void gl_video_set_output_depth(struct gl_video *p, int r, int g, int b) p->depth_g = g; } -struct gl_video *gl_video_init(GL *gl, struct mp_log *log) +struct gl_video *gl_video_init(GL *gl, struct mp_log *log, struct osd_state *osd) { struct gl_video *p = talloc_ptrtype(NULL, p); *p = (struct gl_video) { .gl = gl, .log = log, + .osd_state = osd, .opts = gl_video_opts_def, .gl_target = GL_TEXTURE_2D, .gl_debug = true, diff --git a/video/out/gl_video.h b/video/out/gl_video.h index 2b0178db55..f6d5b2573d 100644 --- a/video/out/gl_video.h +++ b/video/out/gl_video.h @@ -55,14 +55,14 @@ extern const struct gl_video_opts gl_video_opts_hq_def; struct gl_video; -struct gl_video *gl_video_init(GL *gl, struct mp_log *log); +struct gl_video *gl_video_init(GL *gl, struct mp_log *log, struct osd_state *osd); void gl_video_uninit(struct gl_video *p); void gl_video_set_options(struct gl_video *p, struct gl_video_opts *opts); bool gl_video_check_format(struct gl_video *p, int mp_format); void gl_video_config(struct gl_video *p, struct mp_image_params *params); void gl_video_set_output_depth(struct gl_video *p, int r, int g, int b); void gl_video_set_lut3d(struct gl_video *p, struct lut3d *lut3d); -void gl_video_draw_osd(struct gl_video *p, struct osd_state *osd); +void gl_video_draw_osd(struct gl_video *p); void gl_video_upload_image(struct gl_video *p, struct mp_image *img); void gl_video_render_frame(struct gl_video *p); struct mp_image *gl_video_download_image(struct gl_video *p); diff --git a/video/out/vo.c b/video/out/vo.c index 76f980ce5a..98601f0324 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -152,7 +152,7 @@ static int event_fd_callback(void *ctx, int fd) } static struct vo *vo_create(struct mpv_global *global, - struct input_ctx *input_ctx, + struct input_ctx *input_ctx, struct osd_state *osd, struct encode_lavc_context *encode_lavc_ctx, char *name, char **args) { @@ -171,6 +171,7 @@ static struct vo *vo_create(struct mpv_global *global, .global = global, .encode_lavc_ctx = encode_lavc_ctx, .input_ctx = input_ctx, + .osd = osd, .event_fd = -1, .monitor_par = 1, .max_video_queue = 1, @@ -198,6 +199,7 @@ error: struct vo *init_best_video_out(struct mpv_global *global, struct input_ctx *input_ctx, + struct osd_state *osd, struct encode_lavc_context *encode_lavc_ctx) { struct m_obj_settings *vo_list = global->opts->vo.video_driver_list; @@ -207,7 +209,7 @@ struct vo *init_best_video_out(struct mpv_global *global, // Something like "-vo name," allows fallback to autoprobing. if (strlen(vo_list[n].name) == 0) goto autoprobe; - struct vo *vo = vo_create(global, input_ctx, encode_lavc_ctx, + struct vo *vo = vo_create(global, input_ctx, osd, encode_lavc_ctx, vo_list[n].name, vo_list[n].attribs); if (vo) return vo; @@ -217,7 +219,7 @@ struct vo *init_best_video_out(struct mpv_global *global, autoprobe: // now try the rest... for (int i = 0; video_out_drivers[i]; i++) { - struct vo *vo = vo_create(global, input_ctx, encode_lavc_ctx, + struct vo *vo = vo_create(global, input_ctx, osd, encode_lavc_ctx, (char *)video_out_drivers[i]->name, NULL); if (vo) return vo; @@ -321,15 +323,6 @@ double vo_get_next_pts(struct vo *vo, int index) return vo->video_queue[index]->pts; } -int vo_redraw_frame(struct vo *vo) -{ - if (vo->config_ok && vo_control(vo, VOCTRL_REDRAW_FRAME, NULL) == true) { - vo->want_redraw = false; - return 0; - } - return -1; -} - bool vo_get_want_redraw(struct vo *vo) { return vo->config_ok && vo->want_redraw; @@ -354,12 +347,6 @@ void vo_new_frame_imminent(struct vo *vo) vo->hasframe = true; } -void vo_draw_osd(struct vo *vo, struct osd_state *osd) -{ - if (vo->config_ok && vo->driver->draw_osd) - vo->driver->draw_osd(vo, osd); -} - void vo_flip_page(struct vo *vo, int64_t pts_us, int duration) { if (!vo->config_ok) @@ -371,6 +358,13 @@ void vo_flip_page(struct vo *vo, int64_t pts_us, int duration) vo->driver->flip_page(vo); } +void vo_redraw(struct vo *vo) +{ + vo->want_redraw = false; + if (vo->config_ok && vo_control(vo, VOCTRL_REDRAW_FRAME, NULL) == true) + vo_flip_page(vo, 0, -1); +} + void vo_check_events(struct vo *vo) { vo_control(vo, VOCTRL_CHECK_EVENTS, NULL); diff --git a/video/out/vo.h b/video/out/vo.h index 83e819d8e6..38b393a0a8 100644 --- a/video/out/vo.h +++ b/video/out/vo.h @@ -54,6 +54,9 @@ enum mp_voctrl { /* for hardware decoding */ VOCTRL_GET_HWDEC_INFO, // struct mp_hwdec_info* + // Redraw the image previously passed to draw_image() (basically, repeat + // the previous draw_image call). If this is handled, the OSD should also + // be updated and redrawn. VOCTRL_REDRAW_FRAME, VOCTRL_ONTOP, @@ -193,14 +196,11 @@ struct vo_driver { * followed by a draw_osd and a flip_page[_timed] call. * mpi belongs to the caller; if the VO needs it longer, it has to create * a new reference to mpi. + * + * This also should draw the OSD. */ void (*draw_image)(struct vo *vo, struct mp_image *mpi); - /* - * Draws OSD to the screen buffer - */ - void (*draw_osd)(struct vo *vo, struct osd_state *osd); - /* * Blit/Flip buffer to the screen. Must be called after each frame! * pts_us is the frame presentation time, linked to mp_time_us(). @@ -256,6 +256,7 @@ struct vo { struct vo_wayland_state *wayland; struct encode_lavc_context *encode_lavc_ctx; struct input_ctx *input_ctx; + struct osd_state *osd; int event_fd; // check_events() should be called when this has input // current window state @@ -269,19 +270,19 @@ struct vo { struct mpv_global; struct vo *init_best_video_out(struct mpv_global *global, struct input_ctx *input_ctx, + struct osd_state *osd, struct encode_lavc_context *encode_lavc_ctx); int vo_reconfig(struct vo *vo, struct mp_image_params *p, int flags); int vo_control(struct vo *vo, uint32_t request, void *data); void vo_queue_image(struct vo *vo, struct mp_image *mpi); -int vo_redraw_frame(struct vo *vo); bool vo_get_want_redraw(struct vo *vo); bool vo_has_next_frame(struct vo *vo, bool eof); double vo_get_next_pts(struct vo *vo, int index); bool vo_needs_new_image(struct vo *vo); void vo_new_frame_imminent(struct vo *vo); -void vo_draw_osd(struct vo *vo, struct osd_state *osd); void vo_flip_page(struct vo *vo, int64_t pts_us, int duration); +void vo_redraw(struct vo *vo); void vo_check_events(struct vo *vo); void vo_seek_reset(struct vo *vo); void vo_destroy(struct vo *vo); diff --git a/video/out/vo_corevideo.c b/video/out/vo_corevideo.c index 22e9afcc24..25555e3ee1 100644 --- a/video/out/vo_corevideo.c +++ b/video/out/vo_corevideo.c @@ -93,6 +93,7 @@ struct priv { struct quad *quad; struct mpgl_osd *osd; + double vo_pts; // functions to to deal with the the OpenGL texture for containing the // video frame (behaviour changes depending on the rendering path). @@ -129,7 +130,7 @@ static int init_gl(struct vo *vo, uint32_t d_width, uint32_t d_height) gl->TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); if (!p->osd) - p->osd = mpgl_osd_init(gl, vo->log, true); + p->osd = mpgl_osd_init(gl, vo->log, vo->osd); resize(vo); @@ -179,6 +180,8 @@ static void do_render(struct vo *vo) gl->End(); p->fns.unbind_texture(vo); + + mpgl_osd_draw_legacy(p->osd, p->vo_pts, p->osd_res); } static void flip_page(struct vo *vo) @@ -191,6 +194,7 @@ static void flip_page(struct vo *vo) static void draw_image(struct vo *vo, struct mp_image *mpi) { struct priv *p = vo->priv; + p->vo_pts = mpi->pts; p->fns.prepare_texture(vo, mpi); do_render(vo); } @@ -198,8 +202,7 @@ static void draw_image(struct vo *vo, struct mp_image *mpi) static void uninit(struct vo *vo) { struct priv *p = vo->priv; - if (p->osd) - mpgl_osd_destroy(p->osd); + mpgl_osd_destroy(p->osd); p->fns.uninit(vo); mpgl_uninit(p->mpglctx); } @@ -217,14 +220,6 @@ static int preinit(struct vo *vo) return 0; } -static void draw_osd(struct vo *vo, struct osd_state *osd) -{ - struct priv *p = vo->priv; - assert(p->osd); - - mpgl_osd_draw_legacy(p->osd, osd, p->osd_res); -} - static CFStringRef get_cv_csp_matrix(enum mp_csp format) { switch (format) { @@ -569,7 +564,6 @@ const struct vo_driver video_out_corevideo = { .reconfig = reconfig, .control = control, .draw_image = draw_image, - .draw_osd = draw_osd, .flip_page = flip_page, .uninit = uninit, .priv_size = sizeof(struct priv), diff --git a/video/out/vo_direct3d.c b/video/out/vo_direct3d.c index c732d3c19b..b34c1d49ef 100644 --- a/video/out/vo_direct3d.c +++ b/video/out/vo_direct3d.c @@ -131,6 +131,7 @@ typedef struct d3d_priv { struct vo *vo; bool have_image; + double osd_pts; D3DLOCKED_RECT locked_rect; /**< The locked offscreen surface */ RECT fs_movie_rect; /**< Rect (upscaled) of the movie when displayed @@ -233,7 +234,7 @@ static void uninit(struct vo *vo); static void flip_page(struct vo *vo); static mp_image_t *get_screenshot(d3d_priv *priv); static mp_image_t *get_window_screenshot(d3d_priv *priv); - +static void draw_osd(struct vo *vo); static void d3d_matrix_identity(D3DMATRIX *m) { @@ -911,6 +912,8 @@ static uint32_t d3d_draw_frame(d3d_priv *priv) } } + draw_osd(priv->vo); + return VO_TRUE; } @@ -1411,6 +1414,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) } priv->have_image = true; + priv->osd_pts = mpi->pts; d3d_draw_frame(priv); } @@ -1685,13 +1689,13 @@ static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs) } -static void draw_osd(struct vo *vo, struct osd_state *osd) +static void draw_osd(struct vo *vo) { d3d_priv *priv = vo->priv; if (!priv->d3d_device) return; - osd_draw(osd, priv->osd_res, osd_get_vo_pts(osd), 0, osd_fmt_supported, + osd_draw(vo->osd, priv->osd_res, priv->osd_pts, 0, osd_fmt_supported, draw_osd_cb, priv); } @@ -1729,7 +1733,6 @@ const struct vo_driver video_out_direct3d = { .reconfig = reconfig, .control = control, .draw_image = draw_image, - .draw_osd = draw_osd, .flip_page = flip_page, .uninit = uninit, .priv_size = sizeof(d3d_priv), @@ -1745,7 +1748,6 @@ const struct vo_driver video_out_direct3d_shaders = { .reconfig = reconfig, .control = control, .draw_image = draw_image, - .draw_osd = draw_osd, .flip_page = flip_page, .uninit = uninit, .priv_size = sizeof(d3d_priv), diff --git a/video/out/vo_image.c b/video/out/vo_image.c index b82adbba54..b732c417a9 100644 --- a/video/out/vo_image.c +++ b/video/out/vo_image.c @@ -77,14 +77,9 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) struct priv *p = vo->priv; mp_image_setrefp(&p->current, mpi); -} - -static void draw_osd(struct vo *vo, struct osd_state *osd) -{ - struct priv *p = vo->priv; struct mp_osd_res dim = osd_res_from_image_params(vo->params); - osd_draw_on_image(osd, dim, osd_get_vo_pts(osd), OSD_DRAW_SUB_ONLY, p->current); + osd_draw_on_image(vo->osd, dim, mpi->pts, OSD_DRAW_SUB_ONLY, p->current); } static void flip_page(struct vo *vo) @@ -152,7 +147,6 @@ const struct vo_driver video_out_image = .reconfig = reconfig, .control = control, .draw_image = draw_image, - .draw_osd = draw_osd, .flip_page = flip_page, .uninit = uninit, }; diff --git a/video/out/vo_lavc.c b/video/out/vo_lavc.c index ed23a27066..7bc9c1a3b7 100644 --- a/video/out/vo_lavc.c +++ b/video/out/vo_lavc.c @@ -486,8 +486,15 @@ static void draw_image_unlocked(struct vo *vo, mp_image_t *mpi) static void draw_image(struct vo *vo, mp_image_t *mpi) { + struct priv *vc = vo->priv; pthread_mutex_lock(&vo->encode_lavc_ctx->lock); draw_image_unlocked(vo, mpi); + if (vc->lastimg && vc->lastimg_wants_osd && vo->params) { + struct mp_osd_res dim = osd_res_from_image_params(vo->params); + + osd_draw_on_image(vo->osd, dim, mpi->pts, OSD_DRAW_SUB_ONLY, + vc->lastimg); + } pthread_mutex_unlock(&vo->encode_lavc_ctx->lock); } @@ -495,22 +502,6 @@ static void flip_page_timed(struct vo *vo, int64_t pts_us, int duration) { } -static void draw_osd(struct vo *vo, struct osd_state *osd) -{ - struct priv *vc = vo->priv; - - pthread_mutex_lock(&vo->encode_lavc_ctx->lock); - - if (vc->lastimg && vc->lastimg_wants_osd && vo->params) { - struct mp_osd_res dim = osd_res_from_image_params(vo->params); - - osd_draw_on_image(osd, dim, osd_get_vo_pts(osd), OSD_DRAW_SUB_ONLY, - vc->lastimg); - } - - pthread_mutex_unlock(&vo->encode_lavc_ctx->lock); -} - static int control(struct vo *vo, uint32_t request, void *data) { struct priv *vc = vo->priv; @@ -536,7 +527,6 @@ const struct vo_driver video_out_lavc = { .control = control, .uninit = uninit, .draw_image = draw_image, - .draw_osd = draw_osd, .flip_page_timed = flip_page_timed, }; diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c index 37c890ddbe..cfbd0e590f 100644 --- a/video/out/vo_opengl.c +++ b/video/out/vo_opengl.c @@ -111,17 +111,6 @@ static void flip_page(struct vo *vo) mpgl_unlock(p->glctx); } -static void draw_osd(struct vo *vo, struct osd_state *osd) -{ - struct gl_priv *p = vo->priv; - - mpgl_lock(p->glctx); - - gl_video_draw_osd(p->renderer, osd); - - mpgl_unlock(p->glctx); -} - static void draw_image(struct vo *vo, mp_image_t *mpi) { struct gl_priv *p = vo->priv; @@ -132,6 +121,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) mpgl_lock(p->glctx); gl_video_upload_image(p->renderer, mpi); gl_video_render_frame(p->renderer); + gl_video_draw_osd(p->renderer); mpgl_unlock(p->glctx); } @@ -380,6 +370,7 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_REDRAW_FRAME: mpgl_lock(p->glctx); gl_video_render_frame(p->renderer); + gl_video_draw_osd(p->renderer); mpgl_unlock(p->glctx); return true; case VOCTRL_SET_COMMAND_LINE: { @@ -434,7 +425,7 @@ static int preinit(struct vo *vo) if (p->gl->SwapInterval) p->gl->SwapInterval(p->swap_interval); - p->renderer = gl_video_init(p->gl, vo->log); + p->renderer = gl_video_init(p->gl, vo->log, vo->osd); gl_video_set_output_depth(p->renderer, p->glctx->depth_r, p->glctx->depth_g, p->glctx->depth_b); gl_video_set_options(p->renderer, p->renderer_opts); @@ -474,7 +465,6 @@ const struct vo_driver video_out_opengl = { .reconfig = reconfig, .control = control, .draw_image = draw_image, - .draw_osd = draw_osd, .flip_page = flip_page, .uninit = uninit, .priv_size = sizeof(struct gl_priv), @@ -490,7 +480,6 @@ const struct vo_driver video_out_opengl_hq = { .reconfig = reconfig, .control = control, .draw_image = draw_image, - .draw_osd = draw_osd, .flip_page = flip_page, .uninit = uninit, .priv_size = sizeof(struct gl_priv), diff --git a/video/out/vo_opengl_old.c b/video/out/vo_opengl_old.c index ea04283376..3f9e4b0f38 100644 --- a/video/out/vo_opengl_old.c +++ b/video/out/vo_opengl_old.c @@ -59,6 +59,7 @@ struct gl_priv { int scaled_osd; struct mpgl_osd *osd; int osd_color; + double osd_pts; int use_ycbcr; int use_yuv; @@ -1451,7 +1452,7 @@ static void update_yuvconv(struct vo *vo) } } -static void draw_osd(struct vo *vo, struct osd_state *osd) +static void draw_osd(struct vo *vo) { struct gl_priv *p = vo->priv; GL *gl = p->gl; @@ -1475,7 +1476,7 @@ static void draw_osd(struct vo *vo, struct osd_state *osd) gl->Color4ub((p->osd_color >> 16) & 0xff, (p->osd_color >> 8) & 0xff, p->osd_color & 0xff, 0xff - (p->osd_color >> 24)); - mpgl_osd_draw_legacy(p->osd, osd, res); + mpgl_osd_draw_legacy(p->osd, p->osd_pts, res); if (p->scaled_osd) gl->PopMatrix(); @@ -1686,7 +1687,7 @@ static int initGl(struct vo *vo, uint32_t d_width, uint32_t d_height) } if (gl->BindTexture) { - p->osd = mpgl_osd_init(gl, vo->log, true); + p->osd = mpgl_osd_init(gl, vo->log, vo->osd); p->osd->scaled = p->scaled_osd; } @@ -1782,6 +1783,8 @@ static void do_render(struct vo *vo) } if (p->is_yuv || p->custom_prog) glDisableYUVConversion(gl, p->target, p->yuvconvtype); + + draw_osd(vo); } static void flip_page(struct vo *vo) @@ -1906,6 +1909,8 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) struct gl_priv *p = vo->priv; GL *gl = p->gl; + p->osd_pts = mpi->pts; + int slice = p->slice_height; int stride[3]; unsigned char *planes[3]; @@ -2166,7 +2171,6 @@ const struct vo_driver video_out_opengl_old = { .reconfig = reconfig, .control = control, .draw_image = draw_image, - .draw_osd = draw_osd, .flip_page = flip_page, .uninit = uninit, .priv_size = sizeof(struct gl_priv), diff --git a/video/out/vo_sdl.c b/video/out/vo_sdl.c index e31dfdc8f2..57302b0a41 100644 --- a/video/out/vo_sdl.c +++ b/video/out/vo_sdl.c @@ -190,6 +190,7 @@ struct priv { int num_targets; int targets_size; } osd_surfaces[MAX_OSD_PARTS]; + double osd_pts; int mouse_hidden; int brightness, contrast; @@ -741,7 +742,7 @@ static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs) draw_osd_part(vo, imgs->render_index); } -static void draw_osd(struct vo *vo, struct osd_state *osd) +static void draw_osd(struct vo *vo) { struct priv *vc = vo->priv; @@ -749,7 +750,7 @@ static void draw_osd(struct vo *vo, struct osd_state *osd) [SUBBITMAP_RGBA] = true, }; - osd_draw(osd, vc->osd_res, osd_get_vo_pts(osd), 0, osdformats, draw_osd_cb, vo); + osd_draw(vo->osd, vc->osd_res, vc->osd_pts, 0, osdformats, draw_osd_cb, vo); } static int preinit(struct vo *vo) @@ -849,6 +850,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) SDL_SetTextureBlendMode(vc->tex, SDL_BLENDMODE_NONE); if (mpi) { + vc->osd_pts = mpi->pts; if (SDL_LockTexture(vc->tex, NULL, &pixels, &pitch)) { MP_ERR(vo, "SDL_LockTexture failed\n"); return; @@ -900,6 +902,8 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) SDL_SetTextureColorMod(vc->tex, color_mod, color_mod, color_mod); SDL_RenderCopy(vc->renderer, vc->tex, &src, &dst); } + + draw_osd(vo); } static struct mp_image *get_screenshot(struct vo *vo) @@ -1020,6 +1024,5 @@ const struct vo_driver video_out_sdl = { .control = control, .draw_image = draw_image, .uninit = uninit, - .draw_osd = draw_osd, .flip_page = flip_page, }; diff --git a/video/out/vo_vaapi.c b/video/out/vo_vaapi.c index 35caf4d9c6..df96121137 100644 --- a/video/out/vo_vaapi.c +++ b/video/out/vo_vaapi.c @@ -111,6 +111,8 @@ static const bool osd_formats[SUBBITMAP_COUNT] = { [SUBBITMAP_RGBA] = true, }; +static void draw_osd(struct vo *vo); + static void flush_output_surfaces(struct priv *p) { for (int n = 0; n < MAX_OUTPUT_SURFACES; n++) @@ -283,6 +285,8 @@ static void draw_image(struct vo *vo, struct mp_image *mpi) } mp_image_setrefp(&p->output_surfaces[p->output_surface], mpi); + + draw_osd(vo); } static struct mp_image *get_screenshot(struct priv *p) @@ -407,10 +411,13 @@ error: ; } -static void draw_osd(struct vo *vo, struct osd_state *osd) +static void draw_osd(struct vo *vo) { struct priv *p = vo->priv; + struct mp_image *cur = p->output_surfaces[p->output_surface]; + double pts = cur ? cur->pts : 0; + if (!p->osd_format.fourcc) return; @@ -425,7 +432,7 @@ static void draw_osd(struct vo *vo, struct osd_state *osd) for (int n = 0; n < MAX_OSD_PARTS; n++) p->osd_parts[n].active = false; - osd_draw(osd, *res, osd_get_vo_pts(osd), 0, osd_formats, draw_osd_cb, p); + osd_draw(vo->osd, *res, pts, 0, osd_formats, draw_osd_cb, p); } static int get_displayattribtype(const char *name) @@ -524,6 +531,7 @@ static int control(struct vo *vo, uint32_t request, void *data) } case VOCTRL_REDRAW_FRAME: p->output_surface = p->visible_surface; + draw_osd(vo); return true; case VOCTRL_SCREENSHOT: { struct voctrl_screenshot_args *args = data; @@ -654,7 +662,6 @@ const struct vo_driver video_out_vaapi = { .reconfig = reconfig, .control = control, .draw_image = draw_image, - .draw_osd = draw_osd, .flip_page = flip_page, .uninit = uninit, .priv_size = sizeof(struct priv), diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c index 3deac1724b..406ed5f9ed 100644 --- a/video/out/vo_vdpau.c +++ b/video/out/vo_vdpau.c @@ -145,6 +145,7 @@ struct vdpctx { }; static bool status_ok(struct vo *vo); +static void draw_osd(struct vo *vo); static int render_video_to_output_surface(struct vo *vo, VdpOutputSurface output_surface, @@ -214,9 +215,11 @@ static int video_to_output_surface(struct vo *vo) { struct vdpctx *vc = vo->priv; - return render_video_to_output_surface(vo, - vc->output_surfaces[vc->surface_num], - &vc->out_rect_vid, &vc->src_rect_vid); + int r = render_video_to_output_surface(vo, + vc->output_surfaces[vc->surface_num], + &vc->out_rect_vid, &vc->src_rect_vid); + draw_osd(vo); + return r; } static void forget_frames(struct vo *vo, bool seek_reset) @@ -657,7 +660,7 @@ static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs) draw_osd_part(vo, imgs->render_index); } -static void draw_osd(struct vo *vo, struct osd_state *osd) +static void draw_osd(struct vo *vo) { struct vdpctx *vc = vo->priv; @@ -669,7 +672,8 @@ static void draw_osd(struct vo *vo, struct osd_state *osd) [SUBBITMAP_RGBA] = true, }; - osd_draw(osd, vc->osd_rect, osd_get_vo_pts(osd), 0, formats, draw_osd_cb, vo); + double pts = vc->current_image ? vc->current_image->pts : 0; + osd_draw(vo->osd, vc->osd_rect, pts, 0, formats, draw_osd_cb, vo); } static int update_presentation_queue_status(struct vo *vo) @@ -1141,7 +1145,6 @@ const struct vo_driver video_out_vdpau = { .control = control, .draw_image = draw_image, .filter_image = filter_image, - .draw_osd = draw_osd, .flip_page_timed = flip_page_timed, .uninit = uninit, .priv_size = sizeof(struct vdpctx), diff --git a/video/out/vo_wayland.c b/video/out/vo_wayland.c index 1ea63fa890..f41c75f114 100644 --- a/video/out/vo_wayland.c +++ b/video/out/vo_wayland.c @@ -166,6 +166,8 @@ struct priv { int use_triplebuffering; }; +static void draw_osd(struct vo *vo); + /* copied from weston clients */ static int set_cloexec_or_close(int fd) { @@ -678,6 +680,8 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) mp_image_setrefp(&p->original_image, mpi); buffer_finalise_back(buf); + + draw_osd(vo); } static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs) @@ -724,7 +728,7 @@ static const bool osd_formats[SUBBITMAP_COUNT] = { [SUBBITMAP_RGBA] = true, }; -static void draw_osd(struct vo *vo, struct osd_state *osd) +static void draw_osd(struct vo *vo) { struct priv *p = vo->priv; // deattach all buffers and attach all needed buffers in osd_draw @@ -737,7 +741,8 @@ static void draw_osd(struct vo *vo, struct osd_state *osd) wl_surface_commit(s); } - osd_draw(osd, p->osd, osd_get_vo_pts(osd), 0, osd_formats, draw_osd_cb, p); + double pts = p->original_image ? p->original_image->pts : 0; + osd_draw(vo->osd, p->osd, pts, 0, osd_formats, draw_osd_cb, p); } static void flip_page(struct vo *vo) @@ -923,7 +928,6 @@ const struct vo_driver video_out_wayland = { .reconfig = reconfig, .control = control, .draw_image = draw_image, - .draw_osd = draw_osd, .flip_page = flip_page, .uninit = uninit, .options = (const struct m_option[]) { diff --git a/video/out/vo_x11.c b/video/out/vo_x11.c index fa067849af..543e762fce 100644 --- a/video/out/vo_x11.c +++ b/video/out/vo_x11.c @@ -421,15 +421,6 @@ static struct mp_image get_x_buffer(struct priv *p, int buf_index) return img; } -static void draw_osd(struct vo *vo, struct osd_state *osd) -{ - struct priv *p = vo->priv; - - struct mp_image img = get_x_buffer(p, p->current_buf); - - osd_draw_on_image(osd, p->osd, osd_get_vo_pts(osd), 0, &img); -} - static mp_image_t *get_screenshot(struct vo *vo) { struct priv *p = vo->priv; @@ -490,6 +481,8 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) mp_image_clear(&img, 0, 0, img.w, img.h); } + osd_draw_on_image(vo->osd, p->osd, mpi ? mpi->pts : 0, 0, &img); + mp_image_setrefp(&p->original_image, mpi); } @@ -666,7 +659,6 @@ const struct vo_driver video_out_x11 = { .reconfig = reconfig, .control = control, .draw_image = draw_image, - .draw_osd = draw_osd, .flip_page = flip_page, .uninit = uninit, }; diff --git a/video/out/vo_xv.c b/video/out/vo_xv.c index bf564cb136..e353dc27ff 100644 --- a/video/out/vo_xv.c +++ b/video/out/vo_xv.c @@ -615,16 +615,6 @@ static struct mp_image get_xv_buffer(struct vo *vo, int buf_index) return img; } -static void draw_osd(struct vo *vo, struct osd_state *osd) -{ - struct xvctx *ctx = vo->priv; - - struct mp_image img = get_xv_buffer(vo, ctx->current_buf); - - struct mp_osd_res res = osd_res_from_image_params(vo->params); - osd_draw_on_image(osd, res, osd_get_vo_pts(osd), 0, &img); -} - static void wait_for_completion(struct vo *vo, int max_outstanding) { #if HAVE_SHM && HAVE_XEXT @@ -679,6 +669,9 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) mp_image_clear(&xv_buffer, 0, 0, xv_buffer.w, xv_buffer.h); } + struct mp_osd_res res = osd_res_from_image_params(vo->params); + osd_draw_on_image(vo->osd, res, mpi ? mpi->pts : 0, 0, &xv_buffer); + mp_image_setrefp(&ctx->original_image, mpi); } @@ -891,7 +884,6 @@ const struct vo_driver video_out_xv = { .reconfig = reconfig, .control = control, .draw_image = draw_image, - .draw_osd = draw_osd, .flip_page = flip_page, .uninit = uninit, .priv_size = sizeof(struct xvctx),