Enhancement logic about using direct buffer. 60/12060/1
authorSeokYeon Hwang <syeon.hwang@samsung.com>
Tue, 12 Nov 2013 08:08:05 +0000 (17:08 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Tue, 12 Nov 2013 08:13:19 +0000 (17:13 +0900)
Fix some bugs related with device_fd.
Use a device buffer wisely.

Change-Id: Ie8c858348303fa917b856a3212f0407eaca5677d
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
src/gstmarudec.c
src/gstmaruinterface.c
src/gstmaruinterface.h

index f88f2ee..218bf62 100644 (file)
 #define GST_MARUDEC_PARAMS_QDATA g_quark_from_static_string("marudec-params")
 
 /* indicate dts, pts, offset in the stream */
-typedef struct
-{
-  gint idx;
-  GstClockTime timestamp;
-  GstClockTime duration;
-  gint64 offset;
-} GstTSInfo;
 
 #define GST_TS_INFO_NONE &ts_info_none
 static const GstTSInfo ts_info_none = { -1, -1, -1, -1 };
 
-#define MAX_TS_MASK 0xff
-
-typedef struct _GstMaruDec
-{
-  GstElement element;
-
-  GstPad *srcpad;
-  GstPad *sinkpad;
-
-  CodecContext *context;
-  CodecDevice *dev;
-
-  union {
-    struct {
-      gint width, height;
-      gint clip_width, clip_height;
-      gint par_n, par_d;
-      gint fps_n, fps_d;
-      gint old_fps_n, old_fps_d;
-      gboolean interlaced;
-
-      enum PixelFormat pix_fmt;
-    } video;
-    struct {
-      gint channels;
-      gint samplerate;
-      gint depth;
-    } audio;
-  } format;
-
-  gboolean opened;
-  gboolean discont;
-  gboolean clear_ts;
-
-  /* tracking DTS/PTS */
-  GstClockTime next_out;
-
-  /* Qos stuff */
-  gdouble proportion;
-  GstClockTime earliest_time;
-  gint64 processed;
-  gint64 dropped;
-
-
-  /* GstSegment can be used for two purposes:
-   * 1. performing seeks (handling seek events)
-   * 2. tracking playback regions (handling newsegment events)
-   */
-  GstSegment segment;
-
-  GstTSInfo ts_info[MAX_TS_MASK + 1];
-  gint ts_idx;
-
-  /* reverse playback queue */
-  GList *queued;
-
-} GstMaruDec;
-
 typedef struct _GstMaruDecClass
 {
   GstElementClass parent_class;
@@ -940,14 +875,14 @@ get_output_buffer (GstMaruDec *marudec, GstBuffer **outbuf)
 
   CODEC_LOG (DEBUG, "outbuf size of decoded video: %d\n", pict_size);
 
-#ifndef USE_HEAP_BUFFER
+  gst_pad_set_element_private(GST_PAD_PEER(marudec->srcpad), (gpointer)marudec);
+
   /* GstPadBufferAllocFunction is mostly overridden by elements that can
    * provide a hardware buffer in order to avoid additional memcpy operations.
    */
   gst_pad_set_bufferalloc_function(
     GST_PAD_PEER(marudec->srcpad),
     (GstPadBufferAllocFunction) codec_buffer_alloc);
-#endif
 
   ret = gst_pad_alloc_buffer_and_set_caps (marudec->srcpad,
     GST_BUFFER_OFFSET_NONE, pict_size,
@@ -958,16 +893,6 @@ get_output_buffer (GstMaruDec *marudec, GstBuffer **outbuf)
     return ret;
   }
 
-  if ((uintptr_t) GST_BUFFER_DATA (*outbuf) % 16) {
-    GST_DEBUG_OBJECT (marudec,
-      "Downstream can't allocate aligned buffers.");
-    gst_buffer_unref (*outbuf);
-    *outbuf = new_aligned_buffer (pict_size, GST_PAD_CAPS (marudec->srcpad));
-  }
-
-  codec_picture_copy (marudec->context, GST_BUFFER_DATA (*outbuf),
-    GST_BUFFER_SIZE (*outbuf), marudec->dev);
-
   return ret;
 }
 
index 3fa9503..2858a05 100644 (file)
@@ -85,8 +85,8 @@ _codec_write_to_qemu (int32_t ctx_index, int32_t api_index,
   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
 }
 
-static struct mem_info
-secure_device_mem (guint buf_size)
+static int
+secure_device_mem (guint buf_size, gpointer offset)
 {
   int ret = 0;
   uint32_t opaque = 0;
@@ -95,23 +95,14 @@ secure_device_mem (guint buf_size)
   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
   opaque = buf_size;
 
-  ret = ioctl (device_fd, CODEC_CMD_TRY_SECURE_BUFFER, &opaque);
-  if (ret == -1) {
-    CODEC_LOG (DEBUG, "failed to get available buffer\n");
-    info.start = NULL;
-    info.offset = 0;
-  } else {
-    info.start = (gpointer)((uint32_t)device_mem + opaque);
-    info.offset = opaque;
-    CODEC_LOG (DEBUG, "acquire device_memory: 0x%x\n", opaque);
-  }
+  ret = ioctl (device_fd, CODEC_CMD_SECURE_BUFFER, &opaque);
+  offset = opaque;
 
   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
 
-  return info;
+  return ret;
 }
 
-#ifndef USE_HEAP_BUFFER
 static void
 release_device_mem (gpointer start)
 {
@@ -144,20 +135,44 @@ codec_buffer_alloc (GstPad *pad, guint64 offset, guint size,
                   GstCaps *caps, GstBuffer **buf)
 {
   struct mem_info info;
+  uint32_t opaque;
+  int ret = 0;
+  GstMaruDec *marudec;
 
   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
+  opaque = size;
+
   *buf = gst_buffer_new ();
 
-  info = secure_device_mem (size);
+  marudec = (GstMaruDec *)gst_pad_get_element_private(pad);
+
+  _codec_write_to_qemu (marudec->context->index, CODEC_PICTURE_COPY,
+                        0, marudec->dev->fd);
 
-  if (info.start == NULL) {
-    CODEC_LOG (DEBUG, "can not secure memory now, so we will use heap buffer");
+  ret = ioctl (marudec->dev->fd, CODEC_CMD_GET_DATA_INTO_DEVICE_MEM, &opaque);
+
+  if (ret < 0) {
+    CODEC_LOG (DEBUG, "failed to get available buffer\n");
+  } else if (ret == 1) {
+    // FIXME: we must aligned buffer offset.
     info.start = g_malloc (size);
+    info.offset = 0;
+
     GST_BUFFER_FREE_FUNC (*buf) = g_free;
+
+    memcpy (info.start, (uint32_t)device_mem + opaque, size);
+    release_device_mem((uint32_t)device_mem + opaque);
+
+    CODEC_LOG (DEBUG, "we secured last buffer, so we will use heap buffer");
   } else {
-    CODEC_LOG (DEBUG, "device memory start: 0x%p, offset 0x%x\n", info.start, info.offset);
+    // address of "device_mem" and "opaque" is aleady aligned.
+    info.start = (gpointer)((uint32_t)device_mem + opaque);
+    info.offset = opaque;
+
     GST_BUFFER_FREE_FUNC (*buf) = codec_buffer_free;
+
+    CODEC_LOG (DEBUG, "device memory start: 0x%p, offset 0x%x\n", info.start, info.offset);
   }
 
   GST_BUFFER_DATA (*buf) = GST_BUFFER_MALLOCDATA (*buf) = info.start;
@@ -172,7 +187,6 @@ codec_buffer_alloc (GstPad *pad, guint64 offset, guint size,
 
   return GST_FLOW_OK;
 }
-#endif
 
 int
 codec_init (CodecContext *ctx, CodecElement *codec, CodecDevice *dev)
@@ -332,80 +346,6 @@ codec_decode_video (CodecContext *ctx, uint8_t *in_buf, int in_size,
   return len;
 }
 
-void
-codec_picture_copy (CodecContext *ctx, uint8_t *pict,
-                    uint32_t pict_size, CodecDevice *dev)
-{
-  int fd, ret = 0;
-  uint32_t opaque = 0;
-  int is_direct_buffer = 0;
-
-  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
-
-  fd = dev->fd;
-  if (fd < 0) {
-    GST_ERROR ("failed to get %s fd\n", CODEC_DEV);
-    return;
-  }
-
-  if (!dev->buf) {
-    GST_ERROR ("failed to get mmaped memory address\n");
-    return;
-  }
-
-  // determine buffer located in device memory or not.
-  if ((uint32_t)pict >= (uint32_t)(dev->buf) &&
-      (uint32_t)pict < (uint32_t)(dev->buf) + (dev->buf_size)) {
-    is_direct_buffer = 1;
-  }
-
-  CODEC_LOG (DEBUG, "pict_size: %d\n",  pict_size);
-
-  _codec_write_to_qemu (ctx->index, CODEC_PICTURE_COPY,
-                        0, fd);
-
-  if (is_direct_buffer) {
-    // if we can use device memory as a output buffer...
-#ifdef USE_HEAP_BUFFER
-    GST_ERROR ("failed to get mmaped memory address\n");
-#else
-    dev->mem_info.offset = (uint32_t)pict - (uint32_t)(dev->buf);
-    CODEC_LOG (DEBUG, "%d of pict: %p , device_mem: %p\n",
-              ctx->index, pict, dev->buf);
-    CODEC_LOG (DEBUG, "%d of picture_copy, mem_offset = 0x%x\n",
-              ctx->index, dev->mem_info.offset);
-
-    ret = ioctl (fd, CODEC_CMD_USE_DEVICE_MEM, &(dev->mem_info.offset));
-    if (ret < 0) {
-      CODEC_LOG (ERR, "failed to use device memory\n");
-      return;
-    }
-#endif
-  } else {
-    // if we can not use device memory as a output buffer,
-    // we must copy data from device memory to heap buffer.
-    CODEC_LOG (DEBUG, "need a memory\n");
-    opaque = pict_size;
-    ret = ioctl (fd, CODEC_CMD_GET_DATA_INTO_DEVICE_MEM, &opaque);
-    if (ret < 0) {
-      CODEC_LOG (ERR, "failed to secure device memory\n");
-      return;
-    }
-
-    CODEC_LOG (DEBUG, "picture_copy, mem_offset = 0x%x\n",  opaque);
-
-    memcpy (pict, (dev->buf) + opaque, pict_size);
-
-    ret = ioctl(fd, CODEC_CMD_RELEASE_BUFFER, &opaque);
-
-    if (ret < 0) {
-      CODEC_LOG (ERR, "failed to release used memory\n");
-    }
-  }
-
-  CODEC_LOG (DEBUG, "leave: %s\n", __func__);
-}
-
 int
 codec_decode_audio (CodecContext *ctx, int16_t *samples,
                     int *have_data, uint8_t *in_buf,
index c0f49f8..d9fa633 100644 (file)
 
 #include "gstmaru.h"
 
+#define MAX_TS_MASK 0xff
+
+typedef struct
+{
+  gint idx;
+  GstClockTime timestamp;
+  GstClockTime duration;
+  gint64 offset;
+} GstTSInfo;
+
+typedef struct _GstMaruDec
+{
+  GstElement element;
+
+  GstPad *srcpad;
+  GstPad *sinkpad;
+
+  CodecContext *context;
+  CodecDevice *dev;
+
+  union {
+    struct {
+      gint width, height;
+      gint clip_width, clip_height;
+      gint par_n, par_d;
+      gint fps_n, fps_d;
+      gint old_fps_n, old_fps_d;
+      gboolean interlaced;
+
+      enum PixelFormat pix_fmt;
+    } video;
+    struct {
+      gint channels;
+      gint samplerate;
+      gint depth;
+    } audio;
+  } format;
+
+  gboolean opened;
+  gboolean discont;
+  gboolean clear_ts;
+
+  /* tracking DTS/PTS */
+  GstClockTime next_out;
+
+  /* Qos stuff */
+  gdouble proportion;
+  GstClockTime earliest_time;
+  gint64 processed;
+  gint64 dropped;
+
+
+  /* GstSegment can be used for two purposes:
+   * 1. performing seeks (handling seek events)
+   * 2. tracking playback regions (handling newsegment events)
+   */
+  GstSegment segment;
+
+  GstTSInfo ts_info[MAX_TS_MASK + 1];
+  gint ts_idx;
+
+  /* reverse playback queue */
+  GList *queued;
+
+} GstMaruDec;
+
 int
 codec_init (CodecContext *ctx, CodecElement *codec, CodecDevice *dev);