Commit 776fb1cb authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

XCB: use custom picture destroy callback, simplify

parent e3764808
......@@ -31,6 +31,8 @@
#ifdef HAVE_SYS_SHM_H
# include <sys/shm.h>
# include <sys/stat.h>
#else
# define shmdt(mem) free(mem)
#endif
#include <xcb/xcb.h>
......@@ -65,27 +67,31 @@ bool XCB_shm_Check (vlc_object_t *obj, xcb_connection_t *conn)
return false;
}
/**
* Release picture private data: detach the shared memory segment.
*/
static void XCB_picture_Destroy (picture_t *pic)
{
shmdt (pic->p[0].p_pixels);
free (pic);
}
/**
* Initialize a picture buffer as shared memory, according to the video output
* format. If a attach is true, the segment is attached to
* the X server (MIT-SHM extension).
*/
void *XCB_pictures_Alloc (vout_display_t *vd, picture_sys_t **sysp,
size_t size, xcb_connection_t *conn,
xcb_shm_seg_t segment)
int XCB_picture_Alloc (vout_display_t *vd, picture_resource_t *res,
size_t size, xcb_connection_t *conn,
xcb_shm_seg_t segment)
{
picture_sys_t *picsys = malloc (sizeof (*picsys));
if (unlikely(picsys == NULL))
return NULL;
#ifdef HAVE_SYS_SHM_H
/* Allocate shared memory segment */
int id = shmget (IPC_PRIVATE, size, IPC_CREAT | S_IRWXU);
if (id == -1)
{
msg_Err (vd, "shared memory allocation error: %m");
free (picsys);
return NULL;
return -1;
}
/* Attach the segment to VLC */
......@@ -94,8 +100,7 @@ void *XCB_pictures_Alloc (vout_display_t *vd, picture_sys_t **sysp,
{
msg_Err (vd, "shared memory attachment error: %m");
shmctl (id, IPC_RMID, 0);
free (picsys);
return NULL;
return -1;
}
if (segment != 0)
......@@ -127,30 +132,25 @@ void *XCB_pictures_Alloc (vout_display_t *vd, picture_sys_t **sysp,
}
shmctl (id, IPC_RMID, NULL);
picsys->segment = segment;
#else
assert (!attach);
picsys->segment = 0;
assert (segment == 0);
/* XXX: align on 32 bytes for VLC chroma filters */
void *shm = malloc (size);
if (unlikely(shm == NULL))
free (picsys);
return -1;
#endif
*sysp = picsys;
return shm;
res->p_sys = (void *)(uintptr_t)segment;
res->pf_destroy = XCB_picture_Destroy;
res->p[0].p_pixels = shm;
return 0;
}
/**
* Release picture private data: detach the shared memory segment.
*/
void XCB_pictures_Free (void *mem)
picture_t *XCB_picture_NewFromResource (const video_format_t *restrict fmt,
const picture_resource_t *restrict res)
{
#ifdef HAVE_SYS_SHM_H
if (mem != NULL)
shmdt (mem);
#else
free (mem);
#endif
picture_t *pic = picture_NewFromResource (fmt, res);
if (unlikely(pic == NULL))
shmdt (res->p[0].p_pixels);
return pic;
}
......@@ -31,11 +31,12 @@
#include <xcb/shm.h>
bool XCB_shm_Check (vlc_object_t *obj, xcb_connection_t *conn);
int XCB_picture_Alloc (vout_display_t *, picture_resource_t *, size_t size,
xcb_connection_t *, xcb_shm_seg_t);
picture_t *XCB_picture_NewFromResource (const video_format_t *,
const picture_resource_t *);
struct picture_sys_t
static inline xcb_shm_seg_t XCB_picture_GetSegment(const picture_t *pic)
{
xcb_shm_seg_t segment;
};
void *XCB_pictures_Alloc (vout_display_t *, picture_sys_t **, size_t size,
xcb_connection_t *, xcb_shm_seg_t);
void XCB_pictures_Free (void *);
return (uintptr_t)pic->p_sys;
}
......@@ -74,7 +74,6 @@ struct vout_display_sys_t
uint8_t depth; /* useful bits per pixel */
picture_pool_t *pool; /* picture pool */
void *segments[MAX_PICTURES];
};
static picture_pool_t *Pool (vout_display_t *, unsigned);
......@@ -390,29 +389,22 @@ static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
};
picture_Release (pic);
for (unsigned count = 0; count < MAX_PICTURES; count++)
sys->segments[count] = NULL;
unsigned count;
picture_t *pic_array[MAX_PICTURES];
const size_t size = res.p->i_pitch * res.p->i_lines;
for (count = 0; count < MAX_PICTURES; count++)
{
xcb_shm_seg_t seg = (sys->seg_base != 0) ? (sys->seg_base + count) : 0;
res.p[0].p_pixels = XCB_pictures_Alloc (vd, &res.p_sys,
res.p->i_pitch * res.p->i_lines, sys->conn, seg);
if (res.p[0].p_pixels == NULL)
if (XCB_picture_Alloc (vd, &res, size, sys->conn, seg))
break;
pic_array[count] = picture_NewFromResource (&vd->fmt, &res);
if (!pic_array[count])
pic_array[count] = XCB_picture_NewFromResource (&vd->fmt, &res);
if (unlikely(pic_array[count] == NULL))
{
free (res.p_sys);
XCB_pictures_Free (res.p[0].p_pixels);
if (seg != 0)
xcb_shm_detach (sys->conn, seg);
break;
}
sys->segments[count] = res.p[0].p_pixels;
}
if (count == 0)
......@@ -430,7 +422,7 @@ static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
static void Display (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
{
vout_display_sys_t *sys = vd->sys;
xcb_shm_seg_t segment = pic->p_sys->segment;
xcb_shm_seg_t segment = XCB_picture_GetSegment(pic);
xcb_void_cookie_t ck;
if (!sys->visible)
......@@ -582,12 +574,10 @@ static void ResetPictures (vout_display_t *vd)
if (!sys->pool)
return;
for (unsigned i = 0; i < MAX_PICTURES; i++)
{
XCB_pictures_Free (sys->segments[i]);
if (sys->seg_base != 0)
if (sys->seg_base != 0)
for (unsigned i = 0; i < MAX_PICTURES; i++)
xcb_shm_detach (sys->conn, sys->seg_base + i);
}
picture_pool_Delete (sys->pool);
sys->pool = NULL;
}
......@@ -96,7 +96,6 @@ struct vout_display_sys_t
xcb_xv_query_image_attributes_reply_t *att;
picture_pool_t *pool; /* picture pool */
void *segments[MAX_PICTURES];
};
static picture_pool_t *Pool (vout_display_t *, unsigned);
......@@ -599,11 +598,7 @@ static void Close (vlc_object_t *obj)
vout_display_sys_t *p_sys = vd->sys;
if (p_sys->pool)
{
for (unsigned i = 0; i < MAX_PICTURES; i++)
XCB_pictures_Free(p_sys->segments[i]);
picture_pool_Delete (p_sys->pool);
}
/* show the default cursor */
xcb_change_window_attributes (p_sys->conn, p_sys->embed->handle.xid, XCB_CW_CURSOR,
......@@ -620,9 +615,6 @@ static void PoolAlloc (vout_display_t *vd, unsigned requested_count)
{
vout_display_sys_t *p_sys = vd->sys;
for (unsigned count = 0; count < MAX_PICTURES; count++)
p_sys->segments[count] = NULL;
const uint32_t *pitches= xcb_xv_query_image_attributes_pitches (p_sys->att);
const uint32_t *offsets= xcb_xv_query_image_attributes_offsets (p_sys->att);
const unsigned num_planes= __MIN(p_sys->att->num_planes, PICTURE_PLANE_MAX);
......@@ -646,9 +638,7 @@ static void PoolAlloc (vout_display_t *vd, unsigned requested_count)
{
xcb_shm_seg_t seg = p_sys->shm ? xcb_generate_id (p_sys->conn) : 0;
res.p[0].p_pixels = XCB_pictures_Alloc (vd, &res.p_sys,
p_sys->data_size, p_sys->conn, seg);
if (res.p[0].p_pixels == NULL)
if (XCB_picture_Alloc (vd, &res, p_sys->data_size, p_sys->conn, seg))
break;
/* Allocate further planes as specified by XVideo */
......@@ -663,16 +653,9 @@ static void PoolAlloc (vout_display_t *vd, unsigned requested_count)
res.p[1].p_pixels = buf;
}
pic_array[count] = picture_NewFromResource (&vd->fmt, &res);
if (!pic_array[count])
{
free (res.p_sys);
XCB_pictures_Free (res.p[0].p_pixels);
if (seg != 0)
xcb_shm_detach (p_sys->conn, seg);
pic_array[count] = XCB_picture_NewFromResource (&vd->fmt, &res);
if (unlikely(pic_array[count] == NULL))
break;
}
p_sys->segments[count] = res.p[0].p_pixels;
}
if (count == 0)
......@@ -702,7 +685,7 @@ static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
static void Display (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
{
vout_display_sys_t *p_sys = vd->sys;
xcb_shm_seg_t segment = pic->p_sys->segment;
xcb_shm_seg_t segment = XCB_picture_GetSegment(pic);
xcb_void_cookie_t ck;
if (!p_sys->visible)
......
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