diff options
author | Uoti Urpala <uau@symbol.nonexistent.invalid> | 2008-04-04 09:57:58 +0300 |
---|---|---|
committer | Uoti Urpala <uau@symbol.nonexistent.invalid> | 2008-04-23 13:41:05 +0300 |
commit | f894294bae1ff9b2c1802a5ae7e73cfdbc26e645 (patch) | |
tree | 946aafc44d5c9c82a6838c8bd282f40d04808243 | |
parent | b91826280c468b1b5b4baf6e0225dfdb878e214a (diff) | |
download | mpv-f894294bae1ff9b2c1802a5ae7e73cfdbc26e645.tar.bz2 mpv-f894294bae1ff9b2c1802a5ae7e73cfdbc26e645.tar.xz |
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.
-rw-r--r-- | libvo/vo_xv.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c index b7c24948af..fa25f673e4 100644 --- a/libvo/vo_xv.c +++ b/libvo/vo_xv.c @@ -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); @@ -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; @@ -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); @@ -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; @@ -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 */ @@ -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 */ @@ -818,12 +823,12 @@ 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); @@ -831,7 +836,12 @@ static int preinit(struct vo *vo, const char *arg) 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) |