vo: fully replace draw_image with draw_frame

0739cfc209 added the draw_frame API
deprecated draw_image internally. VOs that still used draw_image were
around, but really there's no reason to not just "upgrade" them anyway.
draw_frame is what the "real" VOs that people care about (gpu/gpu-next)
use. So we can just simplfy the code a bit now. VOCTRL_REDRAW_FRAME is
also no longer needed so that can be completely deleted as well. Note
that several of these VOs are legacy crap anyway (e.g. vaapi) and maybe
should just be deleted but whatever. vo_direct3d was also completely
untested (not that anyone should ever use it).
This commit is contained in:
Dudemanguy 2023-09-26 14:26:23 -05:00
parent 043189c229
commit 0b70598358
11 changed files with 58 additions and 126 deletions

View File

@ -968,11 +968,7 @@ static bool render_frame(struct vo *vo)
stats_time_start(in->stats, "video-draw"); stats_time_start(in->stats, "video-draw");
if (vo->driver->draw_frame) { vo->driver->draw_frame(vo, frame);
vo->driver->draw_frame(vo, frame);
} else {
vo->driver->draw_image(vo, mp_image_new_ref(frame->current));
}
stats_time_end(in->stats, "video-draw"); stats_time_end(in->stats, "video-draw");
@ -1065,14 +1061,7 @@ static void do_redraw(struct vo *vo)
frame->duration = -1; frame->duration = -1;
pthread_mutex_unlock(&in->lock); pthread_mutex_unlock(&in->lock);
if (vo->driver->draw_frame) { vo->driver->draw_frame(vo, frame);
vo->driver->draw_frame(vo, frame);
} else if ((full_redraw || vo->driver->control(vo, VOCTRL_REDRAW_FRAME, NULL) < 1)
&& frame->current)
{
vo->driver->draw_image(vo, mp_image_new_ref(frame->current));
}
vo->driver->flip_page(vo); vo->driver->flip_page(vo);
if (frame != &dummy) if (frame != &dummy)

View File

