omxvideodec: separate the buffer pool from the decoder
authorChristian König <christian.koenig@amd.com>
Wed, 5 Mar 2014 10:41:02 +0000 (11:41 +0100)
committerSebastian Dröge <sebastian@centricular.com>
Wed, 12 Mar 2014 11:42:03 +0000 (12:42 +0100)
https://bugzilla.gnome.org/show_bug.cgi?id=726025

omx/Makefile.am
omx/gstomxbufferpool.c [new file with mode: 0644]
omx/gstomxbufferpool.h [new file with mode: 0644]
omx/gstomxvideodec.c

index dbe2f54..9006214 100644 (file)
@@ -12,6 +12,7 @@ endif
 
 libgstomx_la_SOURCES = \
        gstomx.c \
+       gstomxbufferpool.c \
        gstomxvideodec.c \
        gstomxvideoenc.c \
        gstomxaudioenc.c \
diff --git a/omx/gstomxbufferpool.c b/omx/gstomxbufferpool.c
new file mode 100644 (file)
index 0000000..2bb0db0
--- /dev/null
@@ -0,0 +1,574 @@
+/*
+ * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
+ *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
+ * Copyright (C) 2013, Collabora Ltd.
+ *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstomxbufferpool.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_omx_buffer_pool_debug_category);
+#define GST_CAT_DEFAULT gst_omx_buffer_pool_debug_category
+
+typedef struct _GstOMXMemory GstOMXMemory;
+typedef struct _GstOMXMemoryAllocator GstOMXMemoryAllocator;
+typedef struct _GstOMXMemoryAllocatorClass GstOMXMemoryAllocatorClass;
+
+struct _GstOMXMemory
+{
+  GstMemory mem;
+
+  GstOMXBuffer *buf;
+};
+
+struct _GstOMXMemoryAllocator
+{
+  GstAllocator parent;
+};
+
+struct _GstOMXMemoryAllocatorClass
+{
+  GstAllocatorClass parent_class;
+};
+
+#define GST_OMX_MEMORY_TYPE "openmax"
+
+static GstMemory *
+gst_omx_memory_allocator_alloc_dummy (GstAllocator * allocator, gsize size,
+    GstAllocationParams * params)
+{
+  g_assert_not_reached ();
+  return NULL;
+}
+
+static void
+gst_omx_memory_allocator_free (GstAllocator * allocator, GstMemory * mem)
+{
+  GstOMXMemory *omem = (GstOMXMemory *) mem;
+
+  /* TODO: We need to remember which memories are still used
+   * so we can wait until everything is released before allocating
+   * new memory
+   */
+
+  g_slice_free (GstOMXMemory, omem);
+}
+
+static gpointer
+gst_omx_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags)
+{
+  GstOMXMemory *omem = (GstOMXMemory *) mem;
+
+  return omem->buf->omx_buf->pBuffer + omem->mem.offset;
+}
+
+static void
+gst_omx_memory_unmap (GstMemory * mem)
+{
+}
+
+static GstMemory *
+gst_omx_memory_share (GstMemory * mem, gssize offset, gssize size)
+{
+  g_assert_not_reached ();
+  return NULL;
+}
+
+GType gst_omx_memory_allocator_get_type (void);
+G_DEFINE_TYPE (GstOMXMemoryAllocator, gst_omx_memory_allocator,
+    GST_TYPE_ALLOCATOR);
+
+#define GST_TYPE_OMX_MEMORY_ALLOCATOR   (gst_omx_memory_allocator_get_type())
+#define GST_IS_OMX_MEMORY_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_OMX_MEMORY_ALLOCATOR))
+
+static void
+gst_omx_memory_allocator_class_init (GstOMXMemoryAllocatorClass * klass)
+{
+  GstAllocatorClass *allocator_class;
+
+  allocator_class = (GstAllocatorClass *) klass;
+
+  allocator_class->alloc = gst_omx_memory_allocator_alloc_dummy;
+  allocator_class->free = gst_omx_memory_allocator_free;
+}
+
+static void
+gst_omx_memory_allocator_init (GstOMXMemoryAllocator * allocator)
+{
+  GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
+
+  alloc->mem_type = GST_OMX_MEMORY_TYPE;
+  alloc->mem_map = gst_omx_memory_map;
+  alloc->mem_unmap = gst_omx_memory_unmap;
+  alloc->mem_share = gst_omx_memory_share;
+
+  /* default copy & is_span */
+
+  GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
+}
+
+static GstMemory *
+gst_omx_memory_allocator_alloc (GstAllocator * allocator, GstMemoryFlags flags,
+    GstOMXBuffer * buf)
+{
+  GstOMXMemory *mem;
+
+  /* FIXME: We don't allow sharing because we need to know
+   * when the memory becomes unused and can only then put
+   * it back to the pool. Which is done in the pool's release
+   * function
+   */
+  flags |= GST_MEMORY_FLAG_NO_SHARE;
+
+  mem = g_slice_new (GstOMXMemory);
+  /* the shared memory is always readonly */
+  gst_memory_init (GST_MEMORY_CAST (mem), flags, allocator, NULL,
+      buf->omx_buf->nAllocLen, buf->port->port_def.nBufferAlignment,
+      0, buf->omx_buf->nAllocLen);
+
+  mem->buf = buf;
+
+  return GST_MEMORY_CAST (mem);
+}
+
+/* Buffer pool for the buffers of an OpenMAX port.
+ *
+ * This pool is only used if we either passed buffers from another
+ * pool to the OMX port or provide the OMX buffers directly to other
+ * elements.
+ *
+ *
+ * A buffer is in the pool if it is currently owned by the port,
+ * i.e. after OMX_{Fill,Empty}ThisBuffer(). A buffer is outside
+ * the pool after it was taken from the port after it was handled
+ * by the port, i.e. {Empty,Fill}BufferDone.
+ *
+ * Buffers can be allocated by us (OMX_AllocateBuffer()) or allocated
+ * by someone else and (temporarily) passed to this pool
+ * (OMX_UseBuffer(), OMX_UseEGLImage()). In the latter case the pool of
+ * the buffer will be overriden, and restored in free_buffer(). Other
+ * buffers are just freed there.
+ *
+ * The pool always has a fixed number of minimum and maximum buffers
+ * and these are allocated while starting the pool and released afterwards.
+ * They correspond 1:1 to the OMX buffers of the port, which are allocated
+ * before the pool is started.
+ *
+ * Acquiring a buffer from this pool happens after the OMX buffer has
+ * been acquired from the port. gst_buffer_pool_acquire_buffer() is
+ * supposed to return the buffer that corresponds to the OMX buffer.
+ *
+ * For buffers provided to upstream, the buffer will be passed to
+ * the component manually when it arrives and then unreffed. If the
+ * buffer is released before reaching the component it will be just put
+ * back into the pool as if EmptyBufferDone has happened. If it was
+ * passed to the component, it will be back into the pool when it was
+ * released and EmptyBufferDone has happened.
+ *
+ * For buffers provided to downstream, the buffer will be returned
+ * back to the component (OMX_FillThisBuffer()) when it is released.
+ */
+
+static GQuark gst_omx_buffer_data_quark = 0;
+
+G_DEFINE_TYPE (GstOMXBufferPool, gst_omx_buffer_pool, GST_TYPE_BUFFER_POOL);
+
+static gboolean
+gst_omx_buffer_pool_start (GstBufferPool * bpool)
+{
+  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
+
+  /* Only allow to start the pool if we still are attached
+   * to a component and port */
+  GST_OBJECT_LOCK (pool);
+  if (!pool->component || !pool->port) {
+    GST_OBJECT_UNLOCK (pool);
+    return FALSE;
+  }
+  GST_OBJECT_UNLOCK (pool);
+
+  return
+      GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->start (bpool);
+}
+
+static gboolean
+gst_omx_buffer_pool_stop (GstBufferPool * bpool)
+{
+  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
+
+  /* Remove any buffers that are there */
+  g_ptr_array_set_size (pool->buffers, 0);
+
+  if (pool->caps)
+    gst_caps_unref (pool->caps);
+  pool->caps = NULL;
+
+  pool->add_videometa = FALSE;
+
+  return GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->stop (bpool);
+}
+
+static const gchar **
+gst_omx_buffer_pool_get_options (GstBufferPool * bpool)
+{
+  static const gchar *raw_video_options[] =
+      { GST_BUFFER_POOL_OPTION_VIDEO_META, NULL };
+  static const gchar *options[] = { NULL };
+  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
+
+  GST_OBJECT_LOCK (pool);
+  if (pool->port && pool->port->port_def.eDomain == OMX_PortDomainVideo
+      && pool->port->port_def.format.video.eCompressionFormat ==
+      OMX_VIDEO_CodingUnused) {
+    GST_OBJECT_UNLOCK (pool);
+    return raw_video_options;
+  }
+  GST_OBJECT_UNLOCK (pool);
+
+  return options;
+}
+
+static gboolean
+gst_omx_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config)
+{
+  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
+  GstCaps *caps;
+
+  GST_OBJECT_LOCK (pool);
+
+  if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
+    goto wrong_config;
+
+  if (caps == NULL)
+    goto no_caps;
+
+  if (pool->port && pool->port->port_def.eDomain == OMX_PortDomainVideo
+      && pool->port->port_def.format.video.eCompressionFormat ==
+      OMX_VIDEO_CodingUnused) {
+    GstVideoInfo info;
+
+    /* now parse the caps from the config */
+    if (!gst_video_info_from_caps (&info, caps))
+      goto wrong_video_caps;
+
+    /* enable metadata based on config of the pool */
+    pool->add_videometa =
+        gst_buffer_pool_config_has_option (config,
+        GST_BUFFER_POOL_OPTION_VIDEO_META);
+
+    pool->video_info = info;
+  }
+
+  if (pool->caps)
+    gst_caps_unref (pool->caps);
+  pool->caps = gst_caps_ref (caps);
+
+  GST_OBJECT_UNLOCK (pool);
+
+  return GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->set_config
+      (bpool, config);
+
+  /* ERRORS */
+wrong_config:
+  {
+    GST_OBJECT_UNLOCK (pool);
+    GST_WARNING_OBJECT (pool, "invalid config");
+    return FALSE;
+  }
+no_caps:
+  {
+    GST_OBJECT_UNLOCK (pool);
+    GST_WARNING_OBJECT (pool, "no caps in config");
+    return FALSE;
+  }
+wrong_video_caps:
+  {
+    GST_OBJECT_UNLOCK (pool);
+    GST_WARNING_OBJECT (pool,
+        "failed getting geometry from caps %" GST_PTR_FORMAT, caps);
+    return FALSE;
+  }
+}
+
+static GstFlowReturn
+gst_omx_buffer_pool_alloc_buffer (GstBufferPool * bpool,
+    GstBuffer ** buffer, GstBufferPoolAcquireParams * params)
+{
+  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
+  GstBuffer *buf;
+  GstOMXBuffer *omx_buf;
+
+  g_return_val_if_fail (pool->allocating, GST_FLOW_ERROR);
+
+  omx_buf = g_ptr_array_index (pool->port->buffers, pool->current_buffer_index);
+  g_return_val_if_fail (omx_buf != NULL, GST_FLOW_ERROR);
+
+  if (pool->other_pool) {
+    guint i, n;
+
+    buf = g_ptr_array_index (pool->buffers, pool->current_buffer_index);
+    g_assert (pool->other_pool == buf->pool);
+    gst_object_replace ((GstObject **) & buf->pool, NULL);
+
+    n = gst_buffer_n_memory (buf);
+    for (i = 0; i < n; i++) {
+      GstMemory *mem = gst_buffer_peek_memory (buf, i);
+
+      /* FIXME: We don't allow sharing because we need to know
+       * when the memory becomes unused and can only then put
+       * it back to the pool. Which is done in the pool's release
+       * function
+       */
+      GST_MINI_OBJECT_FLAG_SET (mem, GST_MEMORY_FLAG_NO_SHARE);
+    }
+
+    if (pool->add_videometa) {
+      GstVideoMeta *meta;
+
+      meta = gst_buffer_get_video_meta (buf);
+      if (!meta) {
+        gst_buffer_add_video_meta (buf, GST_VIDEO_FRAME_FLAG_NONE,
+            GST_VIDEO_INFO_FORMAT (&pool->video_info),
+            GST_VIDEO_INFO_WIDTH (&pool->video_info),
+            GST_VIDEO_INFO_HEIGHT (&pool->video_info));
+      }
+    }
+  } else {
+    GstMemory *mem;
+
+    mem = gst_omx_memory_allocator_alloc (pool->allocator, 0, omx_buf);
+    buf = gst_buffer_new ();
+    gst_buffer_append_memory (buf, mem);
+    g_ptr_array_add (pool->buffers, buf);
+
+    if (pool->add_videometa) {
+      gsize offset[4] = { 0, };
+      gint stride[4] = { 0, };
+
+      switch (pool->video_info.finfo->format) {
+        case GST_VIDEO_FORMAT_I420:
+          offset[0] = 0;
+          stride[0] = pool->port->port_def.format.video.nStride;
+          offset[1] =
+              stride[0] * pool->port->port_def.format.video.nSliceHeight;
+          stride[1] = pool->port->port_def.format.video.nStride / 2;
+          offset[2] =
+              offset[1] +
+              stride[1] * (pool->port->port_def.format.video.nSliceHeight / 2);
+          stride[2] = pool->port->port_def.format.video.nStride / 2;
+          break;
+        case GST_VIDEO_FORMAT_NV12:
+          offset[0] = 0;
+          stride[0] = pool->port->port_def.format.video.nStride;
+          offset[1] =
+              stride[0] * pool->port->port_def.format.video.nSliceHeight;
+          stride[1] = pool->port->port_def.format.video.nStride;
+          break;
+        default:
+          g_assert_not_reached ();
+          break;
+      }
+
+      gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
+          GST_VIDEO_INFO_FORMAT (&pool->video_info),
+          GST_VIDEO_INFO_WIDTH (&pool->video_info),
+          GST_VIDEO_INFO_HEIGHT (&pool->video_info),
+          GST_VIDEO_INFO_N_PLANES (&pool->video_info), offset, stride);
+    }
+  }
+
+  gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (buf),
+      gst_omx_buffer_data_quark, omx_buf, NULL);
+
+  *buffer = buf;
+
+  pool->current_buffer_index++;
+
+  return GST_FLOW_OK;
+}
+
+static void
+gst_omx_buffer_pool_free_buffer (GstBufferPool * bpool, GstBuffer * buffer)
+{
+  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
+
+  /* If the buffers belong to another pool, restore them now */
+  GST_OBJECT_LOCK (pool);
+  if (pool->other_pool) {
+    gst_object_replace ((GstObject **) & buffer->pool,
+        (GstObject *) pool->other_pool);
+  }
+  GST_OBJECT_UNLOCK (pool);
+
+  gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (buffer),
+      gst_omx_buffer_data_quark, NULL, NULL);
+
+  GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->free_buffer (bpool,
+      buffer);
+}
+
+static GstFlowReturn
+gst_omx_buffer_pool_acquire_buffer (GstBufferPool * bpool,
+    GstBuffer ** buffer, GstBufferPoolAcquireParams * params)
+{
+  GstFlowReturn ret;
+  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
+
+  if (pool->port->port_def.eDir == OMX_DirOutput) {
+    GstBuffer *buf;
+
+    g_return_val_if_fail (pool->current_buffer_index != -1, GST_FLOW_ERROR);
+
+    buf = g_ptr_array_index (pool->buffers, pool->current_buffer_index);
+    g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
+    *buffer = buf;
+    ret = GST_FLOW_OK;
+
+    /* If it's our own memory we have to set the sizes */
+    if (!pool->other_pool) {
+      GstMemory *mem = gst_buffer_peek_memory (*buffer, 0);
+
+      g_assert (mem
+          && g_strcmp0 (mem->allocator->mem_type, GST_OMX_MEMORY_TYPE) == 0);
+      mem->size = ((GstOMXMemory *) mem)->buf->omx_buf->nFilledLen;
+      mem->offset = ((GstOMXMemory *) mem)->buf->omx_buf->nOffset;
+    }
+  } else {
+    /* Acquire any buffer that is available to be filled by upstream */
+    ret =
+        GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->acquire_buffer
+        (bpool, buffer, params);
+  }
+
+  return ret;
+}
+
+static void
+gst_omx_buffer_pool_release_buffer (GstBufferPool * bpool, GstBuffer * buffer)
+{
+  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
+  OMX_ERRORTYPE err;
+  GstOMXBuffer *omx_buf;
+
+  g_assert (pool->component && pool->port);
+
+  if (!pool->allocating && !pool->deactivated) {
+    omx_buf =
+        gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (buffer),
+        gst_omx_buffer_data_quark);
+    if (pool->port->port_def.eDir == OMX_DirOutput && !omx_buf->used) {
+      /* Release back to the port, can be filled again */
+      err = gst_omx_port_release_buffer (pool->port, omx_buf);
+      if (err != OMX_ErrorNone) {
+        GST_ELEMENT_ERROR (pool->element, LIBRARY, SETTINGS, (NULL),
+            ("Failed to relase output buffer to component: %s (0x%08x)",
+                gst_omx_error_to_string (err), err));
+      }
+    } else if (!omx_buf->used) {
+      /* TODO: Implement.
+       *
+       * If not used (i.e. was not passed to the component) this should do
+       * the same as EmptyBufferDone.
+       * If it is used (i.e. was passed to the component) this should do
+       * nothing until EmptyBufferDone.
+       *
+       * EmptyBufferDone should release the buffer to the pool so it can
+       * be allocated again
+       *
+       * Needs something to call back here in EmptyBufferDone, like keeping
+       * a ref on the buffer in GstOMXBuffer until EmptyBufferDone... which
+       * would ensure that the buffer is always unused when this is called.
+       */
+      g_assert_not_reached ();
+      GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->release_buffer
+          (bpool, buffer);
+    }
+  }
+}
+
+static void
+gst_omx_buffer_pool_finalize (GObject * object)
+{
+  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (object);
+
+  if (pool->element)
+    gst_object_unref (pool->element);
+  pool->element = NULL;
+
+  if (pool->buffers)
+    g_ptr_array_unref (pool->buffers);
+  pool->buffers = NULL;
+
+  if (pool->other_pool)
+    gst_object_unref (pool->other_pool);
+  pool->other_pool = NULL;
+
+  if (pool->allocator)
+    gst_object_unref (pool->allocator);
+  pool->allocator = NULL;
+
+  if (pool->caps)
+    gst_caps_unref (pool->caps);
+  pool->caps = NULL;
+
+  G_OBJECT_CLASS (gst_omx_buffer_pool_parent_class)->finalize (object);
+}
+
+static void
+gst_omx_buffer_pool_class_init (GstOMXBufferPoolClass * klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass;
+
+  gst_omx_buffer_data_quark = g_quark_from_static_string ("GstOMXBufferData");
+
+  gobject_class->finalize = gst_omx_buffer_pool_finalize;
+  gstbufferpool_class->start = gst_omx_buffer_pool_start;
+  gstbufferpool_class->stop = gst_omx_buffer_pool_stop;
+  gstbufferpool_class->get_options = gst_omx_buffer_pool_get_options;
+  gstbufferpool_class->set_config = gst_omx_buffer_pool_set_config;
+  gstbufferpool_class->alloc_buffer = gst_omx_buffer_pool_alloc_buffer;
+  gstbufferpool_class->free_buffer = gst_omx_buffer_pool_free_buffer;
+  gstbufferpool_class->acquire_buffer = gst_omx_buffer_pool_acquire_buffer;
+  gstbufferpool_class->release_buffer = gst_omx_buffer_pool_release_buffer;
+}
+
+static void
+gst_omx_buffer_pool_init (GstOMXBufferPool * pool)
+{
+  pool->buffers = g_ptr_array_new ();
+  pool->allocator = g_object_new (gst_omx_memory_allocator_get_type (), NULL);
+}
+
+GstBufferPool *
+gst_omx_buffer_pool_new (GstElement * element, GstOMXComponent * component,
+    GstOMXPort * port)
+{
+  GstOMXBufferPool *pool;
+
+  pool = g_object_new (gst_omx_buffer_pool_get_type (), NULL);
+  pool->element = gst_object_ref (element);
+  pool->component = component;
+  pool->port = port;
+
+  return GST_BUFFER_POOL (pool);
+}
diff --git a/omx/gstomxbufferpool.h b/omx/gstomxbufferpool.h
new file mode 100644 (file)
index 0000000..acc69f6
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *   Author: Christian König <christian.koenig@amd.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#ifndef __GST_OMX_BUFFER_POOL_H__
+#define __GST_OMX_BUFEFR_POOL_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/video/gstvideometa.h>
+#include <gst/video/gstvideopool.h>
+
+#include "gstomx.h"
+
+G_BEGIN_DECLS
+
+#define GST_OMX_BUFFER_POOL(pool) ((GstOMXBufferPool *) pool)
+typedef struct _GstOMXBufferPool GstOMXBufferPool;
+typedef struct _GstOMXBufferPoolClass GstOMXBufferPoolClass;
+
+struct _GstOMXBufferPool
+{
+  GstVideoBufferPool parent;
+
+  GstElement *element;
+
+  GstCaps *caps;
+  gboolean add_videometa;
+  GstVideoInfo video_info;
+
+  /* Owned by element, element has to stop this pool before
+   * it destroys component or port */
+  GstOMXComponent *component;
+  GstOMXPort *port;
+
+  /* For handling OpenMAX allocated memory */
+  GstAllocator *allocator;
+
+  /* Set from outside this pool */
+  /* TRUE if we're currently allocating all our buffers */
+  gboolean allocating;
+  /* TRUE if the pool is not used anymore */
+  gboolean deactivated;
+
+  /* For populating the pool from another one */
+  GstBufferPool *other_pool;
+  GPtrArray *buffers;
+
+  /* Used during acquire for output ports to
+   * specify which buffer has to be retrieved
+   * and during alloc, which buffer has to be
+   * wrapped
+   */
+  gint current_buffer_index;
+};
+
+struct _GstOMXBufferPoolClass
+{
+  GstVideoBufferPoolClass parent_class;
+};
+
+GType gst_omx_buffer_pool_get_type (void);
+
+GstBufferPool *gst_omx_buffer_pool_new (GstElement * element, GstOMXComponent * component, GstOMXPort * port);
+
+G_END_DECLS
+
+#endif /* __GST_OMX_BUFFER_POOL_H__ */
index 0451176..3b6605a 100644 (file)
@@ -25,8 +25,6 @@
 #endif
 
 #include <gst/gst.h>
