add new command for reducing I/O 65/26165/4
authorSeokYeon Hwang <syeon.hwang@samsung.com>
Tue, 19 Aug 2014 02:09:47 +0000 (11:09 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Wed, 20 Aug 2014 04:37:28 +0000 (13:37 +0900)
Add command CODEC_DECODE_VIDEO2(needs device version 3).
Clean-up source.

Change-Id: Iac3d4f3fc5bb831ab599109181222e6e20860119
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
packaging/gst-plugins-emulator.spec
src/gstmaru.h
src/gstmarudec.c
src/gstmaruenc.c
src/gstmaruinterface.c
src/gstmaruinterface.h

index 8b2ea2f..9edab45 100644 (file)
@@ -1,5 +1,5 @@
 Name: gst-plugins-emulator
-Version: 0.2.11
+Version: 0.3.0
 Release: 0
 Summary: GStreamer Decoder and Encoder Plugins for Emulator
 Group: Multimedia/Libraries
index dbb540c..30d5e18 100644 (file)
@@ -32,6 +32,7 @@
 #define __GST_MARU_H__
 
 #include <stdint.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -58,9 +59,9 @@ enum codec_log_level {
 };
 
 #define CODEC_DEV   "/dev/brillcodec"
-#define CODEC_VER   2
+#define CODEC_VER   3
 