@ -78,11 +78,6 @@ enum mp_voctrl {
/* private to vo_gpu */ /* private to vo_gpu */
VOCTRL_LOAD_HWDEC_API, VOCTRL_LOAD_HWDEC_API,
// 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. Optional; emulated if not available.
VOCTRL_REDRAW_FRAME,
// Only used internally in vo_libmpv // Only used internally in vo_libmpv
VOCTRL_PREINIT, VOCTRL_PREINIT,
VOCTRL_UNINIT, VOCTRL_UNINIT,
@ -383,17 +378,6 @@ struct vo_driver {
struct mp_image *(*get_image_ts)(struct vo *vo, int imgfmt, int w, int h, struct mp_image *(*get_image_ts)(struct vo *vo, int imgfmt, int w, int h,
int stride_align, int flags); int stride_align, int flags);
/*
* Render the given frame to the VO's backbuffer. This operation will be
* followed by a draw_osd and a flip_page[_timed] call.
* mpi belongs to the VO; the VO must free it eventually.
*
* This also should draw the OSD.
*
* Deprecated for draw_frame. A VO should have only either callback set.
*/
void (*draw_image)(struct vo *vo, struct mp_image *mpi);
/* Render the given frame. Note that this is also called when repeating /* Render the given frame. Note that this is also called when repeating
* or redrawing frames. * or redrawing frames.
* *

View File

@ -111,13 +111,15 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
return resize(vo); return resize(vo);
} }
static void draw_image(struct vo *vo, mp_image_t *mpi) static void draw_frame(struct vo *vo, struct vo_frame *frame)
{ {
struct priv *priv = vo->priv; struct priv *priv = vo->priv;
struct mp_image *mpi = frame->current;
if (!mpi)
return;
memcpy_pic(priv->dither_buffer, mpi->planes[0], priv->image_width * depth, priv->image_height, memcpy_pic(priv->dither_buffer, mpi->planes[0], priv->image_width * depth, priv->image_height,
priv->image_width * depth, mpi->stride[0]); priv->image_width * depth, mpi->stride[0]);
caca_dither_bitmap(priv->canvas, 0, 0, priv->screen_w, priv->screen_h, priv->dither, priv->dither_buffer); caca_dither_bitmap(priv->canvas, 0, 0, priv->screen_w, priv->screen_h, priv->dither, priv->dither_buffer);
talloc_free(mpi);
} }
static void flip_page(struct vo *vo) static void flip_page(struct vo *vo)
@ -305,7 +307,7 @@ const struct vo_driver video_out_caca = {
.query_format = query_format, .query_format = query_format,
.reconfig = reconfig, .reconfig = reconfig,
.control = control, .control = control,
.draw_image = draw_image, .draw_frame = draw_frame,
.flip_page = flip_page, .flip_page = flip_page,
.uninit = uninit, .uninit = uninit,
.priv_size = sizeof(struct priv), .priv_size = sizeof(struct priv),

View File

@ -850,9 +850,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
d3d_priv *priv = vo->priv; d3d_priv *priv = vo->priv;
switch (request) { switch (request) {
case VOCTRL_REDRAW_FRAME:
d3d_draw_frame(priv);
return VO_TRUE;
case VOCTRL_SET_PANSCAN: case VOCTRL_SET_PANSCAN:
calc_fs_rect(priv); calc_fs_rect(priv);
priv->vo->want_redraw = true; priv->vo->want_redraw = true;
@ -993,27 +990,27 @@ static bool get_video_buffer(d3d_priv *priv, struct mp_image *out)
return true; return true;
} }
static void draw_image(struct vo *vo, mp_image_t *mpi) static void draw_frame(struct vo *vo, struct vo_frame *frame)
{ {
d3d_priv *priv = vo->priv; d3d_priv *priv = vo->priv;
if (!priv->d3d_device) if (!priv->d3d_device)
goto done; return;
struct mp_image buffer; struct mp_image buffer;
if (!get_video_buffer(priv, &buffer)) if (!get_video_buffer(priv, &buffer))
goto done; return;
mp_image_copy(&buffer, mpi); if (!frame->current)
return;
mp_image_copy(&buffer, frame->current);
d3d_unlock_video_objects(priv); d3d_unlock_video_objects(priv);
priv->have_image = true; priv->have_image = true;
priv->osd_pts = mpi->pts; priv->osd_pts = frame->current->pts;
d3d_draw_frame(priv); d3d_draw_frame(priv);
done:
talloc_free(mpi);
} }
static mp_image_t *get_window_screenshot(d3d_priv *priv) static mp_image_t *get_window_screenshot(d3d_priv *priv)
@ -1242,7 +1239,7 @@ const struct vo_driver video_out_direct3d = {
.query_format = query_format, .query_format = query_format,
.reconfig = reconfig, .reconfig = reconfig,
.control = control, .control = control,
.draw_image = draw_image, .draw_frame = draw_frame,
.flip_page = flip_page, .flip_page = flip_page,
.uninit = uninit, .uninit = uninit,
.priv_size = sizeof(d3d_priv), .priv_size = sizeof(d3d_priv),

View File

@ -87,20 +87,19 @@ static bool checked_mkdir(struct vo *vo, const char *buf)
static int reconfig(struct vo *vo, struct mp_image_params *params) static int reconfig(struct vo *vo, struct mp_image_params *params)
{ {
struct priv *p = vo->priv;
mp_image_unrefp(&p->current);
return 0; return 0;
} }
static void draw_image(struct vo *vo, mp_image_t *mpi) static void draw_frame(struct vo *vo, struct vo_frame *frame)
{ {
struct priv *p = vo->priv; struct priv *p = vo->priv;
if (!frame->current)
return;
p->current = mpi; p->current = frame->current;
struct mp_osd_res dim = osd_res_from_image_params(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, p->current); osd_draw_on_image(vo->osd, dim, frame->current->pts, OSD_DRAW_SUB_ONLY, p->current);
} }
static void flip_page(struct vo *vo) static void flip_page(struct vo *vo)
@ -122,7 +121,6 @@ static void flip_page(struct vo *vo)
write_image(p->current, p->opts->opts, filename, vo->global, vo->log); write_image(p->current, p->opts->opts, filename, vo->global, vo->log);
talloc_free(t); talloc_free(t);
mp_image_unrefp(&p->current);
} }
static int query_format(struct vo *vo, int fmt) static int query_format(struct vo *vo, int fmt)
@ -134,9 +132,6 @@ static int query_format(struct vo *vo, int fmt)
static void uninit(struct vo *vo) static void uninit(struct vo *vo)
{ {
struct priv *p = vo->priv;
mp_image_unrefp(&p->current);
} }
static int preinit(struct vo *vo) static int preinit(struct vo *vo)
@ -163,7 +158,7 @@ const struct vo_driver video_out_image =
.query_format = query_format, .query_format = query_format,
.reconfig = reconfig, .reconfig = reconfig,
.control = control, .control = control,
.draw_image = draw_image, .draw_frame = draw_frame,
.flip_page = flip_page, .flip_page = flip_page,
.uninit = uninit, .uninit = uninit,
.global_opts = &vo_image_conf, .global_opts = &vo_image_conf,

View File

@ -32,9 +32,8 @@ struct priv {
double cfg_fps; double cfg_fps;
}; };
static void draw_image(struct vo *vo, mp_image_t *mpi) static void draw_frame(struct vo *vo, struct vo_frame *frame)
{ {
talloc_free(mpi);
} }
static void flip_page(struct vo *vo) static void flip_page(struct vo *vo)
@ -93,7 +92,7 @@ const struct vo_driver video_out_null = {
.query_format = query_format, .query_format = query_format,
.reconfig = reconfig, .reconfig = reconfig,
.control = control, .control = control,
.draw_image = draw_image, .draw_frame = draw_frame,
.flip_page = flip_page, .flip_page = flip_page,
.uninit = uninit, .uninit = uninit,
.priv_size = sizeof(struct priv), .priv_size = sizeof(struct priv),

View File

@ -869,7 +869,7 @@ static int query_format(struct vo *vo, int format)
return 0; return 0;
} }
static void draw_image(struct vo *vo, mp_image_t *mpi) static void draw_frame(struct vo *vo, struct vo_frame *frame)
{ {
struct priv *vc = vo->priv; struct priv *vc = vo->priv;
@ -879,20 +879,16 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
SDL_SetTextureBlendMode(vc->tex, SDL_BLENDMODE_NONE); SDL_SetTextureBlendMode(vc->tex, SDL_BLENDMODE_NONE);
if (mpi) { if (frame->current) {
vc->osd_pts = mpi->pts; vc->osd_pts = frame->current->pts;
mp_image_t texmpi; mp_image_t texmpi;
if (!lock_texture(vo, &texmpi)) { if (!lock_texture(vo, &texmpi))
talloc_free(mpi);
return; return;
}
mp_image_copy(&texmpi, mpi); mp_image_copy(&texmpi, frame->current);
SDL_UnlockTexture(vc->tex); SDL_UnlockTexture(vc->tex);
talloc_free(mpi);
} }
SDL_Rect src, dst; SDL_Rect src, dst;
@ -940,9 +936,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
} }
return 1; return 1;
} }
case VOCTRL_REDRAW_FRAME:
draw_image(vo, NULL);
return 1;
case VOCTRL_SET_PANSCAN: case VOCTRL_SET_PANSCAN:
force_resize(vo); force_resize(vo);
return VO_TRUE; return VO_TRUE;
@ -987,7 +980,7 @@ const struct vo_driver video_out_sdl = {
.query_format = query_format, .query_format = query_format,
.reconfig = reconfig, .reconfig = reconfig,
.control = control, .control = control,
.draw_image = draw_image, .draw_frame = draw_frame,
.uninit = uninit, .uninit = uninit,
.flip_page = flip_page, .flip_page = flip_page,
.wait_events = wait_events, .wait_events = wait_events,

View File

@ -242,13 +242,14 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
return 0; return 0;
} }
static void draw_image(struct vo *vo, mp_image_t *mpi) static void draw_frame(struct vo *vo, struct vo_frame *frame)
{ {
struct priv *p = vo->priv; struct priv *p = vo->priv;
struct mp_image src = *mpi; struct mp_image *src = frame->current;
if (!src)
return;
// XXX: pan, crop etc. // XXX: pan, crop etc.
mp_sws_scale(p->sws, p->frame, &src); mp_sws_scale(p->sws, p->frame, src);
talloc_free(mpi);
} }
static void flip_page(struct vo *vo) static void flip_page(struct vo *vo)
@ -326,7 +327,7 @@ const struct vo_driver video_out_tct = {
.query_format = query_format, .query_format = query_format,
.reconfig = reconfig, .reconfig = reconfig,
.control = control, .control = control,
.draw_image = draw_image, .draw_frame = draw_frame,
.flip_page = flip_page, .flip_page = flip_page,
.uninit = uninit, .uninit = uninit,
.priv_size = sizeof(struct priv), .priv_size = sizeof(struct priv),

View File

@ -563,11 +563,12 @@ static void get_vsync(struct vo *vo, struct vo_vsync_info *info)
present_sync_get_info(x11->present, info); present_sync_get_info(x11->present, info);
} }
static void draw_image(struct vo *vo, struct mp_image *mpi) static void draw_frame(struct vo *vo, struct vo_frame *frame)
{ {
struct priv *p = vo->priv; struct priv *p = vo->priv;
struct mp_image *mpi = frame->current;
if (mpi->imgfmt != IMGFMT_VAAPI) { if (mpi && mpi->imgfmt != IMGFMT_VAAPI) {
struct mp_image *dst = p->swdec_surfaces[p->output_surface]; struct mp_image *dst = p->swdec_surfaces[p->output_surface];
if (!dst || va_surface_upload(p, dst, mpi) < 0) { if (!dst || va_surface_upload(p, dst, mpi) < 0) {
MP_WARN(vo, "Could not upload surface.\n"); MP_WARN(vo, "Could not upload surface.\n");
@ -575,7 +576,6 @@ static void draw_image(struct vo *vo, struct mp_image *mpi)
return; return;
} }
mp_image_copy_attributes(dst, mpi); mp_image_copy_attributes(dst, mpi);
talloc_free(mpi);
mpi = mp_image_new_ref(dst); mpi = mp_image_new_ref(dst);
} }
@ -715,10 +715,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
struct priv *p = vo->priv; struct priv *p = vo->priv;
switch (request) { switch (request) {
case VOCTRL_REDRAW_FRAME:
p->output_surface = p->visible_surface;
draw_osd(vo);
return true;
case VOCTRL_SET_PANSCAN: case VOCTRL_SET_PANSCAN:
resize(p); resize(p);
return VO_TRUE; return VO_TRUE;
@ -858,7 +854,7 @@ const struct vo_driver video_out_vaapi = {
.query_format = query_format, .query_format = query_format,
.reconfig = reconfig, .reconfig = reconfig,
.control = control, .control = control,
.draw_image = draw_image, .draw_frame = draw_frame,
.flip_page = flip_page, .flip_page = flip_page,
.get_vsync = get_vsync, .get_vsync = get_vsync,
.wakeup = vo_x11_wakeup, .wakeup = vo_x11_wakeup,

View File

@ -168,10 +168,6 @@ static void freeMyXImage(struct priv *p, int foo)
static int reconfig(struct vo *vo, struct mp_image_params *fmt) static int reconfig(struct vo *vo, struct mp_image_params *fmt)
{ {
struct priv *p = vo->priv;
mp_image_unrefp(&p->original_image);
vo_x11_config_vo_window(vo); vo_x11_config_vo_window(vo);
if (!resize(vo)) if (!resize(vo))
@ -327,8 +323,7 @@ static void get_vsync(struct vo *vo, struct vo_vsync_info *info)
present_sync_get_info(x11->present, info); present_sync_get_info(x11->present, info);
} }
// Note: REDRAW_FRAME can call this with NULL. static void draw_frame(struct vo *vo, struct vo_frame *frame)
static void draw_image(struct vo *vo, mp_image_t *mpi)
{ {
struct priv *p = vo->priv; struct priv *p = vo->priv;
@ -339,29 +334,27 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
struct mp_image *img = &p->mp_ximages[p->current_buf]; struct mp_image *img = &p->mp_ximages[p->current_buf];
if (mpi) { if (frame->current) {
mp_image_clear_rc_inv(img, p->dst); mp_image_clear_rc_inv(img, p->dst);
struct mp_image src = *mpi; struct mp_image *src = frame->current;
struct mp_rect src_rc = p->src; struct mp_rect src_rc = p->src;
src_rc.x0 = MP_ALIGN_DOWN(src_rc.x0, src.fmt.align_x); src_rc.x0 = MP_ALIGN_DOWN(src_rc.x0, src->fmt.align_x);
src_rc.y0 = MP_ALIGN_DOWN(src_rc.y0, src.fmt.align_y); src_rc.y0 = MP_ALIGN_DOWN(src_rc.y0, src->fmt.align_y);
mp_image_crop_rc(&src, src_rc); mp_image_crop_rc(src, src_rc);
struct mp_image dst = *img; struct mp_image dst = *img;
mp_image_crop_rc(&dst, p->dst); mp_image_crop_rc(&dst, p->dst);
mp_sws_scale(p->sws, &dst, &src); mp_sws_scale(p->sws, &dst, src);
} else { } else {
mp_image_clear(img, 0, 0, img->w, img->h); mp_image_clear(img, 0, 0, img->w, img->h);
} }
osd_draw_on_image(vo->osd, p->osd, mpi ? mpi->pts : 0, 0, img); osd_draw_on_image(vo->osd, p->osd, frame->current ? frame->current->pts : 0, 0, img);
if (mpi != p->original_image) { if (frame->current != p->original_image)
talloc_free(p->original_image); p->original_image = frame->current;
p->original_image = mpi;
}
} }
static int query_format(struct vo *vo, int format) static int query_format(struct vo *vo, int format)
@ -382,8 +375,6 @@ static void uninit(struct vo *vo)
if (p->gc) if (p->gc)
XFreeGC(vo->x11->display, p->gc); XFreeGC(vo->x11->display, p->gc);
talloc_free(p->original_image);
vo_x11_uninit(vo); vo_x11_uninit(vo);
} }
@ -424,15 +415,11 @@ error:
static int control(struct vo *vo, uint32_t request, void *data) static int control(struct vo *vo, uint32_t request, void *data)
{ {
struct priv *p = vo->priv;
switch (request) { switch (request) {
case VOCTRL_SET_PANSCAN: case VOCTRL_SET_PANSCAN:
if (vo->config_ok) if (vo->config_ok)
resize(vo); resize(vo);
return VO_TRUE; return VO_TRUE;
case VOCTRL_REDRAW_FRAME:
draw_image(vo, p->original_image);
return true;
} }
int events = 0; int events = 0;
@ -451,7 +438,7 @@ const struct vo_driver video_out_x11 = {
.query_format = query_format, .query_format = query_format,
.reconfig = reconfig, .reconfig = reconfig,
.control = control, .control = control,
.draw_image = draw_image, .draw_frame = draw_frame,
.flip_page = flip_page, .flip_page = flip_page,
.get_vsync = get_vsync, .get_vsync = get_vsync,
.wakeup = vo_x11_wakeup, .wakeup = vo_x11_wakeup,

View File

@ -465,8 +465,6 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
struct xvctx *ctx = vo->priv; struct xvctx *ctx = vo->priv;
int i; int i;
mp_image_unrefp(&ctx->original_image);
ctx->image_height = params->h; ctx->image_height = params->h;
ctx->image_width = params->w; ctx->image_width = params->w;
ctx->image_format = params->imgfmt; ctx->image_format = params->imgfmt;
@ -702,8 +700,7 @@ static void get_vsync(struct vo *vo, struct vo_vsync_info *info)
present_sync_get_info(x11->present, info); present_sync_get_info(x11->present, info);
} }
// Note: REDRAW_FRAME can call this with NULL. static void draw_frame(struct vo *vo, struct vo_frame *frame)
static void draw_image(struct vo *vo, mp_image_t *mpi)
{ {
struct xvctx *ctx = vo->priv; struct xvctx *ctx = vo->priv;
@ -713,19 +710,17 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
return; return;
struct mp_image xv_buffer = get_xv_buffer(vo, ctx->current_buf); struct mp_image xv_buffer = get_xv_buffer(vo, ctx->current_buf);
if (mpi) { if (frame->current) {
mp_image_copy(&xv_buffer, mpi); mp_image_copy(&xv_buffer, frame->current);
} else { } else {
mp_image_clear(&xv_buffer, 0, 0, xv_buffer.w, xv_buffer.h); 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); 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); osd_draw_on_image(vo->osd, res, frame->current ? frame->current->pts : 0, 0, &xv_buffer);
if (mpi != ctx->original_image) { if (frame->current != ctx->original_image)
talloc_free(ctx->original_image); ctx->original_image = frame->current;
ctx->original_image = mpi;
}
} }
static int query_format(struct vo *vo, int format) static int query_format(struct vo *vo, int format)
@ -748,8 +743,6 @@ static void uninit(struct vo *vo)
struct xvctx *ctx = vo->priv; struct xvctx *ctx = vo->priv;
int i; int i;
talloc_free(ctx->original_image);
if (ctx->ai) if (ctx->ai)
XvFreeAdaptorInfo(ctx->ai); XvFreeAdaptorInfo(ctx->ai);
ctx->ai = NULL; ctx->ai = NULL;
@ -872,14 +865,10 @@ static int preinit(struct vo *vo)
static int control(struct vo *vo, uint32_t request, void *data) static int control(struct vo *vo, uint32_t request, void *data)
{ {
struct xvctx *ctx = vo->priv;
switch (request) { switch (request) {
case VOCTRL_SET_PANSCAN: case VOCTRL_SET_PANSCAN:
resize(vo); resize(vo);
return VO_TRUE; return VO_TRUE;
case VOCTRL_REDRAW_FRAME:
draw_image(vo, ctx->original_image);
return true;
} }
int events = 0; int events = 0;
int r = vo_x11_control(vo, &events, request, data); int r = vo_x11_control(vo, &events, request, data);
@ -898,7 +887,7 @@ const struct vo_driver video_out_xv = {
.query_format = query_format, .query_format = query_format,
.reconfig = reconfig, .reconfig = reconfig,
.control = control, .control = control,
.draw_image = draw_image, .draw_frame = draw_frame,
.flip_page = flip_page, .flip_page = flip_page,
.get_vsync = get_vsync, .get_vsync = get_vsync,
.wakeup = vo_x11_wakeup, .wakeup = vo_x11_wakeup,