Changed a way to use device memory.
[platform/adaptation/emulator/gst-plugins-emulator.git] / src / gstemulapi.c
index 2345206..3405a6a 100644 (file)
 #include "gstemulapi2.h"
 #include "gstemuldev.h"
 
-enum {
-  CODEC_USER_FROM = 0,
-  CODEC_USER_TO,
+void emul_codec_write_to_qemu (int ctx_index, int api_index, CodecDevice *dev)
+{
+  CodecIOParams ioparam;
+
+//  memset(&ioparam, 0, sizeof(ioparam));
+  ioparam.api_index = api_index;
+  ioparam.ctx_index = ctx_index;
+  ioparam.mem_offset = dev->mem_info.offset;
+  if (write (dev->fd, &ioparam, 1) < 0) {
+    printf ("[%s:%d] failed to copy data.\n", __func__, __LINE__);
+  }
+  CODEC_LOG (DEBUG, "[%s] mem_offset = 0x%x\n", __func__, ioparam.mem_offset);
+}
+
+extern int device_fd;
+extern gpointer device_mem;
+
+struct mem_info {
+    gpointer start;
+    uint32_t offset;
 };
 
+static struct mem_info secure_device_mem()
+{
+  uint32_t mem_offset = 0;
+  struct mem_info info;
+
+  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
+
+  ioctl(device_fd, CODEC_CMD_SECURE_MEMORY, &mem_offset);
+  info.start = (gpointer)((uint32_t)device_mem + mem_offset);
+  info.offset = mem_offset;
+
+  CODEC_LOG (DEBUG, "leave: %s\n", __func__);
+  CODEC_LOG (DEBUG, "caramis0 = 0x%x\n", mem_offset);
+
+  return info;
+}
+
+static void release_device_mem(gpointer start)
+{
+  uint32_t offset = start - device_mem;
+  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
+
+  ioctl(device_fd, CODEC_CMD_RELEASE_MEMORY, &offset);
+
+  CODEC_LOG (DEBUG, "leave: %s\n", __func__);
+}
+
+static void emul_buffer_free(gpointer start)
+{
+  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
+
+  release_device_mem(start);
+
+  CODEC_LOG (DEBUG, "leave: %s\n", __func__);
+}
+
+GstFlowReturn emul_buffer_alloc(GstPad *pad, guint64 offset, guint size, GstCaps *caps, GstBuffer **buf)
+{
+  struct mem_info info;
+
+  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
+
+  *buf = gst_buffer_new ();
+
+  info = secure_device_mem();
+
+  CODEC_LOG (DEBUG, "[%s] start: 0x%x, offset 0x%x\n", __func__, info.start, info.offset);
+
+  GST_BUFFER_DATA (*buf) = GST_BUFFER_MALLOCDATA (*buf) = info.start;
+  GST_BUFFER_SIZE (*buf) = size;
+  GST_BUFFER_FREE_FUNC (*buf) = emul_buffer_free;
+
+  GST_BUFFER_OFFSET (*buf) = offset;
+
+  if (caps) {
+    gst_buffer_set_caps (*buf, caps);
+  }
+
+  CODEC_LOG (DEBUG, "leave: %s\n", __func__);
+  return GST_FLOW_OK;
+}
+
 int
 emul_avcodec_init (CodecContext *ctx, CodecElement *codec, CodecDevice *dev)
 {
   int fd;
   uint8_t *mmapbuf;
-  int size = 0, ret = 0;
-  int usable, copyback;
-  CodecIOParams params;
+  int ret = 0;
+  uint32_t mem_offset = 0;
 
   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
@@ -61,101 +139,19 @@ emul_avcodec_init (CodecContext *ctx, CodecElement *codec, CodecDevice *dev)
     return -1;
   }
 
-  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
-    emul_avcodec_init_to (ctx, codec, mmapbuf);    
-  }    else {
-    copyback = CODEC_USER_FROM;
-    ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, &copyback);
+  ioctl(fd, CODEC_CMD_GET_CONTEXT_INDEX, &ctx->index);
+  CODEC_LOG (DEBUG, "recv context index: %d\n", ctx->index);
 