-#define CHECK_VERSION(version)        (device_version > version)
+#define CHECK_VERSION(version)        (device_version >= version)
 
 #define CODEC_LOG(level, fmt, ...) \
   do { \
@@ -79,6 +80,13 @@ enum codec_log_level {
 #define ROUND_UP_8(x) ROUND_UP_X(x, 3)
 #define DIV_ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) >> (x))
 
+static inline bool use_new_decode_api(void) {
+    if (CHECK_VERSION(3)) {
+        return true;
+    }
+    return false;
+}
+
 typedef struct _CodecDevice {
   int       fd;
   uint8_t   *buf;
@@ -135,6 +143,7 @@ enum CODEC_FUNC_TYPE {
   CODEC_PICTURE_COPY,
   CODEC_DEINIT,
   CODEC_FLUSH_BUFFERS,
+  CODEC_DECODE_VIDEO2,
 };
 
 enum CODEC_IO_CMD {
index 86fdb78..c05fa61 100644 (file)
@@ -961,60 +961,43 @@ gst_marudec_video_frame (GstMaruDec *marudec, guint8 *data, guint size,
     const GstTSInfo *dec_info, gint64 in_offset, GstBuffer **outbuf,
     GstFlowReturn *ret)
 {
-  gint len = -1, have_data;
+  gint len = -1;
   gboolean mode_switch;
   gboolean decode;
   GstClockTime out_timestamp, out_duration, out_pts;
   gint64 out_offset;
   const GstTSInfo *out_info;
+  int have_data;
 
   decode = gst_marudec_do_qos (marudec, dec_info->timestamp, &mode_switch);
 
-  GST_DEBUG_OBJECT (marudec, "decode video: input buffer size %d", size);
-  len =
-    codec_decode_video (marudec->context, data, size,
-                          dec_info->idx, in_offset, outbuf,
-                          &have_data, marudec->dev);
-#if 0
-  // skip_frame
-  if (!decode) {
+  if (decode) {
+    // FIXME
   }
-#endif
-  GST_DEBUG_OBJECT (marudec, "after decode: len %d, have_data %d",
-    len, have_data);
 
-#if 0
-  if (len < 0 && (mode_switch || marudec->context->skip_frame)) {
-    len = 0;
-  }
-
-  if (len > 0 && have_data <= 0 && (mode_switch
-      || marudec->context->skip_frame)) {
-    marudec->last_out = -1;
-  }
-#endif
+  GST_DEBUG_OBJECT (marudec, "decode video: input buffer size %d", size);
 
-  if (len < 0 || have_data <= 0) {
-//  if (len < 0) { // have_data <= 0) {
-    GST_DEBUG_OBJECT (marudec, "return flow %d, out %p, len %d",
-      *ret, *outbuf, len);
+  len = codec_decode_video (marudec, data, size,
+        dec_info->idx, in_offset, outbuf, &have_data);
+  if (len < 0 || !have_data) {
     return len;
   }
 
-  out_info = gst_ts_info_get (marudec, dec_info->idx);
-  out_pts = out_info->timestamp;
-  out_duration = out_info->duration;
-  out_offset = out_info->offset;
-
   *ret = get_output_buffer (marudec, outbuf);
+
   if (G_UNLIKELY (*ret != GST_FLOW_OK)) {
     GST_DEBUG_OBJECT (marudec, "no output buffer");
     len = -1;
     GST_DEBUG_OBJECT (marudec, "return flow %d, out %p, len %d",
-      *ret, *outbuf, len);
+        *ret, *outbuf, len);
     return len;
   }
 
+  out_info = gst_ts_info_get (marudec, dec_info->idx);
+  out_pts = out_info->timestamp;
+  out_duration = out_info->duration;
+  out_offset = out_info->offset;
+
   /* Timestamps */
   out_timestamp = -1;
   if (out_pts != -1) {
@@ -1061,11 +1044,6 @@ gst_marudec_video_frame (GstMaruDec *marudec, guint8 *data, guint size,
   } else if (GST_CLOCK_TIME_IS_VALID (dec_info->duration)) {
     GST_LOG_OBJECT (marudec, "Using in_duration");
     out_duration = dec_info->duration;
-#if 0
-  } else if (GST_CLOCK_TIME_IS_VALID (marudec->last_diff)) {
-    GST_LOG_OBJECT (marudec, "Using last-diff");
-    out_duration = marudec->last_diff;
-#endif
   } else {
     if (marudec->format.video.fps_n != -1 &&
         (marudec->format.video.fps_n != 1000 &&
@@ -1087,19 +1065,6 @@ gst_marudec_video_frame (GstMaruDec *marudec, guint8 *data, guint size,
     }
   }
 
-#if 0
-  if (GST_CLOCK_TIME_IS_VALID (out_duration)) {
-    out_duration += out_duration * marudec->picture->repeat_pict / 2;
-  }
-  GST_BUFFER_DURATION (*outbuf) = out_duration;
-
-  if (out_timestamp != -1 && out_duration != -1 && out_duration != 0) {
-    marudec->next_out = out_timestamp + out_duration;
-  } else {
-    marudec->next_out = -1;
-  }
-#endif
-
   if (G_UNLIKELY (!clip_video_buffer (marudec, *outbuf, out_timestamp,
       out_duration))) {
     GST_DEBUG_OBJECT (marudec, "buffer clipped");
index ca762b1..200d9ca 100644 (file)
@@ -617,7 +617,6 @@ gst_maruenc_chain_video (GstPad *pad, GstBuffer *buffer)
   gint ret_size = 0, frame_size = 0;
   int coded_frame = 0, is_keyframe = 0;
   uint32_t mem_offset = 0;
-  uint8_t *working_buf = NULL;
 
   GST_DEBUG_OBJECT (maruenc,
       "Received buffer of time %" GST_TIME_FORMAT,
index 06fbaee..55b3a8a 100644 (file)
 
 #include "gstmaru.h"
 #include "gstmaruinterface.h"
+#include "gstmaruutils.h"
 #include "gstmarumem.h"
 #include "gstmarudevice.h"
 
 extern int device_fd;
 extern gpointer device_mem;
 
-struct mem_info {
-    gpointer start;
-    uint32_t offset;
-    uint32_t size;
-};
-
 typedef struct _CodecHeader {
   int32_t   api_index;
   uint32_t  mem_offset;
@@ -65,12 +60,14 @@ typedef struct _CodecIOParams {
 #define GET_OFFSET(buffer)      ((uint32_t)buffer - (uint32_t)device_mem)
 #define SMALLDATA               0
 
+#define OFFSET_PICTURE_BUFFER   0x100
+
 static int
 _codec_invoke_qemu(int32_t ctx_index, int32_t api_index,
                           uint32_t mem_offset, int fd, CodecBufferId *buffer_id)
 {
-  CodecIOParams ioparam = { 0 };
-  int ret;
+  CodecIOParams ioparam = { 0, };
+  int ret = -1;
 
   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
@@ -78,7 +75,8 @@ _codec_invoke_qemu(int32_t ctx_index, int32_t api_index,
   ioparam.ctx_index = ctx_index;
   ioparam.mem_offset = mem_offset;
 
-  if (CHECK_VERSION(3)) {
+//  if (CHECK_VERSION(3)) {
+  if (true) {
     if (buffer_id) {
       ioparam.buffer_id.buffer_index = buffer_id->buffer_index;
       ioparam.buffer_id.buffer_size = buffer_id->buffer_size;
@@ -95,7 +93,7 @@ _codec_invoke_qemu(int32_t ctx_index, int32_t api_index,
       return -1;
     }
     if (buffer_id) {
-      ret = ioctl(fd, CODEC_CMD_INVOKE_API_AND_RELEASE_BUFFER, buffer_id);
+      ret = ioctl(fd, CODEC_CMD_PUT_DATA_INTO_BUFFER, buffer_id);
     }
   }
 
@@ -148,7 +146,11 @@ codec_buffer_free (gpointer start)
 {
   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
-  release_device_mem (device_fd, start);
+  if (use_new_decode_api()) {
+    release_device_mem (device_fd, start - OFFSET_PICTURE_BUFFER); // FIXME
+  } else {
+    release_device_mem (device_fd, start);
+  }
 
   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
 }
@@ -157,8 +159,8 @@ GstFlowReturn
 codec_buffer_alloc_and_copy (GstPad *pad, guint64 offset, guint size,
                   GstCaps *caps, GstBuffer **buf)
 {
-  int ret = 0;
-  struct mem_info info;
+  bool is_last_buffer = 0;
+  int mem_offset;
   CodecBufferId opaque;
   GstMaruDec *marudec;
   CodecContext *ctx;
@@ -172,37 +174,55 @@ codec_buffer_alloc_and_copy (GstPad *pad, guint64 offset, guint size,
   ctx = marudec->context;
   dev = marudec->dev;
 
-  opaque.buffer_index = ctx->index;
-  opaque.buffer_size = size;
+  if (use_new_decode_api()) {
+    is_last_buffer = marudec->is_last_buffer;
+    mem_offset = marudec->mem_offset;
+  } else {
+    ctx = marudec->context;
 
-  GST_DEBUG ("buffer_and_copy. ctx_id: %d", ctx->index);
+    opaque.buffer_index = ctx->index;
+    opaque.buffer_size = size;
 
-  ret = _codec_invoke_qemu(ctx->index, CODEC_PICTURE_COPY, 0, dev->fd, &opaque);
+    GST_DEBUG ("buffer_and_copy. ctx_id: %d", ctx->index);
 
-  if (ret < 0) {
-    GST_DEBUG ("failed to get available buffer");
-  } else if (ret == 1) {
+    int ret = _codec_invoke_qemu(ctx->index, CODEC_PICTURE_COPY, 0, dev->fd, &opaque);
+    if (ret < 0) {
+      GST_DEBUG ("failed to get available buffer");
+      return GST_FLOW_ERROR;
+    }
+    is_last_buffer = ret;
+    mem_offset = opaque.buffer_size;
+  }
+
+  gpointer *buffer = NULL;
+  if (is_last_buffer) {
     // FIXME: we must aligned buffer offset.
-    info.start = g_malloc (size);
-    info.offset = 0;
+    buffer = g_malloc (size);
 
     GST_BUFFER_FREE_FUNC (*buf) = g_free;
 
-    memcpy (info.start, device_mem + opaque.buffer_size, size);
-    release_device_mem(dev->fd, device_mem + opaque.buffer_size);
+    if (use_new_decode_api()) {
+      memcpy (buffer, device_mem + mem_offset + OFFSET_PICTURE_BUFFER, size);
+    } else {
+      memcpy (buffer, device_mem + mem_offset, size);
+    }
+    release_device_mem(dev->fd, device_mem + mem_offset);
 
     GST_DEBUG ("secured last buffer!! Use heap buffer");
   } else {
     // address of "device_mem" and "opaque" is aleady aligned.
-    info.start = (gpointer)(device_mem + opaque.buffer_size);
-    info.offset = opaque.buffer_size;
+    if (use_new_decode_api()) {
+      buffer = (gpointer)(device_mem + mem_offset + OFFSET_PICTURE_BUFFER);
+    } else {
+      buffer = (gpointer)(device_mem + mem_offset);
+    }
 
     GST_BUFFER_FREE_FUNC (*buf) = codec_buffer_free;
 
-    GST_DEBUG ("device memory start: 0x%p, offset 0x%x", info.start, info.offset);
+    GST_DEBUG ("device memory start: 0x%p, offset 0x%x", (intptr_t)buffer, mem_offset);
   }
 
-  GST_BUFFER_DATA (*buf) = GST_BUFFER_MALLOCDATA (*buf) = info.start;
+  GST_BUFFER_DATA (*buf) = GST_BUFFER_MALLOCDATA (*buf) = buffer;
   GST_BUFFER_SIZE (*buf) = size;
   GST_BUFFER_OFFSET (*buf) = offset;
 
@@ -289,13 +309,14 @@ codec_flush_buffers (CodecContext *ctx, CodecDevice *dev)
 }
 
 int
-codec_decode_video (CodecContext *ctx, uint8_t *in_buf, int in_size,
-                    gint idx, gint64 in_offset, GstBuffer **out_buf,
-                    int *got_picture_ptr, CodecDevice *dev)
+codec_decode_video (GstMaruDec *marudec, uint8_t *in_buf, int in_size,
+                    gint idx, gint64 in_offset, GstBuffer **out_buf, int *have_data)
 {
+  CodecContext *ctx = marudec->context;
+  CodecDevice *dev = marudec->dev;
   int len = 0, ret = 0;
   gpointer buffer = NULL;
-  CodecBufferId opaque;
+  CodecBufferId opaque = { 0, };
 
   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
@@ -308,17 +329,43 @@ codec_decode_video (CodecContext *ctx, uint8_t *in_buf, int in_size,
   codec_decode_video_data_to (in_size, idx, in_offset, in_buf, buffer);
 
   opaque.buffer_index = ctx->index;
-  opaque.buffer_size = SMALLDATA;
-
-  ret = _codec_invoke_qemu(ctx->index, CODEC_DECODE_VIDEO, GET_OFFSET(buffer), dev->fd, &opaque);
+  if (use_new_decode_api()) {
+    int picture_size = gst_maru_avpicture_size (ctx->video.pix_fmt,
+        ctx->video.width, ctx->video.height);
+    if (picture_size < 0) {
+      opaque.buffer_size = SMALLDATA;
+    } else {
+      opaque.buffer_size = picture_size;
+    }
+    ret = _codec_invoke_qemu(ctx->index, CODEC_DECODE_VIDEO2, GET_OFFSET(buffer), dev->fd, &opaque);
+  } else {
+    opaque.buffer_size = SMALLDATA;
+    ret = _codec_invoke_qemu(ctx->index, CODEC_DECODE_VIDEO, GET_OFFSET(buffer), dev->fd, &opaque);
+  }
 
   if (ret < 0) {
+    // FIXME:
     return -1;
   }
+  len = codec_decode_video_data_from (have_data, &ctx->video, device_mem + opaque.buffer_size);
 
-  len = codec_decode_video_data_from (got_picture_ptr, &ctx->video, device_mem + opaque.buffer_size);
+  GST_DEBUG_OBJECT (marudec, "after decode: len %d, have_data %d",
+        len, *have_data);
+  if (len < 0 || *have_data <= 0) {
+    GST_DEBUG_OBJECT (marudec, "return flow %d, out %p, len %d",
+        ret, *out_buf, len);
 
-  release_device_mem(dev->fd, device_mem + opaque.buffer_size);
+    release_device_mem(dev->fd, device_mem + opaque.buffer_size);
+
+    return len;
+  }
+
+  if (use_new_decode_api()) {
+    marudec->is_last_buffer = ret;
+    marudec->mem_offset = opaque.buffer_size;
+  } else {
+    release_device_mem(dev->fd, device_mem + opaque.buffer_size);
+  }
 
   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
 
index 448fd66..cc0cbd8 100644 (file)
@@ -97,6 +97,9 @@ typedef struct _GstMaruDec
   /* reverse playback queue */
   GList *queued;
 
+  // decode result
+  bool is_last_buffer;
+  int mem_offset;
 } GstMaruDec;
 
 int
@@ -106,10 +109,8 @@ void
 codec_deinit (CodecContext *ctx, CodecDevice *dev);
 
 int
-codec_decode_video (CodecContext *ctx, uint8_t *in_buf, int in_size,
-                    gint idx, gint64 in_offset, GstBuffer **out_buf,
-                    int *got_picture_ptr, CodecDevice *dev);
-
+codec_decode_video (GstMaruDec *marudec, uint8_t *in_buf, int in_size,
+                    gint idx, gint64 in_offset, GstBuffer **out_buf, int *have_data);
 
 int
 codec_decode_audio (CodecContext *ctx, int16_t *samples,