XCB: use custom picture destroy callback, simplify
authorRémi Denis-Courmont <remi@remlab.net>
Sun, 14 Jul 2013 19:30:57 +0000 (22:30 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Sun, 14 Jul 2013 19:43:16 +0000 (22:43 +0300)
modules/video_output/xcb/pictures.c
modules/video_output/xcb/pictures.h
modules/video_output/xcb/x11.c
modules/video_output/xcb/xvideo.c

index 9ba674d..f4311d1 100644 (file)
@@ -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;
 }
-
index ed8be74..ad14d4d 100644 (file)
 #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;
+}
index 9812101..cd80029 100644 (file)
@@ -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;
 }
index 7e73c5b..efd851c 100644 (file)
@@ -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)