-    while (1) {
-      ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
-      if (usable) {
-        CODEC_LOG (DEBUG, "[init][%d] failure.\n", __LINE__);
-        continue;
-      }
+  ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &mem_offset);
+  emul_avcodec_init_to (ctx, codec, mmapbuf + mem_offset);
+  dev->mem_info.offset = mem_offset;
+  emul_codec_write_to_qemu (ctx->index, CODEC_INIT, dev);
 
-      emul_avcodec_init_to (ctx, codec, mmapbuf);    
 
-#if 0
-      CODEC_LOG (DEBUG, "[init] write data to qemu.\n");
-      size = sizeof(size);
-      memcpy (mmapbuf + size,
-          &codec->media_type, sizeof(codec->media_type));
-      size += sizeof(codec->media_type);
-      memcpy (mmapbuf + size, &codec->codec_type, sizeof(codec->codec_type));
-      size += sizeof(codec->codec_type);
-      memcpy (mmapbuf + size, codec->name, sizeof(codec->name));
-      size += sizeof(codec->name);
-
-      if (codec->media_type == AVMEDIA_TYPE_VIDEO) {
-        memcpy (mmapbuf + size, &ctx->video, sizeof(ctx->video));
-        size += sizeof(ctx->video);
-      } else if (codec->media_type == AVMEDIA_TYPE_AUDIO) {
-        memcpy (mmapbuf + size, &ctx->audio, sizeof(ctx->audio));
-        size += sizeof(ctx->audio);
-      } else {
-        GST_ERROR ("media type is unknown.\n");
-        ret = -1;
-        break;;
-      }
-
-      memcpy (mmapbuf + size,
-          &ctx->codecdata_size, sizeof(ctx->codecdata_size));
-      size += sizeof(ctx->codecdata_size);
-      if (ctx->codecdata_size) {
-        memcpy (mmapbuf + size, ctx->codecdata, ctx->codecdata_size);
-        size += ctx->codecdata_size;
-      }
-      size -= sizeof(size);
-      memcpy (mmapbuf, &size, sizeof(size));
-
-      CODEC_LOG (DEBUG, "[init] write data: %d\n", size);
-#endif
-      break;
-    }
+  ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &mem_offset);
+  ret = emul_avcodec_init_from (ctx, codec, mmapbuf + mem_offset);
 
-#if 0
-    if (ret < 0) {
-      return ret;
-    }
-#endif
-  }
-
-  CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_INIT;
-  params.mem_offset = dev->mem_info.offset;
-  CODEC_WRITE_TO_QEMU (fd, &params, 1);
-
-  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
-    ret = emul_avcodec_init_from (ctx, codec, mmapbuf);
-  } else {
-    while (1) {
-      ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
-      if (usable) {
-        CODEC_LOG (DEBUG, "[init][%d] failure.\n", __LINE__);
-        continue;
-      }
-
-      ret = emul_avcodec_init_from (ctx, codec, mmapbuf);
-#if 0
-      CODEC_LOG (DEBUG, "[init] read data from qemu.\n");
-      if (codec->media_type == AVMEDIA_TYPE_AUDIO) {
-        memcpy (&ctx->audio.sample_fmt,
-            (uint8_t *)mmapbuf, sizeof(ctx->audio.sample_fmt));
-        size += sizeof(ctx->audio.sample_fmt);
-        CODEC_LOG (DEBUG, "[init] AUDIO sample_fmt: %d\n", ctx->audio.sample_fmt);
-      }
-      CODEC_LOG (DEBUG, "[init] %s\n", codec->media_type ? "AUDIO" : "VIDEO");
-      memcpy (&ret, (uint8_t *)mmapbuf + size, sizeof(ret));
-      size += sizeof(ret);
-      memcpy (&ctx->index, (uint8_t *)mmapbuf + size, sizeof(ctx->index));
-      ctx->codec = codec;
-      CODEC_LOG (DEBUG, "context index: %d\n", ctx->index);
-#endif
-      break;
-    }
-    ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
-  }
+  ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &mem_offset);
 
   CODEC_LOG (DEBUG, "leave: %s, ret: %d\n", __func__, ret);
   return ret;
