implemented two ways to copy data from guest and host
authorKitae Kim <kt920.kim@samsung.com>
Tue, 12 Mar 2013 02:12:37 +0000 (11:12 +0900)
committerKitae Kim <kt920.kim@samsung.com>
Fri, 21 Jun 2013 13:10:04 +0000 (22:10 +0900)
21 files changed:
src/Makefile.am
src/audioconvert.h [new file with mode: 0644]
src/gstemul.c
src/gstemulapi.c
src/gstemulapi.h
src/gstemulapi2.c [new file with mode: 0644]
src/gstemulapi2.h [new file with mode: 0644]
src/gstemulcommon.h
src/gstemuldev.c
src/gstemuldev.h
src/gstemulenc.c [deleted file]
src/gstemulnewdec.c
src/gstemulnewenc.c
src/gstemulutils.c
src/gstmyfilter.c [deleted file]
src/gstmyfilter.h [deleted file]
src/gstplugin.c [deleted file]
src/gstplugin.h [deleted file]
src/gsttransform.c [deleted file]
src/gsttransform.h [deleted file]
src/pixfmt.h [new file with mode: 0644]

index d4f06f2..3a81d56 100644 (file)
@@ -18,7 +18,8 @@ libgstemul_la_SOURCES = gstemul.c \
        gstemulutils.c \
        gstemulnewdec.c \
        gstemulapi.c \
-       gstemuldev.c
+       gstemuldev.c \
+       gstemulapi2.c
 
 # compiler and linker flags used to compile this plugin, set in configure.ac
 libgstemul_la_CFLAGS = $(GST_CFLAGS) -g
diff --git a/src/audioconvert.h b/src/audioconvert.h
new file mode 100644 (file)
index 0000000..be7734d
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2008 Peter Ross
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_AUDIOCONVERT_H
+#define AVUTIL_AUDIOCONVERT_H
+
+#include <stdint.h>
+
+/**
+ * @file
+ * audio conversion routines
+ */
+
+/* Audio channel masks */
+#define AV_CH_FRONT_LEFT             0x00000001
+#define AV_CH_FRONT_RIGHT            0x00000002
+#define AV_CH_FRONT_CENTER           0x00000004
+#define AV_CH_LOW_FREQUENCY          0x00000008
+#define AV_CH_BACK_LEFT              0x00000010
+#define AV_CH_BACK_RIGHT             0x00000020
+#define AV_CH_FRONT_LEFT_OF_CENTER   0x00000040
+#define AV_CH_FRONT_RIGHT_OF_CENTER  0x00000080
+#define AV_CH_BACK_CENTER            0x00000100
+#define AV_CH_SIDE_LEFT              0x00000200
+#define AV_CH_SIDE_RIGHT             0x00000400
+#define AV_CH_TOP_CENTER             0x00000800
+#define AV_CH_TOP_FRONT_LEFT         0x00001000
+#define AV_CH_TOP_FRONT_CENTER       0x00002000
+#define AV_CH_TOP_FRONT_RIGHT        0x00004000
+#define AV_CH_TOP_BACK_LEFT          0x00008000
+#define AV_CH_TOP_BACK_CENTER        0x00010000
+#define AV_CH_TOP_BACK_RIGHT         0x00020000
+#define AV_CH_STEREO_LEFT            0x20000000  ///< Stereo downmix.
+#define AV_CH_STEREO_RIGHT           0x40000000  ///< See AV_CH_STEREO_LEFT.
+
+/** Channel mask value used for AVCodecContext.request_channel_layout
+    to indicate that the user requests the channel order of the decoder output
+    to be the native codec channel order. */
+#define AV_CH_LAYOUT_NATIVE          0x8000000000000000LL
+
+/* Audio channel convenience macros */
+#define AV_CH_LAYOUT_MONO              (AV_CH_FRONT_CENTER)
+#define AV_CH_LAYOUT_STEREO            (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT)
+#define AV_CH_LAYOUT_2_1               (AV_CH_LAYOUT_STEREO|AV_CH_BACK_CENTER)
+#define AV_CH_LAYOUT_SURROUND          (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER)
+#define AV_CH_LAYOUT_4POINT0           (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_CENTER)
+#define AV_CH_LAYOUT_2_2               (AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT)
+#define AV_CH_LAYOUT_QUAD              (AV_CH_LAYOUT_STEREO|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
+#define AV_CH_LAYOUT_5POINT0           (AV_CH_LAYOUT_SURROUND|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT)
+#define AV_CH_LAYOUT_5POINT1           (AV_CH_LAYOUT_5POINT0|AV_CH_LOW_FREQUENCY)
+#define AV_CH_LAYOUT_5POINT0_BACK      (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
+#define AV_CH_LAYOUT_5POINT1_BACK      (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_LOW_FREQUENCY)
+#define AV_CH_LAYOUT_7POINT0           (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
+#define AV_CH_LAYOUT_7POINT1           (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
+#define AV_CH_LAYOUT_7POINT1_WIDE      (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER)
+#define AV_CH_LAYOUT_STEREO_DOWNMIX    (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT)
+
+#if 0
+/**
+ * Return a channel layout id that matches name, 0 if no match.
+ */
+int64_t av_get_channel_layout(const char *name);
+
+/**
+ * Return a description of a channel layout.
+ * If nb_channels is <= 0, it is guessed from the channel_layout.
+ *
+ * @param buf put here the string containing the channel layout
+ * @param buf_size size in bytes of the buffer
+ */
+void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout);
+
+/**
+ * Return the number of channels in the channel layout.
+ */
+int av_get_channel_layout_nb_channels(int64_t channel_layout);
+#endif
+
+#endif /* AVUTIL_AUDIOCONVERT_H */
index b682d65..9e3d40f 100644 (file)
@@ -71,14 +71,12 @@ gst_emul_codec_element_init ()
     perror ("failed to open codec device");
   }
 
-#if 0
   ioctl (fd, CODEC_CMD_GET_VERSION, &version);
   if (version != CODEC_VER) {
     printf ("version conflict between device: %d, plugin: %d\n",
         version, CODEC_VER);
     return FALSE;
   }
-#endif
 
   buffer = mmap (NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
   if (!buffer) {
@@ -102,12 +100,11 @@ gst_emul_codec_element_init ()
     memcpy (&data_length, (uint8_t *)buffer + size, sizeof(data_length));
     size += sizeof(data_length);
     if (!data_length) {
-//      printf ("There is no more avcodec.\n");
       break;
     }
     memcpy (elm, (uint8_t *)buffer + size, data_length);
     size += data_length;
-#if 0
+#if 0 
     printf("codec: %s, longname: %s, decode: %d, media: %d\n",
       elm->name, elm->longname, elm->codec_type, elm->media_type);
 #endif
@@ -127,7 +124,6 @@ plugin_init (GstPlugin *plugin)
 {
   GST_DEBUG_CATEGORY_INIT (emul_debug,
       "tizen-emul", 0, "Tizen Emulator Codec Elements");
-  gboolean ret;
 
   gst_emul_init_pix_fmt_info ();
 
@@ -136,19 +132,21 @@ plugin_init (GstPlugin *plugin)
     return FALSE;
   }
 
-  ret = gst_emuldec_register (plugin, codec_element);
-  if (!ret) {
+  if (!gst_emuldec_register (plugin, codec_element)) {
     GST_ERROR ("failed to register decoder elements");
     return FALSE;
   }
 #if 0
-  ret = gst_emulenc_register (plugin, codec_element);
-  if (!ret) {
+  if (!gst_emulenc_register (plugin, codec_element)) {
     GST_ERROR ("failed to register encoder elements");
     return FALSE;
   }
 #endif
 
+  while ((codec_element = g_list_next (codec_element))) {
+    g_list_free (codec_element);
+  } 
+
   return TRUE;
 }
 
index c4cf537..2345206 100644 (file)
 
 #include "gstemulcommon.h"
 #include "gstemulapi.h"
+#include "gstemulapi2.h"
 #include "gstemuldev.h"
 
-gboolean
+enum {
+  CODEC_USER_FROM = 0,
+  CODEC_USER_TO,
+};
+
+int
 emul_avcodec_init (CodecContext *ctx, CodecElement *codec, CodecDevice *dev)
 {
   int fd;
-  void *mmapbuf;
-  int size = 0;
-  gboolean ret = TRUE;
+  uint8_t *mmapbuf;
+  int size = 0, ret = 0;
+  int usable, copyback;
   CodecIOParams params;
 
-  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;
-  }
+  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);
+
+    while (1) {
+      ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
+      if (usable) {
+        CODEC_LOG (DEBUG, "[init][%d] failure.\n", __LINE__);
+        continue;
+      }
+
+      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;
+    }
 
-  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 0
+    if (ret < 0) {
+      return ret;
+    }
+#endif
   }
 
   CODEC_PARAM_INIT (params);
   params.api_index = CODEC_INIT;
-  params.ctx_index = 0;
+  params.mem_offset = dev->mem_info.offset;
   CODEC_WRITE_TO_QEMU (fd, &params, 1);
 
-  if (codec->media_type == AVMEDIA_TYPE_AUDIO) {
-    memcpy (&ctx->audio.sample_fmt,
-                 (uint8_t *)mmapbuf, sizeof(ctx->audio.sample_fmt));
+  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);
   }
-  ctx->codec = codec;
-
-  printf ("leave: %s\n", __func__);
 
+  CODEC_LOG (DEBUG, "leave: %s, ret: %d\n", __func__, ret);
   return ret;
 }
 
@@ -108,10 +165,11 @@ void
 emul_avcodec_deinit (CodecContext *ctx, CodecDevice *dev)
 {
   int fd;
-  void *mmapbuf;
+  int copyback, usable;
+  void *mmapbuf = NULL;
   CodecIOParams params;
 
-  printf ("enter: %s\n", __func__);
+  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
   fd = dev->fd;
   if (fd < 0) {
@@ -125,32 +183,41 @@ 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 = 0;
+  params.ctx_index = ctx->index;
+  params.mem_offset = dev->mem_info.offset;
   CODEC_WRITE_TO_QEMU (fd, &params, 1);
 
-#if 0
-  /* close device fd and release mapped memory region */
-  gst_emul_codec_device_close (dev);
-#endif
+//  ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
 
-  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,
+    GstBuffer **out_buf, int *got_picture_ptr, CodecDevice *dev)
 {
   int fd;
-  void *mmapbuf;
+  uint8_t *mmapbuf = NULL;
   int len = 0, size = 0;
-  guint out_size;
+  int copyback, usable;
   CodecIOParams params;
 
-  *out_buf = NULL;
-
-  printf ("enter: %s\n", __func__);
+  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
   fd = dev->fd;
   if (fd < 0) {
@@ -158,91 +225,259 @@ 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, 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_video] wait 1.\n");
+        continue;
+      }
+
+      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;
+    }
+  }
 
   /* provide raw image for decoding to qemu */
   CODEC_PARAM_INIT (params);
   params.api_index = CODEC_DECODE_VIDEO;
-  params.ctx_index = 0;
+  params.ctx_index = ctx->index;
+  params.mem_offset = dev->mem_info.offset;
   CODEC_WRITE_TO_QEMU (fd, &params, 1);
 
-  memcpy (&len, (uint8_t *)mmapbuf, sizeof(len));
-  size = sizeof(len);
+  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);
+  }
 
+  CODEC_LOG (DEBUG, "leave: %s\n", __func__);
+  return len;
+}
 
-  printf ("leave: %s\n", __func__);
+void
+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;
 
-  return len;
+  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
+
+  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_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;
+    }
+  }
+#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");
+
+  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;
+    }
+    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;
+  uint8_t *mmapbuf = NULL;
+  int size = 0, len;
+  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 -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 {
+    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;
+    }
   }
 
   CODEC_PARAM_INIT (params);
   params.api_index = CODEC_DECODE_AUDIO;
-  params.ctx_index = 0;
-  params.device_mem_offset = 0;
+  params.ctx_index = ctx->index;
+  params.mem_offset = dev->mem_info.offset;
   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);
+  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;
+    }
+    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, CodecDevice *dev)
 {
   int fd;
   void *mmapbuf;
   int len = 0, outbuf_size, size = 0;
+  int copyback, usable;
   CodecIOParams params;
 
-  printf ("enter: %s\n", __func__);
+  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
   fd = dev->fd;
   if (fd < 0) {
@@ -256,51 +491,72 @@ emul_avcodec_encode_video (CodecContext *ctx, guint8 *in_buf, guint in_size,
     return FALSE;
   }
 
-  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);
+  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, "[init][%d] failure.\n", __LINE__);
+//      sleep(1);
+      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);
+    break;
+  }
 
   CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_DECODE_AUDIO;
-  params.ctx_index = 0;
+  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);
 
+  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_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);
+    memcpy (GST_BUFFER_DATA(*out_buf), (uint8_t *)mmapbuf + size, out_size);
   } else {
-      pritnf ("failed to allocate output buffer\n");
+    pritnf ("failed to allocate output buffer\n");
   }
 #endif
+    break;
+  }
+  ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
 
-  printf ("leave: %s\n", __func__);
+  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 *outbuf, int outbuf_size,
+    const short *inbuf, int inbuf_size, CodecDevice *dev)
 {
   int fd;
   void *mmapbuf;
   int len = 0, size = 0;
+  int copyback, usable;
   CodecIOParams params;
 
-  printf ("enter: %s\n", __func__);
+  CODEC_LOG (DEBUG, "enter: %s\n", __func__);
 
   fd = dev->fd;
   if (fd < 0) {
@@ -314,40 +570,45 @@ emul_avcodec_encode_audio (CodecContext *ctx, CodecDevice *dev)
     return FALSE;
   }
 
-#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
+  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.\n");
+//      sleep(1);
+      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);
+    break;
+  }
 
   CODEC_PARAM_INIT (params);
-  params.api_index = CODEC_DECODE_AUDIO;
-  params.ctx_index = 0;
+  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);
 
-#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));
-  }
+  while (1) {
+    ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
+    if (usable) {
+      CODEC_LOG (DEBUG, "[decode_video] wait. 2\n");
+//      sleep(1);
+      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");
+    CODEC_LOG (DEBUG, "[encode_audio] read data from qemu\n");
+    memcpy (outbuf, (uint8_t *)mmapbuf, outbuf_size);
+    break;
   }
-#endif
+  ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, NULL);
 
-  printf ("leave: %s\n", __func__);
+  CODEC_LOG (DEBUG, "leave: %s\n", __func__);
 
   return len;
 }
index 203d839..a1f2abd 100644 (file)
 
 #include "gstemulcommon.h"
 
-gboolean emul_avcodec_init (CodecContext *ctx, CodecElement *codec, CodecDevice *dev);
-int emul_avcdoec_deinit (CodecContext *ctx, CodecDevice *dev);
+int emul_avcodec_init (CodecContext *ctx, CodecElement *codec,
+  CodecDevice *dev);
+
+void emul_avcodec_deinit (CodecContext *ctx, CodecDevice *dev);
+
+int emul_avcodec_decode_video (CodecContext *ctx, uint8_t *in_buf,
+  int in_size, GstBuffer **out_buf,
+  int *got_picture_ptr, CodecDevice *dev);
 
-int emul_avcodec_decode_video (CodecContext *ctx, guint8 *in_buf, guint in_size,
-        GstBuffer **out_buf, int *got_picture_ptr, CodecDevice *dev);
 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 emul_avcodec_encode_video (CodecContext *ctx, uint8_t*out_buf, int out_size,
+               uint8_t *in_buf, int in_size, CodecDevice *dev);
+
+int emul_avcodec_encode_audio (CodecContext *ctx, uint8_t *outbuf,
+  int outbuf_size, const short *inbuf,
+  int inbuf_size, CodecDevice *dev);
 
-int emul_avcodec_encode_video (CodecContext *ctx, guint8 *in_buf, guint in_size,
-        GstBuffer **out_buf, CodecDevice *dev);
-int emul_avcodec_encode_audio (CodecContext *ctx, CodecDevice *dev);
+void
+emul_av_picture_copy (CodecContext *ctx, uint8_t *pict, uint32_t pict_size, CodecDevice *dev);
 
 #endif /* __GST_EMUL_API_H__ */
diff --git a/src/gstemulapi2.c b/src/gstemulapi2.c
new file mode 100644 (file)
index 0000000..318b6d6
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * GStreamer codec plugin for Tizen Emulator.
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * KiTae Kim <kt920.kim@samsung.com>
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include "gstemulapi2.h"
+
+void
+emul_avcodec_init_to (CodecContext *ctx, CodecElement *codec, uint8_t *device_buf)
+{
+  int size = 0, codec_size;
+
+  CODEC_LOG (DEBUG, "[init] write data to qemu.\n");
+  size = sizeof(size);
+  codec_size =
+    sizeof(codec->media_type) + sizeof(codec->codec_type) + sizeof(codec->name);
+
+#if 0
+  memcpy (device_buf + size,
+      &codec->media_type, sizeof(codec->media_type));
+  size += sizeof(codec->media_type);
+  memcpy (device_buf + size, &codec->codec_type, sizeof(codec->codec_type));
+  size += sizeof(codec->codec_type);
+  memcpy (device_buf + size, codec->name, sizeof(codec->name));
+  size += sizeof(codec->name);
+#endif
+  memcpy (device_buf + size, codec, codec_size);
+  size += codec_size;
+
+  if (codec->media_type == AVMEDIA_TYPE_VIDEO) {
+    memcpy (device_buf + size, &ctx->video, sizeof(ctx->video));
+    size += sizeof(ctx->video);
+  } else if (codec->media_type == AVMEDIA_TYPE_AUDIO) {
+    memcpy (device_buf + size, &ctx->audio, sizeof(ctx->audio));
+    size += sizeof(ctx->audio);
+  } else {
+    GST_ERROR ("media type is unknown.\n");
+    return;
+  }
+
+  memcpy (device_buf + size,
+      &ctx->codecdata_size, sizeof(ctx->codecdata_size));
+  size += sizeof(ctx->codecdata_size);
+  if (ctx->codecdata_size) {
+    memcpy (device_buf + size, ctx->codecdata, ctx->codecdata_size);
+    size += ctx->codecdata_size;
+  }
+  size -= sizeof(size);
+  memcpy (device_buf, &size, sizeof(size));
+
+  CODEC_LOG (DEBUG, "[init] write data: %d\n", size);
+}
+
+int
+emul_avcodec_init_from (CodecContext *ctx, CodecElement *codec, uint8_t *device_buf)
+{
+  int ret = 0, size = 0;
+
+  CODEC_LOG (DEBUG, "[init] read data from qemu.\n");
+  if (codec->media_type == AVMEDIA_TYPE_AUDIO) {
+    memcpy (&ctx->audio.sample_fmt,
+        (uint8_t *)device_buf, 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 *)device_buf + size, sizeof(ret));
+  size += sizeof(ret);
+  memcpy (&ctx->index, (uint8_t *)device_buf + size, sizeof(ctx->index));
+  ctx->codec = codec;
+  CODEC_LOG (DEBUG, "context index: %d\n", ctx->index);
+
+  return ret;
+}
+
+void
+emul_avcodec_decode_video_to (uint8_t *in_buf, int in_size, uint8_t *device_buf)
+{
+  int ret = 0, size = 0;
+
+  CODEC_LOG (DEBUG, "[decode_video] write data to qemu\n");
+  size = sizeof(size);
+  memcpy (device_buf + size, &in_size, sizeof(in_size));
+  size += sizeof(in_size);
+  if (in_size > 0) {
+    memcpy (device_buf + 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(device_buf, &size, sizeof(size));
+}
+
+int
+emul_avcodec_decode_video_from (CodecContext *ctx, int *got_picture_ptr, uint8_t *device_buf)
+{
+  int len = 0, size = 0;
+
+  CODEC_LOG (DEBUG, "[decode_video] read data from qemu.\n");
+  memcpy (&len, (uint8_t *)device_buf, sizeof(len));
+  size = sizeof(len);
+  memcpy (got_picture_ptr,
+      (uint8_t *)device_buf + size, sizeof(*got_picture_ptr));
+  size += sizeof(*got_picture_ptr);
+  memcpy (&ctx->video, (uint8_t *)device_buf + size, sizeof(ctx->video));
+
+  CODEC_LOG (DEBUG, "[decode_video] len: %d, have_date: %d\n", len, *got_picture_ptr);
+
+  return len;
+}
+
+void
+emul_avcodec_decode_audio_to (uint8_t *in_buf, int in_size, uint8_t *device_buf)
+{
+  int size = 0;
+
+  size = sizeof(size);
+  memcpy (device_buf + size, &in_size, sizeof(in_size));
+  size += sizeof(in_size);
+  if (in_size > 0) {
+    memcpy (device_buf + size, in_buf, in_size);
+    size += in_size;
+  }
+
+  size -= sizeof(size);
+  memcpy (device_buf, &size, sizeof(size));
+  CODEC_LOG (DEBUG, "[decode_audio] write size: %d, inbuf_size: %d\n", size, in_size);
+}
+
+int
+emul_avcodec_decode_audio_from (CodecContext *ctx, int *frame_size_ptr, int16_t *samples, uint8_t *device_buf)
+{
+  int len = 0, size = 0;
+
+  CODEC_LOG (DEBUG, "[decode_audio] read data\n");
+  memcpy (&ctx->audio.channel_layout,
+      (uint8_t *)device_buf, sizeof(ctx->audio.channel_layout));
+  size = sizeof(ctx->audio.channel_layout);
+  memcpy (&len, (uint8_t *)device_buf + size, sizeof(len));
+  size += sizeof(len);
+  memcpy (frame_size_ptr, (uint8_t *)device_buf + 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 *)device_buf + size, FF_MAX_AUDIO_FRAME_SIZE);
+  }
+
+  return len;
+}
diff --git a/src/gstemulapi2.h b/src/gstemulapi2.h
new file mode 100644 (file)
index 0000000..a8d5c1a
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * GStreamer codec plugin for Tizen Emulator.
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * KiTae Kim <kt920.kim@samsung.com>
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include "gstemulcommon.h"
+
+void emul_avcodec_init_to (CodecContext *ctx, CodecElement *codec, uint8_t *device_buf);
+
+int emul_avcodec_init_from (CodecContext *ctx, CodecElement *codec, uint8_t *device_buf);
+
+void emul_avcodec_decode_video_to (uint8_t *in_buf, int in_size, uint8_t *device_buf);
+
+int emul_avcodec_decode_video_from (CodecContext *ctx, int *got_picture_ptr, uint8_t *device_buf);
+
+void emul_avcodec_decode_audio_to (uint8_t *in_buf, int in_size, uint8_t *device_buf);
+
+int emul_avcodec_decode_audio_from (CodecContext *ctx, int *frame_size_ptr, int16_t *samples, uint8_t *device_buf);
index 67c97e4..575c512 100644 (file)
@@ -48,40 +48,94 @@ GST_DEBUG_CATEGORY_EXTERN (emul_debug);
 
 G_BEGIN_DECLS
 
