AC_PATH_PROG(VALGRIND_PATH, valgrind, no)
AM_CONDITIONAL(HAVE_VALGRIND, test ! "x$VALGRIND_PATH" = "xno")
-
-dnl check for tbm buffer
-
-AC_ARG_ENABLE(tbmbuf, AC_HELP_STRING([--enable-use-tbmbuf], [use tbm buf]),
- [
- case "${enableval}" in
- yes) BOARD_USE_TBM_BUF=yes ;;
- no) BOARD_USE_TBM_BUF=no ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-use-tbmbuf) ;;
- esac
- ],
- [BOARD_USE_TBM_BUF=yes])
-AM_CONDITIONAL([BOARD_USE_TBM_BUF], [test "x$BOARD_USE_TBM_BUF" = "xyes"])
+dnl check for supporting tbm
+AC_MSG_CHECKING([for supporting tbm])
+AC_ARG_ENABLE(tbm, AC_HELP_STRING([--enable-tbm], [tbm support]),
+ [
+ case "${enableval}" in
+ yes) USE_TBM=yes ;;
+ no) USE_TBM=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-tbm) ;;
+ esac
+ ],
+ [USE_TBM=no])
+AM_CONDITIONAL(USE_TBM, test "x$USE_TBM" = "xyes")
+AC_MSG_RESULT([$USE_TBM])
+if test "x$USE_TBM" = "xyes"; then
+ AC_DEFINE(USE_TBM, 1, [tbm support])
+fi
dnl Check for tv-product
AC_ARG_ENABLE(tv, AC_HELP_STRING([--enable-tv], [use tv]),
sdp: rtp
+allocators : video
+
INDEPENDENT_SUBDIRS = \
tag audio fft video app
libgstallocators_@GST_API_VERSION@_la_SOURCES = \
gstfdmemory.c \
- gstdmabuf.c
+ gstdmabuf.c
libgstallocators_@GST_API_VERSION@_la_LIBADD = $(GST_LIBS) $(LIBM)
libgstallocators_@GST_API_VERSION@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
libgstallocators_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
+libgstallocators_@GST_API_VERSION@__la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
+
+
+if USE_TBM
+libgstallocators_@GST_API_VERSION@_include_HEADERS += \
+ gsttizenmemory.h \
+ gsttizenbufferpool.h
+
+libgstallocators_@GST_API_VERSION@_la_SOURCES += \
+ gsttizenmemory.c \
+ gsttizenbufferpool.c
+
+libgstallocators_@GST_API_VERSION@_la_LIBADD += \
+ $(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_API_VERSION@.la \
+ $(TBM_LIBS)
+
+libgstallocators_@GST_API_VERSION@_la_CFLAGS += $(TBM_CFLAGS)
+endif
if HAVE_INTROSPECTION
BUILT_GIRSOURCES = GstAllocators-@GST_API_VERSION@.gir
#include <gst/allocators/gstdmabuf.h>
#include <gst/allocators/gstfdmemory.h>
+#ifdef USE_TBM
+#include <gst/allocators/gsttizenmemory.h>
+#include <gst/allocators/gsttizenbufferpool.h>
+#endif
+
#endif /* __GST_ALLOCATORS_H__ */
--- /dev/null
+/*
+ * GStreamer tizen buffer pool
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Author: Sejun Park <sejun79.park@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gsttizenbufferpool.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_tizen_vidbufpool_debug);
+#define GST_CAT_DEFAULT gst_tizen_vidbufpool_debug
+
+static GQuark gst_tizen_buffer_data_quark = 0;
+
+static void gst_tizen_buffer_pool_finalize (GObject * object);
+
+#define DEBUG_INIT \
+ GST_DEBUG_CATEGORY_INIT (gst_tizen_vidbufpool_debug, "tizenvideopool", 0, \
+ "Tizen bufferpool");
+
+#define gst_tizen_buffer_pool_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstTizenBufferPool, gst_tizen_buffer_pool,
+ GST_TYPE_BUFFER_POOL, DEBUG_INIT);
+
+static const gchar **
+gst_tizen_buffer_pool_get_options (GstBufferPool * pool)
+{
+ static const gchar *options[] = { GST_BUFFER_POOL_OPTION_VIDEO_META,
+ GST_BUFFER_POOL_OPTION_TIZEN_META, NULL
+ };
+
+ return options;
+}
+
+static gboolean
+gst_tizen_buffer_pool_set_config (GstBufferPool * pool,
+ GstStructure * config)
+{
+ GstTizenBufferPool *_tpool = GST_TIZEN_BUFFER_POOL_CAST (pool);
+ GstVideoInfo info;
+ GstCaps *caps;
+
+ if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
+ goto wrong_config;
+
+ if (caps == NULL)
+ goto no_caps;
+
+ /* now parse the caps from the config */
+ if (!gst_video_info_from_caps (&info, caps))
+ goto wrong_caps;
+
+ if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_UNKNOWN)
+ goto unknown_format;
+
+ _tpool->info = info;
+
+ /* enable metadata based on config of the pool */
+ _tpool->add_videometa = gst_buffer_pool_config_has_option (config,
+ GST_BUFFER_POOL_OPTION_VIDEO_META);
+
+ /* parse extra alignment info */
+ _tpool->add_tizenmeta = gst_buffer_pool_config_has_option (config,
+ GST_BUFFER_POOL_OPTION_TIZEN_META);
+
+ return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config);
+
+ /* ERRORS */
+wrong_config:
+ {
+ GST_WARNING_OBJECT (pool, "invalid config");
+ return FALSE;
+ }
+no_caps:
+ {
+ GST_WARNING_OBJECT (pool, "no caps in config");
+ return FALSE;
+ }
+wrong_caps:
+ {
+ GST_WARNING_OBJECT (pool,
+ "failed getting geometry from caps %" GST_PTR_FORMAT, caps);
+ return FALSE;
+ }
+unknown_format:
+ {
+ GST_WARNING_OBJECT (_tpool, "failed to get format from caps %"
+ GST_PTR_FORMAT, caps);
+ GST_ELEMENT_ERROR (_tpool, RESOURCE, WRITE,
+ ("Failed to create output image buffer of %dx%d pixels",
+ info.width, info.height),
+ ("Invalid input caps %" GST_PTR_FORMAT, caps));
+ return FALSE;
+ }
+}
+
+/* This function handles GstBuffer creation */
+static GstFlowReturn
+gst_tizen_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
+ GstBufferPoolAcquireParams * params)
+{
+ GstTizenBufferPool *_tpool = GST_TIZEN_BUFFER_POOL_CAST (pool);
+ GstVideoInfo *info;
+ GstBuffer *buf;
+ GstMemory *tizen_mem;
+ gint offsets[4] = {0, };
+
+ GST_DEBUG_OBJECT (pool, "gst_tizen_buffer_pool_alloc");
+ info = &_tpool->info;
+
+ if (!(buf = gst_buffer_new ()))
+ goto no_buffer;
+
+ GST_DEBUG_OBJECT (pool, "buffer new :%dx%d : %p", GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info), buf);
+ if (!(tizen_mem = gst_tizen_allocator_alloc ((GstAllocator *)_tpool->allocator, info)))
+ goto mem_create_failed;
+
+ GST_DEBUG_OBJECT (pool, "mem allocated : %p, %dx%d n_plane : %d",
+ buf, GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info));
+
+ gst_buffer_append_memory (buf, tizen_mem);
+
+ if (_tpool->add_videometa) {
+ GstVideoMeta *vmeta;
+
+ GST_DEBUG_OBJECT (pool, "adding GstVideoMeta");
+ /* these are just the defaults for now */
+
+ vmeta = gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
+ GST_VIDEO_INFO_FORMAT (info),
+ GST_VIDEO_INFO_WIDTH (info),
+ GST_VIDEO_INFO_HEIGHT (info),
+ GST_VIDEO_INFO_N_PLANES (info), offsets, info->stride);
+
+ vmeta->map = gst_tizen_video_memory_map;
+ vmeta->unmap = gst_tizen_video_memory_unmap;
+ }
+
+ *buffer = buf;
+
+ return GST_FLOW_OK;
+
+ /* ERROR */
+no_buffer:
+ {
+ GST_WARNING_OBJECT (pool, "can't create image");
+ return GST_FLOW_ERROR;
+ }
+
+mem_create_failed:
+ {
+ GST_WARNING_OBJECT (pool, "Could create GstTizen Memory");
+ return GST_FLOW_ERROR;
+ }
+}
+
+GstBufferPool *
+gst_tizen_buffer_pool_new ()
+{
+ return GST_BUFFER_POOL_CAST (g_object_new (GST_TYPE_TIZEN_BUFFER_POOL, NULL));
+}
+
+static void
+gst_tizen_buffer_pool_class_init (GstTizenBufferPoolClass * klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+ GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass;
+
+ gobject_class->finalize = gst_tizen_buffer_pool_finalize;
+
+ gstbufferpool_class->get_options = gst_tizen_buffer_pool_get_options;
+ gstbufferpool_class->set_config = gst_tizen_buffer_pool_set_config;
+ gstbufferpool_class->alloc_buffer = gst_tizen_buffer_pool_alloc;
+}
+
+static void
+gst_tizen_buffer_pool_init (GstTizenBufferPool * pool)
+{
+ pool->allocator = gst_tizen_allocator_new ();
+ GST_LOG_OBJECT (pool, "Tizen buffer pool init %p", pool);
+}
+
+static void
+gst_tizen_buffer_pool_finalize (GObject * object)
+{
+ GstTizenBufferPool *pool = GST_TIZEN_BUFFER_POOL_CAST (object);
+
+ if (pool->allocator)
+ gst_object_unref (pool->allocator);
+
+ GST_LOG_OBJECT (pool, "finalize Tizen buffer pool %p", pool);
+
+ G_OBJECT_CLASS (gst_tizen_buffer_pool_parent_class)->finalize (object);
+}
--- /dev/null
+/*
+ * GStreamer tizen buffer pool
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Author: Sejun Park <sejun79.park@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GST_TIZEN_BUFFERPOOL_H_
+#define _GST_TIZEN_BUFFERPOOL_H_
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/video/gstvideometa.h>
+#include <gst/video/gstvideopool.h>
+#include "gsttizenmemory.h"
+
+G_BEGIN_DECLS
+
+/**
+ * GST_BUFFER_POOL_OPTION_TIZEN_META:
+ *
+ * An option that can be activated on bufferpool to request TizenVideo metadata
+ * on buffers from the pool.
+ */
+#define GST_BUFFER_POOL_OPTION_TIZEN_META "GstBufferPoolOptionTizenVideoMeta"
+
+typedef struct _GstTizenBufferPool GstTizenBufferPool;
+typedef struct _GstTizenBufferPoolClass GstTizenBufferPoolClass;
+
+/* buffer pool functions */
+#define GST_TYPE_TIZEN_BUFFER_POOL (gst_tizen_buffer_pool_get_type())
+#define GST_IS_TIZEN_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TIZEN_BUFFER_POOL))
+#define GST_TIZEN_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TIZEN_BUFFER_POOL, GstTizenBufferPool))
+#define GST_TIZEN_BUFFER_POOL_CAST(obj) ((GstTizenBufferPool*)(obj))
+
+struct _GstTizenBufferPool
+{
+ GstBufferPool bufferpool;
+
+ GstAllocator *allocator;
+ GstVideoInfo info;
+
+ gboolean add_videometa;
+ gboolean add_tizenmeta;
+
+ gint current_buffer_index;
+};
+
+struct _GstTizenBufferPoolClass
+{
+ GstBufferPoolClass parent_class;
+};
+
+GType gst_tizen_buffer_pool_get_type (void);
+GstBufferPool *gst_tizen_buffer_pool_new ();
+
+
+G_END_DECLS
+
+#endif /* _GST_TIZEN_BUFFER_POOL_H_ */
--- /dev/null
+/*
+ * GStreamer tizen memory
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Author: Sejun Park <sejun79.park@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gsttizenmemory.h"
+#include <tbm_surface_internal.h>
+
+#define GST_TIZEN_ALLOCATOR_NAME "TizenVideoMemory"
+
+
+static GstAllocator *_tizen_allocator;
+
+GST_DEBUG_CATEGORY_STATIC (gst_tizenmemory_debug);
+#define GST_CAT_DEFAULT gst_tizenmemory_debug
+
+#define parent_class gst_tizen_allocator_parent_class
+G_DEFINE_TYPE_WITH_CODE (GstTizenAllocator, gst_tizen_allocator, GST_TYPE_ALLOCATOR,
+ G_ADD_PRIVATE (GstTizenAllocator))
+
+typedef struct
+{
+ tbm_format format;
+ GstVideoFormat vformat; /* Gst video format */
+ GstVideoFormat nformat; /* Gst native video format */
+} GstTizenBufferFormats;
+
+static tbm_format gst_video_format_to_tbm_format (GstVideoFormat format);
+static void cached_tizen_disposed_cb (GstTizenAllocator * allocator, GstMiniObject *obj);
+
+static const GstTizenBufferFormats yuv_formats[] = {
+ {TBM_FORMAT_YUV420, GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_S420},
+ {TBM_FORMAT_NV21, GST_VIDEO_FORMAT_NV21, GST_VIDEO_FORMAT_SN21},
+ {TBM_FORMAT_NV12, GST_VIDEO_FORMAT_NV12, GST_VIDEO_FORMAT_SN12},
+ {TBM_FORMAT_BGRA8888, GST_VIDEO_FORMAT_BGRA, GST_VIDEO_FORMAT_SR32}
+};
+
+static tbm_format
+gst_video_format_to_tbm_format (GstVideoFormat format)
+{
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (yuv_formats); i++) {
+ if (yuv_formats[i].nformat == format)
+ return yuv_formats[i].format;
+ }
+ return -1;
+}
+
+static GstTizenMemory *
+_tizen_video_mem_new (GstAllocator * allocator, GstMemory * parent, GstVideoInfo * vinfo)
+{
+ gint width, height;
+ GstTizenMemory *tmem;
+ tbm_surface_info_s sinfo;
+ tbm_format format;
+ gint i;
+
+ tmem = g_slice_new0 (GstTizenMemory);
+
+ width = GST_VIDEO_INFO_WIDTH (vinfo);
+ height = GST_VIDEO_INFO_HEIGHT (vinfo);
+
+ /* Creates the tbm_surface with buffer objects. */
+ format = gst_video_format_to_tbm_format (GST_VIDEO_INFO_FORMAT (vinfo));
+ tmem->surface = tbm_surface_internal_create_with_flags (width, height, format, TBM_BO_DEFAULT);
+
+ if (!tmem->surface) {
+ GST_ERROR ("Failed to create tbm surface w :%d, h : %d, format : %x", width, height, format);
+ goto failed;
+ }
+
+ tbm_surface_get_info (tmem->surface, &sinfo);
+
+ for (i = 0; i < sinfo.num_planes; i++) {
+ GST_VIDEO_INFO_PLANE_STRIDE (vinfo, i) = sinfo.planes[i].stride;
+ GST_VIDEO_INFO_PLANE_OFFSET (vinfo, i) = sinfo.planes[i].offset;
+
+ }
+ GST_VIDEO_INFO_SIZE (vinfo) = sinfo.size;
+
+ gst_memory_init (GST_MEMORY_CAST (tmem), GST_MEMORY_FLAG_NO_SHARE,
+ allocator, parent, GST_VIDEO_INFO_SIZE (vinfo), 0, 0,
+ GST_VIDEO_INFO_SIZE (vinfo));
+
+ g_mutex_init (&tmem->lock);
+
+ GST_DEBUG ("%p: surface: %p size %" G_GSIZE_FORMAT, tmem, tmem->surface,
+ tmem->mem.maxsize);
+
+ return tmem;
+
+ /* ERRORS */
+failed:
+ {
+ GST_ERROR ("Failed to create tbm surface");
+ g_slice_free (GstTizenMemory, tmem);
+ return NULL;
+ }
+}
+
+static void
+gst_tizen_mem_free (GstAllocator * allocator, GstMemory * mem)
+{
+ GstTizenMemory *tmem = (GstTizenMemory *) mem;
+
+ tbm_surface_internal_destroy (tmem->surface);
+
+ g_mutex_clear (&tmem->lock);
+ g_slice_free (GstTizenMemory, tmem);
+}
+
+static gpointer
+gst_tizen_mem_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags)
+{
+ int err;
+ GstTizenMemory *tmem;
+ tbm_surface_info_s info;
+ gpointer data;
+
+ tmem = (GstTizenMemory *)gmem;
+ g_mutex_lock (&tmem->lock);
+
+ err = tbm_surface_map (tmem->surface, TBM_SURF_OPTION_WRITE|TBM_SURF_OPTION_READ, &info);
+ if (err == TBM_SURFACE_ERROR_NONE) {
+ data = info.planes[0].ptr;
+ } else {
+ GST_ERROR ("failed to get surface info");
+ data = NULL;
+ goto done;
+ }
+
+done:
+ g_mutex_unlock (&tmem->lock);
+
+ return data;
+}
+
+static void
+gst_tizen_mem_unmap (GstMemory * gmem)
+{
+ GstTizenMemory *tmem;
+
+ tmem = (GstTizenMemory *)gmem;
+
+ g_mutex_lock (&tmem->lock);
+ tbm_surface_unmap (tmem->surface);
+ g_mutex_unlock (&tmem->lock);
+}
+
+static void
+gst_tizen_allocator_finalize (GObject *obj)
+{
+ GstTizenAllocator *allocator;
+ GList *iter;
+
+ allocator = GST_TIZEN_ALLOCATOR (obj);
+
+ iter = allocator->priv->mem_cache;
+
+ while (iter) {
+ GstMiniObject *obj = iter->data;
+ gst_mini_object_weak_unref (obj,
+ (GstMiniObjectNotify) cached_tizen_disposed_cb, allocator);
+
+ gst_mini_object_set_qdata (obj,
+ g_quark_from_static_string ("tizenmem"), NULL, NULL);
+ iter = iter->next;
+ }
+
+ g_list_free (allocator->priv->mem_cache);
+ allocator->priv->mem_cache = NULL;
+
+ G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+static GstMemory *
+gst_tizen_mem_share (GstMemory * gmem, gssize offset, gssize size)
+{
+ return NULL;
+}
+
+static void
+gst_tizen_allocator_class_init (GstTizenAllocatorClass * klass)
+{
+ GObjectClass *object_class;
+ GstAllocatorClass *allocator_class;
+
+ allocator_class = GST_ALLOCATOR_CLASS (klass);
+ object_class = G_OBJECT_CLASS (klass);
+
+ allocator_class->alloc = NULL;
+ allocator_class->free = gst_tizen_mem_free;
+
+ object_class->finalize = gst_tizen_allocator_finalize;
+
+}
+
+static void
+gst_tizen_allocator_init (GstTizenAllocator * allocator)
+{
+ GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
+
+ allocator->priv = gst_tizen_allocator_get_instance_private (allocator);
+ alloc->mem_type = GST_TIZEN_MEMORY_TYPE;
+ alloc->mem_map = gst_tizen_mem_map;
+ alloc->mem_unmap = gst_tizen_mem_unmap;
+ alloc->mem_share = gst_tizen_mem_share;
+
+ GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
+}
+
+/**
+ * gst_tizen_allocator_new:
+ *
+ * Return a new tizen allocator.
+ *
+ * Returns: (transfer full): a new fd allocator, or NULL if the allocator
+ * isn't available. Use gst_object_unref() to release the allocator after
+ * usage
+ *
+ */
+GstAllocator *
+gst_tizen_allocator_new (void)
+{
+ static volatile gsize _init = 0;
+
+ if (g_once_init_enter (&_init)) {
+ GST_DEBUG_CATEGORY_INIT (gst_tizenmemory_debug, "tizenmemory", 0,
+ "GstTizenMemory and GstTizenAllocator");
+
+ _tizen_allocator = g_object_new (GST_TYPE_TIZEN_ALLOCATOR, NULL);
+ gst_allocator_register (GST_TIZEN_ALLOCATOR_NAME,
+ gst_object_ref (_tizen_allocator));
+ g_once_init_leave (&_init, 1);
+ }
+ return _tizen_allocator;
+}
+
+GstMemory *
+gst_tizen_allocator_alloc (GstAllocator * allocator, GstVideoInfo * vinfo)
+{
+ return (GstMemory *)_tizen_video_mem_new (_tizen_allocator, NULL, vinfo);
+}
+
+gboolean
+gst_is_tizen_memory (GstMemory * mem)
+{
+ g_return_val_if_fail (mem != NULL, FALSE);
+
+ return GST_IS_TIZEN_ALLOCATOR (mem->allocator);
+}
+
+gint
+gst_tizen_memory_get_num_bos (GstMemory *mem)
+{
+ GstTizenMemory *tmem;
+
+ g_return_val_if_fail (mem != NULL, NULL);
+ g_return_val_if_fail (GST_IS_TIZEN_ALLOCATOR (mem->allocator), NULL);
+
+ tmem = (GstTizenMemory *)mem;
+
+ return (gint) tbm_surface_internal_get_num_bos (tmem->surface);
+}
+
+void *
+gst_tizen_memory_get_bos (GstMemory * mem, gint bo_idx)
+{
+ gint bo_num;
+ GstTizenMemory *tmem;
+
+ g_return_val_if_fail (mem != NULL, NULL);
+ g_return_val_if_fail (GST_IS_TIZEN_ALLOCATOR (mem->allocator), NULL);
+
+ tmem = (GstTizenMemory *)mem;
+
+ bo_num = tbm_surface_internal_get_num_bos(tmem->surface);
+
+ if (bo_idx > bo_num) {
+ GST_ERROR ("Failed to set set bo_idx");
+ return NULL;
+ }
+
+ return tbm_surface_internal_get_bo(tmem->surface, bo_idx);
+}
+
+void *
+gst_tizen_memory_get_surface (GstMemory * mem)
+{
+ GstTizenMemory *tmem;
+
+ g_return_val_if_fail (mem != NULL, NULL);
+ g_return_val_if_fail (GST_IS_TIZEN_ALLOCATOR (mem->allocator), NULL);
+
+ tmem = (GstTizenMemory *)mem;
+
+ return tmem->surface;
+}
+
+static void
+cached_tizen_disposed_cb (GstTizenAllocator * allocator, GstMiniObject *obj)
+{
+ allocator->priv->mem_cache = g_list_remove (allocator->priv->mem_cache, obj);
+}
+
+GstMemory *
+gst_tizen_allocator_dmabuf_export (GstAllocator * allocator, GstMemory * _tmem, int bo_idx)
+{
+ GstTizenMemory *tmem = (GstTizenMemory *) _tmem;
+ GstTizenAllocator *tallocator = GST_TIZEN_ALLOCATOR (allocator);
+ GstMemory * mem;
+ gint fd;
+ tbm_bo bo;
+
+ g_return_val_if_fail (tmem->surface != NULL, NULL);
+
+ bo = tbm_surface_internal_get_bo (tmem->surface, bo_idx);
+ fd = tbm_bo_export_fd (bo);
+
+ tallocator->priv->dmabuf_alloc = gst_dmabuf_allocator_new ();
+
+ mem = gst_dmabuf_allocator_alloc (tallocator->priv->dmabuf_alloc, fd,
+ gst_memory_get_sizes (_tmem, NULL, NULL));
+
+ /* cache */
+ gst_mini_object_weak_ref (GST_MINI_OBJECT (mem),
+ (GstMiniObjectNotify) cached_tizen_disposed_cb, tallocator);
+
+ tallocator->priv->mem_cache = g_list_prepend (tallocator->priv->mem_cache, mem);
+
+ gst_mini_object_set_qdata (GST_MINI_OBJECT (mem),
+ g_quark_from_static_string ("_tmem"), _tmem,
+ (GDestroyNotify) gst_memory_unref);
+ return mem;
+}
+
+GstTizenMemory *
+gst_tizen_allocator_dambuf_import (GstAllocator * allocator, gint * fds, gint planes, gsize offsets[4], GstVideoInfo * vinfo)
+{
+ GstTizenAllocator *tallocator;
+ GstTizenMemory *tmem;
+ GstMemory *mem;
+
+ tmem = g_slice_new0 (GstTizenMemory);
+
+ mem = GST_MEMORY_CAST (tmem);
+
+ gst_memory_init (mem, GST_MEMORY_FLAG_NO_SHARE, allocator, NULL,
+ GST_VIDEO_INFO_SIZE (vinfo), 0, 0, GST_VIDEO_INFO_SIZE (vinfo));
+
+
+ tallocator = GST_TIZEN_ALLOCATOR (allocator);
+
+ return NULL;
+}
+
+gboolean
+gst_tizen_video_memory_map (GstVideoMeta * meta, guint plane, GstMapInfo * info,
+ gpointer * data, gint * stride, GstMapFlags flags)
+{
+ gint err;
+ gint bo_idx;
+ tbm_surface_info_s surface_info;
+ GstBuffer *buffer = meta->buffer;
+ GstTizenMemory *vmem =
+ (GstTizenMemory *) gst_buffer_get_memory (buffer, 0);
+
+ g_return_val_if_fail (((GstMemory *) vmem)->allocator == _tizen_allocator,
+ FALSE);
+
+ err = tbm_surface_map (vmem->surface, TBM_SURF_OPTION_WRITE|TBM_SURF_OPTION_READ, &surface_info);
+ if (err == TBM_SURFACE_ERROR_NONE) {
+ if (surface_info.num_planes > plane) {
+ *data = surface_info.planes[plane].ptr;
+ *stride = surface_info.planes[plane].stride;
+ GST_DEBUG ("_video_memory_map -> plane : %d, data : %p, stride : %d",
+ plane, *data, *stride);
+ } else {
+ GST_ERROR_OBJECT (meta, "invalid format");
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+gboolean
+gst_tizen_video_memory_unmap (GstVideoMeta * meta, guint plane, GstMapInfo * info)
+{
+ GstBuffer *buffer = meta->buffer;
+ GstTizenMemory *vmem =
+ (GstTizenMemory *) gst_buffer_get_memory (buffer, 0);
+
+ g_return_val_if_fail (((GstMemory *) vmem)->allocator == _tizen_allocator,
+ FALSE);
+
+ tbm_surface_unmap (vmem->surface);
+ GST_DEBUG ("_video_memory_unmap -> plane : %d", plane);
+ return TRUE;
+}
--- /dev/null
+/*
+ * GStreamer tizen memory
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Author: Sejun Park <sejun79.park@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __GST_TIZEN_MEMORY_H__
+#define __GST_TIZEN_MEMORY_H__
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/video/gstvideometa.h>
+#include <gst/gstallocator.h>
+#include <gst/gstmemory.h>
+#include <tbm_bufmgr.h>
+#include <tbm_surface.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GstTizenAllocator GstTizenAllocator;
+typedef struct _GstTizenAllocatorClass GstTizenAllocatorClass;
+typedef struct _GstTizenAllocatorPrivate GstTizenAllocatorPrivate;
+
+typedef struct _GstTizenMemory GstTizenMemory;
+#define GST_TYPE_TIZEN_ALLOCATOR (gst_tizen_allocator_get_type())
+GType gst_tizen_allocator_get_type(void);
+
+#define GST_IS_TIZEN_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TIZEN_ALLOCATOR))
+#define GST_IS_TIZEN_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TIZEN_ALLOCATOR))
+#define GST_TIZEN_ALLOCATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TIZEN_ALLOCATOR, GstTizenAllocatorClass))
+#define GST_TIZEN_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TIZEN_ALLOCATOR, GstTizenAllocator))
+#define GST_TIZEN_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TIZEN_ALLOCATOR, GstTizenAllocatorClass))
+#define GST_TIZEN_ALLOCATOR_CAST(obj) ((GstTizenAllocator *)(obj))
+
+#define GST_TIZEN_MEMORY_TYPE "TizenVideoMemory"
+
+struct _GstTizenMemory
+{
+ GstMemory mem;
+
+ tbm_surface_h surface;
+
+ /* <protected> */
+ GMutex lock;
+
+ /* <private> */
+ GDestroyNotify notify;
+ gpointer user_data;
+
+};
+
+struct _GstTizenAllocatorPrivate
+{
+ GList *mem_cache;
+ GstAllocator *dmabuf_alloc;
+};
+
+/**
+ * GstTizenMemoryAllocator
+ *
+ * Base class for allocators with bo memory
+ */
+struct _GstTizenAllocator
+{
+ GstAllocator parent;
+ GstTizenAllocatorPrivate *priv;
+};
+
+
+struct _GstTizenAllocatorClass
+{
+ GstAllocatorClass parent_class;
+};
+
+
+GstAllocator * gst_tizen_allocator_new (void);
+
+GstMemory * gst_tizen_allocator_alloc (GstAllocator * allocator, GstVideoInfo * vinfo);
+
+gboolean gst_is_tizen_memory (GstMemory *mem);
+
+gint gst_tizen_memory_get_num_bos (GstMemory *mem);
+
+void * gst_tizen_memory_get_bos (GstMemory *mem, gint index);
+
+void * gst_tizen_memory_get_surface (GstMemory *mem);
+
+GstMemory * gst_tizen_allocator_dmabuf_export (GstAllocator * allocator, GstMemory *tmem, int bo_idx);
+
+gboolean gst_tizen_video_memory_map (GstVideoMeta * meta, guint plane, GstMapInfo * info,
+ gpointer * data, gint * stride, GstMapFlags flags);
+
+gboolean gst_tizen_video_memory_unmap (GstVideoMeta * meta, guint plane, GstMapInfo * info);
+
+G_END_DECLS
+
+#endif /* _GST_TIZEN_MEMORY_H_ */
libgstvideo_@GST_API_VERSION@_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) $(ORC_LIBS) $(LIBM)
libgstvideo_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
-if BOARD_USE_TBM_BUF
-libgstvideo_@GST_API_VERSION@_la_CFLAGS += -DUSE_TBM_BUFFER $(MMCOMMON_CFLAGS) $(TBM_CFLAGS)
-libgstvideo_@GST_API_VERSION@_la_LIBADD += $(TBM_LIBS) $(MM_COMMON_LIBS)
-libgstvideo_@GST_API_VERSION@_la_LDFLAGS += $(TBM_LDFLAGS) $(MM_COMMON_LDFLAGS)
-endif
-
-
include $(top_srcdir)/common/gst-glib-gen.mak
if HAVE_INTROSPECTION
GstFlowReturn res;
GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans);
GstVideoFilterClass *fclass;
+#ifdef USE_TBM
+ GstMapFlags out_map_flags = GST_MAP_WRITE;
+#endif
if (G_UNLIKELY (!filter->negotiated))
goto unknown_format;
GST_MAP_READ | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))
goto invalid_buffer;
+#ifdef USE_TBM
+ if (!filter->out_info.finfo->format == GST_VIDEO_FORMAT_SN12)
+ out_map_flags |= GST_VIDEO_FRAME_MAP_FLAG_NO_REF;
+
+ if (!gst_video_frame_map (&out_frame, &filter->out_info, outbuf,
+ out_map_flags))
+ goto invalid_buffer;
+#else
if (!gst_video_frame_map (&out_frame, &filter->out_info, outbuf,
GST_MAP_WRITE | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))
goto invalid_buffer;
-
+#endif
res = fclass->transform_frame (filter, &in_frame, &out_frame);
gst_video_frame_unmap (&out_frame);
#include <string.h>
#include <math.h>
#include <mmf/mm_types.h>
+#include <gst/allocators/gsttizenmemory.h>
#include "video-orc.h"
convert_I420_SN12 (GstVideoConverter * convert, const GstVideoFrame * src,
GstVideoFrame * dest )
{
- MMVideoBuffer *mm_video_buf = NULL;
GstMemory *mem = NULL;
+ GstTizenMemory *tmem = NULL;
void *mm_data = NULL;
guint8 *mY, *mUV, *Y, *U, *V;
gint l1, l2;
+ int i, j;
gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
gint width = convert->in_width;
gint height = convert->in_height;
mY = mUV = Y = U = V = NULL;
+ mY = FRAME_GET_PLANE_LINE (dest, 0, 0);
+ mUV = FRAME_GET_PLANE_LINE (dest, 1, 0);
- if(gst_buffer_n_memory(dest->buffer) >= 2) {
- GstMapInfo map_info = GST_MAP_INFO_INIT;
- mem = gst_buffer_peek_memory (dest->buffer, 1);
- if (mem != NULL) {
- gst_memory_map(mem, &map_info, GST_MAP_WRITE);
- mm_data = map_info.data;
- gst_memory_unmap(mem, &map_info);
- mm_video_buf = (MMVideoBuffer*) mm_data;
- }
- }
-
- /* convert from I420 TO SN12/NV12 format here.. */
- if(mm_video_buf == NULL) {
- GST_ERROR(" mm_video_buffer is NULL");
- return;
- }
- mY = mm_video_buf->data[0];
- mUV = mm_video_buf->data[1];
-
- for (int i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
+ for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
GET_LINE_OFFSETS (interlaced, i, l1, l2);
Y = FRAME_GET_Y_LINE (src, l1);
U = FRAME_GET_U_LINE (src, i >> 1);
V = FRAME_GET_V_LINE (src, i >> 1);
- for(int j = 0; j < (width + 1) / 2; j++) {
- *mUV++ = *U++;
- *mUV++ = *V++;
+ for (j = 0; j < (width + 1) / 2; j++) {
+ *mUV++ = *U++;
+ *mUV++ = *V++;
}
}
-
}
-
static GstVideoFormat
get_scale_format (GstVideoFormat format, gint plane)
{
$(GST_CFLAGS)
libgstvideoconvert_la_LIBADD = \
$(top_builddir)/gst-libs/gst/video/libgstvideo-$(GST_API_VERSION).la \
+ $(top_builddir)/gst-libs/gst/allocators/libgstallocators-$(GST_API_VERSION).la \
+ $(GST_ALLOCATORS_LIBS) \
$(GST_BASE_LIBS) \
$(GST_LIBS) \
$(LIBM)
libgstvideoconvert_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
noinst_HEADERS = gstvideoconvert.h
-
-if BOARD_USE_TBM_BUF
-libgstvideoconvert_la_SOURCES += gsttbmbufferpool.c
-libgstvideoconvert_la_CFLAGS += -DUSE_TBM_BUFFER $(MMCOMMON_CFLAGS) $(TBM_CFLAGS)
-libgstvideoconvert_la_LIBADD += $(TBM_LIBS) $(MM_COMMON_LIBS)
-libgstvideoconvert_la_LDFLAGS += $(TBM_LDFLAGS) $(MM_COMMON_LDFLAGS)
-noinst_HEADERS += gsttbmbufferpool.h
-endif
#include <gst/video/gstvideometa.h>
#include <gst/video/gstvideopool.h>
-#ifdef USE_TBM_BUFFER
-#include <mm_types.h>
-#include "gsttbmbufferpool.h"
+#ifdef USE_TBM
+#include <gst/allocators/gsttizenbufferpool.h>
#endif
#include <string.h>
static GstFlowReturn gst_video_convert_transform_frame (GstVideoFilter * filter,
GstVideoFrame * in_frame, GstVideoFrame * out_frame);
-#ifdef USE_TBM_BUFFER
+#ifdef USE_TBM
static gboolean gst_video_convert_decide_allocation (GstBaseTransform * bsrc,
GstQuery * query);
static GstFlowReturn gst_video_convert_prepare_output_buffer (GstBaseTransform * trans,
gst_video_converter_free (space->convert);
}
#ifdef USE_TBM_BUFFER
- if(space->tbm_buffer_pool) {
- gst_buffer_pool_set_active (space->tbm_buffer_pool, FALSE);
- gst_object_unref (space->tbm_buffer_pool);
- space->tbm_buffer_pool = NULL;
+ if (space->pool) {
+ gst_buffer_pool_set_active (space->pool, FALSE);
+ gst_object_unref (space->pool);
+ space->pool = NULL;
}
#endif
G_OBJECT_CLASS (parent_class)->finalize (obj);
gstvideofilter_class->transform_frame =
GST_DEBUG_FUNCPTR (gst_video_convert_transform_frame);
-#ifdef USE_TBM_BUFFER
+#ifdef USE_TBM
gstbasetransform_class->decide_allocation = gst_video_convert_decide_allocation;
gstbasetransform_class->prepare_output_buffer = gst_video_convert_prepare_output_buffer;
#endif
gst_video_convert_init (GstVideoConvert * space)
{
#ifdef USE_TBM_BUFFER
- space->tbm_buffer_pool = NULL;
+ space->pool = NULL;
#endif
space->dither = DEFAULT_PROP_DITHER;
space->dither_quantization = DEFAULT_PROP_DITHER_QUANTIZATION;
return GST_FLOW_OK;
}
-#ifdef USE_TBM_BUFFER
-
+#ifdef USE_TBM
static gboolean
gst_video_convert_decide_allocation (GstBaseTransform * trans,
GstQuery * query)
{
-
GstVideoConvert *vc = NULL;
GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans);
vc = GST_VIDEO_CONVERT_CAST(trans);
- if(filter->out_info.finfo->format == GST_VIDEO_FORMAT_SN12 ) {
-
- guint size = 0;
- guint min = 0;
- guint max = 0;
+ if (filter->out_info.finfo->format == GST_VIDEO_FORMAT_SN12 ) {
+ guint size;
GstStructure *config;
GstCaps *caps = NULL;
-#if 0
- if (gst_query_get_n_allocation_pools (query) > 0) {
- gst_query_parse_nth_allocation_pool (query, 0, &vc->tbm_buffer_pool, &size, &min, &max);
-
- /* adjust size */
- size = MAX (size, sizeof(MMVideoBuffer));
-
- } else {
- vc->tbm_buffer_pool = NULL;
- min = max = 0;
- }
-#endif
- size = sizeof(MMVideoBuffer);
+ GstVideoInfo vinfo;
gst_query_parse_allocation (query, &caps, NULL);
+ gst_video_info_init (&vinfo);
+ gst_video_info_from_caps (&vinfo, caps);
- if (caps) {
- vc->tbm_buffer_pool = gst_mm_buffer_pool_new(GST_ELEMENT_CAST(trans));
- GST_DEBUG("[%s]CREATING VIDEO_BUFFER_POOL",__FUNCTION__);
- }
+ size = vinfo.size;
if (caps) {
- config = gst_buffer_pool_get_config (vc->tbm_buffer_pool);
-
- min = 8;
- max = 13;
-
- gst_buffer_pool_config_set_params (config, caps, size, min, max);
-
- if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) {
- gst_buffer_pool_config_add_option (config,
- GST_BUFFER_POOL_OPTION_VIDEO_META);
- }
+ vc->pool = gst_tizen_buffer_pool_new ();
+ config = gst_buffer_pool_get_config (vc->pool);
- if (!gst_buffer_pool_set_config (vc->tbm_buffer_pool, config)) {
- GST_INFO ("Failed to set config on internal pool");
- gst_object_unref (vc->tbm_buffer_pool);
- vc->tbm_buffer_pool = NULL;
- return FALSE;
- }
-
- gst_query_add_allocation_pool (query, vc->tbm_buffer_pool, size, min, max);
+ gst_buffer_pool_config_set_params (config, caps, size, 2, 0);
+ gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
+ gst_buffer_pool_set_config (vc->pool, config);
- if (!gst_buffer_pool_set_active(vc->tbm_buffer_pool,TRUE)) {
- gst_object_unref (vc->tbm_buffer_pool);
- vc->tbm_buffer_pool = NULL;
+ if (!gst_buffer_pool_set_active (vc->pool, TRUE)) {
+ gst_object_unref (vc->pool);
+ vc->pool = NULL;
GST_INFO ("Failed to activate internal pool");
}
-
- GST_DEBUG("[%s]BUFFER_POOL max:[%d], min:[%d]",__FUNCTION__, max, min);
} else {
- GST_DEBUG("Not using our internal pool and copying buffers for downstream");
+ GST_ERROR("Not using our internal pool and copying buffers for downstream");
return FALSE;
}
}
+ GST_DEBUG("[%s]Creating Tizen Buffer Pool", __FUNCTION__);
+
return GST_BASE_TRANSFORM_CLASS (parent_class)->decide_allocation (trans, query);
}
vc = GST_VIDEO_CONVERT_CAST(trans);
- if(filter->out_info.finfo->format == GST_VIDEO_FORMAT_SN12 ) {
- if(gst_buffer_pool_acquire_buffer(vc->tbm_buffer_pool,outbuf,0) != GST_FLOW_OK) {
- GST_ERROR("[%s] memory prepare failed.",__FUNCTION__);
+ if (filter->out_info.finfo->format == GST_VIDEO_FORMAT_SN12 ) {
+ if (gst_buffer_pool_acquire_buffer(vc->pool, outbuf, 0) != GST_FLOW_OK) {
+ GST_ERROR("[%s] memory prepare failed.",__FUNCTION__);
return GST_FLOW_ERROR;
- }
+ }
return GST_FLOW_OK;
- } else
- return GST_BASE_TRANSFORM_CLASS (parent_class)->prepare_output_buffer(trans, input, outbuf);
+ } else
+ return GST_BASE_TRANSFORM_CLASS (parent_class)->prepare_output_buffer(trans, input, outbuf);
}
#endif
GstVideoPrimariesMode primaries_mode;
gdouble alpha_value;
gint n_threads;
- GstBufferPool *tbm_buffer_pool;
+ GstBufferPool *pool;
};
struct _GstVideoConvertClass
Name: gst-plugins-base
Version: 1.12.2
-Release: 1
+Release: 2
License: LGPL-2.0+
Summary: GStreamer Streaming-Media Framework Plug-Ins
Url: http://gstreamer.freedesktop.org/
%if "%{TIZEN_PRODUCT_TV}" == "1"
--enable-tv\
%endif
- --enable-use-tbmbuf
+ --enable-tbm
make %{?_smp_mflags}
%install