Commit a844bbbb authored by Jean-Paul Saman's avatar Jean-Paul Saman

codec/avcodec/vaapi: Pass VASurface' s to vaapi-x11 vout

When -V vaapi-x11 is used (and ffmpeg-vaapi-x11 option), then pass
VASurface information in picture->p_sys. This only works with direct
rendering and video filters that directly operate on the picture are
a no go.

* vaapi.c: protect surface->i_refcount
* vaapi_x11.c: use direct rendering
parent 92ba7483
/***************************************************************************** /*****************************************************************************
* vaapi.c: VAAPI helpers for the ffmpeg decoder * vaapi.c: VAAPI helpers for the ffmpeg decoder
***************************************************************************** *****************************************************************************
* Copyright (C) 2009 Laurent Aimar * Copyright (C) 2009-2011 Laurent Aimar
* $Id$ * $Id$
* *
* Authors: Laurent Aimar <fenrir_AT_ videolan _DOT_ org> * Authors: Laurent Aimar <fenrir_AT_ videolan _DOT_ org>
...@@ -48,14 +48,6 @@ ...@@ -48,14 +48,6 @@
#ifdef HAVE_AVCODEC_VAAPI #ifdef HAVE_AVCODEC_VAAPI
typedef struct
{
VASurfaceID i_id;
int i_refcount;
unsigned int i_order;
} vlc_va_surface_t;
typedef struct typedef struct
{ {
vlc_va_t va; vlc_va_t va;
...@@ -176,7 +168,7 @@ static void DestroySurfaces( vlc_va_vaapi_t *p_va ) ...@@ -176,7 +168,7 @@ static void DestroySurfaces( vlc_va_vaapi_t *p_va )
for( int i = 0; i < p_va->i_surface_count && p_va->p_surface; i++ ) for( int i = 0; i < p_va->i_surface_count && p_va->p_surface; i++ )
{ {
vlc_va_surface_t *p_surface = &p_va->p_surface[i]; vlc_va_surface_t *p_surface = &p_va->p_surface[i];
vlc_mutex_destroy(&p_surface->lock);
if( p_surface->i_id != VA_INVALID_SURFACE ) if( p_surface->i_id != VA_INVALID_SURFACE )
vaDestroySurfaces( p_va->conn->p_display, &p_surface->i_id, 1 ); vaDestroySurfaces( p_va->conn->p_display, &p_surface->i_id, 1 );
} }
...@@ -218,6 +210,7 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t ...@@ -218,6 +210,7 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t
p_surface->i_id = pi_surface_id[i]; p_surface->i_id = pi_surface_id[i];
p_surface->i_refcount = 0; p_surface->i_refcount = 0;
p_surface->i_order = 0; p_surface->i_order = 0;
vlc_mutex_init(&p_surface->lock);
} }
/* Create a context */ /* Create a context */
...@@ -388,12 +381,33 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff ) ...@@ -388,12 +381,33 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
static vlc_va_surface_t *FindSurface( vlc_va_t *p_external, const VASurfaceID i_surface_id )
{ {
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external); vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external);
vlc_va_surface_t *p_surface = NULL;
if( !p_va->image_cache.buffer ) for( int i = 0; i < p_va->i_surface_count; i++ )
return VLC_EGENERIC; {
vlc_va_surface_t *p_tmp = &p_va->p_surface[i];
if( p_tmp->i_id == i_surface_id )
{
vlc_mutex_lock(&p_tmp->lock);
/* NOTE: p_tmp->i_refcount can be greater then 1, when surfaces are being reclaimed
* this usually only happens when the vout vaapi-x11 is not instantiated yet.
*/
p_tmp->i_refcount++;
p_surface = p_tmp;
vlc_mutex_unlock(&p_surface->lock);
break;
}
}
return p_surface;
}
static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
{
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external);
VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3]; VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3];
...@@ -404,12 +418,19 @@ static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame * ...@@ -404,12 +418,19 @@ static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame *
#endif #endif
return VLC_EGENERIC; return VLC_EGENERIC;
assert(p_picture->p_sys);
if (!p_picture->p_sys) if (!p_picture->p_sys)
return VLC_ENOMEM; return VLC_EGENERIC;
assert( sizeof(p_picture->p_sys) == sizeof(picture_sys_t) ); assert( sizeof(p_picture->p_sys) == sizeof(picture_sys_t) );
p_picture->p_sys->i_surface_id = i_surface_id; /* FindSurface */
p_picture->p_sys->surface = FindSurface( p_external, i_surface_id );
if( !p_picture->p_sys->surface )
return VLC_EGENERIC;
p_picture->format.i_width = p_picture->format.i_visible_width = p_va->i_surface_width;
p_picture->format.i_height = p_picture->format.i_visible_height = p_va->i_surface_height;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -425,7 +446,7 @@ static int Get( vlc_va_t *p_external, AVFrame *p_ff ) ...@@ -425,7 +446,7 @@ static int Get( vlc_va_t *p_external, AVFrame *p_ff )
{ {
vlc_va_surface_t *p_surface = &p_va->p_surface[i]; vlc_va_surface_t *p_surface = &p_va->p_surface[i];
if( !p_surface->i_refcount ) if( p_surface->i_refcount == 0 )
break; break;
if( p_surface->i_order < p_va->p_surface[i_old].i_order ) if( p_surface->i_order < p_va->p_surface[i_old].i_order )
...@@ -435,9 +456,13 @@ static int Get( vlc_va_t *p_external, AVFrame *p_ff ) ...@@ -435,9 +456,13 @@ static int Get( vlc_va_t *p_external, AVFrame *p_ff )
i = i_old; i = i_old;
vlc_va_surface_t *p_surface = &p_va->p_surface[i]; vlc_va_surface_t *p_surface = &p_va->p_surface[i];
vlc_mutex_lock(&p_surface->lock);
p_surface->i_refcount = 1; /* NOTE: when the surface is in use and not consumed by vout vaapi-x11,
* then p_surface->i_refcount can be greater then 0. Thus always increment.
*/
p_surface->i_refcount++;
p_surface->i_order = p_va->i_surface_order++; p_surface->i_order = p_va->i_surface_order++;
vlc_mutex_unlock(&p_surface->lock);
/* */ /* */
for( int i = 0; i < 4; i++ ) for( int i = 0; i < 4; i++ )
...@@ -461,7 +486,11 @@ static void Release( vlc_va_t *p_external, AVFrame *p_ff ) ...@@ -461,7 +486,11 @@ static void Release( vlc_va_t *p_external, AVFrame *p_ff )
vlc_va_surface_t *p_surface = &p_va->p_surface[i]; vlc_va_surface_t *p_surface = &p_va->p_surface[i];
if( p_surface->i_id == i_surface_id ) if( p_surface->i_id == i_surface_id )
{
vlc_mutex_lock(&p_surface->lock);
p_surface->i_refcount--; p_surface->i_refcount--;
vlc_mutex_unlock(&p_surface->lock);
}
} }
} }
......
...@@ -52,11 +52,6 @@ ...@@ -52,11 +52,6 @@
#include <X11/Xutil.h> #include <X11/Xutil.h>
/* It must be large enough to absorb the server display jitter but it is
* useless to used a too large value.
*/
#define MAX_PICTURES (3)
typedef struct vlc_vaapi_x11_window_t typedef struct vlc_vaapi_x11_window_t
{ {
int screen; int screen;
...@@ -78,11 +73,11 @@ struct vout_display_sys_t ...@@ -78,11 +73,11 @@ struct vout_display_sys_t
}; };
static picture_pool_t *Pool (vout_display_t *, unsigned); static picture_pool_t *Pool (vout_display_t *, unsigned);
static void PictureDisplay (vout_display_t *, picture_t *, subpicture_t *); static void DisplayPicture (vout_display_t *, picture_t *, subpicture_t *);
static int Control (vout_display_t *, int, va_list); static int Control (vout_display_t *, int, va_list);
static void Manage (vout_display_t *); static void Manage (vout_display_t *);
/* */
static int FindVAFourCC(vout_display_t *vd) static int FindVAFourCC(vout_display_t *vd)
{ {
vout_display_sys_t *sys = (vout_display_sys_t *) vd->sys; vout_display_sys_t *sys = (vout_display_sys_t *) vd->sys;
...@@ -136,18 +131,8 @@ static int CreateWindow(vout_display_t *vd) ...@@ -136,18 +131,8 @@ static int CreateWindow(vout_display_t *vd)
XWindowAttributes attr; XWindowAttributes attr;
XGetWindowAttributes(sys->conn->p_display_x11, sys->x11.root, &attr); XGetWindowAttributes(sys->conn->p_display_x11, sys->x11.root, &attr);
uint32_t depth = attr.depth; uint32_t depth = attr.depth;
switch(attr.depth) if (depth != 15 && depth != 16 && depth != 24 && depth != 32)
{ depth = 24;
case 8:
case 15:
case 16:
case 24:
case 32: /* de nothing */
break;
default:
depth = 24;
break;
}
XVisualInfo vi; XVisualInfo vi;
XVisualInfo *vi_info = &vi; XVisualInfo *vi_info = &vi;
...@@ -159,6 +144,9 @@ static int CreateWindow(vout_display_t *vd) ...@@ -159,6 +144,9 @@ static int CreateWindow(vout_display_t *vd)
xswa.border_pixel = BlackPixel(sys->conn->p_display_x11, sys->x11.screen); xswa.border_pixel = BlackPixel(sys->conn->p_display_x11, sys->x11.screen);
xswa.background_pixel = WhitePixel(sys->conn->p_display_x11, sys->x11.screen); xswa.background_pixel = WhitePixel(sys->conn->p_display_x11, sys->x11.screen);
msg_Info(vd, "Creating X11 window with: x=%d,y=%d - w=%d,h=%d",
vd->source.i_y_offset, vd->source.i_x_offset,
vd->cfg->display.width, vd->cfg->display.height);
sys->x11.window = XCreateWindow(sys->conn->p_display_x11, sys->x11.root, sys->x11.window = XCreateWindow(sys->conn->p_display_x11, sys->x11.root,
vd->source.i_y_offset, vd->source.i_x_offset, vd->source.i_y_offset, vd->source.i_x_offset,
vd->cfg->display.width, vd->cfg->display.height, vd->cfg->display.width, vd->cfg->display.height,
...@@ -178,7 +166,7 @@ static void DestroyWindow(vout_display_t *vd) ...@@ -178,7 +166,7 @@ static void DestroyWindow(vout_display_t *vd)
{ {
vout_display_sys_t *sys = (vout_display_sys_t *) vd->sys; vout_display_sys_t *sys = (vout_display_sys_t *) vd->sys;
if (sys->x11.window) if (sys->x11.window != None)
{ {
XUnmapWindow(sys->conn->p_display_x11, sys->x11.window); XUnmapWindow(sys->conn->p_display_x11, sys->x11.window);
//x11_wait_event(sys->conn->p_display_x11, sys->x11.window, UnmapNotify); //x11_wait_event(sys->conn->p_display_x11, sys->x11.window, UnmapNotify);
...@@ -210,8 +198,11 @@ static vout_window_t *MakeWindow (vout_display_t *vd) ...@@ -210,8 +198,11 @@ static vout_window_t *MakeWindow (vout_display_t *vd)
int OpenVaapiX11 (vlc_object_t *obj) int OpenVaapiX11 (vlc_object_t *obj)
{ {
vout_display_t *vd = (vout_display_t *) obj; vout_display_t *vd = (vout_display_t *) obj;
vout_display_sys_t *sys = malloc(sizeof(*sys));
if( !vlc_xlib_init( obj ) )
return VLC_EGENERIC;
vout_display_sys_t *sys = malloc(sizeof(*sys));
if (unlikely(sys == NULL)) if (unlikely(sys == NULL))
return VLC_ENOMEM; return VLC_ENOMEM;
...@@ -220,6 +211,7 @@ int OpenVaapiX11 (vlc_object_t *obj) ...@@ -220,6 +211,7 @@ int OpenVaapiX11 (vlc_object_t *obj)
sys->conn = NULL; sys->conn = NULL;
sys->pool = NULL; sys->pool = NULL;
sys->visible = false; sys->visible = false;
sys->embed = MakeWindow(vd); sys->embed = MakeWindow(vd);
if (unlikely(sys->embed == NULL)) if (unlikely(sys->embed == NULL))
goto error; goto error;
...@@ -240,15 +232,18 @@ int OpenVaapiX11 (vlc_object_t *obj) ...@@ -240,15 +232,18 @@ int OpenVaapiX11 (vlc_object_t *obj)
/* */ /* */
vout_display_info_t info = vd->info; vout_display_info_t info = vd->info;
info.has_pictures_invalid = true; info.is_slow = false;
info.has_pictures_invalid = false;
info.has_event_thread = false; info.has_event_thread = false;
info.has_hide_mouse = false;
info.subpicture_chromas = &vd->fmt.i_chroma;
/* Setup vout_display_t once everything is fine */ /* Setup vout_display_t once everything is fine */
vd->info = info; vd->info = info;
vd->pool = Pool; vd->pool = Pool;
vd->prepare = NULL; //PictureRender; vd->prepare = NULL; //PictureRender;
vd->display = PictureDisplay; vd->display = DisplayPicture;
vd->control = Control; vd->control = Control;
vd->manage = NULL; //Manage; vd->manage = NULL; //Manage;
...@@ -306,55 +301,61 @@ static int Control (vout_display_t *vd, int query, va_list ap) ...@@ -306,55 +301,61 @@ static int Control (vout_display_t *vd, int query, va_list ap)
return vout_window_SetFullScreen (sys->embed, c->is_fullscreen); return vout_window_SetFullScreen (sys->embed, c->is_fullscreen);
} }
case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
{
const vout_display_cfg_t *p_cfg =
(const vout_display_cfg_t*)va_arg (ap, const vout_display_cfg_t *);
const bool is_forced = (bool)va_arg (ap, int);
if (is_forced
&& vout_window_SetSize (sys->embed,
p_cfg->display.width,
p_cfg->display.height))
return VLC_EGENERIC;
vout_display_place_t place;
vout_display_PlacePicture (&place, &vd->source, p_cfg, false);
if (place.width != vd->fmt.i_visible_width ||
place.height != vd->fmt.i_visible_height)
{
vout_display_SendEventPicturesInvalid (vd);
return VLC_SUCCESS;
}
#if 0 /* FIXME */
/* Move the picture within the window */
const uint32_t values[] = { place.x, place.y };
xcb_configure_window (sys->conn, sys->window,
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
values);
#endif
return VLC_SUCCESS;
}
case VOUT_DISPLAY_CHANGE_WINDOW_STATE: case VOUT_DISPLAY_CHANGE_WINDOW_STATE:
{ {
unsigned state = va_arg (ap, unsigned); unsigned state = va_arg (ap, unsigned);
return vout_window_SetState (sys->embed, state); return vout_window_SetState (sys->embed, state);
} }
case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
case VOUT_DISPLAY_CHANGE_ZOOM: case VOUT_DISPLAY_CHANGE_ZOOM:
case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED: case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT: case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
case VOUT_DISPLAY_CHANGE_SOURCE_CROP: case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
{
/* I am not sure it is always necessary, but it is way simpler ... */ /* I am not sure it is always necessary, but it is way simpler ... */
vout_display_SendEventPicturesInvalid (vd); /* FIXME: adjust picture size */
return VLC_SUCCESS; const vout_display_cfg_t *cfg;
const video_format_t *source;
bool is_forced = false;
if (query == VOUT_DISPLAY_CHANGE_SOURCE_ASPECT
|| query == VOUT_DISPLAY_CHANGE_SOURCE_CROP)
{
source = (const video_format_t *)va_arg (ap, const video_format_t *);
cfg = vd->cfg;
}
else
{
source = &vd->source;
cfg = (const vout_display_cfg_t*)va_arg (ap, const vout_display_cfg_t *);
if (query == VOUT_DISPLAY_CHANGE_DISPLAY_SIZE)
is_forced = (bool)va_arg (ap, int);
}
/* */
if (query == VOUT_DISPLAY_CHANGE_DISPLAY_SIZE
&& is_forced
&& (cfg->display.width != vd->cfg->display.width
||cfg->display.height != vd->cfg->display.height)
&& vout_window_SetSize (sys->embed,
cfg->display.width, cfg->display.height))
return VLC_EGENERIC;
vout_display_place_t place;
vout_display_PlacePicture (&place, source, cfg, false);
return VLC_SUCCESS;
}
case VOUT_DISPLAY_RESET_PICTURES: case VOUT_DISPLAY_RESET_PICTURES:
{ {
picture_pool_Delete (sys->pool); #if 0
sys->pool = NULL; if (sys->pool)
{
picture_pool_Delete (sys->pool);
sys->pool = NULL;
}
#endif
vout_display_place_t place; vout_display_place_t place;
vout_display_PlacePicture (&place, &vd->source, vd->cfg, false); vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);
...@@ -368,14 +369,12 @@ static int Control (vout_display_t *vd, int query, va_list ap) ...@@ -368,14 +369,12 @@ static int Control (vout_display_t *vd, int query, va_list ap)
return VLC_SUCCESS; return VLC_SUCCESS;
} }
#if 0 /* FIXME */
/* Hide the mouse. It will be send when /* Hide the mouse. It will be send when
* vout_display_t::info.b_hide_mouse is false */ * vout_display_t::info.b_hide_mouse is false */
case VOUT_DISPLAY_HIDE_MOUSE: case VOUT_DISPLAY_HIDE_MOUSE:
xcb_change_window_attributes (sys->conn, sys->embed->handle.xid, /* FIXME */
XCB_CW_CURSOR, &(uint32_t){ sys->cursor });
return VLC_SUCCESS; return VLC_SUCCESS;
#endif
default: default:
msg_Err (vd, "Unknown request in XCB vout display"); msg_Err (vd, "Unknown request in XCB vout display");
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -393,7 +392,22 @@ static void Manage (vout_display_t *vd) ...@@ -393,7 +392,22 @@ static void Manage (vout_display_t *vd)
#endif #endif
} }
static void PictureDisplay (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture) static void PictureRelease(picture_t *pic)
{
assert(pic);
assert(sizeof(pic->p_sys) == sizeof(picture_sys_t));
if( pic->p_sys->surface )
{
vlc_mutex_lock(&pic->p_sys->surface->lock);
pic->p_sys->surface->i_refcount--;
assert(pic->p_sys->surface->i_refcount == 0);
vlc_mutex_unlock(&pic->p_sys->surface->lock);
pic->p_sys->surface = NULL;
}
}
static void DisplayPicture(vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
{ {
vout_display_sys_t *sys = vd->sys; vout_display_sys_t *sys = vd->sys;
VLC_UNUSED(subpicture); VLC_UNUSED(subpicture);
...@@ -406,94 +420,100 @@ static void PictureDisplay (vout_display_t *vd, picture_t *pic, subpicture_t *su ...@@ -406,94 +420,100 @@ static void PictureDisplay (vout_display_t *vd, picture_t *pic, subpicture_t *su
#endif #endif
vout_display_place_t place; vout_display_place_t place;
vout_display_PlacePicture (&place, &vd->source, vd->cfg, false); vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);
VARectangle va_rec = { .x = place.x, .y = place.y,
.width = place.width, .height = place.height };
unsigned int flags = VA_FRAME_PICTURE; unsigned int flags = VA_FRAME_PICTURE;
if (!pic->b_progressive) if (!pic->b_progressive)
flags = pic->b_top_field_first ? VA_TOP_FIELD : VA_BOTTOM_FIELD; flags = pic->b_top_field_first ? VA_TOP_FIELD : VA_BOTTOM_FIELD;
VASurfaceID i_surface_id = pic->p_sys->i_surface_id; assert(pic->p_sys);
if (pic->p_sys->surface == NULL)
{
msg_Err(vd, "Discarding picture - no surface information");
picture_Release(pic);
return;
}
if (pic->p_sys->surface->i_refcount > 1)
{
vlc_mutex_lock(&pic->p_sys->surface->lock);
msg_Err(vd, "Reclaimed picture - %d (%p)", pic->p_sys->surface->i_id, pic);
pic->p_sys->surface->i_refcount--;
assert(pic->p_sys->surface->i_refcount < 3);
vlc_mutex_unlock(&pic->p_sys->surface->lock);
return;
}
VASurfaceID i_surface_id = pic->p_sys->surface->i_id;
assert(sys->x11.window != None);
VAStatus status = vaPutSurface(sys->conn->p_display, VAStatus status = vaPutSurface(sys->conn->p_display,
i_surface_id, i_surface_id,
sys->x11.window, sys->x11.window,
pic->format.i_y_offset, pic->format.i_x_offset,
pic->format.i_visible_width, pic->format.i_visible_height,
vd->source.i_y_offset, vd->source.i_x_offset, vd->source.i_y_offset, vd->source.i_x_offset,
vd->fmt.i_visible_width, vd->fmt.i_visible_height, vd->fmt.i_visible_width, vd->fmt.i_visible_height,
place.x, place.y, place.width, place.height, NULL, 0, //&va_rec, 1, /* client supplied destination clip list, cliplist count */
NULL, 0, /* client supplied destination clip list, cliplist count */
flags); flags);
if (status != VA_STATUS_SUCCESS) if (status != VA_STATUS_SUCCESS)
msg_Err(vd, "failed displaying picture"); msg_Err(vd, "failed displaying picture (id=%d) %d", i_surface_id, status);
PictureRelease(pic); /* Release pic->p_sys->surface */
picture_Release(pic); picture_Release(pic);
} }
static void vlc_va_PictureRelease(picture_t *pic)
{
assert(pic);
assert(sizeof(pic->p_sys) == sizeof(picture_sys_t));
if( --pic->i_refcount > 0 )
return;
picture_Delete(pic);
}
/** /**
* Return a direct buffer * Return a direct buffer
*/ */
static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count) static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
{ {
vout_display_sys_t *sys = vd->sys; vout_display_sys_t *sys = vd->sys;
VLC_UNUSED(requested_count);
assert(requested_count > 0);
if (sys->pool) if (sys->pool)
return sys->pool; return sys->pool;
#if 0 picture_t **pic_array = (picture_t **) calloc(requested_count, sizeof(picture_t *));
vout_display_place_t place; if (!pic_array)
vout_display_PlacePicture (&place, &vd->source, vd->cfg, false); return NULL;
const uint32_t values[] = { place.x, place.y, place.width, place.height };
xcb_configure_window (sys->conn, sys->window,
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
values);
#endif
picture_t *pic_array[MAX_PICTURES];
unsigned int count; unsigned int count;
for (count = 0; count < MAX_PICTURES; count++) for (count = 0; count < requested_count; count++)
{ {
pic_array[count] = picture_NewFromFormat(&vd->fmt); picture_t *pic = (picture_t*) picture_NewFromFormat(&vd->fmt);
if (!pic_array[count]) if (!pic)
break; break;
assert(pic->p_sys == NULL);
picture_sys_t *sys = (picture_sys_t *) calloc(1, sizeof(picture_sys_t)); picture_sys_t *sys = (picture_sys_t *) calloc(1, sizeof(picture_sys_t));
if (!sys) if (!sys)
{ {
picture_Release(pic_array[count]); picture_Release(pic);
break; break;
} }
pic_array[count] = pic;
pic_array[count]->p_sys = sys; pic_array[count]->p_sys = sys;
pic_array[count]->pf_release = vlc_va_PictureRelease; //pic_array[count]->pf_release = PictureRelease;
} }
if (count == 0) if (count == 0)
return NULL; goto error;
sys->pool = picture_pool_New (count, pic_array); sys->pool = picture_pool_New(count, pic_array);
if (!sys->pool) if (!sys->pool)
goto error; goto error;
free(pic_array);
XFlush(sys->conn->p_display_x11); XFlush(sys->conn->p_display_x11);
return sys->pool; return sys->pool;
error: error:
/* Cleanup on error */ /* Cleanup on error */
for (int i = 0; i < MAX_PICTURES; i++) for (unsigned int i = 0; i < count; i++)
{ {
picture_t *pic = pic_array[i]; picture_t *pic = pic_array[i];
if (pic) if (pic)
picture_Release(pic); picture_Release(pic);
} }
free(pic_array);
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment