improve decoding performance as 10 times than before.
[platform/adaptation/emulator/gst-plugins-emulator.git] / src / gstemulapi.c
index c4cf537..d02f170 100644 (file)
 
 #include "gstemulcommon.h"
 #include "gstemulapi.h"
+#include "gstemulapi2.h"
 #include "gstemuldev.h"
 
-gboolean
+static GStaticMutex codec_mutex = G_STATIC_MUTEX_INIT; 
+
+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;
+  ioparam.mem_type = dev->mem_info.type;
+  if (write (dev->fd, &ioparam, 1) < 0) {
+    printf ("[%s:%d] failed to copy data.\n", __func__, __LINE__);
+  }
+}
+
+int
 emul_avcodec_init (CodecContext *ctx, CodecElement *codec, CodecDevice *dev)
 {
   int fd;
-  void *mmapbuf;
-  int size = 0;
-  gboolean ret = TRUE;
-  CodecIOParams params;
+  uint8_t *mmapbuf;
+  int ret = 0;
+  int usable, copyback;
 
-  printf ("enter: %s\n", __func__);
+  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;
+  mmapbuf = (uint8_t *)dev->buf;
   if (!mmapbuf) {
     GST_ERROR ("failed to get mmaped memory address.\n");
-    return FALSE;
+    return -1;
   }
 
-//  printf("codec_init media_type: %d, codec_type: %d, name: %s\n",
-//    media_type, codec_type, name);
-
-  /* copy basic info to initialize codec on the host side.
-   * e.g. width, height, FPS ant etc. */
-  memcpy ((uint8_t *)mmapbuf, &codec->media_type, sizeof(codec->media_type));
-  size = sizeof(codec->media_type);
-  memcpy ((uint8_t *)mmapbuf + size, &codec->codec_type, sizeof(codec->codec_type));
-  size += sizeof(codec->codec_type);
-  memcpy ((uint8_t *)mmapbuf + size, codec->name, sizeof(codec->name));
-  size += sizeof(codec->name);
-
-  switch (codec->media_type) {
-  case AVMEDIA_TYPE_VIDEO:
-    memcpy ((uint8_t *)mmapbuf + size, &ctx->video, sizeof(ctx->video));
-    size += sizeof(ctx->video);
-    break;
-  case AVMEDIA_TYPE_AUDIO:
-    memcpy ((uint8_t *)mmapbuf + size, &ctx->audio, sizeof(ctx->audio));
-    size += sizeof(ctx->audio);
-    break;
-  default:
-    GST_ERROR ("media type is unknown.\n");
-    ret = FALSE;
-    break;
-  }
+  ioctl(fd, CODEC_CMD_GET_CONTEXT_INDEX, &ctx->index);
 
-  memcpy ((uint8_t *)mmapbuf + size, &ctx->codecdata_size, sizeof(ctx->codecdata_size));
-  size += sizeof(ctx->codecdata_size);
-  if (ctx->codecdata_size) {
-    memcpy ((uint8_t *)mmapbuf + size, ctx->codecdata, ctx->codecdata_size);
+  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
+    emul_avcodec_init_to (ctx, codec, mmapbuf);
+  } else {
+    ret = ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, &usable);
+    if (ret < 0) {
+      perror("ioctl failure");
+      CODEC_LOG (ERR, "[%d] return value: %d\n", __LINE__, ret);
+    }
+
+    while (1) {
+      ret = ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
+      if (ret < 0) {
+        perror("ioctl failure");
+        CODEC_LOG (ERR, "[%d] return value: %d\n", __LINE__, ret);
+      } else {
+        if (usable) {
+          CODEC_LOG (DEBUG, "[init] waiting after before.\n");
+          usleep (500);
+          continue;
+        }
+
+        emul_avcodec_init_to (ctx, codec, mmapbuf);
+        break;
+      }
+    }
   }
+  emul_codec_write_to_qemu (ctx->index, CODEC_INIT, dev);
 