@@ -165,9 +161,7 @@ void
 emul_avcodec_deinit (CodecContext *ctx, CodecDevice *dev)
 {
   int fd;
-  int copyback, usable;
   void *mmapbuf = NULL;
-  CodecIOParams params;
 
   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
@@ -183,39 +177,21 @@ emul_avcodec_deinit (CodecContext *ctx, CodecDevice *dev)
     return;
   }
 
-#if 0
-  copyback = CODEC_USER_FROM;
-  ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, &copyback);
-
-  while (1) {
-    ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
-    if (usable) {
-      CODEC_LOG (DEBUG, "[deinit][%d] failure.\n", __LINE__);
-      continue;
-    }
-  } 
-#endif
-
-  CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_DEINIT;
-  params.ctx_index = ctx->index;
-  params.mem_offset = dev->mem_info.offset;
-  CODEC_WRITE_TO_QEMU (fd, &params, 1);
-
-//  ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
+  emul_codec_write_to_qemu (ctx->index, CODEC_DEINIT, dev);
 
   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
 }
 
 int
 emul_avcodec_decode_video (CodecContext *ctx, uint8_t *in_buf, int in_size,
-    GstBuffer **out_buf, int *got_picture_ptr, CodecDevice *dev)
+                          gint idx, gint64 in_offset, GstBuffer **out_buf,
+                          int *got_picture_ptr, CodecDevice *dev)
 {
   int fd;
   uint8_t *mmapbuf = NULL;
-  int len = 0, size = 0;
-  int copyback, usable;
-  CodecIOParams params;
+  int len = 0;
+//  int copyback, usable;
+  uint32_t mem_offset = 0;
 
   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
@@ -231,83 +207,31 @@ emul_avcodec_decode_video (CodecContext *ctx, uint8_t *in_buf, int in_size,
     return -1;
   }
 
-  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
-    emul_avcodec_decode_video_to (in_buf, in_size, mmapbuf);  
-  } else {
-    copyback = CODEC_USER_FROM;
-    ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, &copyback);
+  ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &mem_offset);
+  CODEC_LOG (DEBUG, "[%s] mem_offset = 0x%x\n", __func__, mem_offset);
+  emul_avcodec_decode_video_to (in_buf, in_size, idx, in_offset, mmapbuf + mem_offset);
 
-    while (1) {
-      ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
-      if (usable) {
-        CODEC_LOG (DEBUG, "[decode_video] wait 1.\n");
-        continue;
-      }
+  dev->mem_info.offset = mem_offset;
+  emul_codec_write_to_qemu (ctx->index, CODEC_DECODE_VIDEO, dev);
 
-      emul_avcodec_decode_video_to (in_buf, in_size, mmapbuf);  
-#if 0
-      CODEC_LOG (DEBUG, "[decode_video] write data to qemu\n");
-      size = sizeof(size);
-      memcpy (mmapbuf + size, &in_size, sizeof(in_size));
-      size += sizeof(in_size);
-      if (in_size > 0) {
-        memcpy (mmapbuf + size, in_buf, in_size);
-        size += in_size;
-      }
-
-      size -= sizeof(size);
-      CODEC_LOG (DEBUG, "[decode_video] total: %d, inbuf size: %d\n", size, in_size);
-      memcpy(mmapbuf, &size, sizeof(size));
-#endif
-      break;
-    }
-  }
+  ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &mem_offset);
+  CODEC_LOG (DEBUG, "[%s] mem_offset = 0x%x\n", __func__, mem_offset);
+  len = emul_avcodec_decode_video_from (ctx, got_picture_ptr, mmapbuf + mem_offset);
 