+enum codec_log_level {
+  ERR,
+  WARN,
+  LOG,
+  DEBUG,
+};
+
 #define CODEC_DEV   "/dev/newcodec"
-#define CODEC_VER   10
+#define CODEC_VER   1
 
 #define CODEC_PARAM_INIT(var) \
   memset (&var, 0x00, sizeof(var))
 
 #define CODEC_WRITE_TO_QEMU(fd, var, size) \
   if (write (fd, var, size) < 0) { \
-    printf ("[%d] failed to copy data.\n", __LINE__); \
+    printf ("[%s:%d] failed to copy data.\n", __func__, __LINE__); \
   }
 
+#define CODEC_LOG(level, fmt, ...) \
+  do { \
+    if (level <= LOG) \
+      printf("[gst-emul][%d] " fmt, __LINE__, ##__VA_ARGS__); \
+  } while (0)
+
 #define FF_INPUT_BUFFER_PADDING_SIZE  8
 #define FF_MAX_AUDIO_FRAME_SIZE     192000 // 1 second of 48khz 32bit audio
 #define FF_MIN_BUFFER_SIZE        16384
 
+#define GEN_MASK(x) ((1<<(x))-1)
+#define ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) & ~GEN_MASK(x))
+#define ROUND_UP_4(x) ROUND_UP_X(1, 2)
+
+#if 0
+struct _CodecIOHeader {
+  uint32_t ctx_index;
+  uint32_t mem_offset;
+};
+
+struct _CodecData {
+  uint16_t mediatype;
+  uint16_t codectype;
+  gchar name[32];
+  uint32_t extradata_size;
+  uint8_t *extradata;
+};
+
+struct _CodecCtxData {
+  int result;
+
+  struct _CodecData codec;
+
+  union {
+    struct _VideoData video;
+    struct _AudioData audio;
+  } media;
+};
+
+struct _CodecBuffer {
+  uint32_t bufsize;
+  uint8_t *buf;
+};
+#endif
+
 typedef struct _CodecIOParams {
-  uint32_t  api_index;
-  uint32_t  ctx_index;
-  uint32_t  file_index;
-  uint32_t  mem_index;
-  uint32_t  device_mem_offset;
+  int32_t   api_index;
+  int32_t   ctx_index;
+  uint32_t  mem_offset;
+  uint32_t  mem_type;
 } CodecIOParams;
 
+typedef struct _CodecDevMemInfo {
+  uint32_t  type;
+  uint32_t  index;
+  uint32_t  offset;
+} CodecDevMemInfo;
+
 typedef struct _CodecDevice {
-  int   fd;
-  void    *buf;
+  int       fd;
+  uint8_t   *buf;
   uint32_t  buf_size;
+  CodecDevMemInfo mem_info;
 } CodecDevice;
 
 typedef struct _CodecElement {
-  gchar   name[32];
-  gchar   longname[64];
   uint16_t  codec_type;
   uint16_t  media_type;
+  gchar   name[32];
+  gchar   longname[64];
 #if 0
   union {
     struct {
@@ -99,6 +153,7 @@ typedef struct _VideoData {
   int fps_n, fps_d;
   int par_n, par_d;
   int pix_fmt, bpp;
+  int ticks_per_frame;
 } VideoData;
 
 typedef struct _AudioData {
@@ -109,31 +164,35 @@ typedef struct _AudioData {
 } AudioData;
 
 typedef struct _CodecContext {
+  CodecElement *codec;
+  int index;
+
   uint8_t *codecdata;
   int codecdata_size;
 
   VideoData video;
   AudioData audio;
-
-  CodecElement *codec;
 } CodecContext;
 
 enum CODEC_FUNC_TYPE {
   CODEC_ELEMENT_INIT = 1,
   CODEC_INIT,
-  CODEC_DEINIT,
   CODEC_DECODE_VIDEO,
   CODEC_ENCODE_VIDEO,
   CODEC_DECODE_AUDIO,
   CODEC_ENCODE_AUDIO,
+  CODEC_PICTURE_COPY,
+  CODEC_DEINIT,
 };
 
 enum CODEC_IO_CMD {
-  CODEC_CMD_GET_VERSION = 5,
-  CODEC_CMD_GET_DEVICE_MEM,
-  CODEC_CMD_SET_DEVICE_MEM,
-  CODEC_CMD_GET_MMAP_OFFSET,
-  CODEC_CMD_SET_MMAP_OFFSET,
+  CODEC_CMD_GET_DEVICE_MEM_INFO = 0,
+  CODEC_CMD_RELEASE_DEVICE_MEM,
+  CODEC_CMD_ADD_TASK_QUEUE,
+  CODEC_CMD_REMOVE_TASK_QUEUE,
+  CODEC_CMD_COPY_FROM_DEVICE_MEM,
+  CODEC_CMD_COPY_TO_DEVICE_MEM,
+  CODEC_CMD_GET_VERSION = 20,
 };
 
 enum CODEC_MEDIA_TYPE {
@@ -158,6 +217,12 @@ enum SAMPLT_FORMAT {
   SAMPLE_FMT_NB
 };
 
+enum CODEC_MEMORY_TYPE {
+  CODEC_FIXED_DEVICE_MEM = 0,
+  CODEC_SHARED_DEVICE_MEM,
+};
+
+
 /* Define codec types.
  * e.g. FFmpeg, x264, libvpx and etc.
  */
index ea8845d..59c11eb 100644 (file)
@@ -38,7 +38,7 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 
-#include "gstemulcommon.h"
+#include "gstemulapi.h"
 #include "gstemuldev.h"
 
 
@@ -46,6 +46,7 @@ int
 gst_emul_codec_device_open (CodecDevice *dev)
 {
   int fd;
+//  CodecDevMemInfo mem_info;
   void *mmapbuf;
 
   printf("enter: %s\n", __func__);
@@ -54,20 +55,34 @@ gst_emul_codec_device_open (CodecDevice *dev)
     perror("Failed to open codec device.");
     return -1;
   }
-  GST_DEBUG("succeeded to open %s.\n", CODEC_DEV);
+
+//  GST_DEBUG("succeeded to open %s. %d.\n", CODEC_DEV, fd);
+  printf("succeeded to open %s. %d.\n", CODEC_DEV, fd);
+//  memset(&mem_info, 0x00, sizeof(CodecDevMemInfo));
+  dev->mem_info.index = dev->buf_size;
+
+  ioctl(fd, CODEC_CMD_GET_DEVICE_MEM_INFO, &dev->mem_info);
+
+#if 1
+  printf("mem type: %d, index: %d, offset: %d\n",
+    dev->mem_info.type, dev->mem_info.index, dev->mem_info.offset);
+#endif
 
   mmapbuf = mmap (NULL, dev->buf_size, PROT_READ | PROT_WRITE,
-                  MAP_SHARED, fd, 0);
+                  MAP_SHARED, fd, dev->mem_info.offset);
   if (!mmapbuf) {
     perror("Failed to map device memory of codec.");
     close(fd);
     return -1;
   }
-  GST_DEBUG("succeeded to map device memory.\n");
 
+//  GST_DEBUG("succeeded to map device memory.\n");
+  printf("succeeded to map device memory: %p.\n", mmapbuf);
   dev->fd = fd;
   dev->buf = mmapbuf;
 
+  printf("leave: %s\n", __func__);
+
   return 0;
 }
 
@@ -91,12 +106,19 @@ gst_emul_codec_device_close (CodecDevice *dev)
     return -1;
   }
 
-  GST_DEBUG("Release memory region of %s.\n", CODEC_DEV);
+//  GST_DEBUG("Release memory region of %s.\n", CODEC_DEV);
+  CODEC_LOG(LOG, "Release memory region of %s.\n", CODEC_DEV);
+
   if (munmap(mmapbuf, dev->buf_size) != 0) {
     GST_ERROR("Failed to release memory region of %s.\n", CODEC_DEV);
   }
+  dev->buf = NULL; 
+
+  ioctl(fd, CODEC_CMD_RELEASE_DEVICE_MEM, &dev->mem_info);
+
+//  GST_DEBUG("close %s.\n", CODEC_DEV);
+  CODEC_LOG(LOG, "close %s.\n", CODEC_DEV);
 
-  GST_DEBUG("close %s.\n", CODEC_DEV);
   if (close(fd) != 0) {
     GST_ERROR("Failed to close %s. fd: %d\n", CODEC_DEV, fd);
   }
@@ -105,3 +127,38 @@ gst_emul_codec_device_close (CodecDevice *dev)
 
   return 0;
 }
+
+static GStaticMutex gst_avcodec_mutex = G_STATIC_MUTEX_INIT;
+
+int
+gst_emul_avcodec_open (CodecContext *ctx, CodecElement *codec, CodecDevice *dev)
+{
+  int ret;
+
+  g_static_mutex_lock (&gst_avcodec_mutex);
+
+  if (gst_emul_codec_device_open (dev) < 0) {
+    perror("failed to open device.\n");
+    return -1;
+  }
+  ret = emul_avcodec_init (ctx, codec, dev);
+  g_static_mutex_unlock (&gst_avcodec_mutex);
+
+  return ret;
+}
+
+int
+gst_emul_avcodec_close (CodecContext *ctx, CodecDevice *dev)
+{
+  int ret;
+
+  g_static_mutex_lock (&gst_avcodec_mutex);
+
+  printf ("gst_emul_avcodec_close\n");
+  emul_avcodec_deinit (ctx, dev);
+
+  ret = gst_emul_codec_device_close (dev);
+  g_static_mutex_unlock (&gst_avcodec_mutex);
+
+  return ret;
+}
index 0bb3ccc..c3dd1ac 100644 (file)
@@ -34,4 +34,7 @@
 int gst_emul_codec_device_open (CodecDevice *dev);
 int gst_emul_codec_device_close (CodecDevice *dev);
 
+int gst_emul_avcodec_open (CodecContext *ctx,
+               CodecElement *codec, CodecDevice *dev);
+int gst_emul_avcodec_close (CodecContext *ctx, CodecDevice *dev);
 #endif
diff --git a/src/gstemulenc.c b/src/gstemulenc.c
deleted file mode 100644 (file)
index 4a7040b..0000000
+++ /dev/null
@@ -1,750 +0,0 @@
-/*
- * Emulator
- *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: 
- * KiTae Kim <kt920.kim@samsung.com>
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* First, include the header file for the plugin, to bring in the
- * object definition and other useful things.
- */
-
-/*
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <gst/gst.h>
-#include "gstemulcommon.h"
-
-typedef struct _GstEmulEnc
-{
-  GstElement element;
-
-  GstPad *srcpad;
-  GstPad *sinkpad;
-
-  union {
-    struct {
-      gint width;
-      gint height;
-      gint framerate_num;
-      gint framerate_den;
-      gint pix_fmt;   
-    } video;
-    struct {
-      gint channels;
-      gint samplerate;
-      gint depth;
-    } audio;
-  } format;
-
-  guint extradata_size;
-  guint8 *extradata;
-
-  CodecDev codecbuf;
-} GstEmulEnc;
-
-typedef struct _GstEmulEncClass
-{
-  GstElementClass parent_class;
-
-  GstPadTemplate *sinktempl;
-  GstPadTemplate *srctempl;
-} GstEmulEncClass;
-
-static GstElementClass *parent_class = NULL;
-
-static void gst_emulenc_base_init (GstEmulEncClass *klass);
-static void gst_emulenc_class_init (GstEmulEncClass *klass);
-static void gst_emulenc_init (GstEmulEnc *emulenc);
-static void gst_emulenc_finalize (GObject *object);
-
-static gboolean gst_emulenc_setcaps (GstPad *pad, GstCaps *caps);
-static gboolean gst_emulenc_sink_event (GstPad *pad, GstEvent *event);
-static GstFlowReturn gst_emulenc_chain (GstPad *pad, GstBuffer *buffer);
-
-static gboolean gst_emulenc_src_event (GstPad *pad, GstEvent *event);
-static GstStateChangeReturn gst_emulenc_change_state (GstElement *element, GstStateChange transition);
-
-int gst_emul_codec_init (GstEmulEnc *emulenc);
-void gst_emul_codec_deinit (GstEmulEnc *emulenc);
-int gst_emul_codec_encode_video (GstEmulEnc *emulenc, guint8 *in_buf, guint in_size,
-        GstBuffer **out_buf, GstClockTime in_timestamp);
-
-int gst_emul_codec_dev_open (GstEmulEnc *emulenc);
-
-
-#define GST_EMULENC_PARAMS_QDATA g_quark_from_static_string("emulenc-params"); 
-
-/*
- * Implementation
- */
-    static void
-gst_emulenc_base_init (GstEmulEncClass *klass)
-{
-    GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-    GstCaps *sinkcaps, *srccaps;
-    GstPadTemplate *sinktempl, *srctempl;
-    const char *mimetype = "video/x-h264";
-    CodecInfo *info;
-    gchar *longname, *classification;
-
-    info =
-        (CodecInfo *)g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
-                GST_EMULENC_PARAMS_QDATA);
-
-    longname = g_strdup_printf ("%s Encoder", info->codec_longname);
-
-    classification = g_strdup_printf ("Codec/Encoder/%s",
-            (info->media_type == AVMEDIA_TYPE_VIDEO) ? "Video" : "Audio");
-
-    gst_element_class_set_details_simple (element_class,
-            longname,
-            classification,
-            "accelerated codec for Tizen Emulator",
-            "Kitae Kim <kt920.kim@samsung.com>");
-
-    g_free (longname);
-    g_free (classification);
-
-    sinkcaps = gst_caps_new_simple (mimetype,
-            "width", GST_TYPE_INT_RANGE, 16, 4096,
-            "height", GST_TYPE_INT_RANGE, 16, 4096,
-            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
-    if (!sinkcaps) {
-        sinkcaps = gst_caps_from_string ("unknown/unknown");
-    }
-
-    // if type is video
-    srccaps = gst_caps_from_string ("video/x-raw-rgb; video/x-raw-yuv");
-    // otherwise
-    // srcaps = gst_emul_codectype_to_audio_caps ();
-
-    if (!srccaps) {
-        srccaps = gst_caps_from_string ("unknown/unknown");
-    }
-
-    sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
-            GST_PAD_ALWAYS, sinkcaps);
-    srctempl = gst_pad_template_new ("src", GST_PAD_SRC,
-            GST_PAD_ALWAYS, srccaps);
-
-    gst_element_class_add_pad_template (element_class, srctempl);
-    gst_element_class_add_pad_template (element_class, sinktempl);
-
-    klass->sinktempl = sinktempl;
-    klass->srctempl = srctempl;
-}
-
-    static void
-gst_emulenc_class_init (GstEmulEncClass *klass)
-{
-    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-    GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
-
-    parent_class = g_type_class_peek_parent (klass);
-
-#if 0
-    gobject_class->set_property = gst_emulenc_set_property
-        gobject_class->get_property = gst_emulenc_get_property
-#endif
-
-        gobject_class->finalize = gst_emulenc_finalize;
-
-    gstelement_class->change_state = gst_emulenc_change_state; 
-}
-
-    static void
-gst_emulenc_init (GstEmulEnc *emulenc)
-{
-    GstEmulEncClass *oclass;
-
-    oclass = (GstEmulEncClass*) (G_OBJECT_GET_CLASS(emulenc));
-
-    emulenc->sinkpad = gst_pad_new_from_template (oclass->sinktempl, "sink");
-    gst_pad_set_setcaps_function (emulenc->sinkpad,
-            GST_DEBUG_FUNCPTR(gst_emulenc_setcaps));
-    gst_pad_set_event_function (emulenc->sinkpad,
-            GST_DEBUG_FUNCPTR(gst_emulenc_sink_event));
-    gst_pad_set_chain_function (emulenc->sinkpad,
-            GST_DEBUG_FUNCPTR(gst_emulenc_chain));
-    gst_element_add_pad (GST_ELEMENT(emulenc), emulenc->sinkpad);
-
-    emulenc->srcpad = gst_pad_new_from_template (oclass->srctempl, "src") ;
-    gst_pad_use_fixed_caps (emulenc->srcpad);
-    gst_pad_set_event_function (emulenc->srcpad,
-            GST_DEBUG_FUNCPTR(gst_emulenc_src_event));
-    gst_element_add_pad (GST_ELEMENT(emulenc), emulenc->srcpad);
-}
-
-    static void
-gst_emulenc_finalize (GObject *object)
-{
-    // Deinit Decoder
-    GstEmulEnc *emulenc = (GstEmulEnc *) object;
-
-    G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-    static gboolean
-gst_emulenc_src_event (GstPad *pad, GstEvent *event)
-{
-    return 0;
-}
-
-    static void
-gst_emulenc_get_caps (GstEmulEnc *emulenc, GstCaps *caps)
-{
-    GstStructure *structure;
-
-    int width, height, bits_per_coded_sample;
-    const GValue *fps;
-    //    const GValue *par;
-    //    guint extradata_size;
-    //    guint8 *extradata;
-
-    /* FFmpeg Specific Values */
-    const GstBuffer *buf;
-    const GValue *value;
-
-    structure = gst_caps_get_structure (caps, 0);
-
-    value = gst_structure_get_value (structure, "codec_data");
-    if (value) {
-        buf = GST_BUFFER_CAST (gst_value_get_mini_object (value));
-        emulenc->extradata_size = GST_BUFFER_SIZE (buf);
-        emulenc->extradata = GST_BUFFER_DATA (buf);
-    } else {
-        CODEC_LOG (2, "no codec data\n");
-        emulenc->extradata_size = 0;
-        emulenc->extradata = NULL;
-    }
-
-#if 1 /* video type */
-    /* Common Properites, width, height and etc. */
-    gst_structure_get_int (structure, "width", &width);
-    gst_structure_get_int (structure, "height", &height);
-    gst_structure_get_int (structure, "bpp", &bits_per_coded_sample);
-
-    emulenc->format.video.width = width;
-    emulenc->format.video.height = height;
-
-    fps = gst_structure_get_value (structure, "framerate");
-    if (fps) {
-        emulenc->format.video.framerate_den = gst_value_get_fraction_numerator (fps);
-        emulenc->format.video.framerate_num = gst_value_get_fraction_denominator (fps);
-    }
-
-#if 0
-    par = gst_structure_get_value (structure, "pixel-aspect-ratio");
-    if (par) {
-        sample_aspect_ratio.num = gst_structure_get_fraction_numerator (par);
-        sample_aspect_ratio.den = gst_structure_get_fraction_denominator (par);
-    }
-#endif
-#endif
-
-#if 0 /* audio type */
-    gst_structure_get_int (structure, "channels", &channels);
-    gst_structure_get_int (structure, "rate", &sample_rate);
-    gst_structure_get_int (structure, "block_align", &block_align);
-    gst_structure_get_int (structure, "bitrate", &bit_rate);
-
-    emulenc->format.audio.channels = channels;
-    emulenc->format.audio.samplerate = sample_rate;
-#endif
-
-}
-
-    static gboolean
-gst_emulenc_setcaps (GstPad *pad, GstCaps *caps)
-{
-    GstEmulEnc *emulenc;
-    GstEmulEncClass *oclass;
-    gboolean ret = TRUE;
-
-    emulenc = (GstEmulEnc *) (gst_pad_get_parent (pad));
-    oclass = (GstEmulEncClass *) (G_OBJECT_GET_CLASS (emulenc));
-
-    GST_OBJECT_LOCK (emulenc);
-
-    gst_emulenc_get_caps (emulenc, caps);
-
-#if 0
-    if (!emulenc->format.video.framerate_den ||
-            !emulenc->format.video.framerate_num) {
-        emulenc->format.video.framerate_num = 1; 
-        emulenc->format.video.framerate_den = 25;
-    }
-#endif
-
-    if (gst_emul_codec_dev_open (emulenc) < 0) {
-        CODEC_LOG(1, "failed to access %s or mmap operation\n", CODEC_DEV);
-        GST_OBJECT_UNLOCK (emulenc);
-        gst_object_unref (emulenc);
-        return FALSE;
-    }
-
-    if (gst_emul_codec_init (emulenc) < 0) {
-        CODEC_LOG(1, "cannot initialize codec\n");
-        GST_OBJECT_UNLOCK (emulenc);
-        gst_object_unref (emulenc);
-        return FALSE;
-    }
-
-#if 0 /* open a parser */
-    gst_emul_codec_parser (emulenc);
-#endif
-
-    GST_OBJECT_UNLOCK (emulenc);
-
-    gst_object_unref (emulenc);
-
-    return ret;
-}
-
-    static gboolean
-gst_emulenc_sink_event (GstPad *pad, GstEvent *event)
-{
-    GstEmulEnc *emulenc;
-    gboolean ret = FALSE;
-
-    emulenc = (GstEmulEnc *) gst_pad_get_parent (pad);
-#if 0
-    switch (GST_TYPE_EVENT (event)) {
-        case GST_EVENT_EOS:
-            CODEC_LOG(2, "received GST_EVENT_EOS\n");
-            break;
-        case GST_EVENT_NEWSEGMENT:
-            CODEC_LOG(2, "received GST_EVENT_NEWSEGMENT\n");
-            break;
-    }
-    ret = gst_pad_push_event (emulenc->srcpad, event);
-#endif
-
-    gst_object_unref (emulenc);
-
-    return ret;
-}
-
-    static GstFlowReturn
-gst_emulenc_chain (GstPad *pad, GstBuffer *buffer)
-{
-    GstEmulEnc *emulenc;
-    guint8 *in_buf = NULL;
-    GstBuffer *out_buf;
-    gint in_size = 0;
-    GstClockTime in_timestamp;
-    GstFlowReturn ret = GST_FLOW_OK;
-
-    emulenc = (GstEmulEnc *) (GST_PAD_PARENT (pad));
-
-    in_size = GST_BUFFER_SIZE (buffer);
-    in_buf = GST_BUFFER_DATA (buffer);
-    in_timestamp = GST_BUFFER_TIMESTAMP (buffer);
-
-    gst_emul_codec_encode_video (emulenc, in_buf, in_size, &out_buf, in_timestamp);
-
-    CODEC_LOG(1, "out_buf:%p, ret:%d\n", out_buf, ret);
-
-    ret = gst_pad_push (emulenc->srcpad, out_buf);
-
-    //  g_free (out_buf);
-
-    gst_buffer_unref (buffer);
-
-    return ret;
-}
-
-    static GstStateChangeReturn
-gst_emulenc_change_state (GstElement *element, GstStateChange transition)
-{
-    GstEmulEnc *emulenc = (GstEmulEnc*)element;
-    GstStateChangeReturn ret;
-
-    ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
-    switch (transition) {
-        case GST_STATE_CHANGE_PAUSED_TO_READY:
-            gst_emul_codec_deinit (emulenc);
-        default:
-            break;
-    }
-
-    return ret;
-}
-
-    gboolean
-gst_emulenc_register (GstPlugin *plugin)
-{
-    GTypeInfo typeinfo = {
-        sizeof (GstEmulEncClass),
-        (GBaseInitFunc) gst_emulenc_base_init,
-        NULL,
-        (GClassInitFunc) gst_emulenc_class_init,
-        NULL,
-        NULL,
-        sizeof (GstEmulEnc),
-        0,
-        (GInstanceInitFunc) gst_emulenc_init,
-    };
-
-    GType type;
-    gchar *type_name;
-    gint rank = GST_RANK_PRIMARY;
-
-    /* register element */
-    {
-        int codec_fd, codec_cnt = 0;
-        int func_type = CODEC_QUERY;
-        int index = 0, size = 0;
-        void *buf;
-        CodecInfo *codec_info;
-
-        codec_fd = open(CODEC_DEV, O_RDWR);
-        if (codec_fd < 0) {
-            perror("failed to open codec device");
-            return FALSE;
-        }
-
-        printf("[codec] fd:%d\n", codec_fd);
-        buf = mmap (NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, codec_fd, 0);
-        if (!buf) {
-            perror("failed to mmap");
-        }
-
-        printf("[codec] mmap:%p\n", buf);
-
-        write (codec_fd, &func_type, sizeof(int));
-        memcpy (&codec_cnt, buf, sizeof(int));
-        size = sizeof(uint32_t);
-
-        codec_info = g_malloc0 (codec_cnt * sizeof(CodecInfo));
-        for (; index < codec_cnt; index++) {
-            memcpy(&codec_info[index].media_type, (uint8_t *)buf + size, sizeof(uint16_t));
-            size += sizeof(uint16_t);
-            memcpy(&codec_info[index].codec_type, (uint8_t *)buf + size, sizeof(uint16_t));
-            size += sizeof(uint16_t);
-            memcpy(&codec_info[index].codec_name, (uint8_t *)buf + size, 32);
-            size += 32;
-            memcpy(&codec_info[index].codec_longname, (uint8_t *)buf + size, 64);
-            size += 64;
-        }
-
-        for (index = 0; index < codec_cnt; index++) {
-            if (codec_info[index].codec_type != 0) {
-                continue;
-            }
-
-            type_name = g_strdup_printf ("emulenc_%s", codec_info[index].codec_name);
-            type = g_type_from_name (type_name);
-            if (!type) {
-                type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
-                g_type_set_qdata (type, GST_EMULDEC_PARAMS_QDATA, (gpointer) &codec_info[index]);
-            }
-
-            if (!gst_element_register (plugin, type_name, rank, type)) {
-                g_free (type_name);
-                return FALSE;
-            }
-            g_free (type_name);
-        }
-
-        printf("[codec] close\n");
-        munmap (buf, 4096);
-        close (codec_fd);
-    }
-
-    return TRUE;
-}
-
-void *gst_emul_codec_query (GstEmulEnc *emulenc)
-{
-    int fd, codec_cnt;
-    int size = 0, i;
-    void *mmapbuf;
-    int func_type = CODEC_QUERY;
-    CodecInfo *codec_info;
-
-    CODEC_LOG(1, "enter: %s\n", __func__);
-
-    fd = emulenc->codecbuf.fd;
-    mmapbuf = emulenc->codecbuf.mmapbuf;
-    if (fd < 0) {
-        CODEC_LOG(1, "failed to get %s fd\n", CODEC_DEV);
-        return NULL;
-    }
-
-    if (!mmapbuf) {
-        CODEC_LOG(1, "failed to get mmaped memory address\n");
-        return NULL;
-    }
-
-    write (fd, &func_type, sizeof(func_type));
-    memcpy (&codec_cnt, mmapbuf, sizeof(uint32_t));
-    size += sizeof(uint32_t);
-
-    codec_info = g_malloc0 (codec_cnt * sizeof(CodecInfo));
-
-    for (i = 0; i < codec_cnt; i++) {
-        memcpy (&codec_info[i].mediatype, (uint8_t *)mmapbuf + size, sizeof(uint16_t));
-        size += sizeof(uint16_t);
-        memcpy (&codec_info[i].codectype, (uint8_t *)mmapbuf + size, sizeof(uint16_t));
-        size += sizeof(uint16_t);
-        memcpy (codec_info[i].name, (uint8_t *)mmapbuf + size, 32);
-        size += 32;
-        memcpy (codec_info[i].long_name, (uint8_t *)mmapbuf + size, 64);
-        size += 64;
-    }
-
-    CODEC_LOG(1, "leave: %s\n", __func__);
-
-    return codec_info;
-}
-
-int gst_emul_codec_init (GstEmulEnc *emulenc)
-{
-    int fd;
-    int size = 0, ret;
-    guint extradata_size = 0;
-    guint8 *extradata = NULL;
-    void *mmapbuf;
-    int func_type = CODEC_INIT;
-
-    CODEC_LOG(1, "enter: %s\n", __func__);
-
-    fd = emulenc->codecbuf.fd;
-    mmapbuf = emulenc->codecbuf.mmapbuf;
-    if (fd < 0) {
-        CODEC_LOG(1, "failed to get %s fd\n", CODEC_DEV);
-        return -1;
-    }
-
-    if (!mmapbuf) {
-        CODEC_LOG(1, "failed to get mmaped memory address\n");
-        return -1;
-    }
-
-    extradata_size = emulenc->extradata_size;
-    extradata = emulenc->extradata;
-
-    /* copy basic info to initialize codec on the host side.
-     * e.g. width, height, FPS ant etc. */
-    memcpy ((uint8_t *)mmapbuf, &emulenc->format.video, sizeof(emulenc->format.video));
-    size += sizeof(emulenc->format.video);
-    if (extradata) {
-        memcpy ((uint8_t *)mmapbuf + size, &extradata_size, sizeof(extradata_size));
-        size += sizeof(extradata_size);
-        memcpy ((uint8_t *)mmapbuf + size, extradata, extradata_size);
-    }
-
-    ret = write (fd, &func_type, sizeof(func_type));
-
-    CODEC_LOG(1, "leave: %s\n", __func__);
-
-    return ret; 
-}
-
-void gst_emul_codec_dev_close (GstEmulEnc *emulenc)
-{
-    int fd, ret = 0;
-    int size = 0;
-    void *mmapbuf;
-
-    CODEC_LOG(1, "enter: %s\n", __func__);
-
-    fd = emulenc->codecbuf.fd;
-    mmapbuf = emulenc->codecbuf.mmapbuf;
-
-    if (fd < 0) {
-        CODEC_LOG(1, "failed to get %s fd\n", CODEC_DEV);
-        return;
-    }
-
-    if (!mmapbuf) {
-        CODEC_LOG(1, "failed to get mmaped memory address\n");
-        return;
-    }
-
-    CODEC_LOG(2, "release mmaped memory region of %s\n", CODEC_DEV);
-    ret = munmap(mmapbuf, 12 * 4096);
-    if (ret != 0) {
-        CODEC_LOG(1, "failed to release mmaped memory region of %s\n", CODEC_DEV);
-    }
-
-    CODEC_LOG(2, "close %s fd\n", CODEC_DEV);
-    ret = close (fd);
-    if (ret != 0) {
-        CODEC_LOG(1, "failed to close %s\n", CODEC_DEV);
-    }
-
-    CODEC_LOG(1, "leave: %s\n", __func__);
-}
-
-void gst_emul_codec_deinit (GstEmulEnc *emulenc)
-{
-    int fd, ret;
-    int func_type = CODEC_DEINIT;
-    void *mmapbuf;
-
-    CODEC_LOG(1, "enter: %s\n", __func__);
-
-    fd = emulenc->codecbuf.fd;
-    mmapbuf = emulenc->codecbuf.mmapbuf;
-
-    if (fd < 0) {
-        CODEC_LOG(1, "failed to get %s fd\n", CODEC_DEV);
-        return;
-    }
-
-    if (!mmapbuf) {
-        CODEC_LOG(1, "failed to get mmaped memory address\n");
-        return;
-    }
-
-    ret = write (fd, &func_type, sizeof(func_type));
-
-    /* close device fd and release mapped memory region */
-    gst_emul_codec_dev_close (emulenc);
-
-    CODEC_LOG(1, "leave: %s\n", __func__);
-}
-
-int gst_emul_codec_encode_video (GstEmulEnc *emulenc, guint8 *in_buf, guint in_size,
-        GstBuffer **out_buf, GstClockTime in_timestamp)
-{
-    int fd, size = 0, ret;
-    guint out_size;
-    int func_type = CODEC_DECODE_VIDEO;
-    void *mmapbuf;
-    *out_buf = NULL;
-
-    CODEC_LOG(1, "enter: %s\n", __func__);
-
-    fd = emulenc->codecbuf.fd;
-    mmapbuf = emulenc->codecbuf.mmapbuf;
-
-    if (fd < 0) {
-        CODEC_LOG(1, "failed to get %s fd\n", CODEC_DEV);
-        return -1;
-    }
-
-    if (!mmapbuf) {
-        CODEC_LOG(1, "failed to get mmaped memory address\n");
-        return -1;
-    }
-
-    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);
-
-    /* provide raw image for decoding to qemu */
-    ret = write (fd, &func_type, sizeof(func_type));
-
-    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);
-    } else {
-        CODEC_LOG(1, "failed to allocate output buffer\n");
-    }
-
-    CODEC_LOG(1, "leave: %s\n", __func__);
-
-    return ret;
-}
-
-#if 0
-void emulenc_encode_audio ()
-{
-    int fd, size = 0, ret;
-    guint out_size;
-    int func_type = CODEC_DECODE_AUDIO;
-    void *mmapbuf;
-    *out_buf = NULL;
-
-    CODEC_LOG(1, "enter: %s\n", __func__);
-
-    fd = emulenc->codecbuf.fd;
-    mmapbuf = emulenc->codecbuf.mmapbuf;
-
-    if (fd < 0) {
-        CODEC_LOG(1, "failed to get %s fd\n", CODEC_DEV);
-        return -1;
-    }
-
-    if (!mmapbuf) {
-        CODEC_LOG(1, "failed to get mmaped memory address\n");
-        return -1;
-    }
-
-    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);
-
-    /* provide raw image for decoding to qemu */
-    ret = write (fd, &func_type, sizeof(func_type));
-
-    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) = av_free;
-    if (GST_PAD_CAPS(emulenc->srcpad)) {
-        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);
-    } else {
-        CODEC_LOG(1, "failed to allocate output buffer\n");
-    }
-    CODEC_LOG(1, "leave: %s\n", __func__);
-
-    return ret;
-}
-#endif
index 9eaf906..31f0767 100644 (file)
@@ -213,7 +213,6 @@ gst_emuldec_do_qos (GstEmulDec *emuldec, GstClockTime timestamp,
 
   qostime = gst_segment_to_running_time (&emuldec->segment, GST_FORMAT_TIME,
     timestamp);
-  
 
   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (qostime))) {
     emuldec->processed++;
@@ -252,6 +251,9 @@ gst_emuldec_do_qos (GstEmulDec *emuldec, GstClockTime timestamp,
       return res;
     }
   }