-  CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_INIT;
-  params.ctx_index = 0;
-  CODEC_WRITE_TO_QEMU (fd, &params, 1);
+  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
+    int wait = 0;
+#if 0
+    while (1) {
+      ret = ioctl (fd, CODEC_CMD_WAIT_TASK, &wait);
+      if (ret < 0) {
+        perror("ioctl failure");
+        CODEC_LOG (ERR, "[%d] return value: %d\n", __LINE__, ret);
+      } else {
+        if (wait) {
+          CODEC_LOG (DEBUG, "[init] waiting after write.\n");
+          usleep (500);
+          continue;
+        }
+
+        ret = emul_avcodec_init_from (ctx, codec, mmapbuf);
+        break;
+      }
+    }
+#endif
 
-  if (codec->media_type == AVMEDIA_TYPE_AUDIO) {
-    memcpy (&ctx->audio.sample_fmt,
-                 (uint8_t *)mmapbuf, sizeof(ctx->audio.sample_fmt));
+#if 1 
+    ioctl (fd, CODEC_CMD_WAIT_TASK, &wait);
+    ret = emul_avcodec_init_from (ctx, codec, mmapbuf);
+#endif
+  } else {
+    while (1) {
+      ret = ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
+      if (ret < 0) {
+        perror("ioctl failure");
+        CODEC_LOG (ERR, "[%d] return value: %d\n", __LINE__, ret);
+      } else {
+        if (usable) {
+          CODEC_LOG (DEBUG, "[init][%d] waiting after write.\n", __LINE__);
+          usleep (500);
+          continue;
+        }
+
+        ret = emul_avcodec_init_from (ctx, codec, mmapbuf);
+        break;
+      }
+    }
+    ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
   }
-  ctx->codec = codec;
-
-  printf ("leave: %s\n", __func__);
 
+  CODEC_LOG (DEBUG, "leave: %s, ret: %d\n", __func__, ret);
   return ret;
 }
 
@@ -108,10 +154,9 @@ void
 emul_avcodec_deinit (CodecContext *ctx, CodecDevice *dev)
 {
   int fd;
-  void *mmapbuf;
-  CodecIOParams params;
+  void *mmapbuf = NULL;
 
-  printf ("enter: %s\n", __func__);
+  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
   fd = dev->fd;
   if (fd < 0) {
@@ -125,32 +170,21 @@ emul_avcodec_deinit (CodecContext *ctx, CodecDevice *dev)
     return;
   }
 
-  CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_DEINIT;
-  params.ctx_index = 0;
-  CODEC_WRITE_TO_QEMU (fd, &params, 1);
-
-#if 0
-  /* close device fd and release mapped memory region */
-  gst_emul_codec_device_close (dev);
-#endif
+  emul_codec_write_to_qemu (ctx->index, CODEC_DEINIT, dev);
 
-  printf ("leave: %s\n", __func__);
+  CODEC_LOG (DEBUG, "leave: %s\n", __func__);
 }
 
 int
-emul_avcodec_decode_video (CodecContext *ctx, guint8 *in_buf, guint in_size,
-        GstBuffer **out_buf, int *got_picture_ptr, CodecDevice *dev)
+emul_avcodec_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)
 {
   int fd;
-  void *mmapbuf;
-  int len = 0, size = 0;
-  guint out_size;
-  CodecIOParams params;
-
-  *out_buf = NULL;
+  uint8_t *mmapbuf = NULL;
+  int len = 0;
+  int copyback, usable;
 
-  printf ("enter: %s\n", __func__);
+  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
   fd = dev->fd;
   if (fd < 0) {
@@ -158,42 +192,158 @@ emul_avcodec_decode_video (CodecContext *ctx, guint8 *in_buf, guint in_size,
     return -1;
   }
 
-  mmapbuf = dev->buf;
+  mmapbuf = (uint8_t *)dev->buf;
   if (!mmapbuf) {
     GST_ERROR ("failed to get mmaped memory address\n");
     return -1;
   }
 
-  memcpy ((uint8_t *)mmapbuf, &in_size, sizeof(guint));
-  size = sizeof(guint);
-//  memcpy ((uint8_t *)mmapbuf + size, &dec_info->timestamp, sizeof(GstClockTime));
-//  size += sizeof(GstClockTime);
-  memcpy ((uint8_t *)mmapbuf + size, in_buf, in_size);
+  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
+    emul_avcodec_decode_video_to (in_buf, in_size, idx, in_offset, mmapbuf);
+  } else {
+    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_video] waiting before write.\n");
+        usleep (500);
+        continue;
+      }
+
+      emul_avcodec_decode_video_to (in_buf, in_size, idx, in_offset, mmapbuf);
+      break;
+    }
+  }
 
   /* provide raw image for decoding to qemu */
