xvimagesink: Implement XvImage memory as a GstMemory, not as a GstMeta
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Sat, 23 Feb 2013 08:52:57 +0000 (09:52 +0100)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Sat, 23 Feb 2013 08:58:51 +0000 (09:58 +0100)
sys/xvimage/xvimagepool.c
sys/xvimage/xvimagepool.h
sys/xvimage/xvimagesink.c

index 87c00a0..e38c1ec 100644 (file)
@@ -49,39 +49,6 @@ struct _GstXvImageBufferPoolPrivate
   gboolean need_alignment;
 };
 
-static void gst_xvimage_meta_free (GstXvImageMeta * meta, GstBuffer * buffer);
-
-/* xvimage metadata */
-GType
-gst_xvimage_meta_api_get_type (void)
-{
-  static volatile GType type;
-  static const gchar *tags[] =
-      { "memory", "size", "colorspace", "orientation", NULL };
-
-  if (g_once_init_enter (&type)) {
-    GType _type = gst_meta_api_type_register ("GstXvImageMetaAPI", tags);
-    g_once_init_leave (&type, _type);
-  }
-  return type;
-}
-
-const GstMetaInfo *
-gst_xvimage_meta_get_info (void)
-{
-  static const GstMetaInfo *xvimage_meta_info = NULL;
-
-  if (g_once_init_enter (&xvimage_meta_info)) {
-    const GstMetaInfo *meta =
-        gst_meta_register (GST_XVIMAGE_META_API_TYPE, "GstXvImageMeta",
-        sizeof (GstXvImageMeta), (GstMetaInitFunction) NULL,
-        (GstMetaFreeFunction) gst_xvimage_meta_free,
-        (GstMetaTransformFunction) NULL);
-    g_once_init_leave (&xvimage_meta_info, meta);
-  }
-  return xvimage_meta_info;
-}
-
 /* X11 stuff */
 static gboolean error_caught = FALSE;
 
@@ -96,16 +63,174 @@ gst_xvimagesink_handle_xerror (Display * display, XErrorEvent * xevent)
   return 0;
 }
 