+
+  emuldec->processed++;
+  return TRUE;
 }
 
 static void
@@ -296,7 +298,7 @@ gst_emuldec_drain (GstEmulDec *emuldec)
   oclass = (GstEmulDecClass *) (G_OBJECT_GET_CLASS (emuldec));
 
   // TODO: drain
-#if 1 
+#if 1
   {
     gint have_data, len, try = 0;
 
@@ -305,9 +307,8 @@ gst_emuldec_drain (GstEmulDec *emuldec)
 
       len =
         gst_emuldec_frame (emuldec, NULL, 0, &have_data, &ts_info_none, &ret);
-      if (len < 0 || have_data == 0) {
-        printf("drain. try: %d\n", try);
 
+      if (len < 0 || have_data == 0) {
         break;
       }
     } while (try++ < 10);
@@ -315,6 +316,7 @@ gst_emuldec_drain (GstEmulDec *emuldec)
 #endif
 
   if (emuldec->segment.rate < 0.0) {
+    printf ("reverse playback\n");
     flush_queued (emuldec);
   }
 }
@@ -428,6 +430,9 @@ gst_emuldec_init (GstEmulDec *emuldec)
   if (!emuldec->context) {
     printf("failed to allocate memory.\n");
   }
+  // set default bit_rate
+  emuldec->context->audio.bit_rate = 64000;
+
   emuldec->dev = g_malloc0 (sizeof(CodecDevice));
   if (!emuldec->dev) {
     printf("failed to allocate memory.\n");
@@ -448,7 +453,7 @@ gst_emuldec_finalize (GObject *object)
   GstEmulDec *emuldec = (GstEmulDec *) object;
 
   printf ("gst_emuldec_finalize\n");
-  if (emuldec->context != NULL) {
+  if (emuldec->context) {
     g_free (emuldec->context);
     emuldec->context = NULL;
   }
@@ -460,7 +465,7 @@ static gboolean
 gst_emuldec_src_event (GstPad *pad, GstEvent *event)
 {
   GstEmulDec *emuldec;
-  gboolean res; 
+  gboolean res;
 
   emuldec = (GstEmulDec *) gst_pad_get_parent (pad);
 
@@ -473,27 +478,22 @@ gst_emuldec_src_event (GstPad *pad, GstEvent *event)
     GstClockTimeDiff diff;
     GstClockTime timestamp;
 
-       printf("GST_EVENT_QOS\n");
     gst_event_parse_qos (event, &proportion, &diff, &timestamp);
-    GST_LOG_OBJECT (emuldec, "update QOS: %f, %" GST_TIME_FORMAT,
-      proportion, GST_TIME_ARGS (timestamp));
 
     /* update our QoS values */
     gst_emuldec_update_qos (emuldec, proportion, timestamp + diff);
-
-    /* forward upstream */
-    res = gst_pad_push_event (emuldec->sinkpad, event);
     break;
   }
   default:
-    /* forward upstream */
-    res = gst_pad_push_event (emuldec->sinkpad, event);
     break;
   }
 
+  /* forward upstream */
+  res = gst_pad_push_event (emuldec->sinkpad, event);
+
   gst_object_unref (emuldec);
 
-  return 0;
+  return res;
 }
 
 static gboolean
@@ -509,18 +509,24 @@ gst_emuldec_sink_event (GstPad *pad, GstEvent *event)
 
   switch (GST_EVENT_TYPE (event)) {
   case GST_EVENT_EOS:
-       printf("GST_EVENT_EOS\n");
+    printf("GST_EVENT_EOS\n");
     gst_emuldec_drain (emuldec);
     break;
   case GST_EVENT_FLUSH_STOP:
   {
-       printf("GST_EVENT_FLUSH_STOP\n");
-
+    printf("GST_EVENT_FLUSH_STOP\n");
+#if 0
+  if (emuldec->opened) {
+    emul_avcodec_flush_buffers (emuldec->context, emuldec->dev);
+  }
+#endif
     gst_emuldec_reset_ts (emuldec);
-//    gst_emuldec_reset_qos (emuldec);
+    gst_emuldec_reset_qos (emuldec);
+#if 0
+    gst_emuldec_flush_pcache (emuldec);
+    emuldec->waiting_for_key = TRUE;
+#endif
     gst_segment_init (&emuldec->segment, GST_FORMAT_TIME);
-
-    /* clear queue */
     clear_queued (emuldec);
   }
     break;
@@ -546,7 +552,6 @@ gst_emuldec_sink_event (GstPad *pad, GstEvent *event)
 
       printf ("GST_FORMAT_BYTES\n");
       if (!bit_rate) {
-        // no_bitrate
         GST_WARNING_OBJECT (emuldec, "no bitrate to convert BYTES to TIME");
         gst_event_unref (event);
         gst_object_unref (emuldec);
@@ -575,15 +580,20 @@ gst_emuldec_sink_event (GstPad *pad, GstEvent *event)
       break;
     }
     default:
-      // invlalid format
-      break;
+      GST_WARNING_OBJECT (emuldec, "unknown format received in NEWSEGMENT");
+      gst_event_unref (event);
+      gst_object_unref (emuldec);
+      return ret;
     }
 
-#if 1 
     if (emuldec->context->codec) {
+      printf("before drain, NEWSEGMENT event\n"); 
       gst_emuldec_drain (emuldec);
     }