-  CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_DECODE_VIDEO;
-  params.ctx_index = 0;
-  CODEC_WRITE_TO_QEMU (fd, &params, 1);
+  emul_codec_write_to_qemu (ctx->index, CODEC_DECODE_VIDEO, dev);
+
+  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
+    int wait = 0;
+//    ioctl (fd, CODEC_CMD_WAIT_TASK, &wait);
+#if 0 
+    while (1) {
+      ioctl (fd, CODEC_CMD_WAIT_TASK, &wait);
+      if (wait) {
+        CODEC_LOG (DEBUG, "[decode_video][%d] waiting after write.\n", __LINE__);
+        usleep (500);
+        continue;
+      }
+
+      len = emul_avcodec_decode_video_from (ctx, got_picture_ptr, mmapbuf);
+      break;
+    }
+#endif
 
-  memcpy (&len, (uint8_t *)mmapbuf, sizeof(len));
-  size = sizeof(len);
+#if 1
+       ioctl (fd, CODEC_CMD_WAIT_TASK, &wait);
+    len = emul_avcodec_decode_video_from (ctx, got_picture_ptr, mmapbuf);
+#endif
+  } else {
+    while (1) {
+      ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
+      if (usable) {
+        CODEC_LOG (DEBUG, "[decode_video] waiting after write.\n");
+        usleep (500);
+        continue;
+      }
+      len = emul_avcodec_decode_video_from (ctx, got_picture_ptr, mmapbuf);
+      break;
+    }
+    ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
+  }
+
+  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)
+{
+  int fd;
+  void *mmapbuf = NULL;
+  int copyback, usable;
 
-  printf ("leave: %s\n", __func__);
+  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
-  return len;
+  fd = dev->fd;
+  if (fd < 0) {
+    GST_ERROR ("failed to get %s fd\n", CODEC_DEV);
+    return;
+  }
+
+  mmapbuf = dev->buf;
+  if (!mmapbuf) {
+    GST_ERROR ("failed to get mmaped memory address\n");
+    return;
+  }
+
+  if (dev->mem_info.type == CODEC_SHARED_DEVICE_MEM) {
+    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;
+    }
+  }
+
+  emul_codec_write_to_qemu (ctx->index, CODEC_PICTURE_COPY, dev);
+
+  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
+    int wait = 0;
+//    ioctl (fd, CODEC_CMD_WAIT_TASK, &wait);
+#if 0 
+    while (1) {
+      ioctl (fd, CODEC_CMD_WAIT_TASK, &wait);
+      if (wait) {
+        CODEC_LOG (DEBUG, "[copy_frame] waiting after write.\n");
+        usleep (500);
+        continue;
+      }
+      memcpy (pict, mmapbuf, pict_size);
+      break;
+    }
+#endif
+
+#if 1
+    ioctl (fd, CODEC_CMD_WAIT_TASK, &wait);
+    memcpy (pict, mmapbuf, pict_size);
+#endif
+  } else {
+    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;
+      }
+      memcpy (pict, mmapbuf, pict_size);
+      break;
+    }
+    ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
+  }
+
+  CODEC_LOG (DEBUG, "leave: %s\n", __func__);
 }
 
 int
 emul_avcodec_decode_audio (CodecContext *ctx, int16_t *samples,
-               gint *frame_size_ptr, guint8 *in_buf, guint in_size, CodecDevice *dev)
+                          int *frame_size_ptr, uint8_t *in_buf,
+                          int in_size, CodecDevice *dev)
 {
   int fd;
-  void *mmapbuf = NULL;
-  int size = 0;
-  gint out_size = 0, len;
-  CodecIOParams params;
+  uint8_t *mmapbuf = NULL;
+  int len;
+  int copyback, usable;
+
+  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
   fd = dev->fd;
   if (fd < 0) {
@@ -201,153 +351,220 @@ emul_avcodec_decode_audio (CodecContext *ctx, int16_t *samples,
     return -1;
   }
 
-  mmapbuf = dev->buf;
+  mmapbuf = (uint8_t *)dev->buf;
   if (!mmapbuf) {
     GST_ERROR("failed to get mmaped memory address\n");
     return -1;
   }
 
-  memcpy ((uint8_t *)mmapbuf, &in_size, sizeof(guint));
-  size = sizeof(guint);
-  if (in_size > 0) {
-    memcpy ((uint8_t *)mmapbuf + size, in_buf, in_size);
+  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
+    emul_avcodec_decode_audio_to (in_buf, in_size, mmapbuf);
+  } else {
+    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 = 0;
-  params.device_mem_offset = 0;
-  CODEC_WRITE_TO_QEMU (fd, &params, 1);
-
-  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);
-  if (len > 0) {
-    memcpy (samples, (uint8_t *)mmapbuf + size, FF_MAX_AUDIO_FRAME_SIZE);
+  emul_codec_write_to_qemu (ctx->index, CODEC_DECODE_AUDIO, dev);
+
+  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
+    int wait = 0;
+    ioctl (fd, CODEC_CMD_WAIT_TASK, &wait);
+    len =
+                 emul_avcodec_decode_audio_from (ctx, frame_size_ptr, samples, mmapbuf);
+
+#if 0 
+    while (1) {
+      ioctl (fd, CODEC_CMD_WAIT_TASK, &wait);
+      if (wait) {
+        CODEC_LOG (DEBUG, "[decode_audio] waiting after write.\n");
+        usleep (500);
+        continue;
+      }
+
+      len =
+        emul_avcodec_decode_audio_from (ctx, frame_size_ptr, samples, mmapbuf);
+      break;
+    }
+#endif
+  } else {
+    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;
+      }
+
+      len =
+        emul_avcodec_decode_audio_from (ctx, frame_size_ptr, samples, mmapbuf);
+      break;
+    }
+    ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
   }
 