-  /* provide raw image for decoding to qemu */
-  CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_DECODE_VIDEO;
-  params.ctx_index = ctx->index;
-  params.mem_offset = dev->mem_info.offset;
-  CODEC_WRITE_TO_QEMU (fd, &params, 1);
-
-  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
-    len = emul_avcodec_decode_video_from (ctx, got_picture_ptr, mmapbuf);
-  } else {
-    while (1) {
-      ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
-      if (usable) {
-        CODEC_LOG (DEBUG, "[decode_video] wait 2.\n");
-        continue;
-      }
-
-      len = emul_avcodec_decode_video_from (ctx, got_picture_ptr, mmapbuf);
-#if 0
-      CODEC_LOG (DEBUG, "[decode_video] read data from qemu.\n");
-      memcpy (&len, (uint8_t *)mmapbuf, sizeof(len));
-      size = sizeof(len);
-      memcpy (got_picture_ptr,
-          (uint8_t *)mmapbuf + size, sizeof(*got_picture_ptr));
-      size += sizeof(*got_picture_ptr);
-      memcpy (&ctx->video, (uint8_t *)mmapbuf + size, sizeof(ctx->video));
-
-      CODEC_LOG (DEBUG, "[decode_video] len: %d, have_date: %d\n", len, *got_picture_ptr);
-#endif
-      break;
-    }
-    ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
-  }
+  ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &mem_offset);
 
   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
   return len;
 }
 
 void
-emul_av_picture_copy (CodecContext *ctx, uint8_t *pict, uint32_t pict_size, CodecDevice *dev)
+emul_av_picture_copy (CodecContext *ctx, uint8_t *pict,
+                      uint32_t pict_size, CodecDevice *dev)
 {
   int fd;
   void *mmapbuf = NULL;
-  int copyback, usable;
-  CodecIOParams params;
+//  int copyback, usable;
+  uint32_t mem_offset = 0;
 
   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
@@ -323,63 +247,60 @@ emul_av_picture_copy (CodecContext *ctx, uint8_t *pict, uint32_t pict_size, Code
     return;
   }
 
-  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
-  } else {
-#if 1 
-    copyback = CODEC_USER_FROM;
-    ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, &copyback);
-
-    while (1) {
-      ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
-      if (usable) {
-        CODEC_LOG (DEBUG, "[decode_video] wait 1.\n");
-        continue;
-      }
-      break;
+#if 0
+  ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, NULL);
+
+  while (1) {
+    ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
+    if (usable) {
+      CODEC_LOG (DEBUG, "[copy_frame] waiting before write.\n");
+      usleep (500);
+      continue;
     }
+    break;
   }
-#endif
-
-//  printf("before av_picture_copy. ctx: %d\n", ctx->index);
-
-  CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_PICTURE_COPY;
-  params.ctx_index = ctx->index;
-  params.mem_offset = dev->mem_info.offset;
-  CODEC_WRITE_TO_QEMU (fd, &params, 1);
 
-  CODEC_LOG (DEBUG, "[copy_frame] after write.\n");
+  emul_codec_write_to_qemu (ctx->index, CODEC_PICTURE_COPY, dev);
 
