mirror of
https://github.com/mpv-player/mpv
synced 2025-01-12 09:59:44 +00:00
vo_xv: Free resources in error cases
If preinit() failed after allocating some resources it didn't free them. Also if preinit() completed but all (if any) calls to config() failed then uninit() it not free resources. Add checks to uninit() to make it safe with only a subset of resources allocated, then make it execute independently of vo_config_count and also make preinit() call it in error cases.
This commit is contained in:
parent
b91826280c
commit
f894294bae
@ -82,6 +82,8 @@ struct xvctx {
|
|||||||
int is_paused;
|
int is_paused;
|
||||||
uint32_t drwX, drwY;
|
uint32_t drwX, drwY;
|
||||||
uint32_t max_width, max_height; // zero means: not set
|
uint32_t max_width, max_height; // zero means: not set
|
||||||
|
int event_fd_registered; // for uninit called from preinit
|
||||||
|
int mode_switched;
|
||||||
void (*draw_alpha_fnc)(void *ctx, int x0, int y0, int w, int h,
|
void (*draw_alpha_fnc)(void *ctx, int x0, int y0, int w, int h,
|
||||||
unsigned char *src, unsigned char *srca,
|
unsigned char *src, unsigned char *srca,
|
||||||
int stride);
|
int stride);
|
||||||
@ -239,6 +241,7 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
|
|||||||
}
|
}
|
||||||
vo_vm_switch(vm_width, vm_height, &modeline_width,
|
vo_vm_switch(vm_width, vm_height, &modeline_width,
|
||||||
&modeline_height);
|
&modeline_height);
|
||||||
|
ctx->mode_switched = 1;
|
||||||
hint.x = (vo_screenwidth - modeline_width) / 2;
|
hint.x = (vo_screenwidth - modeline_width) / 2;
|
||||||
hint.y = (vo_screenheight - modeline_height) / 2;
|
hint.y = (vo_screenheight - modeline_height) / 2;
|
||||||
hint.width = modeline_width;
|
hint.width = modeline_width;
|
||||||
@ -684,10 +687,9 @@ static void uninit(struct vo *vo)
|
|||||||
struct xvctx *ctx = vo->priv;
|
struct xvctx *ctx = vo->priv;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!vo_config_count)
|
|
||||||
return;
|
|
||||||
ctx->visible_buf = -1;
|
ctx->visible_buf = -1;
|
||||||
XvFreeAdaptorInfo(ctx->ai);
|
if (ctx->ai)
|
||||||
|
XvFreeAdaptorInfo(ctx->ai);
|
||||||
ctx->ai = NULL;
|
ctx->ai = NULL;
|
||||||
if (ctx->fo) {
|
if (ctx->fo) {
|
||||||
XFree(ctx->fo);
|
XFree(ctx->fo);
|
||||||
@ -696,9 +698,12 @@ static void uninit(struct vo *vo)
|
|||||||
for (i = 0; i < ctx->num_buffers; i++)
|
for (i = 0; i < ctx->num_buffers; i++)
|
||||||
deallocate_xvimage(vo, i);
|
deallocate_xvimage(vo, i);
|
||||||
#ifdef HAVE_XF86VM
|
#ifdef HAVE_XF86VM
|
||||||
vo_vm_close(mDisplay);
|
if (ctx->mode_switched)
|
||||||
|
vo_vm_close(mDisplay);
|
||||||
#endif
|
#endif
|
||||||
mp_input_rm_event_fd(ConnectionNumber(mDisplay));
|
if (ctx->event_fd_registered)
|
||||||
|
mp_input_rm_event_fd(ConnectionNumber(mDisplay));
|
||||||
|
// uninit() shouldn't get called unless initialization went past vo_init()
|
||||||
vo_x11_uninit();
|
vo_x11_uninit();
|
||||||
free(ctx);
|
free(ctx);
|
||||||
vo->priv = NULL;
|
vo->priv = NULL;
|
||||||
@ -748,7 +753,7 @@ static int preinit(struct vo *vo, const char *arg)
|
|||||||
{
|
{
|
||||||
mp_msg(MSGT_VO, MSGL_ERR,
|
mp_msg(MSGT_VO, MSGL_ERR,
|
||||||
MSGTR_LIBVO_XV_XvNotSupportedByX11);
|
MSGTR_LIBVO_XV_XvNotSupportedByX11);
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for Xvideo support */
|
/* check for Xvideo support */
|
||||||
@ -757,7 +762,7 @@ static int preinit(struct vo *vo, const char *arg)
|
|||||||
&ctx->ai))
|
&ctx->ai))
|
||||||
{
|
{
|
||||||
mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_XV_XvQueryAdaptorsFailed);
|
mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_XV_XvQueryAdaptorsFailed);
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check adaptors */
|
/* check adaptors */
|
||||||
@ -818,12 +823,12 @@ static int preinit(struct vo *vo, const char *arg)
|
|||||||
else
|
else
|
||||||
mp_msg(MSGT_VO, MSGL_ERR,
|
mp_msg(MSGT_VO, MSGL_ERR,
|
||||||
MSGTR_LIBVO_XV_NoXvideoSupport);
|
MSGTR_LIBVO_XV_NoXvideoSupport);
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !vo_xv_init_colorkey() )
|
if ( !vo_xv_init_colorkey() )
|
||||||
{
|
{
|
||||||
return -1; // bail out, colorkey setup failed
|
goto error; // bail out, colorkey setup failed
|
||||||
}
|
}
|
||||||
vo_xv_enable_vsync();
|
vo_xv_enable_vsync();
|
||||||
vo_xv_get_max_img_dim(&ctx->max_width, &ctx->max_height);
|
vo_xv_get_max_img_dim(&ctx->max_width, &ctx->max_height);
|
||||||
@ -831,7 +836,12 @@ static int preinit(struct vo *vo, const char *arg)
|
|||||||
ctx->fo = XvListImageFormats(mDisplay, xv_port, (int *) &ctx->formats);
|
ctx->fo = XvListImageFormats(mDisplay, xv_port, (int *) &ctx->formats);
|
||||||
|
|
||||||
mp_input_add_event_fd(ConnectionNumber(mDisplay), x11_fd_callback, vo);
|
mp_input_add_event_fd(ConnectionNumber(mDisplay), x11_fd_callback, vo);
|
||||||
|
ctx->event_fd_registered = 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
uninit(vo); // free resources
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int control(struct vo *vo, uint32_t request, void *data)
|
static int control(struct vo *vo, uint32_t request, void *data)
|
||||||
|
Loading…
Reference in New Issue
Block a user