+  CODEC_LOG (DEBUG, "leave: %s\n", __func__);
   return len;
 }
 
 int
-emul_avcodec_encode_video (CodecContext *ctx, guint8 *in_buf, guint in_size,
-        GstBuffer **out_buf, 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;
-  CodecIOParams params;
+  int len = 0;
+  int copyback, usable;
 
-  printf ("enter: %s\n", __func__);
+  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;
   }
 
-  memcpy ((uint8_t *)mmapbuf + size, &in_size, sizeof(guint));
-  size += sizeof(guint);
-#if 0
-  memcpy ((uint8_t *)mmapbuf + size, &in_timestamp, sizeof(GstClockTime));
-  size += sizeof(GstClockTime);
-#endif
-  memcpy ((uint8_t *)mmapbuf + size, in_buf, in_size);
-
-  CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_DECODE_AUDIO;
-  params.ctx_index = 0;
-  CODEC_WRITE_TO_QEMU (fd, &params, 1);
-
-#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));
-
-  if (GST_BUFFER_DATA(*out_buf)) {
-      memcpy (GST_BUFFER_DATA(*out_buf), (uint8_t *)mmapbuf + size, out_size);
+  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
+    emul_avcodec_encode_video_to (in_buf, in_size, in_timestamp, mmapbuf);
   } else {
-      pritnf ("failed to allocate output buffer\n");
+    ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, NULL);
+
+    while (1) {
+      ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
+      if (usable) {
+        CODEC_LOG (DEBUG, "[encode_video] waiting before write.\n");
+        usleep (500);
+        continue;
+      }
+
+      emul_avcodec_encode_video_to (in_buf, in_size, in_timestamp, mmapbuf);
+      break;
+    }
   }
-#endif
 
