1
0
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:
Uoti Urpala 2008-04-04 09:57:58 +03:00
parent b91826280c
commit f894294bae

View File

@ -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)