-#include <gst/video/gstvideometa.h>
-#include <gst/video/gstvideopool.h>
 
 #if defined (USE_OMX_TARGET_RPI) && defined(__GNUC__)
 #ifndef __VCCOREVER__
 
 #include <string.h>
 
+#include "gstomxbufferpool.h"
 #include "gstomxvideodec.h"
 
 GST_DEBUG_CATEGORY_STATIC (gst_omx_video_dec_debug_category);
 #define GST_CAT_DEFAULT gst_omx_video_dec_debug_category
 
-typedef struct _GstOMXMemory GstOMXMemory;
-typedef struct _GstOMXMemoryAllocator GstOMXMemoryAllocator;
-typedef struct _GstOMXMemoryAllocatorClass GstOMXMemoryAllocatorClass;
-
-struct _GstOMXMemory
-{
-  GstMemory mem;
-
-  GstOMXBuffer *buf;
-};
-
-struct _GstOMXMemoryAllocator
-{
-  GstAllocator parent;
-};
-
-struct _GstOMXMemoryAllocatorClass
-{
-  GstAllocatorClass parent_class;
-};
-
-#define GST_OMX_MEMORY_TYPE "openmax"
-
-static GstMemory *
-gst_omx_memory_allocator_alloc_dummy (GstAllocator * allocator, gsize size,
-    GstAllocationParams * params)
-{
-  g_assert_not_reached ();
-  return NULL;
-}
-
-static void
-gst_omx_memory_allocator_free (GstAllocator * allocator, GstMemory * mem)
-{
-  GstOMXMemory *omem = (GstOMXMemory *) mem;
-
-  /* TODO: We need to remember which memories are still used
-   * so we can wait until everything is released before allocating
-   * new memory
-   */
-
-  g_slice_free (GstOMXMemory, omem);
-}
-
-static gpointer
-gst_omx_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags)
-{
-  GstOMXMemory *omem = (GstOMXMemory *) mem;
-
-  return omem->buf->omx_buf->pBuffer + omem->mem.offset;
-}
-
-static void
-gst_omx_memory_unmap (GstMemory * mem)
-{
-}
-
-static GstMemory *
-gst_omx_memory_share (GstMemory * mem, gssize offset, gssize size)
-{
-  g_assert_not_reached ();
-  return NULL;
-}
-
-GType gst_omx_memory_allocator_get_type (void);
-G_DEFINE_TYPE (GstOMXMemoryAllocator, gst_omx_memory_allocator,
-    GST_TYPE_ALLOCATOR);
-
-#define GST_TYPE_OMX_MEMORY_ALLOCATOR   (gst_omx_memory_allocator_get_type())
-#define GST_IS_OMX_MEMORY_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_OMX_MEMORY_ALLOCATOR))
-
-static void
-gst_omx_memory_allocator_class_init (GstOMXMemoryAllocatorClass * klass)
-{
-  GstAllocatorClass *allocator_class;
-
-  allocator_class = (GstAllocatorClass *) klass;
-
-  allocator_class->alloc = gst_omx_memory_allocator_alloc_dummy;
-  allocator_class->free = gst_omx_memory_allocator_free;
-}
-
-static void
-gst_omx_memory_allocator_init (GstOMXMemoryAllocator * allocator)
-{
-  GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
-
-  alloc->mem_type = GST_OMX_MEMORY_TYPE;
-  alloc->mem_map = gst_omx_memory_map;
-  alloc->mem_unmap = gst_omx_memory_unmap;
-  alloc->mem_share = gst_omx_memory_share;
-
-  /* default copy & is_span */
-
-  GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
-}
-
-static GstMemory *
-gst_omx_memory_allocator_alloc (GstAllocator * allocator, GstMemoryFlags flags,
-    GstOMXBuffer * buf)
-{
-  GstOMXMemory *mem;
-
-  /* FIXME: We don't allow sharing because we need to know
-   * when the memory becomes unused and can only then put
-   * it back to the pool. Which is done in the pool's release
-   * function
-   */
-  flags |= GST_MEMORY_FLAG_NO_SHARE;
-
-  mem = g_slice_new (GstOMXMemory);
-  /* the shared memory is always readonly */
-  gst_memory_init (GST_MEMORY_CAST (mem), flags, allocator, NULL,
-      buf->omx_buf->nAllocLen, buf->port->port_def.nBufferAlignment,
-      0, buf->omx_buf->nAllocLen);
-
-  mem->buf = buf;
-
-  return GST_MEMORY_CAST (mem);
-}
-
-/* Buffer pool for the buffers of an OpenMAX port.
- *
- * This pool is only used if we either passed buffers from another
- * pool to the OMX port or provide the OMX buffers directly to other
- * elements.
- *
- *
- * A buffer is in the pool if it is currently owned by the port,
- * i.e. after OMX_{Fill,Empty}ThisBuffer(). A buffer is outside
- * the pool after it was taken from the port after it was handled
- * by the port, i.e. {Empty,Fill}BufferDone.
- *
- * Buffers can be allocated by us (OMX_AllocateBuffer()) or allocated
- * by someone else and (temporarily) passed to this pool
- * (OMX_UseBuffer(), OMX_UseEGLImage()). In the latter case the pool of
- * the buffer will be overriden, and restored in free_buffer(). Other
- * buffers are just freed there.
- *
- * The pool always has a fixed number of minimum and maximum buffers
- * and these are allocated while starting the pool and released afterwards.
- * They correspond 1:1 to the OMX buffers of the port, which are allocated
- * before the pool is started.
- *
- * Acquiring a buffer from this pool happens after the OMX buffer has
- * been acquired from the port. gst_buffer_pool_acquire_buffer() is
- * supposed to return the buffer that corresponds to the OMX buffer.
- *
- * For buffers provided to upstream, the buffer will be passed to
- * the component manually when it arrives and then unreffed. If the
- * buffer is released before reaching the component it will be just put
- * back into the pool as if EmptyBufferDone has happened. If it was
- * passed to the component, it will be back into the pool when it was
- * released and EmptyBufferDone has happened.
- *
- * For buffers provided to downstream, the buffer will be returned
- * back to the component (OMX_FillThisBuffer()) when it is released.
- */
-
-static GQuark gst_omx_buffer_data_quark = 0;
-
-#define GST_OMX_BUFFER_POOL(pool) ((GstOMXBufferPool *) pool)
-typedef struct _GstOMXBufferPool GstOMXBufferPool;
-typedef struct _GstOMXBufferPoolClass GstOMXBufferPoolClass;
-
-struct _GstOMXBufferPool
-{
-  GstVideoBufferPool parent;
-
-  GstElement *element;
-
-  GstCaps *caps;
-  gboolean add_videometa;
-  GstVideoInfo video_info;
-
-  /* Owned by element, element has to stop this pool before
-   * it destroys component or port */
-  GstOMXComponent *component;
-  GstOMXPort *port;
-
-  /* For handling OpenMAX allocated memory */
-  GstAllocator *allocator;
-
-  /* Set from outside this pool */
-  /* TRUE if we're currently allocating all our buffers */
-  gboolean allocating;
-
-  /* TRUE if the pool is not used anymore */
-  gboolean deactivated;
-
-  /* For populating the pool from another one */
-  GstBufferPool *other_pool;
-  GPtrArray *buffers;
-
-  /* Used during acquire for output ports to
-   * specify which buffer has to be retrieved
-   * and during alloc, which buffer has to be
-   * wrapped
-   */
-  gint current_buffer_index;
-};
-
-struct _GstOMXBufferPoolClass
-{
-  GstVideoBufferPoolClass parent_class;
-};
-
-GType gst_omx_buffer_pool_get_type (void);
-
-G_DEFINE_TYPE (GstOMXBufferPool, gst_omx_buffer_pool, GST_TYPE_BUFFER_POOL);
-
-static gboolean
-gst_omx_buffer_pool_start (GstBufferPool * bpool)
-{
-  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
-
-  /* Only allow to start the pool if we still are attached
-   * to a component and port */
-  GST_OBJECT_LOCK (pool);
-  if (!pool->component || !pool->port) {
-    GST_OBJECT_UNLOCK (pool);
-    return FALSE;
-  }
-  GST_OBJECT_UNLOCK (pool);
-
-  return
-      GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->start (bpool);
-}
-
-static gboolean
-gst_omx_buffer_pool_stop (GstBufferPool * bpool)
-{
-  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
-
-  /* Remove any buffers that are there */
-  g_ptr_array_set_size (pool->buffers, 0);
-
-  if (pool->caps)
-    gst_caps_unref (pool->caps);
-  pool->caps = NULL;
-
-  pool->add_videometa = FALSE;
-
-  return GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->stop (bpool);
-}
-
-static const gchar **
-gst_omx_buffer_pool_get_options (GstBufferPool * bpool)
-{
-  static const gchar *raw_video_options[] =
-      { GST_BUFFER_POOL_OPTION_VIDEO_META, NULL };
-  static const gchar *options[] = { NULL };
-  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
-
-  GST_OBJECT_LOCK (pool);
-  if (pool->port && pool->port->port_def.eDomain == OMX_PortDomainVideo
-      && pool->port->port_def.format.video.eCompressionFormat ==
-      OMX_VIDEO_CodingUnused) {
-    GST_OBJECT_UNLOCK (pool);
-    return raw_video_options;
-  }
-  GST_OBJECT_UNLOCK (pool);
-
-  return options;
-}
-
-static gboolean
-gst_omx_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config)
-{
-  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
-  GstCaps *caps;
-
-  GST_OBJECT_LOCK (pool);
-
-  if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
-    goto wrong_config;
-
-  if (caps == NULL)
-    goto no_caps;
-
-  if (pool->port && pool->port->port_def.eDomain == OMX_PortDomainVideo
-      && pool->port->port_def.format.video.eCompressionFormat ==
-      OMX_VIDEO_CodingUnused) {
-    GstVideoInfo info;
-
-    /* now parse the caps from the config */
-    if (!gst_video_info_from_caps (&info, caps))
-      goto wrong_video_caps;
-
-    /* enable metadata based on config of the pool */
-    pool->add_videometa =
-        gst_buffer_pool_config_has_option (config,
-        GST_BUFFER_POOL_OPTION_VIDEO_META);
-
-    pool->video_info = info;
-  }
-
-  if (pool->caps)
-    gst_caps_unref (pool->caps);
-  pool->caps = gst_caps_ref (caps);
-
-  GST_OBJECT_UNLOCK (pool);
-
-  return GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->set_config
-      (bpool, config);
-
-  /* ERRORS */
-wrong_config:
-  {
-    GST_OBJECT_UNLOCK (pool);
-    GST_WARNING_OBJECT (pool, "invalid config");
-    return FALSE;
-  }
-no_caps:
-  {
-    GST_OBJECT_UNLOCK (pool);
-    GST_WARNING_OBJECT (pool, "no caps in config");
-    return FALSE;
-  }
-wrong_video_caps:
-  {
-    GST_OBJECT_UNLOCK (pool);
-    GST_WARNING_OBJECT (pool,
-        "failed getting geometry from caps %" GST_PTR_FORMAT, caps);
-    return FALSE;
-  }
-}
-
-static GstFlowReturn
-gst_omx_buffer_pool_alloc_buffer (GstBufferPool * bpool,
-    GstBuffer ** buffer, GstBufferPoolAcquireParams * params)
-{
-  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
-  GstBuffer *buf;
-  GstOMXBuffer *omx_buf;
-
-  g_return_val_if_fail (pool->allocating, GST_FLOW_ERROR);
-
-  omx_buf = g_ptr_array_index (pool->port->buffers, pool->current_buffer_index);
-  g_return_val_if_fail (omx_buf != NULL, GST_FLOW_ERROR);
-
-  if (pool->other_pool) {
-    guint i, n;
-
-    buf = g_ptr_array_index (pool->buffers, pool->current_buffer_index);
-    g_assert (pool->other_pool == buf->pool);
-    gst_object_replace ((GstObject **) & buf->pool, NULL);
-
-    n = gst_buffer_n_memory (buf);
-    for (i = 0; i < n; i++) {
-      GstMemory *mem = gst_buffer_peek_memory (buf, i);
-
-      /* FIXME: We don't allow sharing because we need to know
-       * when the memory becomes unused and can only then put
-       * it back to the pool. Which is done in the pool's release
-       * function
-       */
-      GST_MINI_OBJECT_FLAG_SET (mem, GST_MEMORY_FLAG_NO_SHARE);
-    }
-
-    if (pool->add_videometa) {
-      GstVideoMeta *meta;
-
-      meta = gst_buffer_get_video_meta (buf);
-      if (!meta) {
-        gst_buffer_add_video_meta (buf, GST_VIDEO_FRAME_FLAG_NONE,
-            GST_VIDEO_INFO_FORMAT (&pool->video_info),
-            GST_VIDEO_INFO_WIDTH (&pool->video_info),
-            GST_VIDEO_INFO_HEIGHT (&pool->video_info));
-      }
-    }
-  } else {
-    GstMemory *mem;
-
-    mem = gst_omx_memory_allocator_alloc (pool->allocator, 0, omx_buf);
-    buf = gst_buffer_new ();
-    gst_buffer_append_memory (buf, mem);
-    g_ptr_array_add (pool->buffers, buf);
-
-    if (pool->add_videometa) {
-      gsize offset[4] = { 0, };
-      gint stride[4] = { 0, };
-
-      switch (pool->video_info.finfo->format) {
-        case GST_VIDEO_FORMAT_I420:
-          offset[0] = 0;
-          stride[0] = pool->port->port_def.format.video.nStride;
-          offset[1] =
-              stride[0] * pool->port->port_def.format.video.nSliceHeight;
-          stride[1] = pool->port->port_def.format.video.nStride / 2;
-          offset[2] =
-              offset[1] +
-              stride[1] * (pool->port->port_def.format.video.nSliceHeight / 2);
-          stride[2] = pool->port->port_def.format.video.nStride / 2;
-          break;
-        case GST_VIDEO_FORMAT_NV12:
-          offset[0] = 0;
-          stride[0] = pool->port->port_def.format.video.nStride;
-          offset[1] =
-              stride[0] * pool->port->port_def.format.video.nSliceHeight;
-          stride[1] = pool->port->port_def.format.video.nStride;
-          break;
-        default:
-          g_assert_not_reached ();
-          break;
-      }
-
-      gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
-          GST_VIDEO_INFO_FORMAT (&pool->video_info),
-          GST_VIDEO_INFO_WIDTH (&pool->video_info),
-          GST_VIDEO_INFO_HEIGHT (&pool->video_info),
-          GST_VIDEO_INFO_N_PLANES (&pool->video_info), offset, stride);
-    }
-  }
-
-  gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (buf),
-      gst_omx_buffer_data_quark, omx_buf, NULL);
-
-  *buffer = buf;
-
-  pool->current_buffer_index++;
-
-  return GST_FLOW_OK;
-}
-
-static void
-gst_omx_buffer_pool_free_buffer (GstBufferPool * bpool, GstBuffer * buffer)
-{
-  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
-
-  /* If the buffers belong to another pool, restore them now */
-  GST_OBJECT_LOCK (pool);
-  if (pool->other_pool) {
-    gst_object_replace ((GstObject **) & buffer->pool,
-        (GstObject *) pool->other_pool);
-  }
-  GST_OBJECT_UNLOCK (pool);
-
-  gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (buffer),
-      gst_omx_buffer_data_quark, NULL, NULL);
-
-  GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->free_buffer (bpool,
-      buffer);
-}
-
-static GstFlowReturn
-gst_omx_buffer_pool_acquire_buffer (GstBufferPool * bpool,
-    GstBuffer ** buffer, GstBufferPoolAcquireParams * params)
-{
-  GstFlowReturn ret;
-  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
-
-  if (pool->port->port_def.eDir == OMX_DirOutput) {
-    GstBuffer *buf;
-
-    g_return_val_if_fail (pool->current_buffer_index != -1, GST_FLOW_ERROR);
-
-    buf = g_ptr_array_index (pool->buffers, pool->current_buffer_index);
-    g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
-    *buffer = buf;
-    ret = GST_FLOW_OK;
-
-    /* If it's our own memory we have to set the sizes */
-    if (!pool->other_pool) {
-      GstMemory *mem = gst_buffer_peek_memory (*buffer, 0);
-
-      g_assert (mem
-          && g_strcmp0 (mem->allocator->mem_type, GST_OMX_MEMORY_TYPE) == 0);
-      mem->size = ((GstOMXMemory *) mem)->buf->omx_buf->nFilledLen;
-      mem->offset = ((GstOMXMemory *) mem)->buf->omx_buf->nOffset;
-    }
-  } else {
-    /* Acquire any buffer that is available to be filled by upstream */
-    ret =
-        GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->acquire_buffer
-        (bpool, buffer, params);
-  }
-
-  return ret;
-}
-
-static void
-gst_omx_buffer_pool_release_buffer (GstBufferPool * bpool, GstBuffer * buffer)
-{
-  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
-  OMX_ERRORTYPE err;
-  GstOMXBuffer *omx_buf;
-
-  g_assert (pool->component && pool->port);
-
-  if (!pool->allocating && !pool->deactivated) {
-    omx_buf =
-        gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (buffer),
-        gst_omx_buffer_data_quark);
-    if (pool->port->port_def.eDir == OMX_DirOutput && !omx_buf->used) {
-      /* Release back to the port, can be filled again */
-      err = gst_omx_port_release_buffer (pool->port, omx_buf);
-      if (err != OMX_ErrorNone) {
-        GST_ELEMENT_ERROR (pool->element, LIBRARY, SETTINGS, (NULL),
-            ("Failed to relase output buffer to component: %s (0x%08x)",
-                gst_omx_error_to_string (err), err));
-      }
-    } else if (!omx_buf->used) {
-      /* TODO: Implement.
-       *
-       * If not used (i.e. was not passed to the component) this should do
-       * the same as EmptyBufferDone.
-       * If it is used (i.e. was passed to the component) this should do
-       * nothing until EmptyBufferDone.
-       *
-       * EmptyBufferDone should release the buffer to the pool so it can
-       * be allocated again
-       *
-       * Needs something to call back here in EmptyBufferDone, like keeping
-       * a ref on the buffer in GstOMXBuffer until EmptyBufferDone... which
-       * would ensure that the buffer is always unused when this is called.
-       */
-      g_assert_not_reached ();
-      GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->release_buffer
-          (bpool, buffer);
-    }
-  }
-}
-
-static void
-gst_omx_buffer_pool_finalize (GObject * object)
-{
-  GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (object);
-
-  if (pool->element)
-    gst_object_unref (pool->element);
-  pool->element = NULL;
-
-  if (pool->buffers)
-    g_ptr_array_unref (pool->buffers);
-  pool->buffers = NULL;
-
-  if (pool->other_pool)
-    gst_object_unref (pool->other_pool);
-  pool->other_pool = NULL;
-
-  if (pool->allocator)
-    gst_object_unref (pool->allocator);
-  pool->allocator = NULL;
-
-  if (pool->caps)
-    gst_caps_unref (pool->caps);
-  pool->caps = NULL;
-
-  G_OBJECT_CLASS (gst_omx_buffer_pool_parent_class)->finalize (object);
-}
-
-static void
-gst_omx_buffer_pool_class_init (GstOMXBufferPoolClass * klass)
-{
-  GObjectClass *gobject_class = (GObjectClass *) klass;
-  GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass;
-
-  gst_omx_buffer_data_quark = g_quark_from_static_string ("GstOMXBufferData");
-
-  gobject_class->finalize = gst_omx_buffer_pool_finalize;
-  gstbufferpool_class->start = gst_omx_buffer_pool_start;
-  gstbufferpool_class->stop = gst_omx_buffer_pool_stop;
-  gstbufferpool_class->get_options = gst_omx_buffer_pool_get_options;
-  gstbufferpool_class->set_config = gst_omx_buffer_pool_set_config;
-  gstbufferpool_class->alloc_buffer = gst_omx_buffer_pool_alloc_buffer;
-  gstbufferpool_class->free_buffer = gst_omx_buffer_pool_free_buffer;
-  gstbufferpool_class->acquire_buffer = gst_omx_buffer_pool_acquire_buffer;
-  gstbufferpool_class->release_buffer = gst_omx_buffer_pool_release_buffer;
-}
-
-static void
-gst_omx_buffer_pool_init (GstOMXBufferPool * pool)
-{
-  pool->buffers = g_ptr_array_new ();
-  pool->allocator = g_object_new (gst_omx_memory_allocator_get_type (), NULL);
-}
-
-static GstBufferPool *
-gst_omx_buffer_pool_new (GstElement * element, GstOMXComponent * component,
-    GstOMXPort * port)
-{
-  GstOMXBufferPool *pool;
-
-  pool = g_object_new (gst_omx_buffer_pool_get_type (), NULL);
-  pool->element = gst_object_ref (element);
-  pool->component = component;
-  pool->port = port;
-
-  return GST_BUFFER_POOL (pool);
-}
-
 /* prototypes */
 static void gst_omx_video_dec_finalize (GObject * object);