-static GstXvImageMeta *
-gst_buffer_add_xvimage_meta (GstBuffer * buffer, GstXvImageBufferPool * xvpool)
+static GstMemory *
+gst_xvimage_memory_alloc (GstAllocator * allocator, gsize size,
+    GstAllocationParams * params)
+{
+  return NULL;
+}
+
+static void
+gst_xvimage_memory_free (GstAllocator * allocator, GstMemory * gmem)
+{
+  GstXvImageMemory *mem = (GstXvImageMemory *) gmem;
+  GstXvImageSink *xvimagesink;
+
+  if (gmem->parent)
+    goto sub_mem;
+
+  xvimagesink = mem->sink;
+
+  GST_DEBUG_OBJECT (xvimagesink, "free memory %p", mem);
+
+  /* Hold the object lock to ensure the XContext doesn't disappear */
+  GST_OBJECT_LOCK (xvimagesink);
+  /* We might have some buffers destroyed after changing state to NULL */
+  if (xvimagesink->xcontext == NULL) {
+    GST_DEBUG_OBJECT (xvimagesink, "Destroying XvImage after Xcontext");
+#ifdef HAVE_XSHM
+    /* Need to free the shared memory segment even if the x context
+     * was already cleaned up */
+    if (mem->SHMInfo.shmaddr != ((void *) -1)) {
+      shmdt (mem->SHMInfo.shmaddr);
+    }
+#endif
+    if (mem->xvimage)
+      XFree (mem->xvimage);
+    goto beach;
+  }
+
+  g_mutex_lock (&xvimagesink->x_lock);
+
+#ifdef HAVE_XSHM
+  if (xvimagesink->xcontext->use_xshm) {
+    if (mem->SHMInfo.shmaddr != ((void *) -1)) {
+      GST_DEBUG_OBJECT (xvimagesink, "XServer ShmDetaching from 0x%x id 0x%lx",
+          mem->SHMInfo.shmid, mem->SHMInfo.shmseg);
+      XShmDetach (xvimagesink->xcontext->disp, &mem->SHMInfo);
+      XSync (xvimagesink->xcontext->disp, FALSE);
+      shmdt (mem->SHMInfo.shmaddr);
+      mem->SHMInfo.shmaddr = (void *) -1;
+    }
+    if (mem->xvimage)
+      XFree (mem->xvimage);
+  } else
+#endif /* HAVE_XSHM */
+  {
+    if (mem->xvimage) {
+      g_free (mem->xvimage->data);
+      XFree (mem->xvimage);
+    }
+  }
+
+  XSync (xvimagesink->xcontext->disp, FALSE);
+
+  g_mutex_unlock (&xvimagesink->x_lock);
+
+beach:
+  GST_OBJECT_UNLOCK (xvimagesink);
+
+  gst_object_unref (mem->sink);
+
+sub_mem:
+  g_slice_free (GstXvImageMemory, mem);
+}
+
+static gpointer
+xvimage_memory_map (GstXvImageMemory * mem, gsize maxsize, GstMapFlags flags)
+{
+  return mem->xvimage->data + mem->parent.offset;
+}
+
+static gboolean
+xvimage_memory_unmap (GstXvImageMemory * mem)
+{
+  return TRUE;
+}
+
+static GstXvImageMemory *
+xvimage_memory_share (GstXvImageMemory * mem, gssize offset, gsize size)
+{
+  GstXvImageMemory *sub;
+  GstMemory *parent;
+
+  /* We can only share the complete memory */
+  if (offset != 0)
+    return NULL;
+  if (size != -1 && size != mem->size)
+    return NULL;
+
+  /* find the real parent */
+  if ((parent = mem->parent.parent) == NULL)
+    parent = (GstMemory *) mem;
+
+  if (size == -1)
+    size = mem->parent.size - offset;
+
+  /* the shared memory is always readonly */
+  sub = g_slice_new (GstXvImageMemory);
+
+  gst_memory_init (GST_MEMORY_CAST (sub), GST_MINI_OBJECT_FLAGS (parent) |
+      GST_MINI_OBJECT_FLAG_LOCK_READONLY, g_object_ref (mem->parent.allocator),
+      &mem->parent, mem->parent.maxsize, mem->parent.align,
+      mem->parent.offset + offset, size);
+  sub->sink = mem->sink;
+  sub->xvimage = mem->xvimage;
+  sub->SHMInfo = mem->SHMInfo;
+  sub->x = mem->x;
+  sub->y = mem->y;
+  sub->width = mem->width;
+  sub->height = mem->height;
+
+  return sub;
+}
+
+typedef GstAllocator GstXvImageMemoryAllocator;
+typedef GstAllocatorClass GstXvImageMemoryAllocatorClass;
+
+GType xvimage_memory_allocator_get_type (void);
+G_DEFINE_TYPE (GstXvImageMemoryAllocator, xvimage_memory_allocator,
+    GST_TYPE_ALLOCATOR);
+
+#define GST_XVIMAGE_ALLOCATOR_NAME "xvimage"
+#define GST_TYPE_XVIMAGE_MEMORY_ALLOCATOR   (xvimage_memory_allocator_get_type())
+#define GST_IS_XVIMAGE_MEMORY_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_XVIMAGE_MEMORY_ALLOCATOR))
+
+static void
+xvimage_memory_allocator_class_init (GstXvImageMemoryAllocatorClass * klass)
+{
+  GstAllocatorClass *allocator_class;
+
+  allocator_class = (GstAllocatorClass *) klass;
+
+  allocator_class->alloc = gst_xvimage_memory_alloc;
+  allocator_class->free = gst_xvimage_memory_free;
+}
+
+static void
+xvimage_memory_allocator_init (GstXvImageMemoryAllocator * allocator)
+{
+  GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
+
+  alloc->mem_type = GST_XVIMAGE_ALLOCATOR_NAME;
+  alloc->mem_map = (GstMemoryMapFunction) xvimage_memory_map;
+  alloc->mem_unmap = (GstMemoryUnmapFunction) xvimage_memory_unmap;
+  alloc->mem_share = (GstMemoryShareFunction) xvimage_memory_share;
+  /* fallback copy and is_span */
+
+  GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
+}
+
+static GstMemory *
+xvimage_memory_alloc (GstXvImageBufferPool * xvpool)
 {
   GstXvImageSink *xvimagesink;
   int (*handler) (Display *, XErrorEvent *);
   gboolean success = FALSE;
   GstXContext *xcontext;
-  GstXvImageMeta *meta;
   gint width, height, im_format, align = 15, offset;
   GstXvImageBufferPoolPrivate *priv;
+  GstXvImageMemory *mem;
 
   priv = xvpool->priv;
   xvimagesink = xvpool->sink;
@@ -115,21 +240,20 @@ gst_buffer_add_xvimage_meta (GstBuffer * buffer, GstXvImageBufferPool * xvpool)
   height = priv->padded_height;
   im_format = priv->im_format;
 
-  meta =
-      (GstXvImageMeta *) gst_buffer_add_meta (buffer, GST_XVIMAGE_META_INFO,
-      NULL);
+  mem = g_slice_new (GstXvImageMemory);
+
 #ifdef HAVE_XSHM
-  meta->SHMInfo.shmaddr = ((void *) -1);
-  meta->SHMInfo.shmid = -1;
+  mem->SHMInfo.shmaddr = ((void *) -1);
+  mem->SHMInfo.shmid = -1;
 #endif
-  meta->x = priv->align.padding_left;
-  meta->y = priv->align.padding_top;
-  meta->width = priv->info.width;
-  meta->height = priv->info.height;
-  meta->sink = gst_object_ref (xvimagesink);
-  meta->im_format = im_format;
-
-  GST_DEBUG_OBJECT (xvimagesink, "creating image %p (%dx%d)", buffer,
+  mem->x = priv->align.padding_left;
+  mem->y = priv->align.padding_top;
+  mem->width = priv->info.width;
+  mem->height = priv->info.height;
+  mem->sink = gst_object_ref (xvimagesink);
+  mem->im_format = im_format;
+
+  GST_DEBUG_OBJECT (xvimagesink, "creating image %p (%dx%d)", mem,
       width, height);
 
   g_mutex_lock (&xvimagesink->x_lock);
@@ -142,9 +266,9 @@ gst_buffer_add_xvimage_meta (GstBuffer * buffer, GstXvImageBufferPool * xvpool)
   if (xcontext->use_xshm) {
     int expected_size;
 
-    meta->xvimage = XvShmCreateImage (xcontext->disp,
-        xcontext->xv_port_id, im_format, NULL, width, height, &meta->SHMInfo);
-    if (!meta->xvimage || error_caught) {
+    mem->xvimage = XvShmCreateImage (xcontext->disp,
+        xcontext->xv_port_id, im_format, NULL, width, height, &mem->SHMInfo);
+    if (!mem->xvimage || error_caught) {
       g_mutex_unlock (&xvimagesink->x_lock);
 
       /* Reset error flag */
@@ -165,9 +289,9 @@ gst_buffer_add_xvimage_meta (GstBuffer * buffer, GstXvImageBufferPool * xvpool)
     }
 
     /* we have to use the returned data_size for our shm size */
-    meta->size = meta->xvimage->data_size;
+    mem->size = mem->xvimage->data_size;
     GST_LOG_OBJECT (xvimagesink, "XShm image size is %" G_GSIZE_FORMAT,
-        meta->size);
+        mem->size);
 
     /* calculate the expected size.  This is only for sanity checking the
      * number we get from X. */
@@ -188,7 +312,7 @@ gst_buffer_add_xvimage_meta (GstBuffer * buffer, GstXvImageBufferPool * xvpool)
 
         expected_size = offsets[2] + pitches[2] * GST_ROUND_UP_2 (height) / 2;
 
-        for (plane = 0; plane < meta->xvimage->num_planes; plane++) {
+        for (plane = 0; plane < mem->xvimage->num_planes; plane++) {
           GST_DEBUG_OBJECT (xvimagesink,
               "Plane %u has a expected pitch of %d bytes, " "offset of %d",
               plane, pitches[plane], offsets[plane]);
@@ -203,39 +327,39 @@ gst_buffer_add_xvimage_meta (GstBuffer * buffer, GstXvImageBufferPool * xvpool)
         expected_size = 0;
         break;
     }
-    if (expected_size != 0 && meta->size != expected_size) {
+    if (expected_size != 0 && mem->size != expected_size) {
       GST_WARNING_OBJECT (xvimagesink,
           "unexpected XShm image size (got %" G_GSIZE_FORMAT ", expected %d)",
-          meta->size, expected_size);
+          mem->size, expected_size);
     }
 
     /* Be verbose about our XvImage stride */
     {
       guint plane;
 
-      for (plane = 0; plane < meta->xvimage->num_planes; plane++) {
+      for (plane = 0; plane < mem->xvimage->num_planes; plane++) {
         GST_DEBUG_OBJECT (xvimagesink, "Plane %u has a pitch of %d bytes, "
-            "offset of %d", plane, meta->xvimage->pitches[plane],
-            meta->xvimage->offsets[plane]);
+            "offset of %d", plane, mem->xvimage->pitches[plane],
+            mem->xvimage->offsets[plane]);
       }
     }
 
     /* get shared memory */
-    meta->SHMInfo.shmid =
-        shmget (IPC_PRIVATE, meta->size + align, IPC_CREAT | 0777);
-    if (meta->SHMInfo.shmid == -1)
+    mem->SHMInfo.shmid =
+        shmget (IPC_PRIVATE, mem->size + align, IPC_CREAT | 0777);
+    if (mem->SHMInfo.shmid == -1)
       goto shmget_failed;
 
     /* attach */
-    meta->SHMInfo.shmaddr = shmat (meta->SHMInfo.shmid, NULL, 0);
-    if (meta->SHMInfo.shmaddr == ((void *) -1))
+    mem->SHMInfo.shmaddr = shmat (mem->SHMInfo.shmid, NULL, 0);
+    if (mem->SHMInfo.shmaddr == ((void *) -1))
       goto shmat_failed;
 
     /* now we can set up the image data */
-    meta->xvimage->data = meta->SHMInfo.shmaddr;
-    meta->SHMInfo.readOnly = FALSE;
+    mem->xvimage->data = mem->SHMInfo.shmaddr;
+    mem->SHMInfo.readOnly = FALSE;
 
-    if (XShmAttach (xcontext->disp, &meta->SHMInfo) == 0)
+    if (XShmAttach (xcontext->disp, &mem->SHMInfo) == 0)
       goto xattach_failed;
 
     XSync (xcontext->disp, FALSE);
@@ -243,49 +367,50 @@ gst_buffer_add_xvimage_meta (GstBuffer * buffer, GstXvImageBufferPool * xvpool)
     /* Delete the shared memory segment as soon as we everyone is attached.
      * This way, it will be deleted as soon as we detach later, and not
      * leaked if we crash. */
-    shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
+    shmctl (mem->SHMInfo.shmid, IPC_RMID, NULL);
 
     GST_DEBUG_OBJECT (xvimagesink, "XServer ShmAttached to 0x%x, id 0x%lx",
-        meta->SHMInfo.shmid, meta->SHMInfo.shmseg);
+        mem->SHMInfo.shmid, mem->SHMInfo.shmseg);
   } else
   no_xshm:
 #endif /* HAVE_XSHM */
   {
-    meta->xvimage = XvCreateImage (xcontext->disp,
+    mem->xvimage = XvCreateImage (xcontext->disp,
         xcontext->xv_port_id, im_format, NULL, width, height);
-    if (!meta->xvimage || error_caught)
+    if (!mem->xvimage || error_caught)
       goto create_failed;
 
     /* we have to use the returned data_size for our image size */
-    meta->size = meta->xvimage->data_size;
-    meta->xvimage->data = g_malloc (meta->size + align);
+    mem->size = mem->xvimage->data_size;
+    mem->xvimage->data = g_malloc (mem->size + align);
 
     XSync (xcontext->disp, FALSE);
   }
 
-  if ((offset = ((guintptr) meta->xvimage->data & align)))
+  if ((offset = ((guintptr) mem->xvimage->data & align)))
     offset = (align + 1) - offset;
 
   GST_DEBUG_OBJECT (xvimagesink, "memory %p, align %d, offset %d",
-      meta->xvimage->data, align, offset);
+      mem->xvimage->data, align, offset);
 
   /* Reset error handler */
   error_caught = FALSE;
   XSetErrorHandler (handler);
 
-  gst_buffer_append_memory (buffer,
-      gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, meta->xvimage->data,
-          meta->size + align, offset, meta->size, NULL, NULL));
+  gst_memory_init (GST_MEMORY_CAST (mem), 0, g_object_ref (xvpool->allocator),
+      NULL, mem->size + align, align, offset, mem->size);
 
   g_mutex_unlock (&xvimagesink->x_lock);
 
   success = TRUE;
 
 beach:
-  if (!success)
-    meta = NULL;
+  if (!success) {
+    g_slice_free (GstXvImageMemory, mem);
+    mem = NULL;
+  }
 
-  return meta;
+  return GST_MEMORY_CAST (mem);
 
   /* ERRORS */
 create_failed:
@@ -309,7 +434,7 @@ shmget_failed:
         ("Failed to create output image buffer of %dx%d pixels",
             width, height),
         ("could not get shared memory of %" G_GSIZE_FORMAT " bytes",
-            meta->size));
+            mem->size));
     goto beach;
   }
 shmat_failed:
@@ -319,13 +444,13 @@ shmat_failed:
         ("Failed to create output image buffer of %dx%d pixels",
             width, height), ("Failed to shmat: %s", g_strerror (errno)));
     /* Clean up the shared memory segment */
-    shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
+    shmctl (mem->SHMInfo.shmid, IPC_RMID, NULL);
     goto beach;
   }
 xattach_failed:
   {
     /* Clean up the shared memory segment */
-    shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
+    shmctl (mem->SHMInfo.shmid, IPC_RMID, NULL);
     g_mutex_unlock (&xvimagesink->x_lock);
 
     GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
@@ -336,65 +461,6 @@ xattach_failed:
 #endif
 }
 
-static void
-gst_xvimage_meta_free (GstXvImageMeta * meta, GstBuffer * buffer)
-{
-  GstXvImageSink *xvimagesink;
-
-  xvimagesink = meta->sink;
-
-  GST_DEBUG_OBJECT (xvimagesink, "free meta on buffer %p", buffer);
-
-  /* Hold the object lock to ensure the XContext doesn't disappear */
-  GST_OBJECT_LOCK (xvimagesink);
-  /* We might have some buffers destroyed after changing state to NULL */
-  if (xvimagesink->xcontext == NULL) {
-    GST_DEBUG_OBJECT (xvimagesink, "Destroying XvImage after Xcontext");
-#ifdef HAVE_XSHM
-    /* Need to free the shared memory segment even if the x context
-     * was already cleaned up */
-    if (meta->SHMInfo.shmaddr != ((void *) -1)) {
-      shmdt (meta->SHMInfo.shmaddr);
-    }
-#endif
-    if (meta->xvimage)
-      XFree (meta->xvimage);
-    goto beach;
-  }
-
-  g_mutex_lock (&xvimagesink->x_lock);
-
-#ifdef HAVE_XSHM
-  if (xvimagesink->xcontext->use_xshm) {
-    if (meta->SHMInfo.shmaddr != ((void *) -1)) {
-      GST_DEBUG_OBJECT (xvimagesink, "XServer ShmDetaching from 0x%x id 0x%lx",
-          meta->SHMInfo.shmid, meta->SHMInfo.shmseg);
-      XShmDetach (xvimagesink->xcontext->disp, &meta->SHMInfo);
-      XSync (xvimagesink->xcontext->disp, FALSE);
-      shmdt (meta->SHMInfo.shmaddr);
-      meta->SHMInfo.shmaddr = (void *) -1;
-    }
-    if (meta->xvimage)
-      XFree (meta->xvimage);
-  } else
-#endif /* HAVE_XSHM */
-  {
-    if (meta->xvimage) {
-      g_free (meta->xvimage->data);
-      XFree (meta->xvimage);
-    }
-  }
-
-  XSync (xvimagesink->xcontext->disp, FALSE);
-
-  g_mutex_unlock (&xvimagesink->x_lock);
-
-beach:
-  GST_OBJECT_UNLOCK (xvimagesink);
-
-  gst_object_unref (meta->sink);
-}
-
 #ifdef HAVE_XSHM
 /* This function checks that it is actually really possible to create an image
    using XShm */