-  printf ("leave: %s\n", __func__);
+  emul_codec_write_to_qemu (ctx->index, CODEC_ENCODE_VIDEO, dev);
+
+  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
+    int wait = 0;
+    while (1) {
+      ioctl (fd, CODEC_CMD_WAIT_TASK, &wait);
+      if (wait) {
+        CODEC_LOG (DEBUG, "[encode_video] waiting after write.\n");
+        usleep (500);
+        continue;
+      }
+
+      len = emul_avcodec_encode_video_from (out_buf, out_size, mmapbuf);
+      break;
+    }
+  } else {
+    while (1) {
+      ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
+      if (usable) {
+        CODEC_LOG (DEBUG, "[encode_video] waiting after write.\n");
+        usleep (500);
+        continue;
+      }
+
+      len = emul_avcodec_encode_video_from (out_buf, out_size, mmapbuf);
+      break;
+    }
+    ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
+  }
 
+  CODEC_LOG (DEBUG, "leave: %s\n", __func__);
   return len;
 }
 
 int
-emul_avcodec_encode_audio (CodecContext *ctx, 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;
-  CodecIOParams params;
+  int len = 0;
+  int copyback, usable;
 
-  printf ("enter: %s\n", __func__);
+  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;
   }
 
-#if 0
-  memcpy ((uint8_t *)mmapbuf + size, &in_size, sizeof(guint));
-  size += sizeof(guint);
-  memcpy ((uint8_t *)mmapbuf + size, &in_timestamp, sizeof(GstClockTime));
-  size += sizeof(GstClockTime);
-  memcpy ((uint8_t *)mmapbuf + size, in_buf, in_size);
-#endif
-
-  CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_DECODE_AUDIO;
-  params.ctx_index = 0;
-  CODEC_WRITE_TO_QEMU (fd, &params, 1);
-
-#if 0
-  size = 0;
-  memcpy (&out_size, (uint8_t *)mmapbuf + size, sizeof(uint));
-  size += sizeof(guint);
-
-  *out_buf = gst_buffer_new();
-  GST_BUFFER_DATA (out_buf) = GST_BUFFER_MALLOCDATA (out_buf) = av_malloc (out_size);
-  GST_BUFFER_SIZE (out_buf) = out_size;
-  //  GST_BUFFER_FREE_FUNC (out_buf) = g_free;
-  if (GST_PAD_CAPS(emulenc->srcpad)) {
-      gst_buffer_set_caps (*out_buf, GST_PAD_CAPS (emulenc->srcpad));
+  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
+    emul_avcodec_encode_audio_to (out_size, in_size, in_buf, mmapbuf);
+  } else {
+    ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, NULL);
+
+    while (1) {
+      ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
+      if (usable) {
+        CODEC_LOG (DEBUG, "[encode_audio] waiting before write.\n");
+        usleep (500);
+        continue;
+      }
+
+      emul_avcodec_encode_audio_to (out_size, in_size, in_buf, mmapbuf);
+      break;
+    }
   }
 
-  if (GST_BUFFER_DATA(*out_buf)) {
-      memcpy (GST_BUFFER_DATA(*out_buf), (uint8_t *)mmapbuf + size, out_size);
+  emul_codec_write_to_qemu (ctx->index, CODEC_ENCODE_AUDIO, dev);
+
+  if (dev->mem_info.type == CODEC_FIXED_DEVICE_MEM) {
+    int wait = 0;
+    while (1) {
+      ioctl (fd, CODEC_CMD_WAIT_TASK, &wait);
+      if (wait) {
+        CODEC_LOG (DEBUG, "[encode_audio] waiting after write.\n");
+        usleep (500);
+        continue;
+      }
+      len = emul_avcodec_encode_audio_from (out_buf, out_size, mmapbuf);
+      break;
+    }
+
+    len = emul_avcodec_encode_audio_from (out_buf, out_size, mmapbuf);
   } else {
-      pritnf ("failed to allocate output buffer\n");
+    while (1) {
+      ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
+      if (usable) {
+        CODEC_LOG (DEBUG, "[encode_audio] waiting after write.\n");
+        usleep (500);
+        continue;
+      }
+      len = emul_avcodec_encode_audio_from (out_buf, out_size, mmapbuf);
+      break;
+    }
+    ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
   }
-#endif
-
-  printf ("leave: %s\n", __func__);
 
+  CODEC_LOG (DEBUG, "leave: %s\n", __func__);
   return len;
 }