-#endif
+
+    GST_DEBUG_OBJECT (emuldec,
+      "NEWSEGMENT in time start %" GST_TIME_FORMAT " -- stop %"
+      GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
 
     gst_segment_set_newsegment_full (&emuldec->segment, update,
         rate, arate, format, start, stop, time);
@@ -670,14 +680,14 @@ gst_emuldec_setcaps (GstPad *pad, GstCaps *caps)
     GST_DEBUG_OBJECT (emuldec, "Using framerate from codec");
   }
 
+#if 0
   if (strcmp (oclass->codec->name, "aac") == 0) {
     const gchar *format = gst_structure_get_string (structure, "stream-format");
-#if 0
     if (format == NULL || strcmp ("format", "raw") == 0) {
       emuldec->turnoff_parser = TRUE;
     }
-#endif
   }
+#endif
 
   if (!gst_emuldec_open (emuldec)) {
     GST_DEBUG_OBJECT (emuldec, "Failed to open");
@@ -707,41 +717,6 @@ gst_emuldec_setcaps (GstPad *pad, GstCaps *caps)
   return ret;
 }
 
-static GStaticMutex gst_avcodec_mutex = G_STATIC_MUTEX_INIT;
-
-int
-gst_emul_avcodec_open (CodecContext *ctx, CodecElement *codec, CodecDevice *dev)
-{
-  int ret;
-
-  g_static_mutex_lock (&gst_avcodec_mutex);
-
-  if (gst_emul_codec_device_open (dev) < 0) {
-    printf("failed to open device.\n");
-    return -1;
-  }
-  ret = emul_avcodec_init (ctx, codec, dev);
-  g_static_mutex_unlock (&gst_avcodec_mutex);
-
-  return ret;
-}
-
-int
-gst_emul_avcodec_close (CodecContext *ctx, CodecDevice *dev)
-{
-  int ret;
-
-  g_static_mutex_lock (&gst_avcodec_mutex);
-
-  printf ("gst_emul_avcodec_close\n");
-  ret = emul_avcodec_deinit (ctx, dev);
-
-  gst_emul_codec_device_close (dev);
-  g_static_mutex_unlock (&gst_avcodec_mutex);
-
-  return ret;
-}
-
 static gboolean
 gst_emuldec_open (GstEmulDec *emuldec)
 {
@@ -758,11 +733,10 @@ gst_emuldec_open (GstEmulDec *emuldec)
   case AVMEDIA_TYPE_VIDEO:
     width = emuldec->context->video.width;
     height = emuldec->context->video.height;
-    buf_size = gst_emul_avpicture_size (0, width, height);
+    buf_size = gst_emul_avpicture_size (0, width, height) + 100;
     break;
   case AVMEDIA_TYPE_AUDIO:
-//    buf_size = FF_MAX_AUDIO_FRAME_SIZE;
-    buf_size = 1024 * 256; // 256K
+    buf_size = FF_MAX_AUDIO_FRAME_SIZE + 100;
     break;
   default:
     buf_size = -1;
@@ -773,7 +747,7 @@ gst_emuldec_open (GstEmulDec *emuldec)
     return FALSE;
   }
 
-  emuldec->dev->buf_size = buf_size;
+  emuldec->dev->buf_size = gst_emul_align_size(buf_size);
 
   if (gst_emul_avcodec_open (emuldec->context, oclass->codec, emuldec->dev) < 0) {
     gst_emuldec_close (emuldec);
@@ -819,8 +793,19 @@ gst_emuldec_close (GstEmulDec *emuldec)
   int ret;
 
   printf ("gst_emuldec_close\n");
+
+  if (emuldec->context->codecdata) {
+    g_free(emuldec->context->codecdata);
+    emuldec->context->codecdata = NULL;
+  } 
+
   gst_emul_avcodec_close (emuldec->context, emuldec->dev);
 
+  if (emuldec->dev) {
+    g_free(emuldec->dev);
+    emuldec->dev = NULL;
+  }
+
   return TRUE;
 }
 
@@ -870,8 +855,6 @@ gst_emuldec_negotiate (GstEmulDec *emuldec, gboolean force)
     break;
   }
 
-
-
   caps =
     gst_emul_codectype_to_caps (oclass->codec->media_type, emuldec->context,
       oclass->codec->name, FALSE);
@@ -916,6 +899,7 @@ gst_emuldec_negotiate (GstEmulDec *emuldec, gboolean force)
   }
     break;
   case AVMEDIA_TYPE_AUDIO:
+    break;
   default:
     break;
   }
@@ -949,6 +933,57 @@ new_aligned_buffer (gint size, GstCaps *caps)
   return buf;
 }
 
+static GstFlowReturn
+get_output_buffer (GstEmulDec *emuldec, GstBuffer **outbuf)
+{
+  gint pict_size;
+  GstFlowReturn ret;
+
+  ret = GST_FLOW_OK;
+
+  *outbuf = NULL;
+
+  if (G_UNLIKELY (!gst_emuldec_negotiate (emuldec, FALSE))) {
+    GST_DEBUG_OBJECT (emuldec, "negotiate failed");
+    return GST_FLOW_NOT_NEGOTIATED;
+  }
+
+  pict_size = gst_emul_avpicture_size (emuldec->context->video.pix_fmt,
+    emuldec->context->video.width, emuldec->context->video.height);
+
+  ret = gst_pad_alloc_buffer_and_set_caps (emuldec->srcpad,
+    GST_BUFFER_OFFSET_NONE, pict_size,
+    GST_PAD_CAPS (emuldec->srcpad), outbuf);
+  if (G_UNLIKELY (ret != GST_FLOW_OK)) {
+    GST_DEBUG_OBJECT (emuldec, "pad_alloc failed %d (%s)", ret,
+      gst_flow_get_name (ret));
+    return ret;
+  }
+
+  if ((uintptr_t) GST_BUFFER_DATA (*outbuf) % 16) {
+    GST_DEBUG_OBJECT (emuldec,
+      "Downstream can't allocate aligned buffers.");
+    gst_buffer_unref (*outbuf);
+    *outbuf = new_aligned_buffer (pict_size, GST_PAD_CAPS (emuldec->srcpad)); 
+  }
+
+  gst_buffer_set_caps (*outbuf, GST_PAD_CAPS (emuldec->srcpad));
+
+  emul_av_picture_copy (emuldec->context, GST_BUFFER_DATA (*outbuf),
+    GST_BUFFER_SIZE (*outbuf), emuldec->dev);
+
+  return ret;
+}
+
+static gboolean
+clip_video_buffer (GstEmulDec *dec, GstBuffer *buf,
+    GstClockTime in_ts, GstClockTime in_dur)
+{
+  gboolean res = TRUE;
+
+  return res;
+}
+
 static gboolean
 clip_audio_buffer (GstEmulDec *dec, GstBuffer *buf,
     GstClockTime in_ts, GstClockTime in_dur)
@@ -981,20 +1016,21 @@ clip_audio_buffer (GstEmulDec *dec, GstBuffer *buf,
 
   if (G_UNLIKELY ((diff = cstart - in_ts) > 0)) {
     diff =
-      gst_util_uint64_scale_int (diff, dec->format.audio.samplerate,
-      GST_SECOND * (dec->format.audio.depth * dec->format.audio.channels));
+      gst_util_uint64_scale_int (diff, dec->format.audio.samplerate, GST_SECOND) *
+        (dec->format.audio.depth * dec->format.audio.channels);
 
     GST_DEBUG_OBJECT (dec, "clipping start to %" GST_TIME_FORMAT " %"
         G_GINT64_FORMAT " bytes", GST_TIME_ARGS (cstart), diff);
 
     GST_BUFFER_SIZE (buf) -= diff;
     GST_BUFFER_DATA (buf) += diff;
+
   }
 
   if (G_UNLIKELY ((diff = stop - cstop) > 0)) {
     diff =
-      gst_util_uint64_scale_int (diff, dec->format.audio.samplerate,
-      GST_SECOND * (dec->format.audio.depth * dec->format.audio.channels));
+      gst_util_uint64_scale_int (diff, dec->format.audio.samplerate, GST_SECOND) *
+        (dec->format.audio.depth * dec->format.audio.channels);
 
     GST_DEBUG_OBJECT (dec, "clipping stop to %" GST_TIME_FORMAT " %"
         G_GINT64_FORMAT " bytes", GST_TIME_ARGS (cstop), diff);
@@ -1011,19 +1047,161 @@ clip_audio_buffer (GstEmulDec *dec, GstBuffer *buf,
 
 static gint
 gst_emuldec_video_frame (GstEmulDec *emuldec, guint8 *data, guint size,
-               const GstTSInfo *dec_info, GstBuffer **outbuf,
-               GstFlowReturn *ret)
+    const GstTSInfo *dec_info, GstBuffer **outbuf,
+    GstFlowReturn *ret)
 {
-  gint len = -1;
-  GstClockTime out_timestamp, out_duration;
+  gint len = -1, have_data;
+  gboolean mode_switch;
+  gboolean decode;
+  GstClockTime out_timestamp, out_duration, out_pts;
   gint64 out_offset;
+  GstTSInfo *out_info;
 
-#if 0
+  decode = gst_emuldec_do_qos (emuldec, dec_info->timestamp, &mode_switch);
+
+//  printf("decode video: input buffer size: %d\n", size);
   len =
     emul_avcodec_decode_video (emuldec->context, data, size,
-               (int16_t *) GST_BUFFER_DATA (*outbuf), &have_data, emuldec->dev);
+         outbuf, &have_data, emuldec->dev);
+
+  if (!decode) {
+    // skip_frame
+  }
+
+  GST_DEBUG_OBJECT (emuldec, "after decode: len %d, have_data %d",
+    len, have_data);
+
+#if 0
+  if (len < 0 && (mode_switch || emuldec->context->skip_frame)) {
+    len = 0;
+  }
+
+  if (len > 0 && have_data <= 0 && (mode_switch
+      || emuldec->context->skip_frame)) {
+    emuldec->last_out = -1;
+  }
+#endif
+
+  if (len < 0 || have_data <= 0) {
+    GST_DEBUG_OBJECT (emuldec, "return flow %d, out %p, len %d",
+      *ret, *outbuf, len);
+    return len;
+  }
+
+#if 1 
+//  out_info = gst_ts_info_get (emuldec, emuldec->picture->reordered_opaque);
+  out_info = gst_ts_info_get (emuldec, dec_info->idx);  
+  out_pts = out_info->timestamp;
+  out_duration = out_info->duration;
+  out_offset = out_info->offset;
 #endif
 
+  *ret = get_output_buffer (emuldec, outbuf);
+  if (G_UNLIKELY (*ret != GST_FLOW_OK)) {
+    GST_DEBUG_OBJECT (emuldec, "no output buffer");
+    len = -1;
+    GST_DEBUG_OBJECT (emuldec, "return flow %d, out %p, len %d",
+      *ret, *outbuf, len);
+    return len;
+  }
+
+  /* Timestamps */
+  out_timestamp = -1;
+  if (out_pts != -1) {
+    out_timestamp = (GstClockTime) out_pts;
+    GST_LOG_OBJECT (emuldec, "using timestamp %" GST_TIME_FORMAT
+      " returned by ffmpeg", GST_TIME_ARGS (out_timestamp));
+  }
+
+  if (!GST_CLOCK_TIME_IS_VALID (out_timestamp) && emuldec->next_out != -1) {
+    out_timestamp = emuldec->next_out;
+    GST_LOG_OBJECT (emuldec, "using next timestamp %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (out_timestamp));
+  }
+
+  if (!GST_CLOCK_TIME_IS_VALID (out_timestamp)) {
+    out_timestamp = dec_info->timestamp;
+    GST_LOG_OBJECT (emuldec, "using in timestamp %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (out_timestamp));
+  }
+  GST_BUFFER_TIMESTAMP (*outbuf) = out_timestamp;
+
+  /* Offset */
+  if (out_offset != GST_BUFFER_OFFSET_NONE) {
+    GST_LOG_OBJECT (emuldec, "Using offset returned by ffmpeg");
+  } else if (out_timestamp != GST_CLOCK_TIME_NONE) {
+    GstFormat out_fmt = GST_FORMAT_DEFAULT;
+    GST_LOG_OBJECT (emuldec, "Using offset converted from timestamp");
+
+    gst_pad_query_peer_convert (emuldec->sinkpad,
+      GST_FORMAT_TIME, out_timestamp, &out_fmt, &out_offset);
+  } else if (dec_info->offset != GST_BUFFER_OFFSET_NONE) {
+    GST_LOG_OBJECT (emuldec, "using in_offset %" G_GINT64_FORMAT,
+      dec_info->offset);
+    out_offset = dec_info->offset;
+  } else {
+    GST_LOG_OBJECT (emuldec, "no valid offset found");
+    out_offset = GST_BUFFER_OFFSET_NONE;
+  }
+  GST_BUFFER_OFFSET (*outbuf) = out_offset;
+
+  /* Duration */
+  if (GST_CLOCK_TIME_IS_VALID (out_duration)) {
+    GST_LOG_OBJECT (emuldec, "Using duration returned by ffmpeg");
+  } else if (GST_CLOCK_TIME_IS_VALID (dec_info->duration)) {
+    GST_LOG_OBJECT (emuldec, "Using in_duration");
+    out_duration = dec_info->duration;
+#if 0
+  } else if (GST_CLOCK_TIME_IS_VALID (emuldec->last_diff)) {
+    GST_LOG_OBJECT (emuldec, "Using last-diff");
+    out_duration = emuldec->last_diff;
+#endif
+  } else {
+    if (emuldec->format.video.fps_n != -1 &&
+        (emuldec->format.video.fps_n != 1000 &&
+        emuldec->format.video.fps_d != 1)) {
+      GST_LOG_OBJECT (emuldec, "using input framerate for duration");
+      out_duration = gst_util_uint64_scale_int (GST_SECOND,
+        emuldec->format.video.fps_d, emuldec->format.video.fps_n);
+    } else {
+      if (emuldec->context->video.fps_n != 0 &&
+          (emuldec->context->video.fps_d > 0 &&
+            emuldec->context->video.fps_d < 1000)) {
+        GST_LOG_OBJECT (emuldec, "using decoder's framerate for duration");
+        out_duration = gst_util_uint64_scale_int (GST_SECOND,
+          emuldec->context->video.fps_n * 1,
+          emuldec->context->video.fps_d);
+      } else {
+        GST_LOG_OBJECT (emuldec, "no valid duration found");
+      }
+    }
+  }
+
+#if 0
+  if (GST_CLOCK_TIME_IS_VALID (out_duration)) {
+    out_duration += out_duration * emuldec->picture->repeat_pict / 2;
+  }
+  GST_BUFFER_DURATION (*outbuf) = out_duration;
+
+  if (out_timestamp != -1 && out_duration != -1 && out_duration != 0) {
+    emuldec->next_out = out_timestamp + out_duration;
+  } else {
+    emuldec->next_out = -1;
+  }
+#endif
+
+  if (G_UNLIKELY (!clip_video_buffer (emuldec, *outbuf, out_timestamp,
+      out_duration))) {
+    GST_DEBUG_OBJECT (emuldec, "buffer clipped");
+    gst_buffer_unref (*outbuf);
+    *outbuf = NULL;
+    GST_DEBUG_OBJECT (emuldec, "return flow %d, out %p, len %d",
+      *ret, *outbuf, len);
+    return len;
+  }
+
+  GST_DEBUG_OBJECT (emuldec, "return flow %d, out %p, len %d",
+    *ret, *outbuf, len);
   return len;
 }
 
@@ -1042,6 +1220,8 @@ gst_emuldec_audio_frame (GstEmulDec *emuldec, CodecElement *codec,
       new_aligned_buffer (FF_MAX_AUDIO_FRAME_SIZE,
           GST_PAD_CAPS (emuldec->srcpad));
 
+//  printf("decode audio[%p] input buffer size: %d\n", emuldec, size);
+
   len = emul_avcodec_decode_audio (emuldec->context,
       (int16_t *) GST_BUFFER_DATA (*outbuf), &have_data,
       data, size, emuldec->dev);
@@ -1068,6 +1248,7 @@ gst_emuldec_audio_frame (GstEmulDec *emuldec, CodecElement *codec,
       out_timestamp = emuldec->next_out;
     }
 
+    /* calculate based on number of samples */
     out_duration = gst_util_uint64_scale (have_data, GST_SECOND,
         emuldec->format.audio.depth * emuldec->format.audio.channels *
         emuldec->format.audio.samplerate);
@@ -1103,7 +1284,7 @@ gst_emuldec_audio_frame (GstEmulDec *emuldec, CodecElement *codec,
 
   if (len == -1 && !strcmp(codec->name, "aac")) {
     GST_ELEMENT_ERROR (emuldec, STREAM, DECODE, (NULL),
-        ("Decoding of AAC stream by gst-emul-codec failed."));
+        ("Decoding of AAC stream by FFMPEG failed."));
     *ret = GST_FLOW_ERROR;
   }
 
@@ -1114,30 +1295,28 @@ gst_emuldec_audio_frame (GstEmulDec *emuldec, CodecElement *codec,
 
 static gint
 gst_emuldec_frame (GstEmulDec *emuldec, guint8 *data, guint size,
-               gint *got_data, const GstTSInfo *dec_info, GstFlowReturn *ret)
+    gint *got_data, const GstTSInfo *dec_info, GstFlowReturn *ret)
 {
   GstEmulDecClass *oclass;
   GstBuffer *outbuf = NULL;
   gint have_data = 0, len = 0;
 
   if (G_UNLIKELY (emuldec->context->codec == NULL)) {
-    // no_codec
     GST_ERROR_OBJECT (emuldec, "no codec context");
     return -1;
   }
 
   *ret = GST_FLOW_OK;
-
   oclass = (GstEmulDecClass *) (G_OBJECT_GET_CLASS (emuldec));
 
   switch (oclass->codec->media_type) {
   case AVMEDIA_TYPE_VIDEO:
     len = gst_emuldec_video_frame (emuldec, data, size,
-               dec_info, &outbuf, ret);
+        dec_info, &outbuf, ret);
     break;
   case AVMEDIA_TYPE_AUDIO:
     len = gst_emuldec_audio_frame (emuldec, oclass->codec, data, size,
-               dec_info, &outbuf, ret);
+        dec_info, &outbuf, ret);
     if (outbuf == NULL && emuldec->discont) {
       GST_DEBUG_OBJECT (emuldec, "no buffer but keeping timestamp");
 //      emuldec->clear_ts = FALSE;
@@ -1155,8 +1334,8 @@ gst_emuldec_frame (GstEmulDec *emuldec, guint8 *data, guint size,
 
   if (len < 0 || have_data < 0) {
     GST_WARNING_OBJECT (emuldec,
-               "tzdec_%s: decoding error (len: %d, have_data: %d)",
-               oclass->codec->name, len, have_data);
+        "tzdec_%s: decoding error (len: %d, have_data: %d)",
+        oclass->codec->name, len, have_data);
     *got_data = 0;
     return len;
   } else if (len == 0 && have_data == 0) {
@@ -1189,6 +1368,7 @@ gst_emuldec_frame (GstEmulDec *emuldec, guint8 *data, guint size,
     } else {
       // push reverse
       printf("push reverse.\n");
+      GST_DEBUG_OBJECT (emuldec, "queued frame"); 
       emuldec->queued = g_list_prepend (emuldec->queued, outbuf);
       *ret = GST_FLOW_OK;
     }
@@ -1205,7 +1385,7 @@ gst_emuldec_chain (GstPad *pad, GstBuffer *buffer)
   GstEmulDec *emuldec;
   GstEmulDecClass *oclass;
   guint8 *in_buf;
-  guint in_size, len, have_data;
+  gint in_size, len, have_data;
   GstFlowReturn ret = GST_FLOW_OK;
   GstClockTime in_timestamp;
   GstClockTime in_duration;
@@ -1222,7 +1402,7 @@ gst_emuldec_chain (GstPad *pad, GstBuffer *buffer)
     oclass = (GstEmulDecClass *) (G_OBJECT_GET_CLASS (emuldec));
     GST_ELEMENT_ERROR (emuldec, CORE, NEGOTIATION, (NULL),
       ("tzdec_%s: input format was not set before data start",
-               oclass->codec->name));
+        oclass->codec->name));
     gst_buffer_unref (buffer);
     return GST_FLOW_NOT_NEGOTIATED;
   }
@@ -1233,11 +1413,9 @@ gst_emuldec_chain (GstPad *pad, GstBuffer *buffer)
 // FIXME
   if (G_UNLIKELY (discont)) {
     GST_DEBUG_OBJECT (emuldec, "received DISCONT");
-    printf("discont 1\n");
     gst_emuldec_drain (emuldec);
-    printf("discont 2\n");
 //    gst_emuldec_flush_pcache (emuldec);
-    // flush buffers
+//    emul_avcodec_flush buffers (emuldec->context, emuldec->dev);
     emuldec->discont = TRUE;
     gst_emuldec_reset_ts (emuldec);
   }
@@ -1254,9 +1432,9 @@ gst_emuldec_chain (GstPad *pad, GstBuffer *buffer)
   }
 
   if (emuldec->pcache) {
-         GST_LOG_OBJECT (emuldec, "join parse cache");
-         buffer = gst_buffer_join (emuldec->pcache, buffer);
-         emuldec->pcache = NULL;
+    GST_LOG_OBJECT (emuldec, "join parse cache");
+    buffer = gst_buffer_join (emuldec->pcache, buffer);
+    emuldec->pcache = NULL;
   }
 #endif
 
@@ -1281,7 +1459,7 @@ gst_emuldec_chain (GstPad *pad, GstBuffer *buffer)
         }
 
         GST_LOG_OBJECT (emuldec, "estimated duration %" GST_TIME_FORMAT " %u",
-                 GST_TIME_ARGS (diff), emuldec->last_frames);
+          GST_TIME_ARGS (diff), emuldec->last_frames);
 
         emuldec->last_diff = diff;
       }
