Apply GStreamer 1.22.0 into Tizen
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-good / sys / v4l2 / gstv4l2allocator.c
index 48d1bb8..b1a3f72 100644 (file)
 #include <sys/types.h>
 #include <sys/mman.h>
 #include <unistd.h>
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+#include <gst/allocators/gsttizenmemory.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
 
 #define GST_V4L2_MEMORY_TYPE "V4l2Memory"
 
@@ -235,6 +240,13 @@ gst_v4l2_memory_group_free (GstV4l2MemoryGroup * group)
     if (mem)
       gst_memory_unref (mem);
   }
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+  if (group->surface) {
+    GST_INFO ("unref surface[%p]", group->surface);
+    tbm_surface_destroy (group->surface);
+    group->surface = NULL;
+  }
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
 
   g_slice_free (GstV4l2MemoryGroup, group);
 }
@@ -428,6 +440,13 @@ gst_v4l2_allocator_finalize (GObject * obj)
   GstV4l2Allocator *allocator = (GstV4l2Allocator *) obj;
 
   GST_LOG_OBJECT (obj, "called");
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+  if (allocator->bufmgr) {
+    GST_INFO_OBJECT (obj, "deinit tbm bufmgr %p", allocator->bufmgr);
+    tbm_bufmgr_deinit (allocator->bufmgr);
+    allocator->bufmgr = NULL;
+  }
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
 
   gst_atomic_queue_unref (allocator->free_queue);
   gst_object_unref (allocator->obj->element);
@@ -620,7 +639,21 @@ _cleanup_failed_alloc (GstV4l2Allocator * allocator, GstV4l2MemoryGroup * group)
   }
 }
 
-
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+static tbm_format
+__get_tbm_format (GstVideoFormat gst_format)
+{
+  switch (gst_format) {
+  case GST_VIDEO_FORMAT_NV12:
+  case GST_VIDEO_FORMAT_SN12:
+    return TBM_FORMAT_NV12;
+  case GST_VIDEO_FORMAT_I420:
+  case GST_VIDEO_FORMAT_S420:
+  default:
+    return TBM_FORMAT_YUV420;
+  }
+}
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
 
 GstV4l2Allocator *
 gst_v4l2_allocator_new (GstObject * parent, GstV4l2Object * v4l2object)
@@ -660,6 +693,33 @@ gst_v4l2_allocator_new (GstObject * parent, GstV4l2Object * v4l2object)
 
   GST_OBJECT_FLAG_SET (allocator, flags);
 
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+  if (v4l2object->tbm_output &&
+      !V4L2_TYPE_IS_OUTPUT (v4l2object->type) &&
+      v4l2object->mode == GST_V4L2_IO_DMABUF) {
+    tbm_surface_h tmp_surface = NULL;
+    int width = GST_VIDEO_INFO_WIDTH (&v4l2object->info);
+    int height = GST_VIDEO_INFO_HEIGHT (&v4l2object->info);
+
+    tmp_surface = tbm_surface_create (width, height,
+        __get_tbm_format (GST_VIDEO_INFO_FORMAT (&v4l2object->info)));
+    if (tmp_surface) {
+      tbm_surface_get_info (tmp_surface, &allocator->s_info);
+      GST_INFO_OBJECT (allocator, "[%dx%d] -> tbm surface info[%dx%d]",
+          width, height, allocator->s_info.width, allocator->s_info.height);
+      tbm_surface_destroy (tmp_surface);
+    } else {
+      GST_ERROR_OBJECT (allocator, "[%dx%d] surface failed", width, height);
+    }
+
+    allocator->bufmgr = tbm_bufmgr_init (-1);
+    if (!allocator->bufmgr) {
+      GST_ERROR_OBJECT (allocator, "tbm bufmgr failed");
+      gst_object_unref (allocator);
+      return NULL;
+    }
+  }
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
   return allocator;
 }
 
@@ -886,6 +946,9 @@ gst_v4l2_allocator_alloc_dmabuf (GstV4l2Allocator * allocator,
   GstV4l2Object *obj = allocator->obj;
   GstV4l2MemoryGroup *group;
   gint i;
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+  tbm_bo bos[VIDEO_MAX_PLANES] = {NULL, };
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
 
   g_return_val_if_fail (allocator->memory == V4L2_MEMORY_MMAP, NULL);
 
@@ -916,6 +979,13 @@ gst_v4l2_allocator_alloc_dmabuf (GstV4l2Allocator * allocator,
           NULL, group->planes[i].length, 0, group->planes[i].data_offset,
           group->planes[i].length - group->planes[i].data_offset, i, NULL,
           expbuf.fd, group);
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+      if (obj->tbm_output) {
+        bos[i] = tbm_bo_import_fd (allocator->bufmgr, expbuf.fd);
+        GST_INFO_OBJECT (allocator, "obj[%p,i:%d]: fd[%d] -> bo[%p]",
+            obj, expbuf.index, expbuf.fd, bos[i]);
+      }
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
     } else {
       /* Take back the allocator reference */
       gst_object_ref (allocator);
@@ -937,6 +1007,16 @@ gst_v4l2_allocator_alloc_dmabuf (GstV4l2Allocator * allocator,
     group->mem[i] = dma_mem;
   }
 
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+  if (obj->tbm_output && !group->surface) {
+    group->surface = tbm_surface_internal_create_with_bos (&allocator->s_info, bos, group->n_mem);
+    GST_INFO_OBJECT (allocator, "new surface[%p] in memory group[%p]", group->surface, group);
+  }
+  /* release bos - they will be kept in surface. */
+  for (i = 0 ; i < VIDEO_MAX_PLANES && bos[i] ; i++)
+    tbm_bo_unref (bos[i]);
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
+
   gst_v4l2_allocator_reset_size (allocator, group);
 
   return group;
@@ -1105,11 +1185,20 @@ gst_v4l2_allocator_import_dmabuf (GstV4l2Allocator * allocator,
     gint dmafd;
     gsize size, offset, maxsize;
 
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+    if (!gst_is_tizen_memory (dma_mem[i]) && !gst_is_dmabuf_memory (dma_mem[i]))
+#else
     if (!gst_is_dmabuf_memory (dma_mem[i]))
+#endif
       goto not_dmabuf;
 
     size = gst_memory_get_sizes (dma_mem[i], &offset, &maxsize);
 
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+    if (gst_is_tizen_memory (dma_mem[i]))
+      dmafd = gst_tizen_memory_get_fd (dma_mem[i], 0);
+    else
+#endif
     dmafd = gst_dmabuf_memory_get_fd (dma_mem[i]);
 
     GST_LOG_OBJECT (allocator, "[%i] imported DMABUF as fd %i plane %d",