From 2a66f3e5920182f73035467675fdf9fc3e9bb5ca Mon Sep 17 00:00:00 2001
From: Devarsh Thakkar <devarsht@xilinx.com>
Date: Fri, 20 Jan 2017 05:39:49 -0800
Subject: [PATCH 13/24] omxbufpool : Add support for DMA memory in bufpool

 - Wrap the file descriptor coming from omx component
   with DMA memory using dma  allocator and save it inside
   bufpool.

- Tested with this decode->kmssink pipeline.

Signed-off-by: Devarsh Thakkar <devarsht@xilinx.com>
Upstream Status: Pending
---
 omx/gstomxbufferpool.c | 101 +++++++++++++++++++++++++++++++------------------
 omx/gstomxvideodec.c   |   3 +-
 2 files changed, 66 insertions(+), 38 deletions(-)

diff --git a/omx/gstomxbufferpool.c b/omx/gstomxbufferpool.c
index b57612d..b43d4dc 100644
--- a/omx/gstomxbufferpool.c
+++ b/omx/gstomxbufferpool.c
@@ -25,6 +25,8 @@
 #endif
 
 #include "gstomxbufferpool.h"
+#include "gst/allocators/gstdmabuf.h"
+#include <fcntl.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_omx_buffer_pool_debug_category);
 #define GST_CAT_DEFAULT gst_omx_buffer_pool_debug_category
@@ -33,6 +35,8 @@ typedef struct _GstOMXMemory GstOMXMemory;
 typedef struct _GstOMXMemoryAllocator GstOMXMemoryAllocator;
 typedef struct _GstOMXMemoryAllocatorClass GstOMXMemoryAllocatorClass;
 
+guint use_dma = 0;
+
 struct _GstOMXMemory
 {
   GstMemory mem;
@@ -389,10 +393,21 @@ gst_omx_buffer_pool_alloc_buffer (GstBufferPool * bpool,
     gsize offset[GST_VIDEO_MAX_PLANES] = { 0, };
     gint stride[GST_VIDEO_MAX_PLANES] = { nstride, 0, };
 
-    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);
+
+    int fd = (int) (guintptr) omx_buf->omx_buf->pBuffer;
+
+    if (fcntl (fd, F_GETFL) < 0 && errno == EBADF) {
+      use_dma = 0;
+    } else {
+      use_dma = 1;
+    }
+
+    if (!use_dma) {
+      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);
+    }
 
     switch (GST_VIDEO_INFO_FORMAT (&pool->video_info)) {
       case GST_VIDEO_FORMAT_ABGR:
@@ -420,38 +435,50 @@ gst_omx_buffer_pool_alloc_buffer (GstBufferPool * bpool,
         break;
     }
 
-    if (pool->add_videometa) {
-      pool->need_copy = FALSE;
-    } else {
-      GstVideoInfo info;
-      gboolean need_copy = FALSE;
-      gint i;
-
-      gst_video_info_init (&info);
-      gst_video_info_set_format (&info,
-          GST_VIDEO_INFO_FORMAT (&pool->video_info),
-          GST_VIDEO_INFO_WIDTH (&pool->video_info),
-          GST_VIDEO_INFO_HEIGHT (&pool->video_info));
-
-      for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&pool->video_info); i++) {
-        if (info.stride[i] != stride[i] || info.offset[i] != offset[i]) {
-          need_copy = TRUE;
-          break;
-        }
-      }
-
-      pool->need_copy = need_copy;
-    }
-
-    if (pool->need_copy || pool->add_videometa) {
-      /* We always add the videometa. It's the job of the user
-       * to copy the buffer if pool->need_copy is TRUE
-       */
-      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);
+    if (use_dma) {
+      gst_object_unref (pool->allocator);
+      pool->allocator = gst_dmabuf_allocator_new ();
+      buf = gst_buffer_new ();
+      mem = gst_dmabuf_allocator_alloc (pool->allocator, fd,
+		      omx_buf->omx_buf->nAllocLen);
+      mem->offset = 0;
+      mem->size = omx_buf->omx_buf->nAllocLen;
+      gst_buffer_append_memory (buf, mem);
+      g_ptr_array_add (pool->buffers, buf);
+     } else {
+       if (pool->add_videometa) {
+	 pool->need_copy = FALSE;
+       } else {
+	 GstVideoInfo info;
+	 gboolean need_copy = FALSE;
+	 gint i;
+
+	 gst_video_info_init (&info);
+	 gst_video_info_set_format (&info,
+	     GST_VIDEO_INFO_FORMAT (&pool->video_info),
+	     GST_VIDEO_INFO_WIDTH (&pool->video_info),
+	     GST_VIDEO_INFO_HEIGHT (&pool->video_info));
+
+	 for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&pool->video_info); i++) {
+	   if (info.stride[i] != stride[i] || info.offset[i] != offset[i]) {
+	     need_copy = TRUE;
+	     break;
+	   }
+	 }
+
+	 pool->need_copy = need_copy;
+       }
+
+       if (pool->need_copy || pool->add_videometa) {
+	 /* We always add the videometa. It's the job of the user
+	  * to copy the buffer if pool->need_copy is TRUE
+	  */
+	 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);
+       }
     }
   }
 
@@ -503,7 +530,7 @@ gst_omx_buffer_pool_acquire_buffer (GstBufferPool * bpool,
     ret = GST_FLOW_OK;
 
     /* If it's our own memory we have to set the sizes */
-    if (!pool->other_pool) {
+    if (!pool->other_pool && !use_dma) {
       GstMemory *mem = gst_buffer_peek_memory (*buffer, 0);
 
       g_assert (mem
diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c
index c45fc3d..7f26ada 100644
--- a/omx/gstomxvideodec.c
+++ b/omx/gstomxvideodec.c
@@ -155,7 +155,7 @@ gst_omx_video_dec_open (GstVideoDecoder * decoder)
   OMX_VIDEO_PARAM_ENABLEBOARD enable_board;
   OMX_VIDEO_PARAM_ENABLEDMABUFFER enable_dmabuf;
   OMX_VIDEO_PARAM_ENABLEMCU enable_mcu;
-  static int use_dmabuf = 0, use_mcu = 1, use_board = 0;
+  static int use_dmabuf = 1, use_mcu = 1, use_board = 0;
 #endif
 
   GST_DEBUG_OBJECT (self, "Opening decoder");
@@ -214,6 +214,7 @@ gst_omx_video_dec_open (GstVideoDecoder * decoder)
 
   memset (&enable_dmabuf, 0, sizeof (enable_dmabuf));
   enable_dmabuf.bEnable = (OMX_BOOL) use_dmabuf;
+  enable_dmabuf.nPortIndex = 1;
   OMX_SetParameter (self->dec->handle, DMAtype, &enable_dmabuf);
 
   OMX_GetExtensionIndex (self->dec->handle,
-- 
2.7.4