@@ -1291,13 +1469,30 @@ gst_emuldec_chain (GstPad *pad, GstBuffer *buffer)
   }
 #endif
 
+  GST_LOG_OBJECT (emuldec,
+    "Received new data of size %u, offset: %" G_GUINT64_FORMAT ", ts:%"
+    GST_TIME_FORMAT ", dur: %" GST_TIME_FORMAT ", info %d",
+    GST_BUFFER_SIZE (buffer), GST_BUFFER_OFFSET (buffer),
+    GST_TIME_ARGS (in_timestamp), GST_TIME_ARGS (in_duration), in_info->idx);
+
   in_buf = GST_BUFFER_DATA (buffer);
   in_size = GST_BUFFER_SIZE (buffer);
 
   dec_info = in_info;
 
   len =
-               gst_emuldec_frame (emuldec, in_buf, in_size, &have_data, dec_info, &ret);
+    gst_emuldec_frame (emuldec, in_buf, in_size, &have_data, dec_info, &ret);
+
+#if 0
+  if (emuldec->clear_ts) {
+    in_timestamp = GST_CLOCK_TIME_NONE;
+    in_duration = GST_CLOCK_TIME_NONE;
+    in_offset = GST_BUFFER_OFFSET_NONE;
+    in_info = GST_TS_INFO_NONE;
+  } else {
+    emuldec->clear_ts = TRUE;
+  }
+#endif
 
   gst_buffer_unref (buffer);
 
@@ -1322,6 +1517,7 @@ gst_emuldec_change_state (GstElement *element, GstStateChange transition)
     clear_queued (emuldec);
     break;
   default:
+    printf("tzdec: %p, state change: %d\n", emuldec, transition);
     break;
   }
 
@@ -1378,4 +1574,3 @@ gst_emuldec_register (GstPlugin *plugin, GList *element)
 
   return ret;
 }
-
index b6e713a..fac06b7 100644 (file)
  *
  */
 
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <gst/gst.h>
-#include "gstemulcommon.h"
-
-#define GST_EMULENC_PARAMS_QDATA g_quark_from_static_string("emulenc-params"); 
+#include "gstemulutils.h"
+#include "gstemulapi.h"
+#include <gst/base/gstadapter.h>
+
+#define GST_EMULENC_PARAMS_QDATA g_quark_from_static_string("emulenc-params")
 
 typedef struct _GstEmulEnc
 {
@@ -47,13 +41,19 @@ typedef struct _GstEmulEnc
   GstPad *srcpad;
   GstPad *sinkpad;
 
+  CodecContext *context;
+  CodecDevice *dev;
+
   union {
     struct {
-      gint width;
-      gint height;
-      gint framerate_num;
-      gint framerate_den;
-      gint pix_fmt;   
+      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;
@@ -62,21 +62,26 @@ typedef struct _GstEmulEnc
     } audio;
   } format;
 
+  // cache
+  gulong buffer_size;
+
+  gboolean discont;
+
+  GstClockTime adapter_ts;
   GstAdapter *adapter;
 
-  // TODO: needs a certain container such as AVCodecContext.
-  guint extradata_size;
-  guint8 *extradata;
+  guint8 *working_buf;
+  gulong working_buf_size;
 
-  CodecDev codecbuf;
 } GstEmulEnc;
 
 typedef struct _GstEmulEncClass
 {
   GstElementClass parent_class;
 
-  CodecInfo *codecinfo;
-  GstPadTemplate *sinktempl, *srctempl;
+  CodecElement *codec;
+  GstPadTemplate *sinktempl;
+  GstPadTemplate *srctempl;
   GstCaps *sinkcaps;
 } GstEmulEncClass;
 
@@ -88,7 +93,10 @@ static void gst_emulenc_init (GstEmulEnc *emulenc);
 static void gst_emulenc_finalize (GObject *object);
 
 static gboolean gst_emulenc_setcaps (GstPad *pad, GstCaps *caps);
-static gboolean gst_emulenc_getcaps (GstPad *pad);
+static GstCaps *gst_emulenc_getcaps (GstPad *pad);
+
+static GstCaps *gst_emulenc_get_possible_sizes (GstEmulEnc *emulenc,
+  GstPad *pad, const GstCaps *caps);
 
 static GstFlowReturn gst_emulenc_chain_video (GstPad *pad, GstBuffer *buffer);
 static GstFlowReturn gst_emulenc_chain_audio (GstPad *pad, GstBuffer *buffer);
@@ -96,17 +104,7 @@ static GstFlowReturn gst_emulenc_chain_audio (GstPad *pad, GstBuffer *buffer);
 static gboolean gst_emulenc_event_video (GstPad *pad, GstEvent *event);
 static gboolean gst_emulenc_event_src (GstPad *pad, GstEvent *event);
 
-static GstStateChangeReturn gst_emulenc_change_state (GstElement *element, GstStateChange transition);
-
-int gst_emul_codec_init (GstEmulEnc *emulenc);
-void gst_emul_codec_deinit (GstEmulEnc *emulenc);
-
-#if 0
-int gst_emul_codec_encode_video (GstEmulEnc *emulenc, guint8 *in_buf, guint in_size,
-        GstBuffer **out_buf, GstClockTime in_timestamp);
-int gst_emul_codec_encode_audio (GstEmulEnc *emulenc, guint8 *in_buf, guint in_size,
-        GstBuffer **out_buf, GstClockTime in_timestamp);
-#endif
+GstStateChangeReturn gst_emulenc_change_state (GstElement *element, GstStateChange transition);
 
 /*
  * Implementation
@@ -117,38 +115,38 @@ gst_emulenc_base_init (GstEmulEncClass *klass)
     GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
     GstPadTemplate *sinktempl = NULL, *srctempl = NULL;
     GstCaps *sinkcaps = NULL, *srccaps = NULL;
-    CodecInfo *info;
+    CodecElement *codec;
     gchar *longname, *classification;
 
-    info =
-        (CodecInfo *)g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
+    codec =
+        (CodecElement *)g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
          GST_EMULENC_PARAMS_QDATA);
 
-    longname = g_strdup_printf ("%s Encoder", info->codec_longname);
-
+    longname = g_strdup_printf ("%s Encoder", codec->longname);
     classification = g_strdup_printf ("Codec/Encoder/%s",
-            (info->media_type == AVMEDIA_TYPE_VIDEO) ? "Video" : "Audio");
+            (codec->media_type == AVMEDIA_TYPE_VIDEO) ? "Video" : "Audio");
 
     gst_element_class_set_details_simple (element_class,
             longname,
             classification,
             "accelerated codec for Tizen Emulator",
             "Kitae Kim <kt920.kim@samsung.com>");
+
     g_free (longname);
     g_free (classification);
 
 
-  if (!(srccaps = gst_emul_codecname_to_caps (info, TRUE))) {
-    GST_DEBUG ("Couldn't get source caps for encoder '%s'", info->codec_name);
+  if (!(srccaps = gst_emul_codecname_to_caps (codec->name, NULL, TRUE))) {
+    GST_DEBUG ("Couldn't get source caps for encoder '%s'", codec->name);
     srccaps = gst_caps_new_simple ("unknown/unknown", NULL);
   }
 
-  switch (info->media_type) {
+  switch (codec->media_type) {
   case AVMEDIA_TYPE_VIDEO:
     sinkcaps = gst_caps_from_string ("video/x-raw-rgb; video/x-raw-yuv; video/x-raw-gray");
     break;
   case AVMEDIA_TYPE_AUDIO:
-    srccaps = gst_emul_codectype_to_audio_caps (info, TRUE);
+    srccaps = gst_emul_codectype_to_audio_caps (NULL, codec->name, TRUE, codec);
     break;
   default:
     GST_LOG("unknown media type.\n");
@@ -156,7 +154,7 @@ gst_emulenc_base_init (GstEmulEncClass *klass)
   }
 
   if (!sinkcaps) {
-      GST_DEBUG ("Couldn't get sink caps for encoder '%s'", info->codec_name);
+      GST_DEBUG ("Couldn't get sink caps for encoder '%s'", codec->name);
       sinkcaps = gst_caps_new_simple ("unknown/unknown", NULL);
   }
 
@@ -168,12 +166,13 @@ gst_emulenc_base_init (GstEmulEncClass *klass)
   gst_element_class_add_pad_template (element_class, srctempl);
   gst_element_class_add_pad_template (element_class, sinktempl);
 
+  klass->codec = codec;
   klass->sinktempl = sinktempl;
   klass->srctempl = srctempl;
   klass->sinkcaps = NULL;
 }
 
-    static void
+static void
 gst_emulenc_class_init (GstEmulEncClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
@@ -187,11 +186,14 @@ gst_emulenc_class_init (GstEmulEncClass *klass)
 #endif
 
   gobject_class->finalize = gst_emulenc_finalize;
-
   gstelement_class->change_state = gst_emulenc_change_state; 
 }
 
-    static void
+
+#define DEFAULT_VIDEO_BITRATE 300000
+#define DEFAULT_AUDIO_BITRATE 128000
+
+static void
 gst_emulenc_init (GstEmulEnc *emulenc)
 {
   GstEmulEncClass *oclass;
@@ -199,29 +201,41 @@ gst_emulenc_init (GstEmulEnc *emulenc)
 
   emulenc->sinkpad = gst_pad_new_from_template (oclass->sinktempl, "sink");
   gst_pad_set_setcaps_function (emulenc->sinkpad,
-                                GST_DEBUG_FUNCPTR(gst_emulenc_setcaps));
+    GST_DEBUG_FUNCPTR(gst_emulenc_setcaps));
   gst_pad_set_getcaps_function (emulenc->sinkpad,
-                                GST_DEBUG_FUNCPTR(gst_emulenc_getcaps));
+    GST_DEBUG_FUNCPTR(gst_emulenc_getcaps));
 
   emulenc->srcpad = gst_pad_new_from_template (oclass->srctempl, "src");
   gst_pad_use_fixed_caps (emulenc->srcpad);
 
-  switch (oclass->codecinfo->media_type) {
+  switch (oclass->codec->media_type) {
   case AVMEDIA_TYPE_VIDEO:
     gst_pad_set_chain_function (emulenc->sinkpad, gst_emulenc_chain_video);
     gst_pad_set_event_function (emulenc->sinkpad, gst_emulenc_event_video);
-    gst_pad_set_event_function (emulenc->srckpad, gst_emulenc_event_src);
-
+    gst_pad_set_event_function (emulenc->srcpad, gst_emulenc_event_src);
+//    emulenc->bitrate = DEFAULT_VIDEO_BITRATE;
     break;
   case AVMEDIA_TYPE_AUDIO:
-    gst_pad_set_chain_function (emuldec->sinkpad, gst_emulenc_chain_audio);    
+    gst_pad_set_chain_function (emulenc->sinkpad, gst_emulenc_chain_audio);
+//    emulenc->bitrate = DEFAULT_AUDIO_BITRATE;
     break;
   default:
     break;
   }
 
-  gst_element_add_pad (GST_ELEMENT (emulenc), emuldenc->sinkpad);
-  gst_element_add_pad (GST_ELEMENT (emulenc), emuldenc->srcpad);
+  gst_element_add_pad (GST_ELEMENT (emulenc), emulenc->sinkpad);
+  gst_element_add_pad (GST_ELEMENT (emulenc), emulenc->srcpad);
+
+  // init
+  emulenc->context = g_malloc0 (sizeof(CodecContext));
+  if (!emulenc->context) {
+    printf("failed to allocate memory.\n");
+  }
+
+  emulenc->dev = g_malloc0 (sizeof(CodecDevice));
+  if (!emulenc->dev) {
+    printf("failed to allocate memory.\n");
+  }
 
   // need to know what adapter does.
   emulenc->adapter = gst_adapter_new ();
@@ -233,130 +247,286 @@ gst_emulenc_finalize (GObject *object)
     // Deinit Decoder
     GstEmulEnc *emulenc = (GstEmulEnc *) object;
 
+    if (emulenc->context) {
+      g_free (emulenc->context);
+      emulenc->context = NULL;
+    }
+    g_object_unref (emulenc->adapter);
+
     G_OBJECT_CLASS (parent_class)->finalize (object);
+
+
 }
 
-    static gboolean
-gst_emulenc_src_event (GstPad *pad, GstEvent *event)
+static GstCaps *
+gst_emulenc_get_possible_sizes (GstEmulEnc *emulenc, GstPad *pad,
+  const GstCaps *caps)
 {
-    return 0;
+  GstCaps *othercaps = NULL;
+  GstCaps *tmpcaps = NULL;
+  GstCaps *intersect = NULL;
+  guint i;
+
+  othercaps = gst_pad_peer_get_caps (emulenc->srcpad);
+
+  if (!othercaps) {
+    return gst_caps_copy (caps);
+  }
+
+  intersect = gst_caps_intersect (othercaps,
+    gst_pad_get_pad_template_caps (emulenc->srcpad));
+  gst_caps_unref (othercaps);
+
+  if (gst_caps_is_empty (intersect)) {
+    return intersect;
+  }
+
+  if (gst_caps_is_any (intersect)) {
+    return gst_caps_copy (caps);
+  }
+
+  tmpcaps = gst_caps_new_empty ();
+
+  for (i = 0; i <gst_caps_get_size (intersect); i++) {
+    GstStructure *s = gst_caps_get_structure (intersect, i);
+    const GValue *height = NULL;
+    const GValue *width = NULL;
+    const GValue *framerate = NULL;
+    GstStructure *tmps;
+
+    height = gst_structure_get_value (s, "height");
+    width = gst_structure_get_value (s, "width");
+    framerate = gst_structure_get_value (s, "framerate");
+
+    tmps = gst_structure_new ("video/x-rwa-rgb", NULL);
+    if (width) {
+      gst_structure_set_value (tmps, "width", width);
+    }
+    if (height) {
+      gst_structure_set_value (tmps, "height", height);
+    }
+    if (framerate) {
+      gst_structure_set_value (tmps, "framerate", framerate);
+    }
+    gst_caps_merge_structure (tmpcaps, gst_structure_copy (tmps));
+
+    gst_structure_set_name (tmps, "video/x-raw-yuv");
+    gst_caps_merge_structure (tmpcaps, gst_structure_copy (tmps));
+
+    gst_structure_set_name (tmps, "video/x-raw-gray");
+    gst_caps_merge_structure (tmpcaps, tmps);
+  }
+  gst_caps_unref (intersect);
+
+  intersect = gst_caps_intersect (caps, tmpcaps);
+  gst_caps_unref (tmpcaps);
+
+  return intersect;
 }
 
-    static void
-gst_emulenc_get_caps (GstEmulEnc *emulenc, GstCaps *caps)
+static GstCaps *
+gst_emulenc_getcaps (GstPad *pad)
 {
-    GstStructure *structure;
-
-    int width, height, bits_per_coded_sample;
-    const GValue *fps;
-    //    const GValue *par;
-    //    guint extradata_size;
-    //    guint8 *extradata;
+  GstEmulEnc *emulenc = (GstEmulEnc *) GST_PAD_PARENT (pad);
+  GstEmulEncClass *oclass =
+    (GstEmulEncClass *) G_OBJECT_GET_CLASS (emulenc);
+  CodecContext *ctx = NULL;
+  enum PixelFormat pixfmt;
+  GstCaps *caps = NULL;
+  GstCaps *finalcaps = NULL;
+  gint i;
+
+  GST_DEBUG_OBJECT (emulenc, "getting caps");
+
+  if (oclass->codec->media_type == AVMEDIA_TYPE_AUDIO) {
+    caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+  
+    GST_DEBUG_OBJECT (emulenc, "audio caps, return template %" GST_PTR_FORMAT,
+      caps);
+    return caps;
+  }
 
-    /* FFmpeg Specific Values */
-    const GstBuffer *buf;
-    const GValue *value;
+  // cached
+  if (oclass->sinkcaps) {
+    caps = gst_emulenc_get_possible_sizes (emulenc, pad, oclass->sinkcaps);
+    GST_DEBUG_OBJECT (emulenc, "return cached caps %" GST_PTR_FORMAT, caps);
+    return caps;
+  }
 
-    structure = gst_caps_get_structure (caps, 0);
+  GST_DEBUG_OBJECT (emulenc, "probing caps");
+  i = pixfmt = 0;
 