@@ -625,16 +691,17 @@ xvimage_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
   GstXvImageBufferPoolPrivate *priv = xvpool->priv;
   GstVideoInfo *info;
   GstBuffer *xvimage;
-  GstXvImageMeta *meta;
+  GstMemory *mem;
 
   info = &priv->info;
 
   xvimage = gst_buffer_new ();
-  meta = gst_buffer_add_xvimage_meta (xvimage, xvpool);
-  if (meta == NULL) {
+  mem = xvimage_memory_alloc (xvpool);
+  if (mem == NULL) {
     gst_buffer_unref (xvimage);
     goto no_buffer;
   }
+  gst_buffer_append_memory (xvimage, mem);
 
   if (priv->add_metavideo) {
     GST_DEBUG_OBJECT (pool, "adding GstVideoMeta");
@@ -665,6 +732,7 @@ gst_xvimage_buffer_pool_new (GstXvImageSink * xvimagesink)
 
   pool = g_object_new (GST_TYPE_XVIMAGE_BUFFER_POOL, NULL);
   pool->sink = gst_object_ref (xvimagesink);
+  pool->allocator = g_object_new (GST_TYPE_XVIMAGE_MEMORY_ALLOCATOR, NULL);
 
   GST_LOG_OBJECT (pool, "new XvImage buffer pool %p", pool);
 
@@ -703,6 +771,7 @@ gst_xvimage_buffer_pool_finalize (GObject * object)
   if (priv->caps)
     gst_caps_unref (priv->caps);
   gst_object_unref (pool->sink);
+  g_object_unref (pool->allocator);
 
   G_OBJECT_CLASS (gst_xvimage_buffer_pool_parent_class)->finalize (object);
 }
index acb65c7..d281f8a 100644 (file)
@@ -39,7 +39,7 @@
 
 G_BEGIN_DECLS
 
-typedef struct _GstXvImageMeta GstXvImageMeta;
+typedef struct _GstXvImageMemory GstXvImageMemory;
 
 typedef struct _GstXvImageBufferPool GstXvImageBufferPool;
 typedef struct _GstXvImageBufferPoolClass GstXvImageBufferPoolClass;
@@ -47,15 +47,8 @@ typedef struct _GstXvImageBufferPoolPrivate GstXvImageBufferPoolPrivate;
 
 #include "xvimagesink.h"
 
-GType gst_xvimage_meta_api_get_type (void);
-#define GST_XVIMAGE_META_API_TYPE  (gst_xvimage_meta_api_get_type())
-const GstMetaInfo * gst_xvimage_meta_get_info (void);
-#define GST_XVIMAGE_META_INFO  (gst_xvimage_meta_get_info())
-
-#define gst_buffer_get_xvimage_meta(b) ((GstXvImageMeta*)gst_buffer_get_meta((b),GST_XVIMAGE_META_API_TYPE))
-
 /**
- * GstXvImageMeta:
+ * GstXvImageMemory:
  * @sink: a reference to the our #GstXvImageSink
  * @xvimage: the XvImage of this buffer
  * @width: the width in pixels of XvImage @xvimage
@@ -63,11 +56,11 @@ const GstMetaInfo * gst_xvimage_meta_get_info (void);
  * @im_format: the format of XvImage @xvimage
  * @size: the size in bytes of XvImage @xvimage
  *
- * Subclass of #GstMeta containing additional information about an XvImage.
+ * Subclass of #GstMemory containing additional information about an XvImage.
  */
-struct _GstXvImageMeta
+struct _GstXvImageMemory
 {
-  GstMeta meta;
+  GstMemory parent;
 
   /* Reference to the xvimagesink we belong to */
   GstXvImageSink *sink;
@@ -95,6 +88,7 @@ struct _GstXvImageBufferPool
   GstBufferPool bufferpool;
 
   GstXvImageSink *sink;
+  GstAllocator *allocator;
 
   GstXvImageBufferPoolPrivate *priv;
 };
index b7aa26f..5d3bccd 100644 (file)
@@ -267,7 +267,7 @@ gst_xvimagesink_xwindow_draw_borders (GstXvImageSink * xvimagesink,
 static gboolean
 gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
 {
-  GstXvImageMeta *meta;
+  GstXvImageMemory *mem;
   GstVideoCropMeta *crop;
   GstVideoRectangle result;
   gboolean draw_border = FALSE;
@@ -309,22 +309,22 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
     }
   }
 
-  meta = gst_buffer_get_xvimage_meta (xvimage);
+  mem = (GstXvImageMemory *) gst_buffer_peek_memory (xvimage, 0);
 
   crop = gst_buffer_get_video_crop_meta (xvimage);
 
   if (crop) {
-    src.x = crop->x + meta->x;
-    src.y = crop->y + meta->y;
+    src.x = crop->x + mem->x;
+    src.y = crop->y + mem->y;
     src.w = crop->width;
     src.h = crop->height;
     GST_LOG_OBJECT (xvimagesink,
         "crop %dx%d-%dx%d", crop->x, crop->y, crop->width, crop->height);
   } else {
-    src.x = meta->x;
-    src.y = meta->y;
-    src.w = meta->width;
-    src.h = meta->height;
+    src.x = mem->x;
+    src.y = mem->y;
+    src.w = mem->width;
+    src.h = mem->height;
   }
 
   if (xvimagesink->keep_aspect) {
@@ -356,13 +356,13 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
   if (xvimagesink->xcontext->use_xshm) {
     GST_LOG_OBJECT (xvimagesink,
         "XvShmPutImage with image %dx%d and window %dx%d, from xvimage %"
-        GST_PTR_FORMAT, meta->width, meta->height,
+        GST_PTR_FORMAT, mem->width, mem->height,
         xvimagesink->render_rect.w, xvimagesink->render_rect.h, xvimage);
 
     XvShmPutImage (xvimagesink->xcontext->disp,
         xvimagesink->xcontext->xv_port_id,
         xvimagesink->xwindow->win,
-        xvimagesink->xwindow->gc, meta->xvimage,
+        xvimagesink->xwindow->gc, mem->xvimage,
         src.x, src.y, src.w, src.h,
         result.x, result.y, result.w, result.h, FALSE);
   } else
@@ -371,7 +371,7 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
     XvPutImage (xvimagesink->xcontext->disp,
         xvimagesink->xcontext->xv_port_id,
         xvimagesink->xwindow->win,
-        xvimagesink->xwindow->gc, meta->xvimage,
+        xvimagesink->xwindow->gc, mem->xvimage,
         src.x, src.y, src.w, src.h, result.x, result.y, result.w, result.h);
   }
 
@@ -1810,14 +1810,15 @@ gst_xvimagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
 {
   GstFlowReturn res;
   GstXvImageSink *xvimagesink;
-  GstXvImageMeta *meta;
   GstBuffer *to_put;
+  GstXvImageMemory *mem;
 
   xvimagesink = GST_XVIMAGESINK (vsink);
 
-  meta = gst_buffer_get_xvimage_meta (buf);
-
-  if (meta && meta->sink == xvimagesink) {
+  if (gst_buffer_n_memory (buf) == 1
+      && (mem = (GstXvImageMemory *) gst_buffer_peek_memory (buf, 0))
+      && g_strcmp0 (mem->parent.allocator->mem_type, "xvimage") == 0
+      && mem->sink == xvimagesink) {
     /* If this buffer has been allocated using our buffer management we simply
        put the ximage which is in the PRIVATE pointer */
     GST_LOG_OBJECT (xvimagesink, "buffer %p from our pool, writing directly",