-  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
-    CODEC_LOG (DEBUG, "[copy_frame] read data from qemu.\n");
-    memcpy (pict, mmapbuf, pict_size);
-  } else {
-    while (1) {
-      ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
-      if (usable) {
-        CODEC_LOG (DEBUG, "[copy_frame] wait 2.\n");
-        continue;
-      }
-
-      CODEC_LOG (DEBUG, "[copy_frame] read data from qemu.\n");
-      memcpy (pict, mmapbuf, pict_size);
-      break;
+  while (1) {
+    ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
+    if (usable) {
+      CODEC_LOG (DEBUG, "[copy_frame] waiting after write.\n");
+      usleep (500);
+      continue;
     }
-    ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
+    memcpy (pict, mmapbuf, pict_size);
+    break;
   }
+  ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
+#endif
+
+  dev->mem_info.offset = (uint32_t)pict - (uint32_t)device_mem;
+  CODEC_LOG (DEBUG, "[%s] mem_offset = 0x%x\n", __func__, dev->mem_info.offset);
+  emul_codec_write_to_qemu (ctx->index, CODEC_PICTURE_COPY, dev);
+//  ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &mem_offset);
+  ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM2, &(dev->mem_info.offset));
+
+  CODEC_LOG (DEBUG, "caramis1 = 0x%x\n", __func__, mem_offset);
+#if 0
+  memcpy (pict, mmapbuf, pict_size);
+
+  ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &mem_offset);
+#endif
 
   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
 }
 
 int
 emul_avcodec_decode_audio (CodecContext *ctx, int16_t *samples,
-    int *frame_size_ptr, uint8_t *in_buf, int in_size, CodecDevice *dev)
+                          int *frame_size_ptr, uint8_t *in_buf,
+                          int in_size, CodecDevice *dev)
 {
   int fd;
   uint8_t *mmapbuf = NULL;
-  int size = 0, len;
-  int copyback, usable;
-  CodecIOParams params;
+  int len;
+//  int copyback, usable;
+  uint32_t mem_offset = 0;
 
   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
@@ -395,220 +316,166 @@ emul_avcodec_decode_audio (CodecContext *ctx, int16_t *samples,
     return -1;
   }
 
-  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
-    emul_avcodec_decode_audio_to (in_buf, in_size, mmapbuf);    
-  } else {
-    copyback = CODEC_USER_FROM;
-    ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, &copyback);
-
-    while (1) {
-      ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
-      if (usable) {
-        CODEC_LOG (DEBUG, "[decode_audio][%d] wait 1.\n", __LINE__);
-        continue;
-      }
-
-      emul_avcodec_decode_audio_to (in_buf, in_size, mmapbuf);    
 #if 0
-      size = sizeof(size);
-      memcpy (mmapbuf + size, &in_size, sizeof(in_size));
-      size += sizeof(in_size);
-      if (in_size > 0) {
-        memcpy (mmapbuf + size, in_buf, in_size);
-        size += in_size;
-      }
-
-      size -= sizeof(size);
-      memcpy (mmapbuf, &size, sizeof(size));
-      CODEC_LOG (DEBUG, "[decode_audio] write size: %d, inbuf_size: %d\n", size, in_size);
-#endif
-      break;
+  ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, NULL);
+
+  while (1) {
+    ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
+    if (usable) {
+      CODEC_LOG (DEBUG, "[decode_audio] waiting before write.\n");
+      usleep (500);
+      continue;
     }
+
+    emul_avcodec_decode_audio_to (in_buf, in_size, mmapbuf);
+    break;
   }
 