-    value = gst_structure_get_value (structure, "codec_data");
-    if (value) {
-        buf = GST_BUFFER_CAST (gst_value_get_mini_object (value));
-        emulenc->extradata_size = GST_BUFFER_SIZE (buf);
-        emulenc->extradata = GST_BUFFER_DATA (buf);
-    } else {
-        CODEC_LOG (2, "no codec data\n");
-        emulenc->extradata_size = 0;
-        emulenc->extradata = NULL;
+#if 0
+  for (pixfmt = 0; ; pixfmt++) {
+    GstCaps *tmpcaps;
+
+    if (oclass->codec->pix_fmts) {
+      if ((pixfmt = oclass->codec->pix_fmts[i++]) == PIX_FMT_NONE) {
+        GST_DEBUG_OBJECT (emulenc,
+          "At the end of official pixfmt for this codec, breaking out");
+        break;
+      }
+      GST_DEBUG_OBJECT (emulenc,
+        "Got an official pixfmt [%d], attempting to get caps", pixfmt);
+      tmpcaps = get_emul_pixfmt_to_caps (pixfmt, NULL, oclass->codec->name);
+      if (tmpcaps) {
+        GST_DEBUG_OBJECT (emulenc, "Got caps, breaking out");
+        if (!caps) {
+          caps = gst_caps_new_empty ();
+        }
+        gst_caps_append (caps, tmpcaps);
+        continue;
+      }
+      GST_DEBUG_OBJECT (emulenc,
+        "Couldn't figure out caps without context, trying again with a context");
     }
 
-#if 1 /* video type */
-    /* Common Properites, width, height and etc. */
-    gst_structure_get_int (structure, "width", &width);
-    gst_structure_get_int (structure, "height", &height);
-    gst_structure_get_int (structure, "bpp", &bits_per_coded_sample);
+    GST_DEBUG_OBJECT (emulenc, "pixfmt: %d", pixfmt);
+    if (pixfmt >= PIX_FMT_NB) {
+      GST_WARING ("Invalid pixfmt, breaking out");
+      break;
+    }
 
-    emulenc->format.video.width = width;
-    emulenc->format.video.height = height;
+    ctx = g_malloc0 (sizeof(CodecContext));
+    if (!ctx) {
+      GST_DEBUG_OBJECT (emulenc, "no context");
+      break;
+    }
 
-    fps = gst_structure_get_value (structure, "framerate");
-    if (fps) {
-        emulenc->format.video.framerate_den = gst_value_get_fraction_numerator (fps);
-        emulenc->format.video.framerate_num = gst_value_get_fraction_denominator (fps);
+    ctx->video.width = DEFAULT_WIDTH;
+    ctx->video.height = DEFAULT_HEIGHT;
+    ctx->video.fps_n = 1;
+    ctx->video.fps_d = 25;
+    ctx->video.ticks_per_frame = 1;
+    ctx->bit_rate = DEFAULT_VIDEO_BITRATE;
+
+//    ctx->strict_std_compliance = -1;
+    ctx->video.pix_fmt = pixfmt;
+
+    GST_DEBUG ("Attempting to open codec");
+    if (gst_emul_avcodec_open (ctx, oclass->codec, emulenc->dev) >= 0
+      && ctx->video.pix_fmt == pixfmt) {
+      ctx->video.width = -1;
+      if (!caps) {
+        caps = gst_caps_new_empty ();
+      }
+      tmpcasp = gst_emul_codectype_to_caps (oclass->codec->media_type, ctx,
+        oclass->codec->name, TRUE);
+      if (tmpcaps) {
+        gst_caps_append (caps, tmpcaps)
+      } else {
+        GST_LOG_OBJECT (emulenc,
+          "Couldn't get caps for codec: %s", oclass->codec->name);
+      }
+      gst_emul_avcodec_close (ctx, emulenc->dev);
+    } else {
+      GST_DEBUG_OBJECT (emulenc, "Opening codec failed with pixfmt: %d", pixfmt);
     }
 
 #if 0
-    par = gst_structure_get_value (structure, "pixel-aspect-ratio");
-    if (par) {
-        sample_aspect_ratio.num = gst_structure_get_fraction_numerator (par);
-        sample_aspect_ratio.den = gst_structure_get_fraction_denominator (par);
+    if (ctx->priv_data) {
+      gst_emul_avcodec_close (ctx, emulenc->dev);
     }
 #endif
+    g_free (ctx);
+  }
 #endif
 
-#if 0 /* audio type */
-    gst_structure_get_int (structure, "channels", &channels);
-    gst_structure_get_int (structure, "rate", &sample_rate);
-    gst_structure_get_int (structure, "block_align", &block_align);
-    gst_structure_get_int (structure, "bitrate", &bit_rate);
+  if (!caps) {
+    caps = gst_emulenc_get_possible_sizes (emulenc, pad,
+      gst_pad_get_pad_template_caps (pad));
+    GST_DEBUG_OBJECT (emulenc, "probing gave nothing, "
+      "return template %" GST_PTR_FORMAT, caps);
+    return caps;
+  }
 
-    emulenc->format.audio.channels = channels;
-    emulenc->format.audio.samplerate = sample_rate;
-#endif
+  GST_DEBUG_OBJECT (emulenc, "probed caps gave %" GST_PTR_FORMAT, caps);
+  oclass->sinkcaps = gst_caps_copy (caps);
 
+  finalcaps = gst_emulenc_get_possible_sizes (emulenc, pad, caps);
+  gst_caps_unref (caps);
+
+  return finalcaps;
 }
 
-    static gboolean
+static gboolean
 gst_emulenc_setcaps (GstPad *pad, GstCaps *caps)
 {
   GstEmulEnc *emulenc;
   GstEmulEncClass *oclass;
-  gboolean ret = TRUE;
+  GstCaps *other_caps;
+  GstCaps *allowed_caps;
+  GstCaps *icaps;
+  enum PixelFormat pix_fmt;
 
   emulenc = (GstEmulEnc *) (gst_pad_get_parent (pad));
   oclass = (GstEmulEncClass *) (G_OBJECT_GET_CLASS (emulenc));
 
+#if 0
   if (emulenc->opend) {
-    gst_emul_deinit ();
+    gst_emul_avcodec_close (emulenc->context, emulenc->dev);
     emulenc->opened = FALSE;
 
     gst_pad_set_caps (emulenc->srcpad, NULL);
   }
+#endif
 
-  gst_emul_caps_with_codectype (codec_type, caps);
-
-  if (!time_base.den) {
-    time_base.den = 25;
-    time_base.num = 1;
-  } else if (strcmp(  ,"mpeg4") == 0) {
+  gst_emul_caps_with_codectype (oclass->codec->media_type, caps);
+
+  if (!emulenc->context->video.fps_d) {
+    emulenc->context->video.fps_d = 25;
+    emulenc->context->video.fps_n = 1;
+  } else if (!strcmp(oclass->codec->name ,"mpeg4")
+      && (emulenc->context->video.fps_d > 65535)) {
+      emulenc->context->video.fps_n =
+        (gint) gst_util_uint64_scale_int (emulenc->context->video.fps_n,
+            65535, emulenc->context->video.fps_d);
+      emulenc->context->video.fps_d = 65535;
+      GST_LOG_OBJECT (emulenc, "MPEG4 : scaled down framerate to %d / %d",
+          emulenc->context->video.fps_d, emulenc->context->video.fps_n);
   }
 
+  pix_fmt = emulenc->context->video.pix_fmt;
+
   // open codec
+  if (gst_emul_avcodec_open (emulenc->context,
+                 oclass->codec, emulenc->dev) < 0) {
+    GST_DEBUG_OBJECT (emulenc, "tzenc_%s: Failed to open codec",
+               oclass->codec->name);
+    return FALSE;
+  }
 
-  if (gst_emul_codec_dev_open (emulenc) < 0) {
-    CODEC_LOG(1, "failed to access %s or mmap operation\n", CODEC_DEV);
-    gst_object_unref (emulenc);
+  if (pix_fmt != emulenc->context->video.pix_fmt) {
+    gst_emul_avcodec_close (emulenc->context, emulenc->dev);
+    GST_DEBUG_OBJECT (emulenc,
+      "tzenc_%s: AV wants different colorspace (%d given, %d wanted)",
+      oclass->codec->name, pix_fmt, emulenc->context->video.pix_fmt);
     return FALSE;
   }
 
-  if (gst_emul_codec_init (emulenc) < 0) {
-    CODEC_LOG(1, "cannot initialize codec\n");
-    gst_object_unref (emulenc);
+  if (oclass->codec->media_type == AVMEDIA_TYPE_VIDEO
+    && pix_fmt == PIX_FMT_NONE) {
+    GST_DEBUG_OBJECT (emulenc, "tzenc_%s: Failed to determine input format",
+      oclass->codec->name);
     return FALSE;
   }
 
+  GST_DEBUG_OBJECT (emulenc, "picking an output format.");
   allowed_caps = gst_pad_get_allowed_caps (emulenc->srcpad);
   if (!allowed_caps) {
+    GST_DEBUG_OBJECT (emulenc, "but no peer, using template caps");
     allowed_caps =
       gst_caps_copy (gst_pad_get_pad_template_caps (emulenc->srcpad));
   }
 
-  gst_emul_caps_with_codecid (codec_id, codec_type, allowed_caps);
-
-  other_caps = gst_emul_codecname_to_caps (codec_id, TRUE);
+  GST_DEBUG_OBJECT (emulenc, "chose caps %" GST_PTR_FORMAT, allowed_caps);
+  gst_emul_caps_with_codecname (oclass->codec->name,
+    oclass->codec->media_type, allowed_caps, emulenc->context);
 
+  other_caps = gst_emul_codecname_to_caps (oclass->codec->name,
+      emulenc->context, TRUE);
   if (!other_caps) {
-     // deinit
+    gst_emul_avcodec_close (emulenc->context, emulenc->dev);
     return FALSE;
   }
 
@@ -374,9 +544,12 @@ gst_emulenc_setcaps (GstPad *pad, GstCaps *caps)
     newcaps =
       gst_caps_new_full (gst_structure_copy (gst_caps_get_structure (icaps,
               0)), NULL);
+    gst_caps_unref (icaps);
+    icaps = newcaps;
+  }
 
   if (!gst_pad_set_caps (emulenc->srcpad, icaps)) {
-    // deinit
+    gst_emul_avcodec_close (emulenc->context, emulenc->dev);
     gst_caps_unref (icaps);
     return FALSE;
   }
@@ -387,182 +560,475 @@ gst_emulenc_setcaps (GstPad *pad, GstCaps *caps)
   return TRUE;
 }
 
-static gboolean
-gst_emulenc_event_video (GstPad *pad, GstEvent *event)
+static void
+gst_emulenc_setup_working_buf (GstEmulEnc *emulenc)
 {
-  GstEmulEnc *emulenc;
-  emulenc = (GstEmulEnc *) gst_pad_get_parent (pad);
+  guint wanted_size =
+      emulenc->context->video.width * emulenc->context->video.height * 6 +
+      FF_MIN_BUFFER_SIZE;
 
-  switch (GST_TYPE_EVENT (event)) {
-  case GST_EVENT_EOS:
-    CODEC_LOG(2, "received GST_EVENT_EOS\n");
-    // flush_buffers
-    break;
-  case GST_EVENT_CUSTOM_DOWNSTREAM:
-    CODEC_LOG(2, "received GST_EVENT_CUSTOM_DOWNSTREAM\n");
-    break;
+  if (emulenc->working_buf == NULL ||
+    emulenc->working_buf_size != wanted_size) {
+    if (emulenc->working_buf) {
+      g_free (emulenc->working_buf);
+    }
+    emulenc->working_buf_size = wanted_size;
+    emulenc->working_buf = g_malloc0 (emulenc->working_buf_size);
   }
-
-  return gst_pad_push_event (emulenc->srcpad, event);
+// TODO
+//  emulenc->buffer_size = wanted_size;
 }
 
-static gboolean
-gst_emulenc_event_src (GstPad *pad, GstEvent *event)
+GstFlowReturn
+gst_emulenc_chain_video (GstPad *pad, GstBuffer *buffer)
 {
-  switch (GST_EVENT_TYPE (event)) {
-  default:
-    break    
+  GstEmulEnc *emulenc = (GstEmulEnc *) (GST_PAD_PARENT (pad));
+  GstBuffer *outbuf;
+  gint ret_size = 0, frame_size;
+
+  GST_DEBUG_OBJECT (emulenc,
+      "Received buffer of time %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
+
+#if 0
+  GST_OBJECT_LOCK (emulenc);
+  force_keyframe = emulenc->force_keyframe;
+  emulenc->force_keyframe = FALSE;
+  GST_OBJECT_UNLOCK (emulenc);
+
+  if (force_keyframe) {
+    emulenc->picture->pict_type = FF_I_TYPE;
   }
+#endif
 
-  return TRUE;
-}
+  frame_size = gst_emul_avpicture_size (emulenc->context->video.pix_fmt,
+      emulenc->context->video.width, emulenc->context->video.height);
+  g_return_val_if_fail (frame_size == GST_BUFFER_SIZE (buffer),
+      GST_FLOW_ERROR);
 
-// minimum encoding buffer size.
-// Used to avoid some checks during header writing.
-#define FF_MIN_BUFFER_SIZE 16384
+  gst_emulenc_setup_working_buf (emulenc);
 
-static inst
-gst_emul_encode_video (uint8_t *outbuf, int buf_size,
-                      uint8_t *pict_buf, uint32_t pict_buf_size)
-{
-  GstEmulEnc *emulenc = (GetEmulEnc *) (GST_PAD_PARENT (pad));
-  int size = 0, api_index = CODEC_ENCODE_VIDEO;
-  int ret;
+#if 0
+  ret_size =
+      emul_avcodec_encode_video (emulenc->context, emulenc->working_buf,
+      emulenc->working_buf_size, emulenc->picture,
+      GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), emulenc->dev);
+#endif
 
-  ret = write (); 
+  if (ret_size < 0) {
+    GstEmulEncClass *oclass =
+      (GstEmulEncClass *) (G_OBJECT_GET_CLASS (emulenc));
+    GST_ERROR_OBJECT (emulenc,
+        "tzenc_%s: failed to encode buffer", oclass->codec->name);
+    gst_buffer_unref (buffer);
+    return GST_FLOW_OK;
+  }
 
-  return ret;
+#if 0
+  g_queue_push_tail (emulenc->delay, buffer);
+  if (ret_size) {
+    buffer = g_queue_pop_head (emulenc->delay);
+  } else {
+    return GST_FLOW_OK;
+  }
+
+#if 0
+  if (emulenc->file && emulenc->context->stats_out) {
+    if (fprintf (emulenc->file, "%s", emulenc->context->stats_out) < 0) {
+      GST_ELEMENT_ERROR (emulenc, RESOURCE, WRITE,
+        (("Could not write to file \"%s\"."), emulenc->filename),
+        GST_ERROR_SYSTEM);
+    }
+  }
+#endif
+#endif
+
+  outbuf = gst_buffer_new_and_alloc (ret_size);
+  memcpy (GST_BUFFER_DATA(outbuf), emulenc->working_buf, ret_size);
+  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer);
+  GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (outbuf);
+#if 0
+  if (emulenc->context->coded_frame) {
+    if (!emulenc->context->coded_frame->key_frame) {
+      GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
+    }
+  } else {
+    GST_WARNING_OBJECT (emulenc, "codec did not provide keyframe info");
+  }
+#endif
+  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (emulenc->srcpad));
+
+  gst_buffer_unref (buffer);
+
+#if 0
+
+  if (force_keyframe) {
+    gst_pad_push_event (emulenc->srcpad,
+      gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
+      gst_structure_new ("GstForceKeyUnit", "timestamp",
+                         G_TYPE_UINT64, GST_BUFFER_TIMESTAMP (outbuf), NULL)));
+  }
+#endif
+
+  return gst_pad_push (emulenc->srcpad, outbuf);
 }
 
-static GstFlowReturn
+GstFlowReturn
 gst_emulenc_encode_audio (GstEmulEnc *emulenc, guint8 *audio_in,
   guint in_size, guint max_size, GstClockTime timestamp,
   GstClockTime duration, gboolean discont)
 {
   GstBuffer *outbuf;
-  guint8_t *audio_out;
+  guint8 *audio_out;
   gint res;
   GstFlowReturn ret;
-  int size = 0, api_index = CODEC_ENCODE_AUDIO;
+  int size = 0;
 
   outbuf = gst_buffer_new_alloc (max_size + FF_MIN_BUFFER_SIZE);
   audio_out = GST_BUFFER_DATA (outbuf);
 
-  // copy params to qemu
-
-  res = write();
+  GST_LOG_OBJECT (emulenc, "encoding buffer of max size %d", max_size);
+  if (emulenc->buffer_size != max_size) {
+    emulenc->buffer_size = max_size;
+  }
 
-  // copy output and out params from qemu
+  res = emul_avcodec_encode_audio (emulenc->context, audio_out, max_size,
+      (short *) audio_in, in_size, emulenc->dev);
 
   if (res < 0) {
     GST_ERROR_OBJECT (emulenc, "Failed to encode buffer: %d", res);
     gst_buffer_unref (outbuf);
     return GST_FLOW_OK;
   }
+  GST_LOG_OBJECT (emulenc, "got output size %d", res);
 
   GST_BUFFER_SIZE (outbuf) = res;
   GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
-  GST_BUFFER_DURATION (outbuf) = duration
-
+  GST_BUFFER_DURATION (outbuf) = duration;
+  if (discont) {
+    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
+  }
   gst_buffer_set_caps (outbuf, GST_PAD_CAPS (emulenc->srcpad));
 
+  GST_LOG_OBJECT (emulenc, "pushing size %d, timestamp %", GST_TIME_FORMAT,
+      res, GST_TIME_ARGS (timestamp));
+
   ret = gst_pad_push (emulenc->srcpad, outbuf);
 
   return ret;
 }
 
-#if 0
-static void
-emulenc_setup_working_buf (GstEmulEnc * emulenc)
-{
-  guint wanted_size =
-    ffmpegenc->context->width * ffmpegenc->context->height * 6 +
-    FF_MIN_BUFFER_SIZE;
-  /* Above is the buffer size used by ffmpeg/ffmpeg.c */
-  if (ffmpegenc->working_buf == NULL ||
-    ffmpegenc->working_buf_size != wanted_size) {
-    if (ffmpegenc->working_buf)
-      g_free (ffmpegenc->working_buf);
-    ffmpegenc->working_buf_size = wanted_size;
-    ffmpegenc->working_buf = g_malloc (ffmpegenc->working_buf_size);
-  }
-  ffmpegenc->buffer_size = wanted_size;
-}
-#endif
-
-static GstFlowReturn
-gst_emulenc_chain_video (GstPad *pad, GstBuffer *buffer)
-{
-  GstEmulEnc *emulenc = (GetEmulEnc *) (GST_PAD_PARENT (pad));
-  GstBuffer *outbuf;
-  gint in_size = 0;
-
-  // setup_working_buf
-  // width * height * 6 + FF_MIN_BUFFER_SIZE
-  // 
-
-//  gst_emul_encode_video ();
-
-  outbuf = gst_buffer_new_and_alloc (ret_size);
-  memcpy (GST_BUFFER_DATA(outbuf), , ret_size);
-  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer);
-  GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (outbuf);
-
-  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (emulenc->srcpad));
-
-  gst_buffer_unref (buffer);
-  
-  return gst_pad_push (emulenc->srcpad, outbuf);
-}
-
 static GstFlowReturn
 gst_emulenc_chain_audio (GstPad *pad, GstBuffer *buffer)
 {
   GstEmulEnc *emulenc;
   GstEmulEncClass *oclass;
   GstClockTime timestamp, duration;
-  guint size;
+  guint in_size, frame_size;
+  gint osize;
   GstFlowReturn ret;
+  gint out_size;
   gboolean discont;
+  gint8 *in_data;
+  CodecContext *ctx;
 
   emulenc = (GstEmulEnc *) (GST_OBJECT_PARENT (pad));
   oclass = (GstEmulEncClass *) G_OBJECT_GET_CLASS (emulenc);
 
-  size = GST_BUFFER_SIZE (buffer);
+  ctx = emulenc->context;
+
+  in_size = GST_BUFFER_SIZE (buffer);
   timestamp = GST_BUFFER_TIMESTAMP (buffer);
   duration = GST_BUFFER_DURATION (buffer);
   discont = GST_BUFFER_IS_DISCONT (buffer);
 
-  if (discont) {
-    gst_adapter_clear (emulenc->adapter);
-  }
-  
-//  gst_adapter_push (emulenc->adapter, buffer);
+  GST_DEBUG_OBJECT (emulenc,
+    "Received time %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT
+    ", size %d", GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration), in_size);
 
-// TODO
-// gst_emul_encode_audio
+#if 0
+
+  frame_size = ctx->frame_size;
+  osize = av_get_bits_per_sample_format (ctx->audio.sample_fmt) / 8;
+
+  if (frame_size > 1) {
+    guint avail, frame_bytes;
+
+    if (discont) {
+      GST_LOG_OBJECT (emulenc, "DISCONT, clear adapter");
+      gst_adapter_clear (emulenc->adapter);
+      emulenc->discont = TRUE;
+    }
+
+    if (gst_adapter_available (emulenc->adapter) == 0) {
+      GST_LOG_OBJECT (emulenc, "taking buffer timestamp %" GST_TIME_FORMAT,
+        GST_TIME_ARGS (timestamp));
+      emulenc->adapter_ts = timestamp;
+      emulenc->adapter_consumed = 0;
+    } else {
+      GstClockTime upstream_time;
+      GstClockTime consumed_time;
+      guint64 bytes;
+
+      consumed_time =
+        gst_util_uint64_scale (emulenc->adapter_consumed, GST_SECOND,
+            ctx->audio.sample_rate);
+      timestamp = emulenc->adapter_ts + consumed_time;
+      GST_LOG_OBJECT (emulenc, "taking adapter timestamp %" GST_TIME_FORMAT
+        " and adding consumed time %" GST_TIME_FORMAT,
+        GST_TIME_ARGS (emulenc->adapter_ts), GST_TIME_ARGS (consumed_time));
+
+      upstream_time = gst_adapter_prev_timestamp (emulenc->adapter, &bytes);
+      if (GST_CLOCK_TIME_IS_VALID (upstream_time)) {
+        GstClockTimeDiff diff;
+
+        upsteam +=
+          gst_util_uint64_scale (bytes, GST_SECOND,
+            ctx->audio.sample_rate * osize * ctx->audio.channels);
+        diff = upstream_time - timestamp;
+        if (diff >GST_SECOND / 10 || diff < -GST_SECOND / 10) {
+          GST_DEBUG_OBJECT (emulenc, "adapter timestamp drifting, "
+            "taking upstream timestamp %" GST_TIME_FORMAT,
+            GST_TIME_ARGS (upstream_time));
+          timestamp = upstream_time;
+
+          emulenc->adapter_consumed = bytes / (osize * ctx->audio.channels);
+          emulenc->adapter_ts = upstream_time -
+            gst_util_uint64_scale (emulenc->adapter_consumed, GST_SECOND,
+                ctx->audio.sample_rate);
+          emulenc->discont = TRUE;
+        }
+      }
+    }
+
+    GST_LOG_OBJECT (emulenc, "pushing buffer in adapter");
+    gst_adapter_push (emulenc->adapter, buffer);
+
+    frame_bytes = frame_size * osize * ctx->audio.channels;
+    avail = gst_adapter_available (emulenc->adapter);
+
+    GST_LOG_OBJECT (emulenc, "frame_bytes %u, avail %u", frame_bytes, avail);
+
+    while (avail >= frame_bytes) {
+      GST_LOG_OBJECT (emulenc, "taking %u bytes from the adapter", frame_bytes);
+
+      in_data = (guint8 *) gst_adapter_peek (emulenc->adapter, frame_bytes);
+      emulenc->adapter_consumed += frame_size;
+
+      duration =
+        gst_util_uint64_scale (emulenc->adapter_consumed, GST_SECOND,
+          ctx->audio.sample_rate);
+      duration -= (timestamp - emulenc->adapter_ts);
+
+      out_size = frame_bytes * 4;
+
+      ret =
+        gst_emulenc_encode_audio (emulenc, in_data, frame_bytes, out_size,
+          timestamp, duration, emulenc->discont);
+
+      gst_adapter_flush (emulenc->adapter, frame_bytes);
+      if (ret != GST_FLOW_OK) {
+        GST_DEBUG_OBJECT (emulenc, "Failed to push buffer %d (%s)", ret,
+          gst_flow_get_name (ret));
+      }
+
+      timestamp += duration;
+
+      emulenc->discont = FALSE;
+      avail = gst_adapter_available (emulenc->adapter);
+    }
+    GST_LOG_OBJECT (emulenc, "%u bytes left in the adapter", avail);
+  } else {
+    int coded_bps = av_get_bits_per_sample (oclass->codec->name);
+
+    GST_LOG_OBJECT (emulenc, "coded bps %d, osize %d", coded_bps, osize);
+
+    out_size = in_size / osize;
+    if (coded_bps) {
+      out_size = (out_size * coded_bps) / 8;
+    }
+
+    in_data = (guint8 *) GST_BUFFER_DATA (buffer);
+    ret = gst_emulenc_encode_audio (emulenc, in_data, in_size, out_size,
+      timestamp, duration, discont);
+    gst_buffer_unref (buffer);
+    if (ret != GST_FLOW_OK) {
+      GST_DEBUG_OBJECT (emulenc, "Failed to push buffer %d (%s)", ret,
+        gst_flow_get_name (ret));
+    }
+  }
+#endif
 
   return GST_FLOW_OK;
 }
 
