Skip to content

Commit

Permalink
vo_xv: Free resources in error cases
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Uoti Urpala committed Apr 23, 2008
1 parent b918262 commit f894294
Showing 1 changed file with 19 additions and 9 deletions.
28 changes: 19 additions & 9 deletions libvo/vo_xv.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ struct xvctx {
int is_paused;
uint32_t drwX, drwY;
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,
unsigned char *src, unsigned char *srca,
int stride);
Expand Down Expand Up @@ -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,
&modeline_height);
ctx->mode_switched = 1;
hint.x = (vo_screenwidth - modeline_width) / 2;
hint.y = (vo_screenheight - modeline_height) / 2;
hint.width = modeline_width;
Expand Down Expand Up @@ -684,10 +687,9 @@ static void uninit(struct vo *vo)
struct xvctx *ctx = vo->priv;
int i;

if (!vo_config_count)
return;
ctx->visible_buf = -1;
XvFreeAdaptorInfo(ctx->ai);
if (ctx->ai)
XvFreeAdaptorInfo(ctx->ai);
ctx->ai = NULL;
if (ctx->fo) {
XFree(ctx->fo);
Expand All @@ -696,9 +698,12 @@ static void uninit(struct vo *vo)
for (i = 0; i < ctx->num_buffers; i++)
deallocate_xvimage(vo, i);
#ifdef HAVE_XF86VM
vo_vm_close(mDisplay);
if (ctx->mode_switched)
vo_vm_close(mDisplay);
#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();
free(ctx);
vo->priv = NULL;
Expand Down Expand Up @@ -748,7 +753,7 @@ static int preinit(struct vo *vo, const char *arg)
{
mp_msg(MSGT_VO, MSGL_ERR,
MSGTR_LIBVO_XV_XvNotSupportedByX11);
return -1;
goto error;
}

/* check for Xvideo support */
Expand All @@ -757,7 +762,7 @@ static int preinit(struct vo *vo, const char *arg)
&ctx->ai))
{
mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_XV_XvQueryAdaptorsFailed);
return -1;
goto error;
}

/* check adaptors */
Expand Down Expand Up @@ -818,20 +823,25 @@ static int preinit(struct vo *vo, const char *arg)
else
mp_msg(MSGT_VO, MSGL_ERR,
MSGTR_LIBVO_XV_NoXvideoSupport);
return -1;
goto error;
}

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_get_max_img_dim(&ctx->max_width, &ctx->max_height);

ctx->fo = XvListImageFormats(mDisplay, xv_port, (int *) &ctx->formats);

mp_input_add_event_fd(ConnectionNumber(mDisplay), x11_fd_callback, vo);
ctx->event_fd_registered = 1;
return 0;

error:
uninit(vo); // free resources
return -1;
}

static int control(struct vo *vo, uint32_t request, void *data)
Expand Down

0 comments on commit f894294

Please sign in to comment.