-  CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_DECODE_AUDIO;
-  params.ctx_index = ctx->index;
-  params.mem_offset = dev->mem_info.offset;
-  CODEC_WRITE_TO_QEMU (fd, &params, 1);
-
-  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
-    len = emul_avcodec_decode_audio_from (ctx, frame_size_ptr, samples, mmapbuf);
-  } else {
-    while (1) {
-      ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
-      if (usable) {
-        CODEC_LOG (DEBUG, "[decode_audio][%d] wait 2.\n", __LINE__);
-        continue;
-      }
-
-      len = emul_avcodec_decode_audio_from (ctx, frame_size_ptr, samples, mmapbuf);
-#if 0
-      CODEC_LOG (DEBUG, "[decode_audio] read data\n");
-      memcpy (&ctx->audio.channel_layout,
-          (uint8_t *)mmapbuf, sizeof(ctx->audio.channel_layout));
-      size = sizeof(ctx->audio.channel_layout);
-      memcpy (&len, (uint8_t *)mmapbuf + size, sizeof(len));
-      size += sizeof(len);
-      memcpy (frame_size_ptr, (uint8_t *)mmapbuf + size, sizeof(*frame_size_ptr));
-      size += sizeof(*frame_size_ptr);
-      CODEC_LOG (DEBUG, "[decode_audio] len: %d, channel_layout: %lld\n",
-          len, ctx->audio.channel_layout);
-      if (len > 0) {
-        memcpy (samples, (uint8_t *)mmapbuf + size, FF_MAX_AUDIO_FRAME_SIZE);
-      }
-#endif
-      break;
+  emul_codec_write_to_qemu (ctx->index, CODEC_DECODE_AUDIO, dev);
+
+  while (1) {
+    ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
+    if (usable) {
+      CODEC_LOG (DEBUG, "[decode_audio] waiting after write.\n");
+      usleep (500);
+      continue;
     }
-    ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
+
+    len =
+      emul_avcodec_decode_audio_from (ctx, frame_size_ptr, samples, mmapbuf);
+    break;
   }
+  ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
+#endif
+
+  ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &mem_offset);
+  emul_avcodec_decode_audio_to (in_buf, in_size, mmapbuf + mem_offset);
+
+  dev->mem_info.offset = mem_offset;
+  emul_codec_write_to_qemu (ctx->index, CODEC_DECODE_AUDIO, dev);
+
+  ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &mem_offset);
+  len =
+    emul_avcodec_decode_audio_from (ctx, frame_size_ptr, samples, mmapbuf + mem_offset);
+
+  ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &mem_offset);
 
   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
+
   return len;
 }
 
 int
-emul_avcodec_encode_video (CodecContext *ctx, uint8_t*out_buf, int out_size,
-    uint8_t *in_buf, int in_size, CodecDevice *dev)
+emul_avcodec_encode_video (CodecContext *ctx, uint8_t *out_buf,
+                        int out_size, uint8_t *in_buf,
+                        int in_size, int64_t in_timestamp, CodecDevice *dev)
 {
   int fd;
   void *mmapbuf;
-  int len = 0, outbuf_size, size = 0;
+  int len = 0;
   int copyback, usable;
-  CodecIOParams params;
 
   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
   fd = dev->fd;
   if (fd < 0) {
     GST_ERROR ("failed to get %s fd.\n", CODEC_DEV);
-    return FALSE;
+    return -1;
   }
 
   mmapbuf = dev->buf;
   if (!mmapbuf) {
     GST_ERROR ("failed to get mmaped memory address.\n");
-    return FALSE;
+    return -1;
   }
 
-  copyback = CODEC_USER_FROM;
-  ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, &copyback);
-
+//  ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, NULL);
+#if 0
   while (1) {
     ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
     if (usable) {
-      CODEC_LOG (DEBUG, "[init][%d] failure.\n", __LINE__);
-//      sleep(1);
+      CODEC_LOG (DEBUG, "[encode_video] waiting before write.\n");
+      usleep (500);
       continue;
     }
 
-    CODEC_LOG (DEBUG, "[encode_video] write data to qemu\n");
-    memcpy ((uint8_t *)mmapbuf + size, &in_size, sizeof(guint));
-    size += sizeof(guint);
-    memcpy ((uint8_t *)mmapbuf + size, in_buf, in_size);
+    emul_avcodec_encode_video_to (in_buf, in_size, in_timestamp, mmapbuf);
     break;
   }
 
-  CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_ENCODE_VIDEO;
-  params.ctx_index = ctx->index;
-  params.mem_offset = dev->mem_info.offset;
-  CODEC_WRITE_TO_QEMU (fd, &params, 1);
+  emul_codec_write_to_qemu (ctx->index, CODEC_ENCODE_VIDEO, dev);
 