-static GstStateChangeReturn
+static void
+gst_emulenc_flush_buffers (GstEmulEnc *emulenc, gboolean send)
+{
+  GstBuffer *outbuf, *inbuf;
+  gint ret_size;
+
+  GST_DEBUG_OBJECT (emulenc, "flushing buffers with sending %d", send);
+
+#if 0
+  if (!emulenc->opend) {
+    while (!g_queue_is_empty (emulenc->delay)) {
+      gst_buffer_unref (g_queue_pop_head (emulenc->delay));
+    }
+  }
+
+  while (!g_queue_is_empty (emulenc->delay)) {
+    emulenc_setup_working_buf (emulenc);
+
+    ret_size = emul_avcodec_encode_video (emulenc->context,
+      emulenc->working_buf, emulenc->working_buf_size, NULL, NULL, 0,
+      emulenc->dev);
+
+    if (ret_size < 0) {
+      GstEmulEncClass *oclass =
+        (GstEmulEncClass *) (G_OBJECT_GET_CLASS (emulenc));
+      GST_WARNING_OBJECT (emulenc,
+        "tzenc_%s: failed to flush buffer", oclass->codec->name);
+      break;
+    }
+
+    if (emulenc->file && emulenc->context->stats_out) {
+      if (fprintf (emulenc->file, "%s", emulenc->context->stats_out) < 0) {
+        GST_ELEMENT_ERROR (emeulenc, RESOURCE, WRITE,
+          (("Could not write to file \"%s\"."), emulenc->filename),
+          GST_ERROR_SYSTEM);
+      }
+    }
+
+    inbuf = g_queue_pop_head (emulenc->delay);
+
+    outbuf = gst_buffer_new_and_alloc (ret_size);
+    memcpy (GST_BUFFER_DATA (outbuf), emulenc->working_buf, ret_size);
+    GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf);
+    GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf);
+
+    if (!emulenc->context->coded_frame->key_frame) {
+      GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
+    }
+    gst_buffer_set_caps (outbuf, GST_PAD_CAPS (emulenc->srcpad));
+
+    gst_buffer_unref (inbuf);
+
+    if (send) {
+      gst_pad_push (emulenc->srcpad, outbuf);
+    } else {
+      gst_buffer_unref (outbuf);
+    }
+  }
+
+  while (!g_queue_is_empty (emulenc->delay)) {
+    gst_buffer_unref (g_queue_pop_head (emulenc->delay));
+  }
+#endif
+}
+
+static gboolean
+gst_emulenc_event_video (GstPad *pad, GstEvent *event)
+{
+  GstEmulEnc *emulenc;
+  emulenc = (GstEmulEnc *) gst_pad_get_parent (pad);
+
+  switch (GST_EVENT_TYPE (event)) {
+  case GST_EVENT_EOS:
+    gst_emulenc_flush_buffers (emulenc, TRUE);
+    break;
+  case GST_EVENT_CUSTOM_DOWNSTREAM:
+  {
+    const GstStructure *s;
+    s = gst_event_get_structure (event);
+#if 0
+    if (gst_structure_has_name (s, "GstForceKeyUnit")) {
+      emulenc->picture->pict_type = FF_I_TYPE;
+    }
+#endif
+  }
+    break;
+  default:
+    break;
+  }
+
+  return gst_pad_push_event (emulenc->srcpad, event);
+}
+
+static gboolean
+gst_emulenc_event_src (GstPad *pad, GstEvent *event)
+{
+  GstEmulEnc *emulenc = (GstEmulEnc *) (GST_PAD_PARENT (pad));
+  gboolean forward = TRUE;
+
+  switch (GST_EVENT_TYPE (event)) {
+  case GST_EVENT_CUSTOM_UPSTREAM:
+  {
+    const GstStructure *s;
+    s = gst_event_get_structure (event);
+#if 0
+    if (gst_structure_has_name (s, "GstForceKeyUnit")) {
+      GST_OBJECT_LOCK (emulenc);
+      emulenc->force_keyframe = TRUE;
+      GST_OBJECT_UNLOCK (emulenc);
+      forward = FALSE;
+      gst_event_unref (event);
+    }
+#endif
+  }
+    break;
+  default:
+    break;
+  }
+
+  if (forward) {
+    return gst_pad_push_event (emulenc->sinkpad, event);
+  }
+
+  return TRUE;
+}
+
+GstStateChangeReturn
 gst_emulenc_change_state (GstElement *element, GstStateChange transition)
 {
-    GstEmulEnc *emulenc = (GstEmulEnc*)element;
-    GstStateChangeReturn ret;
+  GstEmulEnc *emulenc = (GstEmulEnc*)element;
+  GstStateChangeReturn ret;
 
-    ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+  switch (transition) {
+  default:
+    break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
-    switch (transition) {
-        case GST_STATE_CHANGE_PAUSED_TO_READY:
-            // flush buffer
-            gst_emul_codec_deinit (emulenc);
-        default:
-            break;
+  switch (transition) {
+  case GST_STATE_CHANGE_PAUSED_TO_READY:
+    gst_emulenc_flush_buffers (emulenc, FALSE);
+#if 0
+    if (emulenc->opened) {
+      gst_emul_avcodec_close (emulenc->context, emulenc->dev);
+      emulenc->opened = FALSE;
     }
+#endif
+    gst_adapter_clear (emulenc->adapter);
 
-    return ret;
+#if 0
+    if (emulenc->flie) {
+      fclose (emulenc->file);
+      emulenc->file = NULL;
+    }
+#endif
+
+    if (emulenc->working_buf) {
+      g_free (emulenc->working_buf);
+      emulenc->working_buf = NULL;
+    }
+    break;
+  default:
+    break;
+  }
+
+  return ret;
 }
 
 gboolean
@@ -588,7 +1054,7 @@ gst_emulenc_register (GstPlugin *plugin, GList *element)
   CodecElement *codec = NULL;
 
   /* register element */
-  while ((elem = g_list_next (element))) {
+  while ((elem = g_list_next (elem))) {
     codec = (CodecElement *)elem->data;
     if (!codec) {
       ret = FALSE;
@@ -603,7 +1069,7 @@ gst_emulenc_register (GstPlugin *plugin, GList *element)
     type = g_type_from_name (type_name);
     if (!type) {
       type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
-      g_type_set_qdata (type, GST_EMULDEC_PARAMS_QDATA, (gpointer) codec);
+      g_type_set_qdata (type, GST_EMULENC_PARAMS_QDATA, (gpointer) codec);
     }
 
     if (!gst_element_register (plugin, type_name, rank, type)) {
index cff4e33..af17ecd 100644 (file)
@@ -283,6 +283,7 @@ gst_emul_caps_to_pixfmt (const GstCaps *caps, CodecContext *ctx, gboolean raw)
   if (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps)) {
     ctx->video.fps_d = gst_value_get_fraction_numerator (fps);
     ctx->video.fps_n = gst_value_get_fraction_denominator (fps);
+       ctx->video.ticks_per_frame = 1;
 
     GST_DEBUG ("setting framerate %d/%d = %lf",
         ctx->video.fps_d, ctx->video.fps_n,
@@ -452,7 +453,7 @@ gst_emul_caps_with_codecname (const char *name, int media_type,
     buf = GST_BUFFER_CAST (gst_value_get_mini_object (value));
     size = GST_BUFFER_SIZE (buf);
     data = GST_BUFFER_DATA (buf);
-    printf("extradata: %p, size: %d\n", ctx->codecdata, ctx->codecdata_size);
+    printf("extradata: %p, size: %d\n", data, size);
 
     if (ctx->codecdata) {
       g_free (ctx->codecdata);
@@ -545,10 +546,10 @@ gst_emul_video_caps_new (CodecContext *ctx, const char *name,
 
     caps = gst_caps_new_simple (mimetype,
       "width", G_TYPE_INT, ctx->video.width,
-      "height", G_TYPE_INT, ctx->video.height);
+      "height", G_TYPE_INT, ctx->video.height, NULL);
 
-    num = ctx->video.fps_d / 1;
-    denom = ctx->video.fps_d;
+    num = ctx->video.fps_d / ctx->video.ticks_per_frame;
+    denom = ctx->video.fps_n;
 
     if (!denom) {
       GST_LOG ("invalid framerate: %d/0, -> %d/1", num, num);
@@ -775,7 +776,7 @@ gst_emul_pixfmt_to_caps (enum PixelFormat pix_fmt, CodecContext *ctx, const char
     break;
   }
 
-  if (caps != NULL) {
+  if (caps == NULL) {
     if (bpp != 0) {
       if (r_mask != 0) {
         if (a_mask) {
@@ -1137,3 +1138,20 @@ gst_emul_avpicture_size (int pix_fmt, int width, int height)
 
   return fsize;
 }
+
+int
+gst_emul_align_size (int buf_size)
+{
+  int i, align_size;
+
+  align_size = buf_size / 1024;
+  
+  for (i = 0; i < 14; i++) {
+    if (align_size < (1 << i)) {
+      align_size = 1024 * (1 << i);      
+      break;
+    }    
+  }
+
+  return align_size;
+}
diff --git a/src/gstmyfilter.c b/src/gstmyfilter.c
deleted file mode 100644 (file)
index a15913e..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
- * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * Copyright (C) 2012 kt <<user@hostname.org>>
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Alternatively, the contents of this file may be used under the
- * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
- * which case the following provisions apply instead of the ones
- * mentioned above:
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-myfilter
- *
- * FIXME:Describe myfilter here.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch -v -m fakesrc ! myfilter ! fakesink silent=TRUE
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <gst/gst.h>
-
-#include "gstmyfilter.h"
-
-GST_DEBUG_CATEGORY_STATIC (gst_my_filter_debug);
-#define GST_CAT_DEFAULT gst_my_filter_debug
-
-/* Filter signals and args */
-enum
-{
-  /* FILL ME */
-  LAST_SIGNAL
-};
-
-enum
-{
-  PROP_0,
-  PROP_SILENT
-};
-
-/* the capabilities of the inputs and outputs.
- *
- * describe the real formats here.
- */
-static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
-    GST_PAD_SINK,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("ANY")
-    );
-
-static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
-    GST_PAD_SRC,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("ANY")
-    );
-
-GST_BOILERPLATE (GstMyFilter, gst_my_filter, GstElement,
-    GST_TYPE_ELEMENT);
-
-static void gst_my_filter_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_my_filter_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-
-static gboolean gst_my_filter_set_caps (GstPad * pad, GstCaps * caps);
-static GstFlowReturn gst_my_filter_chain (GstPad * pad, GstBuffer * buf);
-
-/* GObject vmethod implementations */
-
-static void
-gst_my_filter_base_init (gpointer gclass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
-  gst_element_class_set_details_simple(element_class,
-    "MyFilter",
-    "FIXME:Generic",
-    "FIXME:Generic Template Element",
-    "kt <<user@hostname.org>>");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_factory));
-}
-
-/* initialize the myfilter's class */
-static void
-gst_my_filter_class_init (GstMyFilterClass * klass)
-{
-  GObjectClass *gobject_class;
-  GstElementClass *gstelement_class;
-
-  gobject_class = (GObjectClass *) klass;
-  gstelement_class = (GstElementClass *) klass;
-
-  gobject_class->set_property = gst_my_filter_set_property;
-  gobject_class->get_property = gst_my_filter_get_property;
-
-  g_object_class_install_property (gobject_class, PROP_SILENT,
-      g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
-          FALSE, G_PARAM_READWRITE));
-}
-
-/* initialize the new element
- * instantiate pads and add them to element
- * set pad calback functions
- * initialize instance structure
- */
-static void
-gst_my_filter_init (GstMyFilter * filter,
-    GstMyFilterClass * gclass)
-{
-  filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
-  gst_pad_set_setcaps_function (filter->sinkpad,
-                                GST_DEBUG_FUNCPTR(gst_my_filter_set_caps));
-  gst_pad_set_getcaps_function (filter->sinkpad,
-                                GST_DEBUG_FUNCPTR(gst_pad_proxy_getcaps));
-  gst_pad_set_chain_function (filter->sinkpad,
-                              GST_DEBUG_FUNCPTR(gst_my_filter_chain));
-
-  filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
-  gst_pad_set_getcaps_function (filter->srcpad,
-                                GST_DEBUG_FUNCPTR(gst_pad_proxy_getcaps));
-
-  gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
-  gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
-  filter->silent = FALSE;
-}
-
-static void
-gst_my_filter_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstMyFilter *filter = GST_MYFILTER (object);
-
-  switch (prop_id) {
-    case PROP_SILENT:
-      filter->silent = g_value_get_boolean (value);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_my_filter_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstMyFilter *filter = GST_MYFILTER (object);
-
-  switch (prop_id) {
-    case PROP_SILENT:
-      g_value_set_boolean (value, filter->silent);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-/* GstElement vmethod implementations */
-
-/* this function handles the link with other elements */
-static gboolean
-gst_my_filter_set_caps (GstPad * pad, GstCaps * caps)
-{
-  GstMyFilter *filter;
-  GstPad *otherpad;
-
-  filter = GST_MYFILTER (gst_pad_get_parent (pad));
-  otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad;
-  gst_object_unref (filter);
-
-  return gst_pad_set_caps (otherpad, caps);
-}
-
-/* chain function
- * this function does the actual processing
- */
-static GstFlowReturn
-gst_my_filter_chain (GstPad * pad, GstBuffer * buf)
-{
-  GstMyFilter *filter;
-
-  filter = GST_MYFILTER (GST_OBJECT_PARENT (pad));
-
-  if (filter->silent == FALSE)
-    g_print ("I'm plugged, therefore I'm in.\n");
-
-  /* just push out the incoming buffer without touching it */
-  return gst_pad_push (filter->srcpad, buf);
-}
-
-
-/* entry point to initialize the plug-in
- * initialize the plug-in itself
- * register the element factories and other features
- */
-static gboolean
-myfilter_init (GstPlugin * myfilter)
-{
-  /* debug category for fltering log messages
-   *
-   * exchange the string 'Template myfilter' with your description
-   */
-  GST_DEBUG_CATEGORY_INIT (gst_my_filter_debug, "myfilter",
-      0, "Template myfilter");
-
-  return gst_element_register (myfilter, "myfilter", GST_RANK_NONE,
-      GST_TYPE_MYFILTER);
-}
-
-/* PACKAGE: this is usually set by autotools depending on some _INIT macro
- * in configure.ac and then written into and defined in config.h, but we can
- * just set it ourselves here in case someone doesn't use autotools to
- * compile this code. GST_PLUGIN_DEFINE needs PACKAGE to be defined.
- */
-#ifndef PACKAGE
-#define PACKAGE "myfirstmyfilter"
-#endif
-
-/* gstreamer looks for this structure to register myfilters
- *
- * exchange the string 'Template myfilter' with your myfilter description
- */
-GST_PLUGIN_DEFINE (
-    GST_VERSION_MAJOR,
-    GST_VERSION_MINOR,
-    "myfilter",
-    "Template myfilter",
-    myfilter_init,
-    VERSION,
-    "LGPL",
-    "GStreamer",
-    "http://gstreamer.net/"
-)
diff --git a/src/gstmyfilter.h b/src/gstmyfilter.h
deleted file mode 100644 (file)
index ceaf021..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
- * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * Copyright (C) 2012 kt <<user@hostname.org>>
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Alternatively, the contents of this file may be used under the
- * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
- * which case the following provisions apply instead of the ones
- * mentioned above:
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_MYFILTER_H__
-#define __GST_MYFILTER_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-/* #defines don't like whitespacey bits */
-#define GST_TYPE_MYFILTER \
-  (gst_my_filter_get_type())
-#define GST_MYFILTER(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MYFILTER,GstMyFilter))
-#define GST_MYFILTER_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MYFILTER,GstMyFilterClass))
-#define GST_IS_MYFILTER(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MYFILTER))
-#define GST_IS_MYFILTER_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MYFILTER))
-
-typedef struct _GstMyFilter      GstMyFilter;
-typedef struct _GstMyFilterClass GstMyFilterClass;
-
-struct _GstMyFilter
-{
-  GstElement element;
-
-  GstPad *sinkpad, *srcpad;
-
-  gboolean silent;
-};
-
-struct _GstMyFilterClass 
-{
-  GstElementClass parent_class;
-};
-
-GType gst_my_filter_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_MYFILTER_H__ */
diff --git a/src/gstplugin.c b/src/gstplugin.c
deleted file mode 100644 (file)
index 464be87..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
- * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * Copyright (C) YEAR AUTHOR_NAME AUTHOR_EMAIL
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Alternatively, the contents of this file may be used under the
- * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
- * which case the following provisions apply instead of the ones
- * mentioned above:
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-plugin
- *
- * FIXME:Describe plugin here.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch -v -m fakesrc ! plugin ! fakesink silent=TRUE
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <gst/gst.h>
-
-#include "gstplugin.h"
-
-GST_DEBUG_CATEGORY_STATIC (gst_plugin_template_debug);
-#define GST_CAT_DEFAULT gst_plugin_template_debug
-
-/* Filter signals and args */
-enum
-{
-  /* FILL ME */
-  LAST_SIGNAL
-};
-
-enum
-{
-  PROP_0,
-  PROP_SILENT
-};
-
-/* the capabilities of the inputs and outputs.
- *
- * describe the real formats here.
- */
-static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
-    GST_PAD_SINK,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("ANY")
-    );
-
-static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
-    GST_PAD_SRC,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("ANY")
-    );
-
-GST_BOILERPLATE (GstPluginTemplate, gst_plugin_template, GstElement,
-    GST_TYPE_ELEMENT);
-
-static void gst_plugin_template_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_plugin_template_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-
-static gboolean gst_plugin_template_set_caps (GstPad * pad, GstCaps * caps);
-static GstFlowReturn gst_plugin_template_chain (GstPad * pad, GstBuffer * buf);
-
-/* GObject vmethod implementations */
-
-static void
-gst_plugin_template_base_init (gpointer gclass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
-  gst_element_class_set_details_simple(element_class,
-    "Plugin",
-    "FIXME:Generic",
-    "FIXME:Generic Template Element",
-    "AUTHOR_NAME AUTHOR_EMAIL");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_factory));
-}
-
-/* initialize the plugin's class */
-static void
-gst_plugin_template_class_init (GstPluginTemplateClass * klass)
-{
-  GObjectClass *gobject_class;
-  GstElementClass *gstelement_class;
-
-  gobject_class = (GObjectClass *) klass;
-  gstelement_class = (GstElementClass *) klass;
-
-  gobject_class->set_property = gst_plugin_template_set_property;
-  gobject_class->get_property = gst_plugin_template_get_property;
-
-  g_object_class_install_property (gobject_class, PROP_SILENT,
-      g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
-          FALSE, G_PARAM_READWRITE));
-}
-
-/* initialize the new element
- * instantiate pads and add them to element
- * set pad calback functions
- * initialize instance structure
- */
-static void
-gst_plugin_template_init (GstPluginTemplate * filter,
-    GstPluginTemplateClass * gclass)
-{
-  filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
-  gst_pad_set_setcaps_function (filter->sinkpad,
-                                GST_DEBUG_FUNCPTR(gst_plugin_template_set_caps));
-  gst_pad_set_getcaps_function (filter->sinkpad,
-                                GST_DEBUG_FUNCPTR(gst_pad_proxy_getcaps));
-  gst_pad_set_chain_function (filter->sinkpad,
-                              GST_DEBUG_FUNCPTR(gst_plugin_template_chain));
-
-  filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
-  gst_pad_set_getcaps_function (filter->srcpad,
-                                GST_DEBUG_FUNCPTR(gst_pad_proxy_getcaps));
-
-  gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
-  gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
-  filter->silent = FALSE;
-}
-
-static void
-gst_plugin_template_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstPluginTemplate *filter = GST_PLUGIN_TEMPLATE (object);
-
-  switch (prop_id) {
-    case PROP_SILENT:
-      filter->silent = g_value_get_boolean (value);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_plugin_template_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstPluginTemplate *filter = GST_PLUGIN_TEMPLATE (object);
-
-  switch (prop_id) {
-    case PROP_SILENT:
-      g_value_set_boolean (value, filter->silent);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-/* GstElement vmethod implementations */
-
-/* this function handles the link with other elements */
-static gboolean
-gst_plugin_template_set_caps (GstPad * pad, GstCaps * caps)
-{
-  GstPluginTemplate *filter;
-  GstPad *otherpad;
-
-  filter = GST_PLUGIN_TEMPLATE (gst_pad_get_parent (pad));
-  otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad;
-  gst_object_unref (filter);
-
-  return gst_pad_set_caps (otherpad, caps);
-}
-
-/* chain function
- * this function does the actual processing
- */
-static GstFlowReturn
-gst_plugin_template_chain (GstPad * pad, GstBuffer * buf)
-{
-  GstPluginTemplate *filter;
-
-  filter = GST_PLUGIN_TEMPLATE (GST_OBJECT_PARENT (pad));
-
-  if (filter->silent == FALSE)
-    g_print ("I'm plugged, therefore I'm in.\n");
-
-  /* just push out the incoming buffer without touching it */
-  return gst_pad_push (filter->srcpad, buf);
-}
-
-
-/* entry point to initialize the plug-in
- * initialize the plug-in itself
- * register the element factories and other features
- */
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
-  /* debug category for fltering log messages
-   *
-   * exchange the string 'Template plugin' with your description
-   */
-  GST_DEBUG_CATEGORY_INIT (gst_plugin_template_debug, "plugin",
-      0, "Template plugin");
-
-  return gst_element_register (plugin, "plugin", GST_RANK_NONE,
-      GST_TYPE_PLUGIN_TEMPLATE);
-}
-
-/* PACKAGE: this is usually set by autotools depending on some _INIT macro
- * in configure.ac and then written into and defined in config.h, but we can
- * just set it ourselves here in case someone doesn't use autotools to
- * compile this code. GST_PLUGIN_DEFINE needs PACKAGE to be defined.
- */
-#ifndef PACKAGE
-#define PACKAGE "myfirstplugin"
-#endif
-
-/* gstreamer looks for this structure to register plugins
- *
- * exchange the string 'Template plugin' with your plugin description
- */
-GST_PLUGIN_DEFINE (
-    GST_VERSION_MAJOR,
-    GST_VERSION_MINOR,
-    "plugin",
-    "Template plugin",
-    plugin_init,
-    VERSION,
-    "LGPL",
-    "GStreamer",
-    "http://gstreamer.net/"
-)
diff --git a/src/gstplugin.h b/src/gstplugin.h
deleted file mode 100644 (file)
index f1fe4ed..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
- * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * Copyright (C) YEAR AUTHOR_NAME AUTHOR_EMAIL
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Alternatively, the contents of this file may be used under the
- * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
- * which case the following provisions apply instead of the ones
- * mentioned above:
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_PLUGIN_TEMPLATE_H__
-#define __GST_PLUGIN_TEMPLATE_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-/* #defines don't like whitespacey bits */
-#define GST_TYPE_PLUGIN_TEMPLATE \
-  (gst_plugin_template_get_type())
-#define GST_PLUGIN_TEMPLATE(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PLUGIN_TEMPLATE,GstPluginTemplate))
-#define GST_PLUGIN_TEMPLATE_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PLUGIN_TEMPLATE,GstPluginTemplateClass))
-#define GST_IS_PLUGIN_TEMPLATE(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PLUGIN_TEMPLATE))
-#define GST_IS_PLUGIN_TEMPLATE_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PLUGIN_TEMPLATE))
-
-typedef struct _GstPluginTemplate      GstPluginTemplate;
-typedef struct _GstPluginTemplateClass GstPluginTemplateClass;
-
-struct _GstPluginTemplate
-{
-  GstElement element;
-
-  GstPad *sinkpad, *srcpad;
-
-  gboolean silent;
-};
-
-struct _GstPluginTemplateClass 
-{
-  GstElementClass parent_class;
-};
-
-GType gst_plugin_template_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_PLUGIN_TEMPLATE_H__ */
diff --git a/src/gsttransform.c b/src/gsttransform.c
deleted file mode 100644 (file)
index 6cf223e..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2006 Stefan Kost <ensonic@users.sf.net>
- * Copyright (C) YEAR AUTHOR_NAME AUTHOR_EMAIL
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-plugin
- *
- * FIXME:Describe plugin here.
- *
- * <refsect2>
- * <title>Example launch line</title>
- * |[
- * gst-launch -v -m fakesrc ! plugin ! fakesink silent=TRUE
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-#include <gst/controller/gstcontroller.h>
-
-#include "gsttransform.h"
-
-GST_DEBUG_CATEGORY_STATIC (gst_plugin_template_debug);
-#define GST_CAT_DEFAULT gst_plugin_template_debug
-
-/* Filter signals and args */
-enum
-{
-  /* FILL ME */
-  LAST_SIGNAL
-};
-
-enum
-{
-  PROP_0,
-  PROP_SILENT,
-};
-
-/* the capabilities of the inputs and outputs.
- *
- * FIXME:describe the real formats here.
- */
-static GstStaticPadTemplate sink_template =
-GST_STATIC_PAD_TEMPLATE (
-  "sink",
-  GST_PAD_SINK,
-  GST_PAD_ALWAYS,
-  GST_STATIC_CAPS ("ANY")
-);
-
-static GstStaticPadTemplate src_template =
-GST_STATIC_PAD_TEMPLATE (
-  "src",
-  GST_PAD_SRC,
-  GST_PAD_ALWAYS,
-  GST_STATIC_CAPS ("ANY")
-);
-
-/* debug category for fltering log messages
- *
- * FIXME:exchange the string 'Template plugin' with your description
- */
-#define DEBUG_INIT(bla) \
-  GST_DEBUG_CATEGORY_INIT (gst_plugin_template_debug, "plugin", 0, "Template plugin");
-
-GST_BOILERPLATE_FULL (GstPluginTemplate, gst_plugin_template, GstBaseTransform,
-    GST_TYPE_BASE_TRANSFORM, DEBUG_INIT);
-
-static void gst_plugin_template_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_plugin_template_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-
-static GstFlowReturn gst_plugin_template_transform_ip (GstBaseTransform * base,
-    GstBuffer * outbuf);
-
-/* GObject vmethod implementations */
-
-static void
-gst_plugin_template_base_init (gpointer klass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_set_details_simple (element_class,
-    "Plugin",
-    "Generic/Filter",
-    "FIXME:Generic Template Filter",
-    "AUTHOR_NAME AUTHOR_EMAIL");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_template));
-}
-
-/* initialize the plugin's class */
-static void
-gst_plugin_template_class_init (GstPluginTemplateClass * klass)
-{
-  GObjectClass *gobject_class;
-
-  gobject_class = (GObjectClass *) klass;
-  gobject_class->set_property = gst_plugin_template_set_property;
-  gobject_class->get_property = gst_plugin_template_get_property;
-
-  g_object_class_install_property (gobject_class, PROP_SILENT,
-    g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
-          FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
-
-  GST_BASE_TRANSFORM_CLASS (klass)->transform_ip =
-      GST_DEBUG_FUNCPTR (gst_plugin_template_transform_ip);
-}
-
-/* initialize the new element
- * initialize instance structure
- */
-static void
-gst_plugin_template_init (GstPluginTemplate *filter, GstPluginTemplateClass * klass)
-{
-  filter->silent = FALSE;
-}
-
-static void
-gst_plugin_template_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstPluginTemplate *filter = GST_PLUGIN_TEMPLATE (object);
-
-  switch (prop_id) {
-    case PROP_SILENT:
-      filter->silent = g_value_get_boolean (value);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_plugin_template_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstPluginTemplate *filter = GST_PLUGIN_TEMPLATE (object);
-
-  switch (prop_id) {
-    case PROP_SILENT:
-      g_value_set_boolean (value, filter->silent);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-/* GstBaseTransform vmethod implementations */
-
-/* this function does the actual processing
- */
-static GstFlowReturn
-gst_plugin_template_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
-{
-  GstPluginTemplate *filter = GST_PLUGIN_TEMPLATE (base);
-
-  if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (outbuf)))
-    gst_object_sync_values (G_OBJECT (filter), GST_BUFFER_TIMESTAMP (outbuf));
-
-  if (filter->silent == FALSE)
-    g_print ("I'm plugged, therefore I'm in.\n");
-  
-  /* FIXME: do something interesting here.  This simply copies the source
-   * to the destination. */
-
-  return GST_FLOW_OK;
-}
-
-
-/* entry point to initialize the plug-in
- * initialize the plug-in itself
- * register the element factories and other features
- */
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
-  /* initialize gst controller library */
-  gst_controller_init(NULL, NULL);
-
-  return gst_element_register (plugin, "plugin", GST_RANK_NONE,
-      GST_TYPE_PLUGIN_TEMPLATE);
-}
-
-/* gstreamer looks for this structure to register plugins
- *
- * FIXME:exchange the string 'Template plugin' with you plugin description
- */
-GST_PLUGIN_DEFINE (
-    GST_VERSION_MAJOR,
-    GST_VERSION_MINOR,
-    "plugin",
-    "Template plugin",
-    plugin_init,
-    VERSION,
-    "LGPL",
-    "GStreamer",
-    "http://gstreamer.net/"
-)
diff --git a/src/gsttransform.h b/src/gsttransform.h
deleted file mode 100644 (file)
index be9ce86..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* 
- * GStreamer
- * Copyright (C) 2006 Stefan Kost <ensonic@users.sf.net>
- * Copyright (C) YEAR AUTHOR_NAME AUTHOR_EMAIL
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifndef __GST_PLUGIN_TEMPLATE_H__
-#define __GST_PLUGIN_TEMPLATE_H__
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_PLUGIN_TEMPLATE \
-  (gst_plugin_template_get_type())
-#define GST_PLUGIN_TEMPLATE(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PLUGIN_TEMPLATE,GstPluginTemplate))
-#define GST_PLUGIN_TEMPLATE_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PLUGIN_TEMPLATE,GstPluginTemplateClass))
-#define GST_IS_PLUGIN_TEMPLATE(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PLUGIN_TEMPLATE))
-#define GST_IS_PLUGIN_TEMPLATE_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PLUGIN_TEMPLATE))
-
-typedef struct _GstPluginTemplate      GstPluginTemplate;
-typedef struct _GstPluginTemplateClass GstPluginTemplateClass;
-
-struct _GstPluginTemplate {
-  GstBaseTransform element;
-
-  gboolean silent;
-};
-
-struct _GstPluginTemplateClass {
-  GstBaseTransformClass parent_class;
-};
-
-GType gst_plugin_template_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_PLUGIN_TEMPLATE_H__ */
diff --git a/src/pixfmt.h b/src/pixfmt.h
new file mode 100644 (file)
index 0000000..9defee7
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_PIXFMT_H
+#define AVUTIL_PIXFMT_H
+
+/**
+ * @file
+ * pixel format definitions
+ *
+ * @warning This file has to be considered an internal but installed
+ * header, so it should not be directly included in your projects.
+ */
+
+// #include "libavutil/avconfig.h"
+
+/**
+ * Pixel format. Notes:
+ *
+ * PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA
+ * color is put together as:
+ *  (A << 24) | (R << 16) | (G << 8) | B
+ * This is stored as BGRA on little-endian CPU architectures and ARGB on
+ * big-endian CPUs.
+ *
+ * When the pixel format is palettized RGB (PIX_FMT_PAL8), the palettized
+ * image data is stored in AVFrame.data[0]. The palette is transported in
+ * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is
+ * formatted the same as in PIX_FMT_RGB32 described above (i.e., it is
+ * also endian-specific). Note also that the individual RGB palette
+ * components stored in AVFrame.data[1] should be in the range 0..255.
+ * This is important as many custom PAL8 video codecs that were designed
+ * to run on the IBM VGA graphics adapter use 6-bit palette components.
+ *
+ * For all the 8bit per pixel formats, an RGB32 palette is in data[1] like
+ * for pal8. This palette is filled in automatically by the function
+ * allocating the picture.
+ *
+ * Note, make sure that all newly added big endian formats have pix_fmt&1==1
+ *       and that all newly added little endian formats have pix_fmt&1==0
+ *       this allows simpler detection of big vs little endian.
+ */
+enum PixelFormat {
+    PIX_FMT_NONE= -1,
+    PIX_FMT_YUV420P,   ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
+    PIX_FMT_YUYV422,   ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
+    PIX_FMT_RGB24,     ///< packed RGB 8:8:8, 24bpp, RGBRGB...
+    PIX_FMT_BGR24,     ///< packed RGB 8:8:8, 24bpp, BGRBGR...
+    PIX_FMT_YUV422P,   ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
+    PIX_FMT_YUV444P,   ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
+    PIX_FMT_YUV410P,   ///< planar YUV 4:1:0,  9bpp, (1 Cr & Cb sample per 4x4 Y samples)
+    PIX_FMT_YUV411P,   ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
+    PIX_FMT_GRAY8,     ///<        Y        ,  8bpp
+    PIX_FMT_MONOWHITE, ///<        Y        ,  1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb
+    PIX_FMT_MONOBLACK, ///<        Y        ,  1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb
+    PIX_FMT_PAL8,      ///< 8 bit with PIX_FMT_RGB32 palette
+    PIX_FMT_YUVJ420P,  ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_range
+    PIX_FMT_YUVJ422P,  ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_range
+    PIX_FMT_YUVJ444P,  ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_range
+    PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing
+    PIX_FMT_XVMC_MPEG2_IDCT,
+    PIX_FMT_UYVY422,   ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
+    PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
+    PIX_FMT_BGR8,      ///< packed RGB 3:3:2,  8bpp, (msb)2B 3G 3R(lsb)
+    PIX_FMT_BGR4,      ///< packed RGB 1:2:1 bitstream,  4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits
+    PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1,  8bpp, (msb)1B 2G 1R(lsb)
+    PIX_FMT_RGB8,      ///< packed RGB 3:3:2,  8bpp, (msb)2R 3G 3B(lsb)
+    PIX_FMT_RGB4,      ///< packed RGB 1:2:1 bitstream,  4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits
+    PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1,  8bpp, (msb)1R 2G 1B(lsb)
+    PIX_FMT_NV12,      ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V)
+    PIX_FMT_NV21,      ///< as above, but U and V bytes are swapped
+
+    PIX_FMT_ARGB,      ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
+    PIX_FMT_RGBA,      ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
+    PIX_FMT_ABGR,      ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
+    PIX_FMT_BGRA,      ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
+
+    PIX_FMT_GRAY16BE,  ///<        Y        , 16bpp, big-endian
+    PIX_FMT_GRAY16LE,  ///<        Y        , 16bpp, little-endian
+    PIX_FMT_YUV440P,   ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
+    PIX_FMT_YUVJ440P,  ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of PIX_FMT_YUV440P and setting color_range
+    PIX_FMT_YUVA420P,  ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
+    PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    PIX_FMT_RGB48BE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian
+    PIX_FMT_RGB48LE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian
+
+    PIX_FMT_RGB565BE,  ///< packed RGB 5:6:5, 16bpp, (msb)   5R 6G 5B(lsb), big-endian
+    PIX_FMT_RGB565LE,  ///< packed RGB 5:6:5, 16bpp, (msb)   5R 6G 5B(lsb), little-endian
+    PIX_FMT_RGB555BE,  ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0
+    PIX_FMT_RGB555LE,  ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0
+
+    PIX_FMT_BGR565BE,  ///< packed BGR 5:6:5, 16bpp, (msb)   5B 6G 5R(lsb), big-endian
+    PIX_FMT_BGR565LE,  ///< packed BGR 5:6:5, 16bpp, (msb)   5B 6G 5R(lsb), little-endian
+    PIX_FMT_BGR555BE,  ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1
+    PIX_FMT_BGR555LE,  ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1
+
+    PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers
+    PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers
+    PIX_FMT_VAAPI_VLD,  ///< HW decoding through VA API, Picture.data[3] contains a vaapi_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+
+    PIX_FMT_YUV420P16LE,  ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    PIX_FMT_YUV420P16BE,  ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    PIX_FMT_YUV422P16LE,  ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    PIX_FMT_YUV422P16BE,  ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    PIX_FMT_YUV444P16LE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    PIX_FMT_YUV444P16BE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    PIX_FMT_VDPAU_MPEG4,  ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+    PIX_FMT_DXVA2_VLD,    ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer
+
+    PIX_FMT_RGB444LE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0
+    PIX_FMT_RGB444BE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0
+    PIX_FMT_BGR444LE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1
+    PIX_FMT_BGR444BE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1
+    PIX_FMT_Y400A,     ///< 8bit gray, 8bit alpha
+    PIX_FMT_BGR48BE,   ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big-endian
+    PIX_FMT_BGR48LE,   ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as little-endian
+    PIX_FMT_YUV420P9BE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    PIX_FMT_YUV420P9LE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    PIX_FMT_YUV420P10BE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    PIX_FMT_YUV420P10LE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    PIX_FMT_YUV422P10BE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    PIX_FMT_YUV422P10LE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    PIX_FMT_YUV444P9BE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    PIX_FMT_YUV444P9LE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    PIX_FMT_YUV444P10BE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    PIX_FMT_NB,        ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
+};
+
+#if AV_HAVE_BIGENDIAN
+#   define PIX_FMT_NE(be, le) PIX_FMT_##be
+#else
+#   define PIX_FMT_NE(be, le) PIX_FMT_##le
+#endif
+
+#define PIX_FMT_RGB32   PIX_FMT_NE(ARGB, BGRA)
+#define PIX_FMT_RGB32_1 PIX_FMT_NE(RGBA, ABGR)
+#define PIX_FMT_BGR32   PIX_FMT_NE(ABGR, RGBA)
+#define PIX_FMT_BGR32_1 PIX_FMT_NE(BGRA, ARGB)
+
+#define PIX_FMT_GRAY16 PIX_FMT_NE(GRAY16BE, GRAY16LE)
+#define PIX_FMT_RGB48  PIX_FMT_NE(RGB48BE,  RGB48LE)
+#define PIX_FMT_RGB565 PIX_FMT_NE(RGB565BE, RGB565LE)
+#define PIX_FMT_RGB555 PIX_FMT_NE(RGB555BE, RGB555LE)
+#define PIX_FMT_RGB444 PIX_FMT_NE(RGB444BE, RGB444LE)
+#define PIX_FMT_BGR48  PIX_FMT_NE(BGR48BE,  BGR48LE)
+#define PIX_FMT_BGR565 PIX_FMT_NE(BGR565BE, BGR565LE)
+#define PIX_FMT_BGR555 PIX_FMT_NE(BGR555BE, BGR555LE)
+#define PIX_FMT_BGR444 PIX_FMT_NE(BGR444BE, BGR444LE)
+
+#define PIX_FMT_YUV420P9  PIX_FMT_NE(YUV420P9BE , YUV420P9LE)
+#define PIX_FMT_YUV444P9  PIX_FMT_NE(YUV444P9BE , YUV444P9LE)
+#define PIX_FMT_YUV420P10 PIX_FMT_NE(YUV420P10BE, YUV420P10LE)
+#define PIX_FMT_YUV422P10 PIX_FMT_NE(YUV422P10BE, YUV422P10LE)
+#define PIX_FMT_YUV444P10 PIX_FMT_NE(YUV444P10BE, YUV444P10LE)
+#define PIX_FMT_YUV420P16 PIX_FMT_NE(YUV420P16BE, YUV420P16LE)
+#define PIX_FMT_YUV422P16 PIX_FMT_NE(YUV422P16BE, YUV422P16LE)
+#define PIX_FMT_YUV444P16 PIX_FMT_NE(YUV444P16BE, YUV444P16LE)
+
+#endif /* AVUTIL_PIXFMT_H */