wrapper/gstreamer plugin based on xcore

sample launch line:

gst-launch-1.0 xcamsrc sensor=0 capturemode=0x4000 memtype=4 \
  buffercount=8 fpsn=25 fpsd=1 width=1920 height=1080        \
  pixelformat=0 field=0 bytesperline=3840                    \
  ! video/x-raw, format=NV12, width=1920, height=1080,       \
    framerate=30/1 ! queue ! vaapiencode_h264 ! fakesink
diff --git a/Makefile.am b/Makefile.am
index bc424d2..387d7a7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,2 +1,2 @@
 
-SUBDIRS = xcore tests pkgconfig
+SUBDIRS = xcore wrapper tests pkgconfig 
diff --git a/configure.ac b/configure.ac
index e44e4e9..103c022 100644
--- a/configure.ac
+++ b/configure.ac
@@ -142,6 +142,8 @@
 
 AC_CONFIG_FILES([Makefile
                  xcore/Makefile
+                 wrapper/Makefile
+                 wrapper/gstreamer/Makefile
                  tests/Makefile
                  pkgconfig/Makefile
                  pkgconfig/xcam_core.pc
diff --git a/tests/test-xcamsrc-camera.sh b/tests/test-xcamsrc-camera.sh
new file mode 100755
index 0000000..c61fcb6
--- /dev/null
+++ b/tests/test-xcamsrc-camera.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+gst-launch-1.0 xcamsrc sensor=0 capturemode=0x4000 memtype=4 buffercount=8 fpsn=25 fpsd=1 width=1920 height=1080 pixelformat=0 field=0 bytesperline=3840 ! video/x-raw, format=NV12, width=1920, height=1080, framerate=30/1 ! queue ! vaapiencode_h264 ! fakesink
diff --git a/wrapper/Makefile.am b/wrapper/Makefile.am
new file mode 100644
index 0000000..875ebce
--- /dev/null
+++ b/wrapper/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = gstreamer
diff --git a/wrapper/gstreamer/Makefile.am b/wrapper/gstreamer/Makefile.am
new file mode 100644
index 0000000..a98eb77
--- /dev/null
+++ b/wrapper/gstreamer/Makefile.am
@@ -0,0 +1,69 @@
+lib_LTLIBRARIES = libstub.la
+
+GST_CFLAGS = -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/lib/glib-2.0/include
+
+PTHREAD_LDFLAGS = -pthread
+
+STUB_CXXFLAGS = -fPIC -std=c++11
+STUB_LIBS = \
+		   $(NULL)
+
+if HAVE_LIBDRM
+STUB_CXXFLAGS += $(LIBDRM_CFLAGS)
+STUB_LIBS += $(LIBDRM_LIBS)
+endif
+
+libstub_la_SOURCES = stub.cpp bufmap.cpp v4l2dev.cpp fmt.cpp
+
+libstub_la_CXXFLAGS = -I$(top_builddir)/xcore -I$(top_builddir)/xcore/base \
+			$(GST_CFLAGS) \
+			 $(STUB_CXXFLAGS)	\
+			 $(NULL)    
+libstub_la_LDFLAGS = \
+			-no-undefined	\
+			$(PTHREAD_LDFLAGS)  \
+			$(NULL)
+
+libstub_la_LIBADD = $(top_builddir)/xcore/libxcam_core.la \
+		       $(STUB_LIBS)  \
+		       -lpthread \
+		       $(NULL)
+
+noinst_HEADERS = stub.h bufmap.h v4l2dev.h fmt.h
+
+# Note: plugindir is set in configure
+plugindir="\$(libdir)/gstreamer-1.0"
+
+##############################################################################
+# TODO: change libgstxcamsrc.la to something else, e.g. libmysomething.la     #
+##############################################################################
+plugin_LTLIBRARIES = libgstxcamsrc.la
+
+##############################################################################
+# TODO: for the next set of variables, name the prefix if you named the .la, #
+#  e.g. libmysomething.la => libmysomething_la_SOURCES                       #
+#                            libmysomething_la_CFLAGS                        #
+#                            libmysomething_la_LIBADD                        #
+#                            libmysomething_la_LDFLAGS                       #
+##############################################################################
+
+# sources used to compile this plug-in
+libgstxcamsrc_la_SOURCES = gstxcambufferpool.c	\
+			   gstxcamsrc.c
+
+# compiler and linker flags used to compile this plugin, set in configure.ac
+libgstxcamsrc_la_CFLAGS = $(GST_CFLAGS)	\
+			  -I$(top_builddir)/xcore -I$(top_builddir)/xcore/base   \
+			  -I$(top_builddir)/wrapper/gstreamer
+
+libgstxcamsrc_la_LIBADD = $(GST_LIBS)	\
+			  $(top_builddir)/wrapper/gstreamer/libstub.la	\
+			  -lgstvideo-1.0    \
+			  -lgstallocators-1.0
+
+libgstxcamsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+libgstxcamsrc_la_LIBTOOLFLAGS = --tag=disable-static
+
+# headers we need but don't want installed
+noinst_HEADERS = gstxcambufferpool.h	\
+		 gstxcamsrc.h
diff --git a/wrapper/gstreamer/bufmap.cpp b/wrapper/gstreamer/bufmap.cpp
new file mode 100644
index 0000000..c4ab5af
--- /dev/null
+++ b/wrapper/gstreamer/bufmap.cpp
@@ -0,0 +1,38 @@
+/*
+ * bufmap.cpp - map V4l2Buffer to GstBuffer
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: John Ye <john.ye@intel.com>
+ */
+
+#include "bufmap.h"
+
+namespace XCam {
+
+SmartPtr<BufMap> BufMap::_instance(NULL);
+Mutex BufMap::_mutex;
+
+SmartPtr<BufMap>
+BufMap::instance()
+{
+    SmartLock lock(_mutex);
+    if (_instance.ptr())
+        return _instance;
+    _instance = new BufMap;
+    return _instance;
+}
+
+};
diff --git a/wrapper/gstreamer/bufmap.h b/wrapper/gstreamer/bufmap.h
new file mode 100644
index 0000000..5318383
--- /dev/null
+++ b/wrapper/gstreamer/bufmap.h
@@ -0,0 +1,72 @@
+/*
+ * bufmap.h - map V4l2Buffer to GstBuffer
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: John Ye <john.ye@intel.com>
+ */
+
+#ifndef __BUFMAP_H__
+#define __BUFMAP_H__
+
+#include <gst/gst.h>
+#include <map>
+#include "xcam_defs.h"
+#include "v4l2_buffer_proxy.h"
+#include "atomisp_device.h"
+
+namespace XCam {
+
+class BufMap {
+public:
+    static SmartPtr<BufMap> instance();
+
+    GstBuffer* gbuf(SmartPtr<V4l2Buffer> &buf) {
+        uint32_t vbuf_idx = buf->get_buf().index;
+        if (_v2g.find(vbuf_idx) == _v2g.end()) { //non-existing
+            return NULL;
+        }
+        return _v2g[vbuf_idx];
+    }
+    SmartPtr<V4l2Buffer> vbuf(GstBuffer* gbuf) {
+        if (_g2v.find(gbuf) == _g2v.end()) { //non-existing
+            return NULL;
+        }
+        return _g2v[gbuf];
+    }
+    void setmap(GstBuffer* gbuf, SmartPtr<V4l2Buffer>& buf) {
+        _g2v[gbuf] = buf;
+        _v2g[buf->get_buf().index] = gbuf;
+    }
+
+private:
+    XCAM_DEAD_COPY (BufMap);
+
+private:
+    BufMap()
+        : _g2v(std::map<GstBuffer*, SmartPtr<V4l2Buffer> >())
+        , _v2g(std::map<uint32_t, GstBuffer*>())
+    {};
+
+    static SmartPtr<BufMap> _instance;
+    static Mutex        _mutex;
+
+    std::map <GstBuffer*, SmartPtr<V4l2Buffer> > _g2v;
+    std::map <uint32_t, GstBuffer*> _v2g;
+};
+
+} //namespace
+
+#endif // __BUFMAP_H__
diff --git a/wrapper/gstreamer/fmt.cpp b/wrapper/gstreamer/fmt.cpp
new file mode 100644
index 0000000..7cde0b7
--- /dev/null
+++ b/wrapper/gstreamer/fmt.cpp
@@ -0,0 +1,62 @@
+/*
+ * fmt.cpp - deal with the supported formats
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: John Ye <john.ye@intel.com>
+ */
+
+#include "fmt.h"
+#include <linux/videodev2.h>
+
+#include <map>
+
+std::map<uint32_t, GstVideoFormat> fourcc2fmt = {
+
+    { V4L2_PIX_FMT_NV12, GST_VIDEO_FORMAT_NV12 },
+    { V4L2_PIX_FMT_NV21, GST_VIDEO_FORMAT_NV21 },
+    { V4L2_PIX_FMT_YVU410,  GST_VIDEO_FORMAT_YVU9 },
+    { V4L2_PIX_FMT_YUV410,  GST_VIDEO_FORMAT_YUV9 },
+    { V4L2_PIX_FMT_YUV420,  GST_VIDEO_FORMAT_I420 },
+    { V4L2_PIX_FMT_YUYV,    GST_VIDEO_FORMAT_YUY2 },
+    { V4L2_PIX_FMT_YVU420,  GST_VIDEO_FORMAT_YV12 },
+    { V4L2_PIX_FMT_UYVY,    GST_VIDEO_FORMAT_UYVY },
+    { V4L2_PIX_FMT_YUV411P, GST_VIDEO_FORMAT_Y41B },
+    { V4L2_PIX_FMT_YUV422P, GST_VIDEO_FORMAT_Y42B }
+#ifdef V4L2_PIX_FMT_YVYU
+    , { V4L2_PIX_FMT_YVYU, GST_VIDEO_FORMAT_YVYU}
+#endif
+
+};
+
+#define GST_V4L2_MAX_SIZE (1<<15)
+
+void caps_append(GstCaps *caps)
+{
+    GstStructure *structure;
+    std::map<uint32_t, GstVideoFormat>::iterator iter;
+
+    for (iter = fourcc2fmt.begin(); iter != fourcc2fmt.end(); iter++) {
+        structure = gst_structure_new ("video/x-raw",
+                                       "format", G_TYPE_STRING,
+                                       gst_video_format_to_string (iter->second),
+                                       NULL);
+        gst_structure_set (structure,
+                           "width", GST_TYPE_INT_RANGE, 1, GST_V4L2_MAX_SIZE,
+                           "height", GST_TYPE_INT_RANGE, 1, GST_V4L2_MAX_SIZE,
+                           "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 100, 1, NULL);
+        gst_caps_append_structure (caps, structure);
+    }
+}
diff --git a/wrapper/gstreamer/fmt.h b/wrapper/gstreamer/fmt.h
new file mode 100644
index 0000000..1892f7d
--- /dev/null
+++ b/wrapper/gstreamer/fmt.h
@@ -0,0 +1,37 @@
+/*
+ * fmt.h - deal with the supported formats
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: John Ye <john.ye@intel.com>
+ */
+
+#ifndef __FMT_H__
+#define __FMT_H__
+
+#include <gst/video/video-format.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void caps_append(GstCaps *caps);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __FMT_H__
diff --git a/wrapper/gstreamer/gstxcambufferpool.c b/wrapper/gstreamer/gstxcambufferpool.c
new file mode 100644
index 0000000..73a3535
--- /dev/null
+++ b/wrapper/gstreamer/gstxcambufferpool.c
@@ -0,0 +1,123 @@
+/*
+ * gstxcambufferpool.c - bufferpool
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: John Ye <john.ye@intel.com>
+ */
+
+/**
+ * SECTION:element-xcambufferpool
+ *
+ * FIXME:Describe xcambufferpool here.
+ *
+ * <refsect2>
+ * <title>Example launch line</title>
+ * |[
+ * gst-launch -v -m fakesrc ! xcambufferpool ! fakesink silent=TRUE
+ * ]|
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <stdint.h>
+
+#include <gst/gst.h>
+#include <gst/video/gstvideopool.h>
+
+#include "gstxcambufferpool.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_xcam_debug);
+#define GST_CAT_DEFAULT gst_xcam_debug
+
+static gboolean
+gst_xcambufferpool_start (GstBufferPool *bpool);
+
+static GstFlowReturn
+gst_xcambufferpool_acquire_buffer (GstBufferPool *bpool, GstBuffer **buffer, GstBufferPoolAcquireParams *params);
+
+static void
+gst_xcambufferpool_release_buffer (GstBufferPool *bpool, GstBuffer *buffer);
+
+#define gst_xcambufferpool_parent_class parent_class
+G_DEFINE_TYPE (Gstxcambufferpool, gst_xcambufferpool, GST_TYPE_BUFFER_POOL);
+
+static void
+gst_xcambufferpool_class_init (GstxcambufferpoolClass * klass)
+{
+    GObjectClass *object_class;
+    GstBufferPoolClass *bufferpool_class;
+
+    object_class = G_OBJECT_CLASS (klass);
+    bufferpool_class = GST_BUFFER_POOL_CLASS (klass);
+
+    bufferpool_class->start = gst_xcambufferpool_start;
+    bufferpool_class->acquire_buffer = gst_xcambufferpool_acquire_buffer;
+    bufferpool_class->release_buffer = gst_xcambufferpool_release_buffer;
+
+}
+
+static void
+gst_xcambufferpool_init (Gstxcambufferpool *pool)
+{
+}
+
+static gboolean
+gst_xcambufferpool_start (GstBufferPool *bpool)
+{
+    Gstxcambufferpool *pool = GST_XCAMBUFFERPOOL_CAST (bpool);
+
+    libxcam_start ();
+
+    pool->allocator = gst_dmabuf_allocator_new();
+    if (pool->allocator == NULL) {
+        printf ("gst_xcambufferpool_new::gst_dmabuf_allocator_new failed\n");
+        return NULL;
+    }
+
+    return TRUE;
+}
+
+static GstFlowReturn
+gst_xcambufferpool_acquire_buffer (GstBufferPool *bpool, GstBuffer **buffer, GstBufferPoolAcquireParams *params)
+{
+    return xcam_bufferpool_acquire_buffer (bpool, buffer, params);
+}
+
+static void
+gst_xcambufferpool_release_buffer (GstBufferPool *bpool, GstBuffer *buffer)
+{
+    return xcambufferpool_release_buffer (bpool, buffer);
+}
+
+
+GstBufferPool *
+gst_xcambufferpool_new (Gstxcamsrc *xcamsrc, GstCaps *caps)
+{
+    Gstxcambufferpool *pool;
+    GstStructure *s;
+
+    pool = (Gstxcambufferpool *)g_object_new (GST_TYPE_XCAMBUFFERPOOL, NULL);
+    s = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool));
+    gst_buffer_pool_config_set_params (s, caps, 1999, 32, 32);
+    gst_buffer_pool_config_add_option (s, GST_BUFFER_POOL_OPTION_VIDEO_META);
+    gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST (pool), s);
+
+    pool->src = xcamsrc;
+    return GST_BUFFER_POOL (pool);
+}
diff --git a/wrapper/gstreamer/gstxcambufferpool.h b/wrapper/gstreamer/gstxcambufferpool.h
new file mode 100644
index 0000000..2d9f748
--- /dev/null
+++ b/wrapper/gstreamer/gstxcambufferpool.h
@@ -0,0 +1,63 @@
+/*
+ * gstxcambufferpool.h - buffer pool
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: John Ye <john.ye@intel.com>
+ */
+
+#ifndef __GST_XCAMBUFFERPOOL_H__
+#define __GST_XCAMBUFFERPOOL_H__
+
+#include <gst/gst.h>
+#include "gstxcamsrc.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_XCAMBUFFERPOOL \
+  (gst_xcambufferpool_get_type())
+#define GST_XCAMBUFFERPOOL(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_XCAMBUFFERPOOL,Gstxcambufferpool))
+#define GST_XCAMBUFFERPOOL_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_XCAMBUFFERPOOL,GstxcambufferpoolClass))
+#define GST_IS_XCAMBUFFERPOOL(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_XCAMBUFFERPOOL))
+#define GST_IS_XCAMBUFFERPOOL_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_XCAMBUFFERPOOL))
+#define GST_XCAMBUFFERPOOL_CAST(obj)            ((Gstxcambufferpool *)(obj))
+#define GST_XCAMBUFFERPOOL_GET_CLASS (obj)  \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_XCAMBUFFERPOOL, GstxcambufferpoolClass))
+
+typedef struct _Gstxcambufferpool      Gstxcambufferpool;
+typedef struct _GstxcambufferpoolClass GstxcambufferpoolClass;
+typedef struct _GstxcamMeta        GstxcamMeta;
+
+struct _Gstxcambufferpool
+{
+    GstBufferPool parent;
+    GstAllocator *allocator;
+    Gstxcamsrc *src;
+};
+
+struct _GstxcambufferpoolClass
+{
+    GstBufferPoolClass parent_class;
+};
+
+GType gst_xcambufferpool_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_XCAMBUFFERPOOL_H__ */
diff --git a/wrapper/gstreamer/gstxcamsrc.c b/wrapper/gstreamer/gstxcamsrc.c
new file mode 100644
index 0000000..7cc9538
--- /dev/null
+++ b/wrapper/gstreamer/gstxcamsrc.c
@@ -0,0 +1,459 @@
+/*
+ * gstxcamsrc.c - gst xcamsrc plugin
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: John Ye <john.ye@intel.com>
+ */
+
+/**
+ * SECTION:element-xcamsrc
+ *
+ * FIXME:Describe xcamsrc here.
+ *
+ * <refsect2>
+ * <title>Example launch line</title>
+ * |[
+ * gst-launch-1.0 xcamsrc sensor=0 capturemode=0x4000 memtype=4 buffercount=8 fpsn=25 fpsd=1   \
+ *  width=1920 height=1080 pixelformat=0 field=0 bytesperline=3840 ! video/x-raw, format=NV12, \
+ *  width=1920, height=1080, framerate=30/1 ! queue ! vaapiencode_h264 ! fakesink
+ * ]|
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/video/video-format.h>
+#include <linux/videodev2.h>
+
+#include <stdio.h>
+#include <signal.h>
+
+#include "stub.h"
+#include "fmt.h"
+#include "gstxcamsrc.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_xcamsrc_debug);
+#define GST_CAT_DEFAULT gst_xcamsrc_debug
+
+#define DEFAULT_BLOCKSIZE   1843200
+#define DEFAULT_CAPTURE_DEVICE  "/dev/video3"
+
+#define DEFAULT_PROP_SENSOR     0
+#define DEFAULT_PROP_CAPTUREMODE    0
+#define DEFAULT_PROP_MEMTYPE        1
+#define DEFAULT_PROP_BUFFERCOUNT    6
+#define DEFAULT_PROP_FPSN       0
+#define DEFAULT_PROP_FPSD       0
+#define DEFAULT_PROP_WIDTH      0
+#define DEFAULT_PROP_HEIGHT     0
+#define DEFAULT_PROP_PIXELFORMAT    0
+#define DEFAULT_PROP_FIELD      0
+#define DEFAULT_PROP_BYTESPERLINE   0
+
+enum
+{
+    PROP_0,
+    PROP_SENSOR,
+    PROP_CAPTUREMODE,
+    PROP_MEMTYPE,
+    PROP_BUFFERCOUNT,
+    PROP_FPSN,
+    PROP_FPSD,
+    PROP_WIDTH,
+    PROP_HEIGHT,
+    PROP_PIXELFORMAT,
+    PROP_FIELD,
+    PROP_BYTESPERLINE
+};
+
+
+#define gst_xcamsrc_parent_class parent_class
+G_DEFINE_TYPE (Gstxcamsrc, gst_xcamsrc, GST_TYPE_PUSH_SRC);
+
+GstCaps *gst_xcamsrc_get_all_caps (void);
+
+static void gst_xcamsrc_finalize (GObject * object);
+static void gst_xcamsrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void gst_xcamsrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+static GstCaps* gst_xcamsrc_get_caps (GstBaseSrc *src, GstCaps *filter);
+static gboolean gst_xcamsrc_set_caps (GstBaseSrc *src, GstCaps *caps);
+static gboolean gst_xcamsrc_start (GstBaseSrc *src);
+static gboolean gst_xcamsrc_stop (GstBaseSrc * basesrc);
+static GstFlowReturn gst_xcamsrc_alloc (GstBaseSrc *src, guint64 offset, guint size, GstBuffer **buffer);
+static GstFlowReturn gst_xcamsrc_fill (GstPushSrc *src, GstBuffer *out);
+
+static void
+gst_xcamsrc_class_init (GstxcamsrcClass * klass)
+{
+    GObjectClass *gobject_class;
+    GstElementClass *element_class;
+    GstBaseSrcClass *basesrc_class;
+    GstPushSrcClass *pushsrc_class;
+
+    gobject_class = (GObjectClass *) klass;
+    element_class = (GstElementClass *) klass;
+    basesrc_class = GST_BASE_SRC_CLASS (klass);
+    pushsrc_class = GST_PUSH_SRC_CLASS (klass);
+
+    gobject_class->finalize = gst_xcamsrc_finalize;
+    gobject_class->set_property = gst_xcamsrc_set_property;
+    gobject_class->get_property = gst_xcamsrc_get_property;
+
+    g_object_class_install_property (gobject_class, PROP_SENSOR,
+                                     g_param_spec_int ("sensor", "Sensor id", "Sensor id",
+                                             0, G_MAXINT, DEFAULT_PROP_SENSOR, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+    g_object_class_install_property (gobject_class, PROP_CAPTUREMODE,
+                                     g_param_spec_int ("capturemode", "capture mode", "capture mode",
+                                             0, G_MAXINT, DEFAULT_PROP_CAPTUREMODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property (gobject_class, PROP_MEMTYPE,
+                                     g_param_spec_int ("memtype", "memory type", "memory type",
+                                             0, G_MAXINT, DEFAULT_PROP_MEMTYPE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property (gobject_class, PROP_BUFFERCOUNT,
+                                     g_param_spec_int ("buffercount", "buffer count", "buffer count",
+                                             0, G_MAXINT, DEFAULT_PROP_BUFFERCOUNT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property (gobject_class, PROP_FPSN,
+                                     g_param_spec_int ("fpsn", "fps n", "fps n",
+                                             0 , G_MAXINT, DEFAULT_PROP_FPSN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property (gobject_class, PROP_FPSD,
+                                     g_param_spec_int ("fpsd", "fps d", "fps d",
+                                             0, G_MAXINT, DEFAULT_PROP_FPSD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property (gobject_class, PROP_WIDTH,
+                                     g_param_spec_int ("width", "width", "width",
+                                             0, G_MAXINT, DEFAULT_PROP_WIDTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property (gobject_class, PROP_HEIGHT,
+                                     g_param_spec_int ("height", "height", "height",
+                                             0, G_MAXINT, DEFAULT_PROP_HEIGHT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property (gobject_class, PROP_PIXELFORMAT,
+                                     g_param_spec_int ("pixelformat", "pixelformat", "pixelformat",
+                                             0, G_MAXINT, DEFAULT_PROP_PIXELFORMAT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property (gobject_class, PROP_FIELD,
+                                     g_param_spec_int ("field", "field", "field",
+                                             0, G_MAXINT, DEFAULT_PROP_FIELD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property (gobject_class, PROP_BYTESPERLINE,
+                                     g_param_spec_int ("bytesperline", "bytes perline", "bytes perline",
+                                             0, G_MAXINT, DEFAULT_PROP_BYTESPERLINE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+    gst_element_class_set_details_simple(element_class,
+                                         "Libxcam Source",
+                                         "Source/Base",
+                                         "Capture camera video using xcam library",
+                                         "John Ye <john.ye@intel.com>");
+
+    gst_element_class_add_pad_template (element_class,
+                                        gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, gst_xcamsrc_get_all_caps ()));
+
+    basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_xcamsrc_get_caps);
+    basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_xcamsrc_set_caps);
+    basesrc_class->alloc = GST_DEBUG_FUNCPTR (gst_xcamsrc_alloc);
+
+    basesrc_class->start = GST_DEBUG_FUNCPTR (gst_xcamsrc_start);
+    basesrc_class->stop = GST_DEBUG_FUNCPTR (gst_xcamsrc_stop);
+    pushsrc_class->fill = GST_DEBUG_FUNCPTR (gst_xcamsrc_fill);
+}
+
+Gstxcamsrc *g_src;
+
+void handler (int sig)
+{
+    libxcam_stop ();
+    libxcam_close ();
+    exit (1);
+}
+
+static void
+gst_xcamsrc_init (Gstxcamsrc *xcamsrc)
+{
+    g_src = xcamsrc;
+    signal (SIGSEGV, handler);
+    libxcam_set_device_name (DEFAULT_CAPTURE_DEVICE);
+    gst_base_src_set_format (GST_BASE_SRC (xcamsrc), GST_FORMAT_TIME);
+    gst_base_src_set_live (GST_BASE_SRC (xcamsrc), TRUE);
+
+    xcamsrc->_fps_n = 0;
+    xcamsrc->_fps_d = 0;
+
+    gst_base_src_set_blocksize (GST_BASE_SRC (xcamsrc), DEFAULT_BLOCKSIZE);
+}
+
+static void
+gst_xcamsrc_finalize (GObject * object)
+{
+    Gstxcamsrc *src = GST_XCAMSRC (object);
+
+    libxcam_stop ();
+    libxcam_close ();
+
+    G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gboolean
+gst_xcamsrc_start (GstBaseSrc *src)
+{
+    Gstxcamsrc *xcamsrc = GST_XCAMSRC (src);
+
+    xcamsrc->offset = 0;
+    xcamsrc->ctrl_time = 0;
+
+    gst_object_sync_values (GST_OBJECT (src), xcamsrc->ctrl_time);
+
+    return TRUE;
+}
+
+static gboolean
+gst_xcamsrc_stop (GstBaseSrc * basesrc)
+{
+    Gstxcamsrc *src = GST_XCAMSRC_CAST (basesrc);
+    libxcam_stop ();
+    return TRUE;
+}
+
+static GstCaps*
+gst_xcamsrc_get_caps (GstBaseSrc *src, GstCaps *filter)
+{
+    Gstxcamsrc *xcamsrc = GST_XCAMSRC (src);
+    return gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (xcamsrc));
+}
+
+static gboolean
+gst_xcamsrc_set_caps (GstBaseSrc *src, GstCaps *caps)
+{
+    Gstxcamsrc *xcamsrc = GST_XCAMSRC (src);
+
+    guint32 block_size = DEFAULT_BLOCKSIZE;
+    /**
+     * set_sensor_id
+     * set_capture_mode
+     * set_mem_type
+     * set_buffer_count
+     * set_framerate
+     * open
+     * set_format
+     *
+     **/
+    libxcam_set_framerate (xcamsrc->_fps_n, xcamsrc->_fps_d);
+    libxcam_open ();
+    libxcam_set_format (xcamsrc->width, xcamsrc->height, xcamsrc->pixelformat, xcamsrc->field, xcamsrc->bytes_perline);
+
+    libxcam_get_blocksize (&block_size);
+    gst_base_src_set_blocksize (GST_BASE_SRC (xcamsrc), block_size);
+
+    xcamsrc->duration = gst_util_uint64_scale_int (GST_SECOND, xcamsrc->_fps_d, xcamsrc->_fps_n);
+    xcamsrc->pool = gst_xcambufferpool_new (src, caps);
+
+    gst_buffer_pool_set_active (GST_BUFFER_POOL_CAST (xcamsrc->pool), TRUE);
+    return TRUE;
+}
+
+
+
+static GstFlowReturn gst_xcamsrc_alloc (GstBaseSrc *src, guint64 offset, guint size, GstBuffer **buffer)
+{
+    GstFlowReturn ret;
+    Gstxcamsrc *xcamsrc = GST_XCAMSRC (src);
+
+    ret = gst_buffer_pool_acquire_buffer (xcamsrc->pool, buffer, NULL);
+    return ret;
+}
+
+// FIXME: timestamp is already set in xcore, isn't it?
+static GstFlowReturn
+gst_xcamsrc_fill (GstPushSrc *basesrc, GstBuffer *buf)
+{
+    Gstxcamsrc *src = GST_XCAMSRC_CAST (basesrc);
+    GstClockTime abs_time, base_time, timestamp, duration;
+    GstClock *clock;
+    GstClockTime delay;
+
+    timestamp = GST_BUFFER_TIMESTAMP (buf);
+    duration = src->duration;
+
+    GST_OBJECT_LOCK (src);
+    if ((clock = GST_ELEMENT_CLOCK (src))) {
+        base_time = GST_ELEMENT (src)->base_time;
+        gst_object_ref (clock);
+    } else {
+        base_time = GST_CLOCK_TIME_NONE;
+    }
+    GST_OBJECT_UNLOCK (src);
+
+    if (clock) {
+        abs_time = gst_clock_get_time (clock);
+        gst_object_unref (clock);
+    } else {
+        abs_time = GST_CLOCK_TIME_NONE;
+    }
+
+    if (timestamp != GST_CLOCK_TIME_NONE) {
+        struct timespec now;
+        GstClockTime gstnow;
+
+        clock_gettime (CLOCK_MONOTONIC, &now);
+        gstnow = GST_TIMESPEC_TO_TIME (now);
+
+        if (gstnow < timestamp && (timestamp - gstnow) > (10 * GST_SECOND)) {
+            GTimeVal now;
+
+            g_get_current_time (&now);
+            gstnow = GST_TIMEVAL_TO_TIME (now);
+        }
+        if (gstnow > timestamp) {
+            delay = gstnow - timestamp;
+        } else {
+            delay = 0;
+        }
+    } else {
+        if (GST_CLOCK_TIME_IS_VALID (duration))
+            delay = duration;
+        else
+            delay = 0;
+    }
+
+    GST_BUFFER_OFFSET (buf) = src->offset++;
+    GST_BUFFER_OFFSET_END (buf) = src->offset;
+
+    if (G_LIKELY (abs_time != GST_CLOCK_TIME_NONE)) {
+        timestamp = abs_time - base_time;
+
+        if (timestamp > delay)
+            timestamp -= delay;
+        else
+            timestamp = 0;
+    } else {
+        timestamp = GST_CLOCK_TIME_NONE;
+    }
+
+    if (GST_CLOCK_TIME_IS_VALID (duration)) {
+        src->ctrl_time += duration;
+    } else {
+        src->ctrl_time = timestamp;
+    }
+
+    gst_object_sync_values (GST_OBJECT (src), src->ctrl_time);
+
+    GST_BUFFER_TIMESTAMP (buf) = timestamp;
+    GST_BUFFER_DURATION (buf) = duration;
+
+    return GST_FLOW_OK;
+}
+
+static void gst_xcamsrc_get_property (GObject *object,
+                                      guint prop_id, GValue *value, GParamSpec *pspec)
+{
+    //TODO
+}
+
+// FIXME do we need to support all these properties?
+static void gst_xcamsrc_set_property (GObject *object,
+                                      guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+    Gstxcamsrc *src = GST_XCAMSRC (object);
+    int val;
+    enum v4l2_memory set_val;
+
+    switch (prop_id) {
+    case PROP_SENSOR:
+        libxcam_set_sensor_id (g_value_get_int (value));
+        break;
+    case PROP_CAPTUREMODE:
+        libxcam_set_capture_mode (g_value_get_int (value));
+        break;
+    case PROP_MEMTYPE:
+        val = g_value_get_int (value);
+        if (val == 1)
+            set_val = V4L2_MEMORY_MMAP;
+        else if (val == 2)
+            set_val = V4L2_MEMORY_USERPTR;
+        else if (val == 3)
+            set_val = V4L2_MEMORY_OVERLAY;
+        else
+            set_val = V4L2_MEMORY_DMABUF;
+        libxcam_set_mem_type (set_val);
+        break;
+    case PROP_BUFFERCOUNT:
+        src->buf_count = g_value_get_int (value);
+        libxcam_set_buffer_count (g_value_get_int (value));
+        break;
+    case PROP_FPSN:
+        src->_fps_n = g_value_get_int (value);
+        break;
+    case PROP_FPSD:
+        src->_fps_d = g_value_get_int (value);
+        break;
+    case PROP_WIDTH:
+        src->width = g_value_get_int (value);
+        break;
+    case PROP_HEIGHT:
+        src->height = g_value_get_int (value);
+        break;
+    case PROP_PIXELFORMAT:
+        // FIXME
+        src->pixelformat = V4L2_PIX_FMT_NV12;
+        break;
+    case PROP_FIELD:
+        // TODO
+        src->field = V4L2_FIELD_NONE;
+        break;
+    case PROP_BYTESPERLINE:
+        src->bytes_perline = g_value_get_int (value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+GstCaps *
+gst_xcamsrc_get_all_caps (void)
+{
+    static GstCaps *caps = NULL;
+    if (caps == NULL) {
+        caps = gst_caps_new_empty ();
+        caps_append(caps);
+    }
+    return gst_caps_ref (caps);
+}
+
+
+static gboolean
+xcamsrc_init (GstPlugin * xcamsrc)
+{
+    GST_DEBUG_CATEGORY_INIT (gst_xcamsrc_debug, "xcamsrc",
+                             0, "xcamsrc");
+
+    return gst_element_register (xcamsrc, "xcamsrc", GST_RANK_NONE,
+                                 GST_TYPE_XCAMSRC);
+}
+
+#ifndef PACKAGE
+#define PACKAGE "libxam"
+#endif
+
+GST_PLUGIN_DEFINE (
+    GST_VERSION_MAJOR,
+    GST_VERSION_MINOR,
+    xcamsrc,
+    "xcamsrc",
+    xcamsrc_init,
+    VERSION,
+    GST_LICENSE_UNKNOWN,
+    "Xcamsrc",
+    "https://github.com/01org/libxcam"
+)
diff --git a/wrapper/gstreamer/gstxcamsrc.h b/wrapper/gstreamer/gstxcamsrc.h
new file mode 100644
index 0000000..eadc3fc
--- /dev/null
+++ b/wrapper/gstreamer/gstxcamsrc.h
@@ -0,0 +1,79 @@
+/*
+ * gstxcamsrc.h - gst xcamsrc plugin
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: John Ye <john.ye@intel.com>
+ */
+
+#ifndef __GST_XCAMSRC_H__
+#define __GST_XCAMSRC_H__
+
+#include <gst/gst.h>
+#include <gst/base/gstpushsrc.h>
+#include <linux/videodev2.h>
+
+G_BEGIN_DECLS
+
+/* #defines don't like whitespacey bits */
+#define GST_TYPE_XCAMSRC \
+  (gst_xcamsrc_get_type())
+#define GST_XCAMSRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_XCAMSRC,Gstxcamsrc))
+#define GST_XCAMSRC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_XCAMSRC,GstxcamsrcClass))
+#define GST_IS_XCAMSRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_XCAMSRC))
+#define GST_IS_XCAMSRC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_XCAMSRC))
+#define GST_XCAMSRC_CAST(obj)   ((Gstxcamsrc *) obj)
+
+typedef struct _Gstxcamsrc      Gstxcamsrc;
+typedef struct _GstxcamsrcClass GstxcamsrcClass;
+
+struct _Gstxcamsrc
+{
+    GstPushSrc pushsrc;
+
+    GstBufferPool *pool;
+
+    guint buf_count;
+
+    guint _fps_n;
+    guint _fps_d;
+
+    guint width;
+    guint height;
+    guint pixelformat;
+    enum v4l2_field field;
+    guint bytes_perline;
+
+    GstClockTime duration;
+    GstClockTime ctrl_time;
+
+    guint64 offset;
+
+};
+
+struct _GstxcamsrcClass
+{
+    GstPushSrcClass parent_class;
+};
+
+GType gst_xcamsrc_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_XCAMSRC_H__ */
diff --git a/wrapper/gstreamer/stub.cpp b/wrapper/gstreamer/stub.cpp
new file mode 100644
index 0000000..2df2396
--- /dev/null
+++ b/wrapper/gstreamer/stub.cpp
@@ -0,0 +1,202 @@
+/*
+ * stub.cpp - stub utilities that implemented in CPP
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: John Ye <john.ye@intel.com>
+ */
+
+#include "stub.h"
+#include "bufmap.h"
+#include "v4l2dev.h"
+
+#include <stdio.h>
+
+using namespace XCam;
+
+int libxcam_set_device_name (const char *ch)
+{
+    V4l2Dev::_device_name = ch;
+    return 0;
+}
+
+int libxcam_set_sensor_id (int id)
+{
+    SmartPtr<V4l2Device> device = V4l2Dev::instance();
+    return (int) device->set_sensor_id (id);
+}
+int libxcam_set_capture_mode (uint32_t cap_mode)
+{
+    SmartPtr<V4l2Device> device = V4l2Dev::instance();
+    return (int) device->set_capture_mode (cap_mode);
+}
+int libxcam_set_mem_type (enum v4l2_memory mem_type)
+{
+    SmartPtr<V4l2Device> device = V4l2Dev::instance();
+    return (int) device->set_mem_type (mem_type);
+}
+int libxcam_set_buffer_count (uint32_t buf_count)
+{
+    SmartPtr<V4l2Device> device = V4l2Dev::instance();
+    return (int) device->set_buffer_count (buf_count);
+}
+int libxcam_set_framerate (uint32_t fps_n, uint32_t fps_d)
+{
+    SmartPtr<V4l2Device> device = V4l2Dev::instance();
+    return (int) device->set_framerate (fps_n, fps_d);
+}
+int libxcam_open ()
+{
+    SmartPtr<V4l2Device> device = V4l2Dev::instance();
+    return (int) device->open ();
+}
+int libxcam_close ()
+{
+    SmartPtr<V4l2Device> device = V4l2Dev::instance();
+    return (int) device->close ();
+}
+int libxcam_set_format (uint32_t width, uint32_t height, uint32_t pixelformat, enum v4l2_field field, uint32_t bytes_perline)
+{
+    SmartPtr<V4l2Device> device = V4l2Dev::instance();
+    return (int) device->set_format (width, height, pixelformat, field, bytes_perline);
+}
+int libxcam_get_blocksize (uint32_t *blocksize)
+{
+    SmartPtr<V4l2Device> device = V4l2Dev::instance();
+    struct v4l2_format format;
+    int ret ;
+    ret = (int) device->get_format (format);
+    *blocksize = format.fmt.pix.sizeimage;
+    return ret;
+}
+int libxcam_start ()
+{
+    SmartPtr<V4l2Device> device = V4l2Dev::instance();
+    struct v4l2_format format;
+    device->get_format (format);
+#if HAVE_LIBDRM
+    AtomispDevice *atom_isp_dev = (AtomispDevice *) device.ptr();
+    SmartPtr<DrmDisplay> drmdisp = DrmDisplay::instance();
+    struct v4l2_rect rect = {0, 0, (int)format.fmt.pix.width, (int)format.fmt.pix.height};
+    drmdisp->drm_init (&format.fmt.pix,
+                       "i915",
+                       9,
+                       3,
+                       1920,
+                       1080,
+                       format.fmt.pix.pixelformat,
+                       device->get_capture_buf_type(),
+                       &rect);
+    atom_isp_dev->set_drm_display (drmdisp);
+#endif
+    return (int) device->start();
+}
+
+int libxcam_stop ()
+{
+    SmartPtr<V4l2Device> device = V4l2Dev::instance();
+    return (int) device->stop();
+}
+
+int libxcam_dequeue_buffer (SmartPtr<V4l2Buffer> &buf)
+{
+    SmartPtr<V4l2Device> device = V4l2Dev::instance();
+    int ret;
+
+    ret = device->poll_event (5000);
+    if (ret < 0) {
+        printf ("device(%s) poll event failed\n", device->get_device_name());
+        return -1;
+    } else if (ret == 0) {
+        printf ("device(%s) poll event did not detect events\n", device->get_device_name());
+        return -1;
+    }
+
+    ret = device->dequeue_buffer (buf);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        printf ("device(%s) dequeue buffer failed\n", device->get_device_name() );
+        return ret;
+    }
+
+    return (int) XCAM_RETURN_NO_ERROR;
+}
+int libxcam_enqueue_buffer (SmartPtr<V4l2Buffer> &buf)
+{
+    SmartPtr<V4l2Device> device = V4l2Dev::instance();
+    int ret;
+
+    ret = device->queue_buffer (buf);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        printf ("device(%s) queue buffer failed\n", device->get_device_name());
+        return ret;
+    }
+    return (int) XCAM_RETURN_NO_ERROR;
+}
+
+// FIXME remove the following 4 functions
+GstBuffer* bufmap_2gbuf(SmartPtr<V4l2Buffer> &buf)
+{
+    SmartPtr<BufMap> bufmap = BufMap::instance();
+    return bufmap->gbuf(buf);
+}
+
+SmartPtr<V4l2Buffer> bufmap_2vbuf(GstBuffer* gbuf)
+{
+    SmartPtr<BufMap> bufmap = BufMap::instance();
+    return bufmap->vbuf(gbuf);
+}
+
+void bufmap_setmap(GstBuffer* gbuf, SmartPtr<V4l2Buffer> buf)
+{
+    SmartPtr<BufMap> bufmap = BufMap::instance();
+    bufmap->setmap(gbuf, buf);
+}
+
+GstFlowReturn
+xcam_bufferpool_acquire_buffer (GstBufferPool *bpool, GstBuffer **buffer, GstBufferPoolAcquireParams *params)
+{
+    GstBuffer *gbuf = NULL;
+    Gstxcambufferpool *pool = GST_XCAMBUFFERPOOL_CAST (bpool);
+    Gstxcamsrc *xcamsrc = pool->src;
+
+    SmartPtr<V4l2Buffer> buf;
+    libxcam_dequeue_buffer (buf);
+
+    struct v4l2_buffer vbuf = buf->get_buf();
+
+    gbuf = bufmap_2gbuf(buf);
+    if (!gbuf) {
+        gbuf = gst_buffer_new();
+        GST_BUFFER (gbuf)->pool = (GstBufferPool*) pool;
+
+        gst_buffer_append_memory (gbuf,
+                                  gst_dmabuf_allocator_alloc (pool->allocator, vbuf.m.fd, vbuf.length));
+        bufmap_setmap(gbuf, buf);
+    }
+
+    GST_BUFFER_TIMESTAMP (gbuf) = GST_TIMEVAL_TO_TIME (vbuf.timestamp);
+    *buffer = gbuf;
+
+    return GST_FLOW_OK;
+}
+
+void
+xcambufferpool_release_buffer (GstBufferPool *bpool, GstBuffer *gbuf)
+{
+    SmartPtr<V4l2Buffer> buf = bufmap_2vbuf(gbuf);
+    libxcam_enqueue_buffer (buf);
+}
+
+
diff --git a/wrapper/gstreamer/stub.h b/wrapper/gstreamer/stub.h
new file mode 100644
index 0000000..aee0ec0
--- /dev/null
+++ b/wrapper/gstreamer/stub.h
@@ -0,0 +1,61 @@
+/*
+ * stub.h - stub utilities that implemented in CPP
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: John Ye <john.ye@intel.com>
+ */
+
+#ifndef __STUB_H__
+#define __STUB_H__
+
+#include <unistd.h>
+#include <stdint.h>
+#include <linux/videodev2.h>
+
+#include <gst/gst.h>
+#include <gst/allocators/allocators.h>
+#include <gst/video/gstvideopool.h>
+#include "gstxcambufferpool.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum v4l2_memory;
+enum v4l2_field;
+struct v4l2_format;
+struct v4l2_buffer;
+
+int libxcam_set_device_name (const char* ch);
+int libxcam_set_sensor_id (int id);
+int libxcam_set_capture_mode (uint32_t cap_mode);
+int libxcam_set_mem_type (enum v4l2_memory mem_type);
+int libxcam_set_buffer_count (uint32_t buf_count);
+int libxcam_set_framerate (uint32_t fps_n, uint32_t fps_d);
+int libxcam_open ();
+int libxcam_close ();
+int libxcam_set_format (uint32_t width, uint32_t height, uint32_t pixelformat, enum v4l2_field field, uint32_t bytes_perline);
+int libxcam_get_blocksize (uint32_t *blocksize);
+int libxcam_start ();
+int libxcam_stop ();
+GstFlowReturn xcam_bufferpool_acquire_buffer (GstBufferPool *bpool, GstBuffer **buffer, GstBufferPoolAcquireParams *params);
+void xcambufferpool_release_buffer (GstBufferPool *bpool, GstBuffer *buffer);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  //__STUB_H__
diff --git a/wrapper/gstreamer/v4l2dev.cpp b/wrapper/gstreamer/v4l2dev.cpp
new file mode 100644
index 0000000..5381887
--- /dev/null
+++ b/wrapper/gstreamer/v4l2dev.cpp
@@ -0,0 +1,40 @@
+/*
+ * v4l2dev.cpp - wrapper of V4l2Device
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: John Ye <john.ye@intel.com>
+ */
+
+#include "v4l2dev.h"
+#include "atomisp_device.h"
+
+namespace XCam {
+
+SmartPtr<V4l2Device> V4l2Dev::_device (NULL);
+Mutex V4l2Dev::_mutex;
+const char* V4l2Dev::_device_name (NULL);
+
+SmartPtr<V4l2Device>
+V4l2Dev::instance ()
+{
+    SmartLock lock(_mutex);
+    if (_device.ptr())
+        return _device;
+    _device = new AtomispDevice (_device_name);
+    return _device;
+}
+
+};
diff --git a/wrapper/gstreamer/v4l2dev.h b/wrapper/gstreamer/v4l2dev.h
new file mode 100644
index 0000000..46a2950
--- /dev/null
+++ b/wrapper/gstreamer/v4l2dev.h
@@ -0,0 +1,45 @@
+/*
+ * v4l2dev.h - wrapper of V4l2Device
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: John Ye <john.ye@intel.com>
+ */
+
+#ifndef __V4L2DEV_H__
+#define __V4L2DEV_H__
+
+#include <stdint.h>
+#include "xcam_defs.h"
+#include "xcam_mutex.h"
+#include "v4l2_buffer_proxy.h"
+#include "v4l2_device.h"
+
+namespace XCam {
+
+class V4l2Dev {
+public:
+    static SmartPtr<V4l2Device> instance();
+    static const char*      _device_name;
+
+private:
+    V4l2Dev ();
+    static SmartPtr<V4l2Device> _device;
+    static Mutex        _mutex;
+};
+
+};
+
+#endif  //__V4L2DEV_H__