-  size = 0;
   while (1) {
-    copyback = CODEC_USER_TO;
-    ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &copyback);
-
-#if 0
-  size = 0;
-  memcpy (&out_size, (uint8_t *)mmapbuf + size, sizeof(uint));
-  size += sizeof(guint);
-
-  ret = gst_pad_alloc_buffer_and_set_caps (emulenc->srcpad,
-      GST_BUFFER_OFFSET_NONE, out_size,
-      GST_PAD_CAPS (emulenc->srcpad), out_buf);
-
-  gst_buffer_set_caps (*out_buf, GST_PAD_CAPS (emulenc->srcpad));
+    ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
+    if (usable) {
+      CODEC_LOG (DEBUG, "[encode_video] waiting after write.\n");
+      usleep (500);
+      continue;
+    }
 
-  if (GST_BUFFER_DATA(*out_buf)) {
-    memcpy (GST_BUFFER_DATA(*out_buf), (uint8_t *)mmapbuf + size, out_size);
-  } else {
-    pritnf ("failed to allocate output buffer\n");
-  }
-#endif
+    len = emul_avcodec_encode_video_from (out_buf, out_size, mmapbuf);
     break;
   }
   ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
+#endif
 
   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
-
   return len;
 }
 
 int
-emul_avcodec_encode_audio (CodecContext *ctx, uint8_t *outbuf, int outbuf_size,
-    const short *inbuf, int inbuf_size, CodecDevice *dev)
+emul_avcodec_encode_audio (CodecContext *ctx, uint8_t *out_buf,
+                          int out_size, uint8_t *in_buf,
+                          int in_size, CodecDevice *dev)
 {
   int fd;
   void *mmapbuf;
-  int len = 0, size = 0;
+  int len = 0;
   int copyback, usable;
-  CodecIOParams params;
 
   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
   fd = dev->fd;
   if (fd < 0) {
     GST_ERROR ("failed to get %s fd.\n", CODEC_DEV);
-    return FALSE;
+    return -1;
   }
 
   mmapbuf = dev->buf;
   if (!mmapbuf) {
     GST_ERROR ("failed to get mmaped memory address.\n");
-    return FALSE;
+    return -1;
   }
 
-  copyback = CODEC_USER_FROM;
-  ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, &copyback);
-
+//  ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, NULL);
+#if 0
   while (1) {
     ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
     if (usable) {
-      CODEC_LOG (DEBUG, "[decode_video] wait.\n");
-//      sleep(1);
+      CODEC_LOG (DEBUG, "[encode_audio] waiting before write.\n");
+      usleep (500);
       continue;
     }
 
-    CODEC_LOG (DEBUG, "[encode_audio] write data to qemu\n");
-    memcpy ((uint8_t *)mmapbuf + size, &inbuf_size, sizeof(inbuf_size));
-    size += sizeof(inbuf_size);
-    memcpy ((uint8_t *)mmapbuf + size, inbuf, inbuf_size);
+    emul_avcodec_encode_audio_to (out_size, in_size, in_buf, mmapbuf);
     break;
   }
 
-  CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_ENCODE_AUDIO;
-  params.ctx_index = ctx->index;
-  params.mem_offset = dev->mem_info.offset;
-  CODEC_WRITE_TO_QEMU (fd, &params, 1);
+  emul_codec_write_to_qemu (ctx->index, CODEC_ENCODE_AUDIO, dev);
 
   while (1) {
     ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
     if (usable) {
-      CODEC_LOG (DEBUG, "[decode_video] wait. 2\n");
-//      sleep(1);
+      CODEC_LOG (DEBUG, "[encode_audio] waiting after write.\n");
+      usleep (500);
       continue;
     }
-
-    CODEC_LOG (DEBUG, "[encode_audio] read data from qemu\n");
-    memcpy (outbuf, (uint8_t *)mmapbuf, outbuf_size);
+    len = emul_avcodec_encode_audio_from (out_buf, out_size, mmapbuf);
     break;
   }
-  ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, NULL);
+  ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
+#endif
 
   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
-
   return len;
 }